;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
;;;;    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