home *** CD-ROM | disk | FTP | other *** search
- ;--------------------------------ENHKBD.ASM -------------------------------
-
- ;Assembly language file for ENHKBD unit
- ;Written by Kim Kokkonen, TurboPower Software
-
- ;Version 1.0, 1/3/88
- ; initial release
-
- ;Version 1.1, 1/29/88
- ; support the NumLock key!
-
- ;Version 1.2, 2/23/88, with help from Brian Foley
- ; don't let NumLock key affect dedicated cursor pad on enhanced keyboard
- ; minimize conflict with QuickKeys and other int 9 handlers
- ; allow Ctrl-Alt-Del with int 9 installed
- ; add method to disable handlers temporarily
- ; use safer test for enhanced keyboard
- ; support alt-keypad keys with Alt-LeftShift combination
- ; add RestoreKbdVectors routine for use by TSR's
-
- ;Released to the public domain
-
- DATA SEGMENT BYTE PUBLIC
- EXTRN HasEnhancedKbd : BYTE
- EXTRN EnableEnhanced : BYTE
- DATA ENDS
-
- CODE SEGMENT BYTE PUBLIC
-
- ASSUME CS:CODE, DS:DATA
-
- PUBLIC GetIntVec, SetIntVec
- PUBLIC InitVectors
- PUBLIC EnhancedKbd
- PUBLIC NewInt09, NewInt16
-
- ;CS-relative variables, easily accessible to interrupt handlers
- PrevInt09 LABEL DWORD
- PrevInt09Ofs DW ?
- PrevInt09Seg DW ?
- PrevInt16 LABEL DWORD
- PrevInt16Ofs DW ?
- PrevInt16Seg DW ?
-
- ;*********************************************************** GetIntVec
- ;Return an interrupt vector
- ;procedure GetIntVec(IntNo : Byte; var Vector : pointer);
-
- GetIntVec PROC NEAR
- PUSH BP
- MOV BP,SP
- MOV AL,[BP+8] ;Get interrupt number
- MOV AH,35h
- INT 21h
- MOV AX,ES ;Save interrupt segment
- LES DI,[BP+4] ;ES:DI => result
- MOV ES:[DI],BX ;Offset
- MOV ES:[DI+2],AX ;Segment
- MOV SP,BP
- POP BP
- RET 6
- GetIntVec ENDP
-
- ;*********************************************************** SetIntVec
- ;Set an interrupt vector
- ;procedure SetIntVec(IntNo : Byte; Vector : Pointer);
-
- SetIntVec PROC NEAR
- MOV BX,SP ;Set up stack frame
- PUSH DS
- LDS DX,SS:[BX+2] ;Get interrupt address
- MOV AL,SS:[BX+6] ;Get interrupt number
- MOV AH,25h
- INT 21h
- POP DS
- RET 6
- SetIntVec ENDP
-
- ;*********************************************************** EnhancedKbd
- ;See if enhanced keyboard BIOS installed
- ;function EnhancedKbd : Boolean;
-
- EnhancedKbd PROC NEAR
- MOV AH,05 ;Stuff buffer function
- MOV CX,0FFFFh ;Stuff FFFF
- INT 16h
- MOV AH,11h ;Read enhanced function
- INT 16h
- CMP AX,0FFFFh ;Did we read the FFFF?
- MOV AX,0 ;Prepare for False
- JNZ EnhDone
- MOV AH,10h ;Get the key out of the buffer
- INT 16h
- MOV AX,1 ;Set to true
- EnhDone:
- RET
- EnhancedKbd ENDP
-
- ;*********************************************************** NewInt09
- ;Handle hardware keyboard interrupts
-
- IndexTable LABEL BYTE ;Table of indexes into WordTable
- DB 0FFh ;00h
- DB 00 ;01h - Esc
- DB 0FFh ;02h
- DB 0FFh ;03h
- DB 0FFh ;04h
- DB 0FFh ;05h
- DB 0FFh ;06h
- DB 0FFh ;07h
- DB 0FFh ;08h
- DB 0FFh ;09h
- DB 0FFh ;0Ah
- DB 0FFh ;0Bh
- DB 0FFh ;0Ch
- DB 0FFh ;0Dh
- DB 01 ;0Eh - Backspace
- DB 02 ;0Fh - Tab
- DB 0FFh ;10h
- DB 0FFh ;11h
- DB 0FFh ;12h
- DB 0FFh ;13h
- DB 0FFh ;14h
- DB 0FFh ;15h
- DB 0FFh ;16h
- DB 0FFh ;17h
- DB 0FFh ;18h
- DB 0FFh ;19h
- DB 03 ;1Ah - Left Brack
- DB 04 ;1Bh - Right Brack
- DB 05 ;1Ch - Enter
- DB 0FFh ;1Dh
- DB 0FFh ;1Eh
- DB 0FFh ;1Fh
- DB 0FFh ;20h
- DB 0FFh ;21h
- DB 0FFh ;22h
- DB 0FFh ;23h
- DB 0FFh ;24h
- DB 0FFh ;25h
- DB 0FFh ;26h
- DB 06 ;27h - Semicolon
- DB 07 ;28h - Quote
- DB 08 ;29h - Backquote
- DB 0FFh ;2Ah
- DB 09 ;2Bh - Backslash
- DB 0FFh ;2Ch
- DB 0FFh ;2Dh
- DB 0FFh ;2Eh
- DB 0FFh ;2Fh
- DB 0FFh ;30h
- DB 0FFh ;31h
- DB 0FFh ;32h
- DB 10 ;33h - Comma
- DB 11 ;34h - Period
- DB 12 ;35h - Slash
- DB 0FFh ;36h
- DB 13 ;37h - Pad-Asterisk
- DB 0FFh ;38h
- DB 0FFh ;39h
- DB 0FFh ;3Ah
- DB 0FFh ;3Bh
- DB 0FFh ;3Ch
- DB 0FFh ;3Dh
- DB 0FFh ;3Eh
- DB 0FFh ;3Fh
- DB 0FFh ;40h
- DB 0FFh ;41h
- DB 0FFh ;42h
- DB 0FFh ;43h
- DB 0FFh ;44h
- DB 0FFh ;45h
- DB 0FFh ;46h
- DB 14 ;47h - Home
- DB 15 ;48h - Up
- DB 16 ;49h - PgUp
- DB 17 ;4Ah - Pad-Minus
- DB 18 ;4Bh - Left
- DB 19 ;4Ch - Pad-5
- DB 20 ;4Dh - Right
- DB 21 ;4Eh - Pad-Plus
- DB 22 ;4Fh - End
- DB 23 ;50h - Down
- DB 24 ;51h - PgDn
- DB 25 ;52h - Insert
- DB 26 ;53h - Del
-
- WordTable LABEL WORD ;Table of Scan words to return
- ; Control Alt
- DW 0FFFFh, 0100h ;Esc
- DW 0FFFFh, 0E00h ;Backspace
- DW 9400h, 0A500h ;Tab
- DW 0FFFFh, 1A00h ;Left Brack
- DW 0FFFFh, 1B00h ;Right Brack
- DW 0FFFFh, 1C00h ;Enter
- DW 0FFFFh, 2700h ;Semicolon
- DW 0FFFFh, 2800h ;Quote
- DW 0FFFFh, 2900h ;Backquote
- DW 0FFFFh, 2B00h ;Backslash
- DW 0FFFFh, 3300h ;Comma
- DW 0FFFFh, 3400h ;Period
- DW 0FFFFh, 3500h ;Slash
- DW 0FFFFh, 3700h ;Pad-Asterisk
- DW 0FFFFh, 9700h ;Home
- DW 8D00h, 9800h ;Up
- DW 0FFFFh, 9900h ;PgUp
- DW 8E00h, 4A00h ;Pad-minus
- DW 0FFFFh, 9B00h ;Left
- DW 8F00h, 9C00h ;Pad-5
- DW 0FFFFh, 9D00h ;Right
- DW 9000h, 4E00h ;Pad-Plus
- DW 0FFFFh, 9F00h ;End
- DW 9100h, 0A000h ;Down
- DW 0FFFFh, 0A100h ;PgDn
- DW 9200h, 0A200h ;Insert
- DW 9300h, 0A300h ;Del
-
- BiosShiftFlags EQU BYTE PTR 17h ;Addresses in BIOS data area
- BufferHead EQU WORD PTR 1Ah
- BufferTail EQU WORD PTR 1Ch
- BufferStart EQU WORD PTR 80h
- BufferEnd EQU WORD PTR 82h
-
- NewInt09 PROC FAR
- STI ;Interrupts on
- PUSH AX ;Save registers we use
- PUSH BX
- PUSH CX
- PUSH DS
-
- MOV AX,SEG DATA
- MOV DS,AX ;Point to Turbo data area
- CMP EnableEnhanced,0 ;Enhanced functions enabled?
- JZ Int09Orig ;No, get out
-
- MOV AX,0040h
- MOV DS,AX ;Point to BIOS data area
-
- MOV AL,DS:BiosShiftFlags ;Shift status in AL
- MOV CL,AL ;Save shift state in CL
- TEST AL,00001100b ;Either Control or Alt depressed?
- JZ TestPad5 ;No, check special case of Pad-5
-
- AND AL,00001100b ;Just Ctrl-Alt bits
- CMP AL,00001100b ;Both Ctrl and Alt depressed?
- JE Int09Orig ;Get out in case of Ctrl-Alt-Del
-
- MOV AL,CL ;Restore shift state
- AND AL,00001111b ;All shift bits
- CMP AL,00001010b ;Just Alt-LeftShift?
- JE Int09Orig ;Get out so Alt-Keypad works
-
- IN AL,60h ;Read scan code
- CMP AL,53h ;Is it in range 0..53h?
- JA Int09Orig ;If not, pass on to BIOS int 09 handler
-
- MOV BX,offset IndexTable ;Point to index table
- XLAT BYTE PTR CS:[0] ;Get index
- CMP AL,0FFh ;AL = FFh?
- JNZ MatchedScan ;Special case if AL <> FFh
-
- Int09Orig: ;Let BIOS int 09 handler take care of it
- POP DS ;Restore registers
- POP CX
- POP BX
- POP AX
- JMP PrevInt09 ;Transfer to previous interrupt 09
-
- TestPad5:
- IN AL,60h ;Read scan code
- CMP AL,4Ch ;Pad-5 key?
- JNZ Int09Orig ;No, get out
- MOV AX,4C00h ;Set up scan code to return
- TEST CL,00100000b ;Is NumLock set?
- JZ NoNumLock ;No, it's not
- NumLockSet:
- TEST CL,00000011b ;Is a shift key depressed?
- JNZ StoreScanWord ;Yes, we want to store 4C00 in buffer
- JMP SHORT Int09Orig ;No, let original int 9 do it
- NoNumLock:
- TEST CL,00000011b ;Is a shift key depressed?
- JZ StoreScanWord ;No, store scan word
- JMP SHORT Int09Orig ;Yes, let original int 9 do it
-
- MatchedScan:
- SHL AX,1 ;Multiply scan index by 2
- SHL AX,1 ;Multiply by 2 again
- MOV BX,AX ;BX = Index * 4
- TEST CL,00001000b ;Alt depressed?
- JZ NoAltKey ;No, use first column of table
- ADD BX,2 ;Yes, use second column of table
- NoAltKey:
- MOV AX,CS:WordTable[BX] ;Get the scan word
- CMP AX,0FFFFh ;Case handled by BIOS?
- JZ Int09Orig ;Yes, get out of here
-
- StoreScanWord:
- MOV CX,AX ;Save scan word in CX
- IN AL,61h ;Read control port value
- MOV AH,AL ;Save in AH
- OR AL,80h ;Set high bit
- OUT 61h,AL ;Reset keyboard
- MOV AL,AH ;Retrieve original value
- OUT 61h,AL ;Enable keyboard
- CLI ;Stop CPU interrupts
- MOV AL,20h ;End of interrupt
- OUT 20h,AL ;To the interrupt controller
-
- MOV BX,DS:BufferTail ;Point to end of keyboard buffer
- MOV AX,BX ;Transfer to AX
- ADD AX,0002 ;Advance to next position
- CMP AX,DS:BufferEnd ;Wrap around if needed
- JNE CheckFull ;No need to wrap
- MOV AX,DS:BufferStart ;Else to beginning of buffer
- CheckFull:
- CMP AX,DS:BufferHead ;Bumping in to start?
- JE NewInt09Done ;Exit if full
- MOV [BX],CX ;Store keystroke
- MOV DS:BufferTail,AX ;Advance tail
- NewInt09Done:
- STI ;Interrupts on
- POP DS ;Restore registers
- POP CX
- POP BX
- POP AX
- IRET ;Return to caller
- NewInt09 ENDP
-
- ;*********************************************************** NewInt16
- ;Handle software keyboard interrupts
- NewInt16 PROC FAR
- PUSH DX ;Save registers we use
- PUSH DS
- PUSHF ;Save flags
- STI ;Allow interrupts
-
- MOV DX,SEG DATA
- MOV DS,DX ;Assure DS points to Turbo data
- CMP EnableEnhanced,0 ;Enhanced functions enabled?
- JZ Int16Orig ;No, pass to previous int 16
- CMP HasEnhancedKbd,0 ;Is enhanced keyboard installed?
- JZ Int16Orig ;No, leave call alone
-
- OR AH,AH ;AH=0?
- JNZ TryAH1 ;No, try AH=1
- AH0:
- OR AH,10h ;Use enhanced BIOS call instead
- CALL PrevInt16 ;Call previous int 16 (pops flags)
- OR AH,AH ;AH=0?
- JZ AH0Done ;Yes, done
- CMP AL,0E0h ;AL=E0h?
- JNZ AH0Done ;No, leave it alone
- XOR AL,AL ;Clear low byte of scan word
- AH0Done:
- POP DS ;Restore registers
- POP DX
- IRET ;Return to caller
-
- TryAH1:
- CMP AH,1 ;AH=1?
- JNZ Int16Orig ;No, let original int 16 do it
- AH1:
- OR AH,10h ;Use enhanced BIOS call instead
- CALL PrevInt16 ;Call previous int 16 (pops flags)
- PUSHF ;Save result flags
- JZ AH1Done ;Just return if no key available
- OR AH,AH ;AH=0?
- JZ AH1Done ;Yes, done
- CMP AL,0E0h ;AL=E0h?
- JNZ AH1Done ;Yes, clear it
- XOR AL,AL ;Clear low byte of scan word
- AH1Done:
- POPF ;Restore result flags
- POP DS ;Restore registers
- POP DX
- RET 2 ;Return with flags intact
-
- Int16Orig:
- POPF ;Restore flags
- POP DS
- POP DX
- JMP PrevInt16 ;Let old int16 handle the rest
- NewInt16 ENDP
-
- ;*********************************************************** InitVectors
- ;Save and setup interrupt vectors
- InitVectors PROC NEAR
- MOV AX,3509h ;Get current int 9
- INT 21h
- MOV PrevInt09Ofs,BX ;Save it in CS-relative variables
- MOV PrevInt09Seg,ES
- PUSH DS
- PUSH CS
- POP DS
- MOV DX,offset NewInt09
- MOV AX,2509h ;Install new int 9
- INT 21h
- POP DS
- MOV AX,3516h ;Get current int 16
- INT 21h
- MOV PrevInt16Ofs,BX ;Save it in CS-relative variables
- MOV PrevInt16Seg,ES
- PUSH DS
- PUSH CS
- POP DS
- MOV DX,offset NewInt16
- MOV AX,2516h ;Install new int 16
- INT 21h
- POP DS
- RET
- InitVectors ENDP
-
- CODE ENDS
- END
-
-