handlers.asm
来自「这是一些例程」· 汇编 代码 · 共 1,284 行 · 第 1/4 页
ASM
1,284 行
.MODEL small, pascal
INCLUDE tsr.inc
.CODE
; Stack buffer used by TSR. Size is determined by constant STACK_SIZ,
; declared in TSR.INC file. NewStack points to top of stack.
EVEN
BYTE STACK_SIZ DUP(?) ; Stack buffer
NewStack LABEL BYTE ; Pointer to top of stack
; Structures for interrupt handlers or "interrupt service routines."
; The following handlers are replaced during installation. Such routines
; usually set a flag to indicate they are active, call the original
; interrupt handler, optionally do some processing (such as detecting a
; hot key), and when finished clear the active flag.
HandArray LABEL BYTE ; Array of handler structures
; Num Flag OldHand NewHand
intClock INTR < 8h, FALSE, NULL, Clock>
intKeybrd INTR < 9h, FALSE, NULL, Keybrd>
intVideo INTR <10h, FALSE, NULL, Video>
intDiskIO INTR <13h, FALSE, NULL, DiskIO>
intMisc INTR <15h, FALSE, NULL, SkipMiscServ>
intIdle INTR <28h, FALSE, NULL, Idle>
intMultex INTR <2Fh, FALSE, NULL, Multiplex>
CHAND EQU ($ - HandArray) / (SIZEOF INTR) ; Number of handlers in array
; Interrupt trap routines. These interrupt routines are set up
; temporarily to trap keyboard break errors and critical errors
; while the TSR is active. When the TSR finishes its tasks, it
; restores the old interrupts before returning.
TrapArray LABEL BYTE ; Array of trap structures
; Num Flag OldHand NewHand
intCtrlBk INTR <1Bh, FALSE, NULL, CtrlBreak>
intCtrlC INTR <23h, FALSE, NULL, CtrlC>
intCritEr INTR <24h, FALSE, NULL, CritError>
CTRAP EQU ($ - TrapArray) / (SIZEOF INTR) ; Number of traps in array
; Address of application's stack. Before calling the main body of the TSR,
; the Activate procedure stores the application's stack address, then resets
; SS:SP to point to LABEL NewStack (see above). This gives the TSR its own
; stack space without making demands on the current stack. Activate restores
; the application's stack before returning.
OldStackAddr FPVOID ? ; SS:SP pointer to application stack
; The TSR must set up its own disk transfer area if it calls DOS functions
; that use the DTA (see section "Preserving Existing Data" in Chapter 11 of
; the Programmer's Guide). DTA_SIZ is defined in the TSR.INC include file.
IFDEF DTA_SIZ
OldDtaAddr FPVOID ? ; Address of application's DTA
DtaBuff BYTE DTA_SIZ DUP(?) ; DTA buffer
ENDIF
; Multiplex data. STR_LEN is defined in the TSR.INC include file
IDnumber BYTE 0 ; TSR's identity number
IDstring BYTE STR_LEN DUP (0) ; Copy of identifier string
IDstrlen WORD ? ; Length of identifier string
ShareAddr FPVOID ? ; Address of shared memory
; Miscellaneous data
TsrRequestFlag BYTE FALSE ; Flag set when hot key is pressed
TsrActiveFlag BYTE FALSE ; Flag set when TSR executes
BreakCheckFlag BYTE ? ; Break-checking status of application
TsrPspSeg WORD ? ; Segment address of PSP
TsrAddr FPVOID ? ; Pointer to main part of TSR
CritErrAddr FPVOID ? ; Pointer to MS-DOS critical error flag
InDosAddr FPVOID ? ; Pointer to MS-DOS InDos flag
; Scan and shift codes for hot key. Install procedure initializes
; HotScan, HotShift, and HotMask during installation.
HotScan BYTE ? ; Scan code hot key
HotShift BYTE ? ; Shift value of hot key
HotMask BYTE ? ; Mask unwanted shift values
Version LABEL WORD ; DOS version number
minor BYTE ?
major BYTE ?
; Timer data, used when the TSR is activated at a preset time instead
; of activated from the keyboard. The following variables serve the
; same purposes as the counter variables used in the ALARM.ASM program
; presented in Chapter 11 of the Programmer's Guide. Refer to the
; header comments in the Install procedure for an explanation of how
; to set up a time-activated TSR.
Tick91 BYTE 91 ; Measures 91 timer ticks (5 seconds)
CountDown WORD 0 ; Counts 5-second intervals
;* Clock - Interrupt handler for Interrupt 08 (timer). Executes at each
;* timer interrupt; these occur an average of 18.2 times per second. Clock
;* first allows the original timer service routine to execute. It then
;* checks the flag TsrRequestFlag maintained either by the keyboard handler
;* (if keyboard activated) or by this procedure (if time activated). If
;* TsrRequestFlag = TRUE and system is okay, Clock invokes the TSR by
;* calling the Activate procedure. Uses an active flag to prevent the
;* Clock procedure from being reentered while executing.
;*
;* Uses: intClock, TsrActiveFlag, CountDown
;*
;* Params: None
;*
;* Return: None
Clock PROC FAR
pushf ; Simulate interrupt by pushing flags,
call cs:intClock.OldHand ; far calling orig Int 08 routine
.IF cs:intClock.Flag == FALSE ; If not already in this handler:
mov cs:intClock.Flag, TRUE ; Set active flag
sti ; Interrupts are okay
push ds ; Save application's DS
push cs
pop ds ; Set DS to resident code segment
ASSUME ds:@code
call CheckRequest ; Check conditions
.IF !carry? ; If TSR requested and safe,
mov TsrActiveFlag, TRUE ; activate TSR
call Activate
mov TsrActiveFlag, FALSE
.ENDIF ; End carry flag check
cmp CountDown, 0 ; If CountDown = 0, TSR is not time
je ticked ; activated or has already executed
dec Tick91 ; Else count down 91 timer ticks
jnz ticked ; If 91 ticks have not elapsed, exit
mov Tick91, 91 ; Else reset secondary counter and
dec CountDown ; subract one 5-second interval
ja ticked ; If counter not yet drained, exit
mov TsrRequestFlag, TRUE ; Else raise request flag
ticked:
mov intClock.Flag, FALSE ; Clear active flag
pop ds ; Recover application's DS
ASSUME ds:NOTHING
.ENDIF ; End in-handler check
iret
Clock ENDP
;* Keybrd - Interrupt handler for Interrupt 09 (keyboard).
;*
;* IBM PC/AT and compatibles:
;* Gets the scan code of the current keystroke from port 60h. Then
;* compares the scan code and shift state to the hot key. If they
;* match, sets TsrRequestFlag to signal the handlers Clock and Idle
;* that the TSR is requested.
;*
;* IBM PS/2 series:
;* Only the instructions at KeybrdMonitor (see below) are installed
;* as Interrupt 09 handler, since above method should not be used to
;* determine current keystroke in IBM PS/2 series. In this case, the
;* Interrupt 15h handler MiscServ takes care of checking the scan codes
;* and setting the request flag when the hot key is pressed.
;*
;* Time-activated TSRs:
;* If the TSR is activated by time instead of by a hotkey, KeybrdMonitor
;* serves as the Interrupt 09 handler for both PC/AT and PS/2 systems.
;*
;* Uses: intKeybrd, TsrRequestFlag
;*
;* Params: None
;*
;* Return: None
Keybrd PROC FAR
sti ; Interrupts are okay
push ax ; Save AX register
in al, 60h ; AL = scan code of current key
call CheckHotKey ; Check for hot key
.IF !carry? ; If not hot key:
; Hot key pressed. Reset the keyboard to throw away keystroke.
cli ; Disable interrupts while resetting
in al, 61h ; Get current port 61h state
or al, 10000000y ; Turn on bit 7 to signal clear keybrd
out 61h, al ; Send to port
and al, 01111111y ; Turn off bit 7 to signal break
out 61h, al ; Send to port
mov al, 20h ; Reset interrupt controller
out 20h, al
sti ; Reenable interrupts
pop ax ; Recover AX
mov cs:TsrRequestFlag, TRUE ; Raise request flag
iret ; Exit interrupt handler
.ENDIF ; End hot-key check
; No hot key was pressed, so let normal Int 09 service routine take over
pop ax ; Recover AX and fall through
cli ; Interrupts cleared for service
KeybrdMonitor LABEL FAR ; Installed as Int 09 handler for
; PS/2 or for time-activated TSR
mov cs:intKeybrd.Flag, TRUE ; Signal that interrupt is busy
pushf ; Simulate interrupt by pushing flags,
call cs:intKeybrd.OldHand ; far calling old Int 09 routine
mov cs:intKeybrd.Flag, FALSE
iret
Keybrd ENDP
;* Video - Interrupt handler for Interrupt 10h (video). Allows the original
;* video service routine to execute. Maintains an active flag to prevent
;* the TSR from being called while Interrupt 10h is executing.
;*
;* Uses: intVideo
;*
;* Params: Registers passed to Interrupt 10h
;*
;* Return: Registers returned by Interrupt 10h
Video PROC FAR
mov cs:intVideo.Flag, TRUE ; Set active flag
pushf ; Simulate interrupt by pushing flags,
call cs:intVideo.OldHand ; far calling old Int 10h routine
mov cs:intVideo.Flag, FALSE ; Clear active flag
iret
Video ENDP
;* DiskIO - Interrupt handler for Interrupt 13h (disk I/O). Allows the
;* original disk I/O service routine to execute. Maintains an active flag
;* to prevent the TSR from being called while Interrupt 13h is executing.
;*
;* Uses: intDiskIO
;*
;* Params: Registers passed to Interrupt 13h
;*
;* Return: Registers and the carry flag returned by Interrupt 13h
DiskIO PROC FAR
mov cs:intDiskIO.Flag, TRUE ; Set active flag
pushf ; Simulate interrupt by pushing flags,
call cs:intDiskIO.OldHand ; far calling old Int 13h routine
mov cs:intDiskIO.Flag, FALSE; Clear active flag without
; disturbing flags register
sti ; Enable interrupts
ret 2 ; Simulate IRET without popping flags
; (since services use carry flag)
DiskIO ENDP
;* MiscServ - Interrupt handler for Interrupt 15h (Miscellaneous System
;* Services).
;*
;* IBM PC/AT and compatibles:
;* Stub at SkipMiscServ is used as handler, bypassing all calls to
;* Interrupt 15h. Keypresses are checked by Keybrd (Int 09 handler).
;*
;* IBM PS/2 series:
;* This procedure handles calls to Interrupt 15h, searching for
;* Function 4Fh (Keyboard Intercept Service). When AH = 4Fh, gets
;* scan code of current keystroke in AL register. Then compares the
;* scan code and shift state to the hot key. If they match, sets
;* TsrRequestFlag to signal the handlers Clock and Idle that the
;* TSR is requested.
;*
;* Uses: intMisc, TsrRequestFlag
;*
;* Params: Registers passed to Interrupt 15h
;*
;* Return: Registers returned by Interrupt 15h
MiscServ PROC FAR
sti ; Interrupts okay
.IF ah == 4Fh ; If Keyboard Intercept Service,
push ax ; preserve AX,
call CheckHotKey ; check for hot key
pop ax
.IF !carry? ; If hot key,
mov cs:TsrRequestFlag, TRUE ; raise request flag,
clc ; signal BIOS not to process the key,
ret 2 ; simulate IRET without popping flags
.ENDIF ; End carry flag check
.ENDIF ; End Keyboard Intercept check
cli ; Disable interrupts and fall through
SkipMiscServ LABEL FAR ; Interrupt 15h handler if PC/AT
jmp cs:intMisc.OldHand
MiscServ ENDP
;* CtrlBreak - Interrupt trap for Interrupt 1Bh (CTRL+BREAK Handler).
;* Disables CTRL+BREAK processing.
;*
;* Params: None
;*
;* Return: None
CtrlBreak PROC FAR
iret
CtrlBreak ENDP
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?