home *** CD-ROM | disk | FTP | other *** search
- ; *********** EVENTCHN.ASM *******************************************
-
- .model medium, basic
- .data
-
- IntNumber dw -1 ; the requested INT vector
-
- .code
-
- PreviousVector LABEL DWORD ; placed in the code segment to...
- PVOffset dw -1 ; ...facilitate chaining
- PVSegment dw 77 ; a signature to avoid multi-installs
-
- EXTRN SetUEvent:FAR ; this is in the BC runtime
- EXTRN B_OnExit:FAR ; ditto
-
- InstallHandler PROC intnum ; intnum passed BYVAL
-
- ; This takes care of wrapping our metaphorical tentacles around the
- ; PC. We take over the interrupt vector, saving the previous contents
- ; so that we can put things back the way they were when we exit.
-
- cmp PVSegment, 77 ; insure this is first time
- jne iherr
- mov ax, intnum ; get the requested vector
- cmp ax, 255
- ja iherr ; vector too high...
- mov dx, offset RemoveInt
- push cs ; push far address of RemoveInt
- push dx ; to register the exit routine
- call B_OnExit ; so that we don't hang machine
- or ax, ax ; registered OK?
- jz iherr ; error: too many registered routines
- mov ax, intnum ; _onexit corrupted this
- mov IntNumber, ax ; save for removal routine
- mov ah, 35H ; use DOS to get current...
- INT 21H ; ...holder of the vector
- mov PVSegment, es ; save for chaining, removal
- mov PVOffset, bx
- push ds ; hold DS a moment
- mov bx, cs ; transfer CS to DS
- mov ds, bx
- mov dx, offset IntHandler; get address of our MASM handler
- mov ah, 25H ; tell DOS we're taking this vector
- INT 21H ; grab the vector, Victor
- pop ds ; restore DS
- xor ax, ax ; return zero: all OK
- @@: ret
-
- iherr: mov ax, -1 ; couldn't install: return TRUE
- jmp @b
-
- InstallHandler ENDP
-
- RemoveInt PROC uses ds
-
- ; RemoveInt will undo the InstallHandler by restoring the PC to the
- ; state it was in before we came along. If we don't, the interrupt
- ; vector will point into volatile space when the program terminates.
- ;
- ; Because we "register" this routine with B_OnExit, restoring the
- ; machine state becomes a part of BASIC's normal shutdown process...
- ; we don't need to call this routine explicitly.
-
- mov ax, IntNumber ; vector we're using
- mov ah, 25H ; SET VECTOR call
- lds dx, PreviousVector ; saved original vector
- INT 21H ; restore it
- mov PVSegment, 77 ; only needed for .QLB purposes
- ret
-
- RemoveInt ENDP
-
- IntHandler PROC FAR ;note that we don't just say "PROC" here
-
- ; This routine notifies the BASIC runtime that an event has occurred.
- ; You MUST save and restore any registers you use. In this example
- ; we're overly pessimistic, assuming that BC will destroy everything.
-
- assume cs:@code, ds:nothing, es:nothing, ss:nothing
-
- push ds ; only save the registers you really need to
- push di
- push es
- push si
- push dx
- push cx
- push bx
- push ax
- call SetUEvent ; notify BC/QB that the event occurred
- pop ax
- pop bx
- pop cx
- pop dx
- pop si
- pop es
- pop di
- pop ds
- jmp [PreviousVector]
-
- IntHandler ENDP
-
- END
-
-