;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; KEYBOARD DRIVER MODULE ;;;; (C) Copyright 1995 Gregory Ercolano ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; This handles all keyboard input, including: ; ; > Preprocessing special sequences (CTRL-BREAK, PGUP, etc) ; > Translating particular keys into appropriate sequences ; > Outputing sequences to the serial port ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INITIALIZE KEYBOARD ; Redirect the ^BREAK interrupt to our own trap.. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; initkeyboard proc near cli ;; SAVE ALL REGS push ax ;; MASK OUT KEYBOARD INTERRUPTS in al,21h push ax or al,00011011b ; Disable COM1/COM2, KEYBOARD, TIMER out 21h,al push bx push cx ;; ENTER LOW MEMORY SEGMENT (INTERRUPT VECTOR TABLE) push ds mov ax,0000h mov ds,ax ; TRAP CTRL-BREAK INTERRUPT (INT 1BH) mov [ds:006ch],offset kbbreakint mov [ds:006eh],cs ; TRAP KEYBOARD INTERRUPTS (INT 09H) mov bx,[ds:0024h] mov cx,[ds:0026h] mov [ds:0024h],offset kbhardint mov [ds:0026h],cs pop ds ;; CREATE A FAR JUMP TO THE BIOS KEYBOARD HANDLER mov byte ptr [ds:keybdint1],0eah mov [ds:keybdint2],bx mov [ds:keybdint3],cx ;; RESTORE ALL REGS pop cx pop bx pop ax ;; RESTORE KEYBOARD INTERRUPTS out 21h,al pop ax sti ret kbhardint: push ds push ax mov ax,0b800h mov ds,ax inc byte ptr [ds:0] pop ax pop ds ; ; FALL THRU TO THE (SAVED) BIOS VECTOR ; ifdef PROM_BURN ; >> ; >> FAKE A FAR JUMP TO THE SAVED VECTOR ; >> THIS HAS NOT BEEN TESTED! ; >> db 0ea dw _DATA:keybdint1 ; offset relative to data segment dw PROM_DATASEG ; prom segment for data area else ; SHORT JUMP TO THE DATA AREA jmp tokeybdbios endif initkeyboard endp ; BREAK INTERRUPT HANDLER - ^BREAK KEY INVOKES THIS ROUTINE kbbreakint: iret ; do nothing. int 16h will return with ; AX=0000, unlike ^@ which returns 0300. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; HANDLE KEYPRESS ; Gobble up and handle any special keyboard keys (PGUP, PGDN, etc) ; or translate keypresses to sequences of characters, or, simply pass ; the raw ascii character out to the serial port. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; handlekey proc near push ax ; I YAM HERE ; We need to emulate proper VT100 sequences for up/down arrows ; ALSO: Need to find a good key combo to do pageup/dn, arrow up/dn ; cmp ax,4800h ; UP ARROW jnz hk_xuparr mov ax,1 ; # lines to adjust call scrollbackadjust jmp hk_done hk_xuparr: cmp ax,5000h ; DN ARROW jnz hk_xdnarr mov ax,-1 ; # lines to adjust call scrollbackadjust jmp hk_done hk_xdnarr: cmp ax,4900h ; PAGEUP jnz hk_xpgup mov ax,24d ; # lines to adjust call scrollbackadjust jmp hk_done hk_xpgup: cmp ax,5100h ; PAGEDOWN jnz hk_xpgdn mov ax,-24d ; # lines to adjust call scrollbackadjust jmp hk_done hk_xpgdn: ; BEFORE PROCESSING OTHER KEYPRESS CODES, ; MAKE SURE WE'RE NOT IN BACKSCROLL MODE ; if we are, disable backscroll cmp [vidbackscroll],0 jz hk_notbscroll mov [vidbackscroll],0 call vidresscrn hk_notbscroll: cmp ax,0000h ; CTRL-BREAK? jnz hk_xctrlbrk mov si,offset breakmsg1 call printstring ; print <BREAK> to local screen ifndef PROM ;; IF NOT PROM TESTING, RETURN TO DOS!! mov al,[vidcolor] int 3 ; DEBUGGING ONLY! endif ;; I YAM HERE - GENERATE A SERIAL <BREAK> SEQUENCE call serialbreak jmp hk_done hk_xctrlbrk: cmp ax,0f00h ; SHIFT-TAB jnz hk_xshifttab call vidtoggledebug ; toggle debug mode jmp hk_done hk_xshifttab: cmp ax,5230h ; INS key with num lock on (0) jnz hk_xesc xor byte ptr [vidblank],1 call blankupdate jmp hk_done hk_xesc: ; SEND THE RAW KEYPRESS TO THE SERIAL PORT call serialout ; send ascii value to the serial port hk_done: pop ax ret handlekey endp