;****************************************************************************** ;* INT9 keyboard handler #9 (32-bit) ;* by Lee Hamel (hamell@cs.pdx.edu) ;* June 15th, 1994 ;* ;* All keyboard buffering code by James Ketrenos (ketrenoj@cs.pdx.edu) ;****************************************************************************** .386P PIC_CMD EQU 20h NONSPEC_EOI EQU 20h _data segment dword public use32 PUBLIC _keys _keys db 256 dup (0) PUBLIC _keynumpress _keynumpress db 0 PUBLIC _keylast _keylast db 0 PUBLIC _oldkeylast _oldkeylast db 0 toASCII db 0,27,'1234567890-=',14,15 db 'qwertyuiop',0,0,13,0,'as' db 'dfghjkl',0,0,'''',0,0,'zxcv' db 'bnm',0,'./',0,0,0,' ',0,1,2,3,4,5 db 6,7,8,9,10,0,0,24,25,26,'-',21,22,23,0,18 db 19,20,16,17,0,0,0,11,12,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,27,'!',0,'#',0,'%',0,0,0,0,0,0,0,14,15 db 'QWERTYUIOP',0,0,13,0,'AS' db 'DFGHJKL:',0,'"',0,0,'ZXCV' db 'BNM',0,0,'?',0,0,0,' ',0,1,2,3,4,5 db 6,7,8,9,10,0,0,24,25,26,'-',21,22,23,0,18 db 19,20,16,17,0,0,0,11,12,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 e0flag db 0 oldint9off dd ? oldint9sel dw ? keyinst db 0 keyhead db 0 keytail db 0 keybuffer db 256 dup(0) keyrepeat db 256 dup(0) _data ENDS _text segment para public use32 assume cs:_text, ds:_data ;***************************************************************************** ; ; ClearKeys_ and GetKey_ routines by James Ketrenos (ketrenoj@cs.pdx.edu) ; ;***************************************************************************** PUBLIC ClearKeys_ ClearKeys_ PROC push bx ;; ********************************************* ;; Clear the buffer by setting TAIL on HEAD ;; ********************************************* mov bl,keyhead mov keytail,bl mov [_keylast],0 pop bx ret ClearKeys_ ENDP PUBLIC GetKey_ GetKey_ PROC push eax ebx xor eax,eax ;; ********************************************* ;; Check to see if buffer is EMPTY ;; ********************************************* movzx ebx,keytail ;; Point to the end of the buffer cmp bl,keyhead ;; : and if it is equal to the front, jz GKDone ;; : then the buffer is empty, so wait. ;; ********************************************* ;; Get next key from KEYBOARD BUFFER ;; ********************************************* mov al,keybuffer[ebx] ;; Fetch the ASCII Code inc [keytail] ;; Increment the KeyTail ;; : NOTE that it loops at bl==256 cmp al,1Bh ; Esc jne GKDone cmp keyrepeat[1],2 ; dont want Esc repeating jb GKDone xor al,al GKDone: mov [_keylast],al pop ebx eax ret ;; Return to caller and all that stuff GetKey_ ENDP PUBLIC Set_New_Int9_ Set_New_Int9_ PROC cmp [keyinst],1 je exitnew9 mov [keyinst],1 cli pushad push ds es mov eax,3509h int 21h mov [oldint9off],ebx mov [oldint9sel],es mov eax,2509h mov edx,offset New_Int9 push cs pop ds int 21h pop es ds popad sti exitnew9: ret Set_New_Int9_ ENDP PUBLIC Set_Old_Int9_ Set_Old_Int9_ PROC cmp [keyinst],0 je exitold9 mov [keyinst],0 cli pushad push ds mov edx,[oldint9off] mov ds,[oldint9sel] mov eax,2509h int 21h pop ds popad sti exitold9: ret Set_Old_Int9_ ENDP New_Int9 PROC push eax ebx ecx ds mov ax,_data mov ds,ax in al,60h mov ah,al ; these 5 lines of code only necessary on XT's ; in al,61h ; or al,80h ; out 61h,al ; and al,7Fh ; out 61h,al ; pushfd ; this calls the BIOS handler ; call [oldint9pm] cmp ah,0E0h jae e0flagset movzx ebx,ah and bl,01111111b add bl,[e0flag] mov [e0flag],0 rol ah,1 jc keyrelease keypress: mov ah,1 sub ah,_keys[ebx] ; old key status add [_keynumpress],ah mov _keys[ebx],1 ; key pressed mov bh,_keys[2ah] ; get left shift status or bh,_keys[36h] ; get right shift status ror bh,1 ; put in bit 7 add bl,bh ; final key value xor bh,bh ; clear for index use mov al,toASCII[ebx] ; get translated value ;; ********************************************* ;; Check to see if buffer is FULL ;; ********************************************* movzx ecx,keyhead ;; Point to the front of the buffer inc cl ;; : and if the next space places cmp cl,keytail ;; : us on the end of the buffer, jz int9_done ;; : then the buffer is full ... dec cl ;; : otherwise, we help fill it. ;; ********************************************* ;; Put key into KEYBOARD BUFFER (Adding scancode) ;; ********************************************* mov keybuffer[ecx],al ;; Save the ASCII Code into buffer inc cl ;; Increment the KeyHead mov keyhead,cl ;; : NOTE that it loops at bl==256 cmp keyrepeat[ebx],2 je int9_done inc keyrepeat[ebx] jmp int9_done keyrelease: dec [_keynumpress] mov _keys[ebx],0 ; key released mov keyrepeat[ebx],0 jmp int9_done e0flagset: mov [e0flag],128 int9_done: mov al,NONSPEC_EOI out PIC_CMD,al pop ds ecx ebx eax iretd New_Int9 ENDP _text ENDS END