
#include <linuxmt/config.h>

#ifdef CONFIG_SIBO_CONSOLE_DIRECT

; Small program to read the Keyboard and send characters out to the serial
; port. The Key modifiers are ignored as they are too difficult to interpret.

; SDW 28th May 99

	.text
	.global _psiongetchar

;--------------------------------------------------------------
; scan keyboard a columm at a time.

_psiongetchar:
	cli
	mov bx, #key_map	;pointer to key character

	mov ax, #0x0008		;reset columm counter

	mov key_col, ax

	mov key_value, #0x0000	;clear key value
	mov key_modifier, ah

scan_col:
	out 0x15, al		;done help to give time for hardware to respond
	in ax, 0x2c
	and ax, #0xfff0
	or ax, key_col
	out 0x2c, ax

	mov cx, #0x0020
loop1:				;delay a little to let hardware settle
	loop loop1
 
	in ax, 0x20		;read row data

	mov cl, al		;get 'modifiers'
	and cl ,#0x80
	or cl, key_modifier
	ror cl, 1
	mov key_modifier, cl
	
	push bx
	
	and ax, #0x077F		;get 'key' (remove modifer bit)
	jz scan_no_key

	test ax, #0x0001	;bit 0
	jne scan_match
	inc bx

	test ax, #0x0002	;bit 1
	jne scan_match
	inc bx

	test ax, #0x0004	;bit 2
	jne scan_match
	inc bx

	test ax, #0x0008	;bit 3
	jne scan_match
	inc bx

	test ax, #0x0010	;bit 4
	jne scan_match
	inc bx

	test ax, #0x0020	;bit 5
	jne scan_match
	inc bx			

	test ax, #0x0040	;bit 6
	jne scan_match
	inc bx			

	test ax, #0x0100	;bit 8
	jne scan_match
	inc bx			

	test ax, #0x0200	;bit 9
	jne scan_match
	inc bx			
				;must be bit 10
;	test ax, #0x0400	;bit 10
;	jne scan_match
;	inc bx			

scan_match:
	mov al, [bx]		;look up character
	mov key_value, al
	
scan_no_key:
	mov ax, key_col

	inc key_col		;increase columm counter
	pop bx
	add bx, #0x000A
	
	cmp ax, #0x0F		;have we done all of rows?
	jne scan_col

	mov al, key_modifier	;check modifier state and modify key
	and al, #0x80
	cmp al, #0x00
	je scan_no_psion

	mov bx, #key_psion
	add bx, key_value
	mov al, [bx]
	mov key_value, al

scan_no_psion:
	mov al, key_modifier	;check modifier state and modify key
	and al, #0x05
	cmp al, #0x00
	je scan_no_shift

	mov bx, #key_shift
	add bx, key_value
	mov al, [bx]
	mov key_value, al

scan_no_shift:
	mov al, key_value 	;modifiers and key pressed
	mov ah, key_modifier
	sti
	ret


;--------------------------------------------------------------
;--------------------------------------------------------------
	.data
	

key_col:
	.word 0x0000

key_value:
	.word 0x00
key_modifier:
	.byte 0x00

#ifdef CONFIG_SIBO_DEFAULT_KEYMAP
; Table of how columms and rows relate to key value

key_map:
	.byte 0x0A, 0x1A, 0x09, 0x79, 0x27, 0x25, 0x6E, 0x08, 0x05, 0x02
	.byte 0x00, 0x2F, 0x2D, 0x2B, 0x30, 0x70, 0x2A, 0x07, 0x04, 0x01
	.byte 0x08, 0x6B, 0x69, 0x38, 0x39, 0x6F, 0x6C, 0x00, 0x06, 0x03
	.byte 0x00, 0x2C, 0xFF, 0x6D, 0x6A, 0x75, 0x37, 0x00, 0x00, 0x00
	.byte 0x20, 0x72, 0x34, 0x35, 0x74, 0x67, 0x62, 0x00, 0x00, 0x00
	.byte 0x00, 0x66, 0x76, 0x63, 0x64, 0x65, 0x33, 0x00, 0x00, 0x00
	.byte 0x00, 0x71, 0x61, 0x7A, 0x73, 0x77, 0x78, 0x00, 0x00, 0x00
	.byte 0x00, 0x31, 0x32, 0x36, 0x2E, 0x18, 0x68, 0x1B, 0x00, 0x00

; following tables are used to change value should a particular key be
; pressed. 'Psion' applied before 'Shift'

key_psion:
	.byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
	.byte 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
	.byte 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
	.byte 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
	.byte 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
	.byte 0x28, 0x29, 0x2A, 0x7C, 0x2C, 0x2D, 0x2E, 0x2F
	.byte 0x5D, 0x31, 0x23, 0x5C, 0x7E, 0x60, 0x40, 0x7B
	.byte 0x7D, 0x5B, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
	.byte 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47
	.byte 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F
	.byte 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57
	.byte 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
	.byte 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67
	.byte 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F
	.byte 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77
	.byte 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F

key_shift:
	.byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
	.byte 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
	.byte 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
	.byte 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
	.byte 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
	.byte 0x28, 0x29, 0x3A, 0x3D, 0x3C, 0x5F, 0x3E, 0x3B
	.byte 0x29, 0x21, 0x22, 0x23, 0x24, 0x25, 0x5E, 0x26
	.byte 0x3F, 0x28, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
	.byte 0x40, 0x41, 0x58, 0x43, 0x44, 0x45, 0x46, 0x47
	.byte 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F
	.byte 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57
	.byte 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
	.byte 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47
	.byte 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F
	.byte 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57
	.byte 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
#endif
#endif
