TITLE LC Interrupt trap routine NAME LCINT INCLUDE DOS.MAC ; BE SURE TO INCLUDE THE CORRECT ; DOS.MAC!! ;**************************************************************************** ; ; This is the heart of a C driven interrupt handler. This file was used to ; write a critical error handler that remained resident. (It replaced the ; "Abort, Retry, Ignore" prompt with a window.) This file can be adapted to ; any interrupt and any C routine with a little work. THIS HAS BEEN USED ONLY ; IN THE S MODEL. ; ;**************************************************************************** DOS_INT EQU 24H ; int to be replaced WRITE_INT EQU 25H ; DOS write int vector READ_INT EQU 35H ; DOS read int vector XREG STRUC REG_AX DW ? ; general purpose registers REG_BX DW ? REG_CX DW ? REG_DX DW ? REG_SI DW ? REG_DI DW ? XREG ENDS SREGS STRUC REG_ES DW ? ; segment registers REG_CS DW ? REG_SS DW ? REG_DS DW ? SREGS ENDS DSEG INT_REGS XREG <> ; saved regs. at int time INT_SEGREGS SREGS <> ; saved seg. regs. EXTRN _TOP:WORD ; declared by C.ASM -- points ; to top of stack ENDDS EXTRN INTTIME:NEAR ; your int routine goes here! PSEG ;; ; interrupt time data storage ;; C_ENVIRONMENT_DS DW ? ; filled by int init, used... C_ENVIRONMENT_ES DW ? ; ...to recreate C environment C_ENVIRONMENT_SS DW ? C_ENVIRONMENT_SP DW ? INT_TIME_ES DW ? INT_TIME_DS DW ? ; temp save of DS at int time INT_TIME_SI DW ? ; temp save of SI at int time INT_TIME_BP DW ? ; added to account for no BP or SP... INT_TIME_SP DW ? ; ...in above structures RETURN_VALUE DW ? ; return value from C service routine DOS_SERVICE DD ? ; address of DOS Service routine INT_TWOONE DD ? ; old INT 21 vector INT_IN_PROGRESS DB ? ; interrupt in progress flag -- not ; used here 'cause int 24H cannot be ; recursive! ;;************************************************************************** ; name LC_SERVICE_INT ; ; description Entered at (software) interrupt time, this routine ; restores the C enviroment and processes the interrupt ; trapping all references to the quad file ;; IF LPROG LC_SERVICE_INT PROC FAR ELSE LC_SERVICE_INT PROC NEAR ENDIF MOV CS:INT_IN_PROGRESS,1 ; clear int in progress flag MOV CS:INT_TIME_ES,ES ; save ES so it can be overwritten MOV CS:INT_TIME_DS,DS ; save DS so it can be overwritten MOV CS:INT_TIME_SI,SI ; save SI so it can be overwritten MOV CS:INT_TIME_BP,BP ; save BP as structs do not have it MOV CS:INT_TIME_SP,SP ; save SP as structs do not have it MOV DS,CS:C_ENVIRONMENT_DS ; set up C enviroment MOV SI,OFFSET INT_REGS ; point to input regs struct MOV DS:[SI].REG_AX,AX ; save general purpose regs MOV DS:[SI].REG_BX,BX MOV DS:[SI].REG_CX,CX MOV DS:[SI].REG_DX,DX MOV DS:[SI].REG_DI,DI MOV AX,CS:INT_TIME_SI ; SI has been overwritten MOV DS:[SI].REG_SI,AX MOV SI,OFFSET INT_SEGREGS ; point to input segment regs struct MOV AX,CS:INT_TIME_ES ; ES has been overwritten MOV DS:[SI].REG_ES,AX MOV DS:[SI].REG_SS,SS MOV AX,CS:INT_TIME_DS ; DS has been overwritten MOV DS:[SI].REG_DS,AX MOV ES,CS:C_ENVIRONMENT_ES ; complete C environment MOV SS,CS:C_ENVIRONMENT_SS MOV SP,CS:C_ENVIRONMENT_SP CALL INTTIME ; call the C routine MOV CS:RETURN_VALUE,AX ; save return value XOR AX,AX MOV SI,OFFSET INT_REGS ; point to input regs struct MOV AX,DS:[SI].REG_SI ; SI needs to be saved while used MOV CS:INT_TIME_SI,AX MOV AX,DS:[SI].REG_AX ; restore general purpose regs MOV BX,DS:[SI].REG_BX MOV CX,DS:[SI].REG_CX MOV DX,DS:[SI].REG_DX MOV DI,DS:[SI].REG_DI MOV SI,OFFSET INT_SEGREGS ; point to input segment regs struct MOV ES,DS:[SI].REG_DS ; DS needs to be saved while used MOV CS:INT_TIME_DS,ES MOV ES,DS:[SI].REG_ES MOV SS,DS:[SI].REG_SS MOV SI,CS:INT_TIME_SI ; restore pointing registers MOV DS,CS:INT_TIME_DS MOV BP,CS:INT_TIME_BP ; special BP restore MOV SP,CS:INT_TIME_SP ; special SP restore MOV CS:INT_IN_PROGRESS,0 ; clear int in progress flag MOV AX,CS:RETURN_VALUE ; move the return value IRET ; return from interrupt LC_SERVICE_INT ENDP ;**************************************************************************** ; description set up the LC interrupt routines ; ; INT_INIT -- Hooks into the specified int. ; INT_TERM -- Unhooks (restores) the specified int. ; ; NOTE: INT_INIT must be called be int processing can begin...it saves the ; current C environment for use at interrupt time. ;; PUBLIC INT_INIT IF LPROG INT_INIT PROC FAR ELSE INT_INIT PROC NEAR ENDIF PUSH DS ; save changed seg regs PUSH ES MOV CS:C_ENVIRONMENT_DS,DS ; save C environment for int time MOV CS:C_ENVIRONMENT_ES,ES MOV CS:C_ENVIRONMENT_SS,SS MOV AX,_TOP ; determine int time SP SUB AX,400H ; gives 1024 byte stack MOV CS:C_ENVIRONMENT_SP,AX MOV AH,READ_INT ; read int vector function MOV AL,DOS_INT ; specify DOS service vector INT 21H MOV WORD PTR CS:DOS_SERVICE+2,ES ; save current vector MOV WORD PTR CS:DOS_SERVICE,BX LEA DX,LC_SERVICE_INT ; Use DOS to set new int address PUSH CS POP DS MOV AH,WRITE_INT MOV AL,DOS_INT INT 21H POP ES ; restore changed seg regs POP DS RET INT_INIT ENDP ;********************* INT_TERM -- kill ints. ******************************* PUBLIC INT_TERM IF LPROG INT_TERM PROC FAR ELSE INT_TERM PROC NEAR ENDIF PUSH DS ; DS gets changed MOV DS,WORD PTR CS:DOS_SERVICE+2 ; Restore previous DOS service vector MOV DX,WORD PTR CS:DOS_SERVICE MOV AH,WRITE_INT MOV AL,DOS_INT INT 21H POP DS ; restore DS RET INT_TERM ENDP ENDPS END