home *** CD-ROM | disk | FTP | other *** search
- ;
- ;Routines to set up a program as TSR, by hooking the keyboard interrupt
- ;locally and testing the scancodes against given scancode hot key.
- ;This module was tested in TINY model only.
- ;This module is based on "MSDOS encyclopedia" snap.asm example pp 360-380.
- ;You may want to refer to that reference for more information.
- ;Unlike the original article we assume here DOS 3.1 or above.
- ;
- ; Defined functions (see also TSR.H):
- ;
- ; 1. int HookKbdInterrupt(void (*Func)(), unsigned int ScanCode);
- ; Hook the keyboard interrupts so that Func is called if ScanCode is
- ; detected. Returns:
- ; 0 - everything O.K..
- ; 1 - already installed.
- ; 2 - can not install (int 02fh ID is in use).
- ;
- ; Compile as "tasm tsr.asm/mx"
- ;
- ; Written by Gershon Elber, Sep. 1990
- ;
- dosseg
-
- public _HookKbdInterrupt
- public _InstalledTSRSegment
-
- .model tiny ;select tiny model
-
- .code ;TC-compatible code segment
-
- MultiplexID equ 'G' ;Hopefully unique int 2FH ID value.
- TSRStackSize equ 0100h ;Resident stack size in bytes.
-
- KB_FLAG equ 017h
-
- KBIns equ 080h
- KBCaps equ 040h
- KBNum equ 020h
- KBScroll equ 010h
- KBAlt equ 008h
- KBCtl equ 004h
- KBLeft equ 002h
- KBRight equ 001h
-
- TRUE equ -1
- FALSE equ 0
-
- ;****************************************************************************
- ;Hook to activate the TSR application routine. *
- ;****************************************************************************
- DoTSRApplication proc near
- ;
- push ds
- push ax
- ;
- push cs
- pop ds
- mov ax,cs
- ;
- mov PrevSP,sp ;Save previous SS:SP and set ours.
- mov PrevSS,ss
- mov ss,ax
- mov sp,offset StackTop
- ;
- push es
- push bx
- push cx
- push dx
- push si
- push di
- push bp
- ;
- cld
- ;
- ;Set up the interrupt trapping routines.
- ;
- mov cx,NTrap
- mov si,offset StartTrapList
- DoTSR1: lodsb
- ;
- mov byte ptr [si],FALSE ;Zero the trap flag.
- ;
- push ax
- mov ah,035h ;Get old interrupt vector.
- int 021h ;/
- mov [si+1],bx ;And save it.
- mov [si+3],es ;/
- pop ax
- ;
- mov dx,[si+5] ;ds:dx hold out interrupt handler.
- mov ah,025h ;Set new interrupt vector.
- int 021h ;/
- ;
- add si,007
- loop DoTSR1
- ;
- mov ax,03300h ;Disable break during disk I/O.
- int 021h ; |
- mov PrevBreak,dl ; |
- xor dl,dl ; |
- mov ax,03301h ; |
- int 021h ;/
- ;
- ;Preserve previous extrended error information.
- ;
- push ds
- xor bx,bx
- mov ah,059h ;Get extrended error info
- int 021h
- mov cs:PrevExtErrDs,ds
- pop ds
- mov PrevExtErrAx,ax
- mov PrevExtErrBx,bx
- mov PrevExtErrCx,cx
- mov PrevExtErrDx,dx
- mov PrevExtErrSi,si
- mov PrevExtErrDi,di
- mov PrevExtErrEs,es
- ;
- mov ah,051h ;Get current PSP
- int 021h ; |
- mov PrevPSP,bx ;/
- ;
- mov bx,TSRPSP ;Set our PSP
- mov ah,050h ; |
- int 021h ;/
- ;
- mov ah,02fh ;Get DTA address
- int 021h ; |
- mov PrevDTAoffs,bx ; |
- mov PrevDTAseg,es ;/
- ;
- push ds
- mov ds,TSRPSP
- mov dx,00080h ;ds:dx is new DTA.
- mov ah,01ah ;Set DTA address.
- int 021h ;/
- pop ds
- ;
- mov byte ptr cs:ActiveTSR,TRUE
- ;
- mov ax,00e07h ;Do some noise
- int 010h ;/
- ;
- call word ptr [FuncAddr]
- ;
- mov ax,00e07h ;Do some noise
- int 010h ;/
- mov byte ptr cs:ActiveTSR,FALSE
- ;
- push ds
- lds dx,PrevDTA ;Restore DTA.
- mov ah,01ah ;Set DTA address.
- int 021h ;/
- pop ds
- ;
- mov bx,PrevPSP ;Restore PSP.
- mov ah,050h ;Set PSP address.
- int 021h ;/
- ;
- mov dx,offset PrevExtErrInfo ;Restore extended error information
- mov ax,05d0ah ; |
- int 021h ;/
- ;
- mov dl,PrevBreak ;Restore previous MSDOS break status.
- mov ax,03301h ; |
- int 021h ;/
- ;
- mov cx,NTrap
- mov si,offset StartTrapList
- push ds
- ;
- DoTSR5: lods byte ptr cs:[si] ;Restore previous traps.
- lds dx,cs:[si+1]
- mov ah,025h
- int 021h
- add si,00007h
- loop DoTSR5
- ;
- pop ds
- ;
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop es
- ;
- mov ss,PrevSS
- mov sp,PrevSP
- ;
- pop ax
- pop ds
- ;
- mov byte ptr cs:HotFlag,FALSE
- ;
- ret
- ;
- DoTSRApplication endp
-
- ;
- ;****************************************************************************
- ;This Function verifies we are not in DOS. *
- ;****************************************************************************
- VerifyDOSState proc near
- ;
- push ds
- push bx
- push ax
- ;
- lds bx,cs:ErrorModeAddr
- mov ah,[bx]
- ;
- lds bx,cs:InDosAddr
- mov al,[bx]
- ;
- xor bx,bx
- cmp bl,cs:InISR28
- ;
- rcl bl,01h
- ;
- cmp bx,ax
- ;
- pop ax
- pop bx
- pop ds
- ;
- ret
- ;
- VerifyDOSState endp
-
- ;****************************************************************************
- ;This Function verifies we are not in BIOS. *
- ;****************************************************************************
- VerifyIntState proc near
- ;
- push ax
- ;
- mov ax,000001011b ;RR = 1, RIS = 1.
- out 020h,al
- jmp short VerInt1 ;Buy some time.
- VerInt1:in al,020h
- cmp ah,al
- jc short VerInt2 ;Hardware interrupt is been serviced?
- ;
- xor al,al
- cmp al,cs:InISR5
- jc short VerInt2
- ;
- cmp al,cs:InISR9
- jc short VerInt2
- ;
- cmp al,cs:InISR10
- jc short VerInt2
- ;
- cmp al,cs:InISR13
- ;
- VerInt2:pop ax
- ;
- ret
- ;
- VerifyIntState endp
-
- ;****************************************************************************
- ;This Function verifies we are not in DOS/BIOS. *
- ;****************************************************************************
- VerifyTSRState proc near
- ;
- ror cs:HotFlag,1 ;Hot key has been pressed?
- cmc
- jc short VerTSR1
- ;
- ror cs:ActiveTSR,1 ;Are we in the middle of serving our TSR?
- jc short VerTSR1
- ;
- call VerifyDOSState
- jc short VerTSR1
- ;
- call VerifyIntState
- ;
- VerTSR1:ret
- ;
- VerifyTSRState endp
-
- ;****************************************************************************
- ;The following routines monitor activity in different interrupt vectors. *
- ;****************************************************************************
- ISR5 proc far
- ;
- inc cs:InISR5
- ;
- pushf
- cli
- call cs:PrevISR5
- ;
- dec cs:InISR5
- ;
- iret
- ;
- ISR5 endp
-
- ;****************************************************************************
- ISR8 proc far
- ;
- pushf
- cli
- call cs:PrevISR8
- ;
- cmp cs:InISR8,0
- jne short ISR8b ;Exit if already in this handler.
- ;
- inc cs:InISR8
- ;
- sti
- call VerifyTSRState
- jc short ISR8a
- ;
- call DoTSRApplication
- ;
- ISR8a: dec cs:InISR8
- ;
- ISR8b: iret
- ;
- ISR8 endp
-
- ;****************************************************************************
- ISR9 proc far
- ;
- push ds
- push ax
- push bx
- ;
- push cs
- pop ds
- ;
- in al,060h
- ;
- pushf
- cli
- call cs:PrevISR9
- ;
- mov ah,ds:InISR9
- or ah,ds:HotFlag
- jnz short ISR9d
- ;
- inc ds:InISR9
- sti
- ;
- cmp ds:HotSeqLen,0
- je short ISR9a
- ;
- mov bx,ds:HotIndex
- cmp al,[bx+HotSequence]
- jne short ISR9b
- ;
- inc bx
- cmp bx,ds:HotSeqLen
- jb short ISR9c
- ;
- ISR9a: push ds
- mov ax,0040h
- mov ds,ax
- mov al,ds:[KB_FLAG]
- pop ds
- ;
- and al,ds:HotKbMask
- cmp al,ds:HotKBFlag
- jne short ISR9c
- ;
- mov byte ptr ds:HotFlag,TRUE
- ;
- ISR9b: xor bx,bx
- ;
- ISR9c: mov ds:HotIndex,bx
- dec ds:InISR9
- ;
- ISR9d: pop bx
- pop ax
- pop ds
- ;
- iret
- ;
- ISR9 endp
-
- ;****************************************************************************
- ISR10 proc far
- ;
- inc cs:InISR10
- ;
- pushf
- cli
- call cs:PrevISR10
- ;
- dec cs:InISR10
- ;
- iret
- ;
- ISR10 endp
-
- ;****************************************************************************
- ISR13 proc far
- ;
- inc cs:InISR13
- ;
- pushf
- cli
- call cs:PrevISR13
- ;
- pushf
- dec cs:InISR13
- popf
- ;
- sti
- ret 2
- ;
- ISR13 endp
-
- ;****************************************************************************
- ISR1B proc far
- ;
- mov byte ptr cs:Trap1B,TRUE
- ;
- iret
- ;
- ISR1B endp
-
- ;****************************************************************************
- ISR23 proc far
- ;
- mov byte ptr cs:Trap23,TRUE
- ;
- iret
- ;
- ISR23 endp
-
- ;****************************************************************************
- ISR24 proc far
- ;
- mov byte ptr cs:Trap24,TRUE
- ;
- mov al,3 ;fail the MSDOS call.
- ;
- iret
- ;
- ISR24 endp
-
- ;****************************************************************************
- ISR28 proc far
- ;
- pushf
- cli
- call cs:PrevISR28
- ;
- cmp cs:InISR28,0
- jne short ISR28b
- ;
- inc cs:InISR28
- ;
- call VerifyTSRState
- jc short ISR28a
- ;
- call DoTSRApplication
- ;
- ISR28a: dec cs:InISR28
- ;
- ISR28b: iret
- ;
- ISR28 endp
-
- ;****************************************************************************
- ISR2F proc far
- ;
- cmp ah,MultiplexID
- je short ISR2Fa
- ;
- jmp cs:PrevISR2F
- ;
- ISR2Fa: test al,al
- jnz short ISR2Fb
- ;
- mov al,0ffh
- mov bx,cs ;Return the installed TSR segment.
- ;
- ISR2Fb: iret
- ;
- ISR2F endp
-
- ;****************************************************************************
- ; Data section: *
- ;****************************************************************************
- .data? ;TC-comp. uninitialized data segment.
-
- _InstalledTSRSegment dw ? ;If already installed - segment addr.
-
- ErrorModeAddr dd ? ;MSDOS ErrorMode flag address.
- InDosAddr dd ? ;MSDOS InDOS flag address.
- ;
- NISR dw (EndISRList-StartISRList) / 8 ;# of installed ISRs.
- ;
- StartISRList db 005h ;Int number.
- InISR5 db FALSE
- PrevISR5 dd ?
- dw offset ISR5
- ;
- db 008h ;Int number.
- InISR8 db FALSE
- PrevISR8 dd ?
- dw offset ISR8
- ;
- db 009h ;Int number.
- InISR9 db FALSE
- PrevISR9 dd ?
- dw offset ISR9
- ;
- db 010h ;Int number.
- InISR10 db FALSE
- PrevISR10 dd ?
- dw offset ISR10
- ;
- db 013h ;Int number.
- InISR13 db FALSE
- PrevISR13 dd ?
- dw offset ISR13
- ;
- db 028h ;Int number.
- InISR28 db FALSE
- PrevISR28 dd ?
- dw offset ISR28
- ;
- db 02fh ;Int number.
- InISR2f db FALSE
- PrevISR2f dd ?
- dw offset ISR2f
- ;
- EndISRList label byte
- ;
- TSRPSP dw ? ;Resident PSP
- PrevPSP dw ? ;Previous PSP
- PrevSP dw ? ;Previous SS:SP
- PrevSS dw ?
- ;
- PrevBreak db ?
- ;
- PrevDTA label dword
- PrevDTAoffs dw ?
- PrevDTAseg dw ?
- ;
- HotIndex dw 0 ;Index of next scancode in seq.
- HotSeqLen dw EndHotSeq-HotSequence ;Length of hot keys seq.
- ;
- HotSequence db ? ;Hot sequence of scan codes.
- EndHotSeq label byte
- ;
- HotKBFlag db ?
- HotKBMask db (KBIns or KBCaps or KBNum or KBScroll) xor 0ffh
- HotFlag db FALSE
- ;
- ActiveTSR db FALSE
- ;
- DOSVersion label word
- db ? ;Minor version number.
- MajorVersion db ? ;Major version number.
- ;
- ;Data used by the TSR application trapping.
- ;
- PrevExtErrInfo label byte
- PrevExtErrAx dw ?
- PrevExtErrBx dw ?
- PrevExtErrCx dw ?
- PrevExtErrDx dw ?
- PrevExtErrSi dw ?
- PrevExtErrDi dw ?
- PrevExtErrDs dw ?
- PrevExtErrEs dw ?
- dw 3 dup(0)
- ;
- NTrap dw (EndTrapList-StartTrapList) / 8
- ;
- StartTrapList db 01bh
- Trap1B db FALSE
- PrevISR1B dd ?
- dw offset ISR1B
- ;
- db 023h
- Trap23 db FALSE
- PrevISR23 dd ?
- dw offset ISR23
- ;
- db 024h
- Trap24 db FALSE
- PrevISR24 dd ?
- dw offset ISR24
- ;
- EndTrapList label byte
- ;
- FuncAddr dw ? ;Address of TSR application.
-
- ;****************************************************************************
- ; Stack to be used by the resident section (in code segment...): *
- ;****************************************************************************
- .code
-
- db TSRStackSize dup("Stack ")
- StackTop label word
-
- ;****************************************************************************
- ; Transient code - called only once in initialization process. *
- ;****************************************************************************
- .code
-
- ;****************************************************************************
- ;This Function hooks the keyboard interrupt handler to ours, and save *
- ;the requested scancode and function to call for it. *
- ;Returns 0 in ax if O.k. otherwise error code (see header of this file. *
- ;****************************************************************************
- _HookKbdInterrupt proc near
- ;
- push bp
- mov bp,sp
- push bx
- push cx
- push dx
- push si
- push di
- push es
- push ds
- ;
- mov ax,[bp+6] ;Get scan code to compare with.
- mov byte ptr HotKBFlag,al ; |
- mov byte ptr HotSequence,ah ;/
- ;
- mov ax,[bp+4] ;Get Func address.
- mov word ptr FuncAddr,ax ;/
- ;
- mov ax,cs
- mov ds,ax
- ;
- mov TSRPSP,cs
- ;
- mov ah,030h ;Get dos version.
- int 021h ; |
- xchg ah,al ; |
- mov DosVersion,ax ;/
- ;
- mov ah,MultiplexID ;Verify its not already installed.
- xor al,al ; |
- int 02fh ; |
- test al,al ; |
- jz short Hook3 ; |
- cmp al,0ffh ; |
- jne short Hook2 ; |
- mov ax,00001h ; | Already installed.
- mov _InstalledTSRSegment,bx ; | Save installed TSR segment.
- jmp short Hook9 ; |
- Hook2: mov ax,00002h ; | Can not install.
- jmp short Hook9 ;/
- ;
- Hook3: mov ah,034h ;Get InDOS address.
- int 021h ; |
- mov word ptr InDOSAddr,bx ; |
- mov word ptr InDOSAddr+2,es ; |
- dec bx ; | Error mode is just before it.
- mov word ptr ErrorModeAddr,bx ; |
- mov word ptr ErrorModeAddr+2,es ;/
- ;
- mov cx,NISR
- mov si,offset StartISRList
- Hook4: lodsb
- ;
- push ax
- mov ah,035h ;Get old interrupt vector.
- int 021h ; |
- mov [si+1],bx ; | And save it
- mov [si+3],es ;/
- pop ax
- ;
- push ds
- mov dx,[si+5]
- push cs
- pop ds
- mov ah,025h ;Set our interrupt vector
- int 021h ;/
- pop ds
- add si,00007h
- loop Hook4
- ;
- mov es,cs:[02ch] ;Free the environment.
- mov ah,049h ; |
- int 021h ;/
- ;
- xor ax,ax
- ;
- Hook9: pop ds
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop bp
- ;
- ret
- ;
- _HookKbdInterrupt endp
-
- end
-