; LarkMonIntML.dsm ; Interrupt assistance ; L. Stewart, September 14, 1982 10:51 PM ; L. Stewart, October 26, 1982 1:51 PM ; INT 5 will be CallDebugger ; L. Stewart, November 8, 1982 ; delete DOXXI, add osstatic globals ; November 10, 1982 3:50 PM, leave 3FC - 3FF empty ; February 7, 1983 8:12 PM, new monitor ; February 23, 1983 10:31 AM, incorporate wdc ; February 25, 1983 3:47 PM, DoEOI, check for badint $INCLUDE(Lark.d) $INCLUDE(8086LIB.D) ; interrupt data SLRType EQU 070H ; IR0 SLTType EQU 071H EncType EQU 072H SIOType EQU 073H AlAType EQU 074H AlBType EQU 075H AlCType EQU 076H AlDType EQU 077H ei70ip EQU 01C0H ei70cs EQU 01C2H ei71ip EQU 01C4H ei71cs EQU 01C6H ei72ip EQU 01C8H ei72cs EQU 01CAH ei73ip EQU 01CCH ei73cs EQU 01CEH ei74ip EQU 01D0H ei74cs EQU 01D2H ei75ip EQU 01D4H ei75cs EQU 01D6H ei76ip EQU 01D8H ei76cs EQU 01DAH ei77ip EQU 01DCH ei77cs EQU 01DEH C_CODE SEGMENT C_DATA SEGMENT EXTRN _stackLimit:WORD lenStatics EQU 267 intpv LABEL WORD _SLRInt DW ? _SLTInt DW ? _EncInt DW ? _SIOInt DW ? _AlAInt DW ? _AlBInt DW ? _AlCInt DW ? _AlDInt DW ? _wdc DW 0 _OStack DW 0 _IStack DW 256 DUP (?) _ISTop DW 0 C_DATA ENDS EXTRN _CallDebugger:NEAR EXTRN _Call0:NEAR EXTRN _Zero:NEAR ASSUME CS:C_CODE, DS:C_DATA ; Enable interrupts _IntOn PROC NEAR MOV _wdc,0 STI RET _IntOn ENDP ; Disable interrupts _IntOff PROC NEAR MOV _wdc,8000 CLI RET _IntOff ENDP ; Analog D (IR7) AlDInt: PUSH BX MOV BX,_AlDInt JMP _intcom ; Analog C (IR6) AlCInt: PUSH BX MOV BX,_AlCInt JMP _intcom ; Analog B (IR5) AlBInt: PUSH BX MOV BX,_AlBInt JMP _intcom ; Analog A (IR4) AlAInt: PUSH BX MOV BX,_AlAInt JMP _intcom ; 8274 (IR3) SIOInt: PUSH BX MOV BX,_SIOInt JMP _intcom ; Encryption (IR2) EncInt: PUSH BX MOV BX,_EncInt JMP _intcom ; SLT (IR1) SLTInt: PUSH BX MOV BX,_SLTInt JMP _intcom ; SLR (IR0) SLRInt: PUSH BX MOV BX,_SLRInt JMP _intcom CALL _intcom ; for symbol! never executed _intcom: PUSH AX PUSH CX PUSH DX PUSH SI PUSH DI PUSH BP ; check ISR MOV AL,00BH OUT intctl,AL IN AL,intctl OR AL,AL JNZ hndokb MOV BX,0800CH CALL _CallDebugger JMP iretr hndokb: ; check handler OR BX,BX JNZ hndok MOV BX,08002H ; ; if this happens, the interrupt type will be in AL ; CALL _CallDebugger JMP iretr hndok: MOV _OStack,SP ; save old stack MOV SP,OFFSET _ISTop PUSH _stackLimit MOV AX,OFFSET _IStack+20 MOV _stackLimit,AX INC _wdc CALL _Call0 DEC _wdc POP _stackLimit MOV SP,_OStack iretr: ; interrupt handlers should return true if they want an EOI OR BX,BX JE noeoi MOV AL,020H OUT intctl,AL noeoi: POP BP POP DI POP SI POP DX POP CX POP AX POP BX IRET ; Send EOI to the PIC _DoEOI PROC NEAR MOV AL,020H OUT intctl,AL RET _DoEOI ENDP ; Set up interrupt vectors _IntInit PROC NEAR MOV CX,OFFSET intpv MOV BX,lenStatics CALL _Zero ; now set up actual handlers MOV CX,ei70ip MOV BX,16 CALL _Zero XOR BX,BX MOV [ei70ip+BX],OFFSET SLRInt MOV [ei71ip+BX],OFFSET SLTInt MOV [ei72ip+BX],OFFSET EncInt MOV [ei73ip+BX],OFFSET SIOInt MOV [ei74ip+BX],OFFSET AlAInt MOV [ei75ip+BX],OFFSET AlBInt MOV [ei76ip+BX],OFFSET AlCInt MOV [ei77ip+BX],OFFSET AlDInt RET _IntInit ENDP ; Set 8259 mask, 1's indicate channels to be enabled _IntMask PROC NEAR MOV AL,BL XOR AL,0FFH OUT intdata,AL RET _IntMask ENDP ; read 8259 mask, 1's indicate enabled channels _ReadIMask PROC NEAR IN AL,intdata XOR AL,0FFH MOV BL,AL XOR BH,BH RET _ReadIMask ENDP ; EnableInt(proc, type) ; where type is in 0..7 _EnableInt PROC NEAR AND BX,7 MOV SI,OFFSET intpv ADD SI,BX ADD SI,BX MOV WORD PTR [SI],CX MOV CX,BX MOV AX,1 SAL AX,CX MOV BX,AX ; enable mask bits given in BL IN AL,intdata XOR BL,0FFH AND AL,BL OUT intdata,AL RET _EnableInt ENDP ; disable interrupt type given in BL _DisableInt PROC NEAR AND BX,7 MOV SI,OFFSET intpv ADD SI,BX ADD SI,BX ; word offset MOV WORD PTR [SI],0 MOV CX,BX MOV AX,1 SAL AX,CX MOV BX,AX IN AL,intdata OR AL,BL OUT intdata,AL RET _DisableInt ENDP ; read 8259 IRR _ReadIRR PROC NEAR MOV AL,00AH OUT intctl,AL IN AL,intctl MOV BL,AL XOR BH,BH RET _ReadIRR ENDP ; read 8259 ISR _ReadISR PROC NEAR MOV AL,00BH OUT intctl,AL IN AL,intctl MOV BL,AL XOR BH,BH RET _ReadISR ENDP ; increment wakeup disable counter _IWDC PROC NEAR ; added check MOV AX,_wdc OR AX,AX JNS iwok MOV BX,08003H CALL _CallDebugger iwok: ; end added check INC _wdc CLI RET _IWDC ENDP ; decrement wakeup disable counter _DWDC PROC NEAR DEC _wdc MOV AX,_wdc OR AX,AX ; added check JNS dwok MOV BX,08003H CALL _CallDebugger OR AX,AX dwok: ; end added check JNZ dwdcr STI dwdcr: RET _DWDC ENDP ; return wakeup disable counter _GetWDC PROC NEAR MOV BX,_wdc RET _GetWDC ENDP PUBLIC _IntInit PUBLIC _IntOn PUBLIC _IntOff PUBLIC _IntMask PUBLIC _ReadIMask PUBLIC _DoEOI PUBLIC _EnableInt PUBLIC _DisableInt PUBLIC _ReadIRR PUBLIC _ReadISR PUBLIC _wdc PUBLIC _IWDC PUBLIC _DWDC PUBLIC _GetWDC C_CODE ENDS END