Path: utzoo!attcan!uunet!tut.cis.ohio-state.edu!pt.cs.cmu.edu!dsl.pitt.edu!pitt!willett!ForthNet From: ForthNet@willett.pgh.pa.us (ForthNet articles from GEnie) Newsgroups: comp.lang.forth Subject: LMI Forth(s) Message-ID: <1880.UUL1.3#5129@willett.pgh.pa.us> Date: 21 Oct 90 01:58:24 GMT Organization: String, Scotch tape, and Paperclips. (in Pgh, PA) Lines: 106 To: ALL Refer#: NONE From: RAY DUNCAN Read: (N/A) Subj: 80386 UR/F INTERRUPTS Status: PUBLIC MESSAGE Several of our users have asked me for an example of an interrupt handler for 80386 UR/FORTH 1.15 that could execute high level code during an interrupt service. Example code is provided below. This code can be downloaded from the LMI BBS conference #4 in the file URTIM386.ZIP. *** CAVEAT PROGRAMMER *** If virtual memory is enabled, and a page fault occurs during an interrupt service, the only clue might be a hard reset of the machine. You may find it easier to disable the VMM if you are going to write your own interrupt handlers. Also beware of slow high level code executed at interrupt time; the effect of nested interrupts can be unpredictable. *** CAVEAT PROGRAMMER *** Take extreme care when executing high level code during an interrupt; many UR/FORTH video, graphics, and compiler words are NOT reentrant. ASM FORTH DEFINITIONS HEX 01C CONSTANT INT_# \ timer tick interrupt 2VARIABLE PREV_PVEC \ prev prot mode int vector VARIABLE PREV_RVEC \ prev real mode int vector 2VARIABLE OLDSTACK \ store SS, ESP at ISR entry VARIABLE HANDLER \ CFA of high level handler CREATE DSTACK 400 ALLOT \ data stack for ISR CREATE RSTACK 400 ALLOT \ return stack for ISR 0. PREV_PVEC 2! 0 PREV_RVEC ! 0 HANDLER ! \ --- ; this routine terminates execution of threaded code, \ restores registers to their state at the ISR entry, and \ executes the interrupt return. CODE INTRET SS, OLDSTACK MOV \ restore old stack ESP, OLDSTACK 4 + MOV GS POP FS POP ES POP DS POP \ restore registers EBP POP EDI POP ESI POP EDX POP ECX POP EBX POP EAX POP IRETD END-CODE \ 32-bit int return \ This is the low-level or machine interrupt handler. \ We service the interrupt in protected mode regardless of \ the mode that the interrupt occurred in. PROC INTSVC EAX PUSH EBX PUSH ECX PUSH EDX PUSH \ save ESI PUSH EDI PUSH EBP PUSH \ registers DS PUSH ES PUSH FS PUSH GS PUSH EAX, # DS0 MOV \ PharLap data selector DS, AX MOV ES, AX MOV \ (always the same) OLDSTACK , SS MOV \ save old stack ptr OLDSTACK 4 + , ESP MOV SS, AX MOV \ set up new stacks ESP, # DSTACK 400 + MOV EBP, # RSTACK 400 + MOV CLD \ clear Direction flag EAX, HANDLER MOV EAX, EAX OR ' INTRET JZ EAX JMP END-PROC \ branch to handler \ This word captures the real mode and protected mode vectors \ so that the interrupt will always be serviced in prot mode. \ --- ; initialize interrupt vector : TRAP PREV_PVEC D@ OR 0= IF INT_# regECX ! \ get prev prot mode vec 2502 regEAX ! 21 INT86 regES @ regEBX @ PREV_PVEC D! INT_# regECX ! \ get prev real mode vec 2503 regEAX ! 21 INT86 regEBX @ PREV_RVEC ! THEN XS0 regDS ! INTSVC regEDX ! \ set protected INT_# regECX ! 2506 regEAX ! \ mode handler 21 INT86 ; \ This word releases the interrupt vectors. \ In general, you ALWAYS need to restore the original interrupt \ vector before your application exits. In this particular \ case, however, UR/FORTH automatically restores the timer tick \ vector when it terminates (because the multitasker uses it) \ so execution of UNTRAP isn't strictly necessary. \ --- ; release interrupt vector : UNTRAP PREV_RVEC @ regEBX ! \ prev real mode vector PREV_PVEC D@ \ prev protected mode vector regEDX ! regDS ! INT_# regECX ! 2507 regEAX ! 21 INT86 ; \ restore old handler DECIMAL \ EXAMPLE of a high level interrupt handler. It increments TEST-VAR \ each time a timer tick occurs, then performs an interrupt \ return. Load this code, then enter: TEST-VAR @ . \ repeatedly to watch variable incrementing. VARIABLE TEST-VAR : TEST-HANDLER 1 TEST-VAR +! INTRET ; ' TEST-HANDLER HANDLER ! \ install the high-level handler TRAP \ capture the timer tick interrupt NET/Mail : LMI Forth Board, Los Angeles, CA (213) 306-3530 ----- This message came from GEnie via willett through a semi-automated process. Report problems to: dwp@willett.pgh.pa.us or uunet!willett!dwp