home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
pascal
/
library
/
dos
/
keyboard
/
enhanced
/
enhkbd.asm
next >
Wrap
Assembly Source File
|
1990-11-16
|
16KB
|
416 lines
;--------------------------------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