home *** CD-ROM | disk | FTP | other *** search
- ; This program intecepts keyboard data and creates a bit pattern determined
- ; according to whether or not certain keys are currently being pressed.
- ;
- ; The bit pattern is stored in the "inter-application communication area"
- ; at 0000:04f0. It is interpreted as:
- ;
- ; 7 6 5 4 3 2 1 0 (bit number)
- ; C m P H l d r u (bit name)
- ; | | | | | | | |
- ; | | | | | | | +- bit 0 (01h) - set = 1 while [up arrow] is pressed
- ; | | | | | | +--- bit 1 (02h) - set = 1 while [right arrow] is pressed
- ; | | | | | +----- bit 2 (04h) - set = 1 while [down arrow] is pressed
- ; | | | | +------- bit 3 (08h) - set = 1 while [left arrow] is pressed
- ; | | | |
- ; | | | +--------- bit 4 (10h) - set = 1 while [Home] is pressed
- ; | | +----------- bit 5 (20h) - set = 1 while [PgUp] is pressed
- ; | +------------- bit 6 (40h) - set = 1 while grey [-] is pressed
- ; +--------------- bit 7 (80h) - set = 1 while [CapsLock] is pressed
- ;
- ; As soon as the key is released, the relevant bit is reset to 0.
- ;
- ; The byte at 0000:04f1 is the "pass-through/filter" mode flag. When this
- ; byte is zero, all keystrokes are passed to the normal keyboard handler.
- ; When it's non-zero, all selected keystrokes are filtered (disabled for
- ; normal input). BIOS and DOS keyboard calls will not recognize them.
- ;
- ; The Alt-NumLock keystrokes toggles between pass-through and filter modes.
- ;
- ; This program is installed and remains resident. It is a COM-format
- ; file, so it must be converted with EXE2BIN.
- ;
- ; Copyright (c) Ziff-Davis Publishing Co., 1986. All rights reserved.
- ;
- ; = equates ===============
-
- KB_DATA_PORT equ 60h ; These are listed in the PC and XT
- KB_CTRL_PORT equ 61h ; Technical Reference Manuals
-
- KB_FLAG equ 417h ; the BIOS shift-key status (in segment 0)
- ALT_STATE equ 8 ; Bit pattern while the [Alt] key is pressed
- NUMLOCK_KEY equ 69 ; scan-code of the [NumLock] key
-
- INT_CTL_PORT equ 20h ; Interrupt controller port (8259 chip)
- EOI equ 20h ; End-Of-Interrupt code sent to 8259
-
- RELEASE_BIT equ 80h ;also called the "break" bit: a key was pressed
-
- KEY_BITS equ 04f0h ;the address of the key bits flags (segment 0)
- MODE_FLAG equ 04f1h ;when 0, all keys are passed to normal kbint
- INST_FLAG equ 04f2h ; set to 1234h during installation.
-
- com_seg segment
- assume cs:com_seg,ds:com_seg
- org 100h ; must have for COM-file format program
- kbm proc far
- jmp set_up ; get past data and install interrupt handler
-
- ; ============= program data area ==========
-
- norm_key_int label dword ; type DWORD so it can be used in a FAR jump
- nki_offset dw 0 ; This address is stored in the SET_UP proc
- nki_segment dw 0 ; It's the address of the previous kbint routine
-
- ; ------------------------------------------------------------------------
- ; KBD_INT
- ; 1.) read the keyboard
- ; 2.) set/reset bits in mouse movement byte
- ; 3.) execute normal keyboard interrupt
- ;
- ; scan bit key suggested meaning
- ; code flag name (defined by user)
- ; ---- ---- --------- --------------------
- kbd_tbl db 72, 1 ; num.pad 8 go up
- db 77, 2 ; num.pad 6 go right
- db 80, 4 ; num.pad 2 go down
- db 75, 8 ; num.pad 4 go left
-
- db 76, 4 ; num.pad 5 go down
- db 71, 16 ; Home button 1
- db 73, 32 ; PgUp button 2
- db 74, 64 ; grey minus button 3
- db 58, 128; CapsLock "high-gear shift" for fast motion
- tbl_end label byte
-
- ; ------------------------------------------------------------------------
- ; KBD_INT
- ; This procedure intercepts the ROM-BIOS KB_INT.
- ; It sets and resets bits of a kbd flag as the user presses and releases keys.
- ; When the byte at 0000:04f1 is 0, the keystroke is passed on to the
- ; original keyboard handler.
-
- kbd_int proc far
- sti
- cld
- push ax
- push si
- push ds
-
- in al,KB_DATA_PORT ; read scan-code from keyboard into AL
- mov ah,al ; save original byte in AH
- and al,7fh ; mask off "release bit" for comparison
-
- mov si,offset kbd_tbl
-
- k_20: cmp si,offset tbl_end ; at end of table?
- ja k_25 ; yes, key not found. Exit to normal kbint
- cmp al,byte ptr cs:[si] ; is this the key?
- je k_30 ; yes, process the keystroke
- inc si ; no, point past the scan mode
- inc si ; point past the bit-mask
- jmp k_20 ; and loop back to the next entry
- k_25:
- ;------- check for mode-toggle by user
- cmp ah,NUMLOCK_KEY ; is this a press of [NumLock]
- jne k_27 ; no, go
- sub si,si ; yes, look to BIOS data area
- mov ds,si
- test byte ptr ds:[KB_FLAG],ALT_STATE ; is [Alt] pressed?
- jz k_27 ; no, pass the key on
-
- xor byte ptr ds:[MODE_FLAG],1 ; yes, toggle the mode and
- jmp short k_exit ; exit w/o processing
-
- ;------- the keystroke is to be processed by the normal keyboard interrupt
- k_27: pop ds
- pop si
- pop ax
- jmp cs:[norm_key_int] ; continue at normal keyboard handler
-
- k_30:
- ;------- process the scan code into a bit-pattern
- mov al,cs:[si+1] ; get bit-flag mask
-
- sub si,si
- mov ds,si ; point to segment of KEY_BITS
-
- test ah,RELEASE_BIT ; is this key being released?
- jz k_40 ; no, go
-
- ;------- process key release
- not al ; flip-flop mask bits
- and byte ptr ds:[KEY_BITS],al ; mask off released key bit
- jmp k_50
- k_40:
- ;------- process key press
- or byte ptr ds:[KEY_BITS],al ; set the bit for pressed key
-
- ;------- determine whether key should be passed or to normal keyboard handler
- k_50:
- cmp byte ptr ds:[MODE_FLAG],0 ;should key be processed further?
- je k_27 ; yes, continue at kb int
-
- ;------ the keystroke is to be ignored by the rest of the system.
- ;------ wrap up this keyboard interrupt.
-
- k_exit: in al,KB_CTRL_PORT ; get current value of keyboard control lines
- mov ah,al ; save it
- or al,80h ; set the "enable kbd" but
- out KB_CTRL_PORT,al ; and write it out the control port
- xchg ah,al ; fetch the original control port value
- out KB_CTRL_PORT,al ; and write it back
-
- pop ds
- pop si
-
- cli
- mov al,EOI ; send End-Of-Interrupt signal
- out INT_CTL_PORT,al ; to the 8259 Interrupt Controller
- pop ax
- iret ; exit to interrupted program
- kbd_int endp
-
- LAST_BYTE equ offset $+1 ; This is the address passed to INT 27H
- ; Notice that the code of SET_UP
- ; procedure is not preserved in memory
- ;-------------------------------------------------------------------------
- ; SET_UP
- ; This routine is executed only once, when the program is installed.
-
- inst_msg db 'KBM KeyBoard Mouse Driver',0dh,0ah
- db 'Copyright (c) 1986 Ziff-Davis Publishing Co.,',0dh,0ah,'$'
-
- err_msg1 db 07,'Already installed',0dh,0ah,'$'
- err_msg2 db 'Wrong DOS version.',0dh,0ah,'$'
-
- set_up proc near
-
- ;-------- make sure this is DOS 2.0 or later
- mov ah,30h
- int 21h
- cmp al,2
- jae su_10
- mov dx,offset err_msg2
- jmp msg_exit
- su_10:
- ;-------- see if KBM has already been installed
- mov ax,0
- mov es,ax
- cmp es:[INST_FLAG],1234h ; Already installed?
- jne su_20 ; no, continue
- mov dx,offset err_msg1 ; yes, exit with message
- jmp msg_exit
- su_20: mov word ptr es:[INST_FLAG],1234h ; flag says KBM is installed
-
- ;-------- save the old kbint vector and set up the new one
- mov al,9
- mov ah,35h ; DOS GET_VECTOR service
- int 21h ; for interrupt 9 [KBINT]
-
- mov al,9 ;get address of the current kbint handler
- mov ah,35h ;DOS GET_VECTOR service
- int 21h
- mov nki_segment,es ; save old address
- mov nki_offset,bx
-
- mov dx,offset kbd_int ; set INT 9 to local keyboard interceptor
- mov al,9 ; set vector for INT 9 to DS:DX
- mov ah,25h ; DOS SET_VECTOR service
- int 21h
-
- mov ax,0
- mov es,ax ; initialize variables:
- mov byte ptr es:[MODE_FLAG],0 ; process all keystrokes
- mov byte ptr es:[KEY_BITS],0 ; no keys are pressed
-
- ;-------- display message to indicate install`tion complete
- mov dx,offset inst_msg
- mov ah,9
- int 21h
-
- ;-------- exit to DOS, leaving the interrupt handler resident
- mov dx,LAST_BYTE
- int 27h
-
- msg_exit: mov ah,9
- int 21h
- int 20h
- set_up endp
- kbm endp
- com_seg ends
- end kbm