#### keyreflex and friends respond to keyboard events. Ring-buffer the ups 
###  and downs. Fancier interpretation is on somebody else. Processes may
##   get copies of the raw ring buffer.
#    keyreflex uses an xray. keyvent is the 
#      Ha3sm-arbitrary MFII->keycode table.


# June 2003   where's the PS/2 mouse crap?

			# two osimplay extensions or macros.
DISMISSKBD () {		# callee-saves scabbing for one entry with lots of
	pull D		# exits.
	pull A
	dismiss
		}


#
RINGKEY () {			# about 10 insns
	ringstore $keyring D	byte	# byte
	ring $keyring			# byte ringcrement by default
	1+ @ $keybytesseen
			}


L askaux




L  keyreflex
		# the keyboard/pointer IRQ reflex
		# Key byte, cPC event firstIRQ+1, happened. IRET 
		# frame on stack.
		# Register values belong to someone else. We're the boss
		# because we do stuff like save the 2 we use first.
		# In Ha3sm this could have multiple listeners.
		# There will always be one 0wner listener.
		# We HAVE to differentiate the mouse from this on PS/2,
		#  and many current PCs.
push A
push D
zero A				
recieve 0x60	byte
			##### MOUSE DIFFERENTIATE GOES HERE
1- @ $keyspam
		when	sign	short    notkeyspam
DISMISSKBD
  L notkeyspam
		xjump $keybyte A		
			# dismissed by whatever xray beam is jumped on.
xray keybyte 256
	beam	plainkey		0		255
	beam	askoverloadedkey	$((0x1c))	$((0x1d))
	beam	askoverloadedkey	$((0x2a))	$((0x2a))
	beam	askoverloadedkey	$((0x35))	$((0x35))
	beam	askoverloadedkey	$((0x38))	$((0x38))
	beam	askoverloadedkey	$((0x47))	$((0x49))
	beam	askoverloadedkey	$((0x4b))	$((0x4b))
	beam	askoverloadedkey	$((0x4d))	$((0x4d))
	beam	askoverloadedkey	$((0x4f))	$((0x4f))
	beam	askoverloadedkey	$((0x50))	$((0x53))
	beam	askoverloadedkey	$((0x5b))	$((0x5d))
	beam	askoverloadedkey	$((0x9c))	$((0x9d))
	beam	askoverloadedkey	$((0xaa))	$((0xaa))
	beam	askoverloadedkey	$((0xb5))	$((0xb5))
	beam	askoverloadedkey	$((0xb8))	$((0xb8))
	beam	askoverloadedkey	$((0xc7))	$((0xc9))
	beam	askoverloadedkey	$((0xcb))	$((0xcb))
	beam	askoverloadedkey	$((0xcd))	$((0xcd))
	beam	askoverloadedkey	$((0xcf))	$((0xcf))
	beam	askoverloadedkey	$((0xd0))	$((0xd3))
	beam	askoverloadedkey	$((0xdb))	$((0xdd))
	beam	do_e0			$((0xe0))	$((0xe0))
	beam	pausekey		$((0xe1))	$((0xe1))
	beam	locknum			69 		69
yarx


L askoverloadedkey
	ANDtest -1 with @ $was_e0
	when	zero	overloadedkey	
    L plainkey				# fall thru
	= A to D
	RINGKEY
		DISMISSKBD
    L overloadedkey
	= 0 to @ $was_e0			# twas, now aint
	= $e0asbyte A to A
	ANDtest -1 with @ $numlock
		when	not	zero	nonumlock
	= 2 to @ $keyspam
    L nonumlock
        = A to D
        RINGKEY
        		DISMISSKBD

L do_e0					# set flag for action at next byte
	= -1 to @ $was_e0
			DISMISSKBD


L pausekey			# key byte e1 + spam. pause has no "break". 
				#  I feel like faking one just 
				#	to keep things symmetrical.
        = 5 to @ $keyspam
        = 114 to A
        = A to D
        RINGKEY
        = $((114+128)) to A
        = A to D
        RINGKEY
			DISMISSKBD


L locknum			# toggle the numlock flag. numlock 
				#   effects keyspam in the hardware.
	XOR -1 with @ $numlock
	= A to D
	RINGKEY
DISMISSKBD



cell 	keyspam		was_e0		numlock		keybytesseen

strand keyring 128 1



			# enumerating the 0s could save a branch, yes?
L keyvent		# UNUSED???? UNUSED???UNUSED???UNUSED???UNUSED???

#	0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
HL
ab 	0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   # 0
HL
ab	0   0   0   0   0   0   0   0   0   0   0   0   96  97  0   0
HL
ab	0   0   0   0   0   0   0   0   0   0   98  0   0   0   0   0
HL
ab	0   0   0   0   0   99	0   0   100 0   0   0   0   0   0   0   # 3
HL
ab	0   0   0   0   0   0   0   101 102 103 0   104 0   105 0   106
HL
ab	107 108 109 110 0   0   0   0   0   0   0   111 112 113 0   0 
HL
ab      0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   # 6
HL
ab      0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   # 7
HL
ab      0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   # 8
HL
ab      0   0   0   0   0   0   0   0   0   0   0   0   224 225 0   0
HL
ab      0   0   0   0   0   0   0   0   0   0   226 0   0   0   0   0
HL
ab      0   0   0   0   0   227 0   0   228 0   0   0   0   0   0   0   # b
HL
ab      0   0   0   0   0   0   0   229 230 231 0   232 0   233 0   234
HL
ab      235 236 237 238 0   0   0   0   0   0   0   239 240 241 0   0
HL
ab      0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   #
HL
ab      0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   #




echo "
cPC keyboard reflex. Uses some fancy osimplay; xray, ring... MF II is just
enough (retarded) parsing to be really annoying. I want to think of it as
a lookup table, hence the eXecution arRAY. Common case is like 14
instructions. An interrupt costs 50 clocks minimum, one way. Not bad for a
lossless muxing driver. The illogic of the MF II stuff is spread between
the xray, the table, and a couple special cases.

I uniquely ID all keys by the second byte recieved. I ring buffer all
makes and breaks, and each half-stroke increments the events-eLAPsed
counter. Keys with more that 2 bytes of MF II spam hike a spam counter
appropriately so the spam can be dropped. The logic of the key event spam
counter is an underrunning down-counter with an effective pad of only 2
billion events. You've been warned ;o)

This implements an arbitrary contiguous sequence of codes for the MF II
keys in occurance order, at 96 & up, plus the up sides (breaks) which _DO_
have bit7 on in the ring buffer. A ring buffer with an eLAPsed counter
serves multiple readers (multiplexes) easily. That's not how multiplexing
will work though. You can't let processes write thier own indexes in
0wnerland. Each listener will get a localized copy of the ringbuffer. Thus
each process has a virtual keyboard with no syscalls required. This is
some system load, but hugely simple. And all of ownerland only needs one
keyboard transmitter. And only guest processes on the local box will need
copies of the console KBD.

keyreflex only uses regs A and D.

" > /dev/null

