###      FORREAL MODE   	32unP


#### 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 ring buffer.
#    keyreflex uses an xray. keyvent is the MFII->keycode table.
# The xray is 1k of "code" in a reflex, but it only rides one beam per hit.
#
 # The Ha3sm keyboard driver is make/break in the ring, no typematic. The
 #  mouse stuff is off IRQ firstIRQ+12.


			# two osimplay extensions or macros.

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


DISMISSKBD32unP () {		# callee-saves mux.
	pull D
	pull A
	dismisso
		}


cell 	keyspam	 was_e0	 numlock  keybytesseen


L 	keyreflex32unP
		# the keyboard IRQ reflex
		# Key byte, cPC INT firstIRQ+1, happened. IRET frame on estack.
		# Register values belong to someone else. We're the boss
		# because we do stuff like save the 2 we use first.
		# We push A and D here, pull them in all the exit points
		#	courtesy of DISMISSKBD32unP
push A
push D
zero A				# clean index
recieve 0x60	byte		# Got it. Now what?

1- @ $keyspam
	when	sign	notkeyspam
					DISMISSKBD32unP
  L notkeyspam
		xjump $keybyte A	
  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


# beam
  L askoverloadedkey			
	ANDtest -1 with @ $was_e0
	when	not zero	overloadedkey
		= A to D
		RINGKEY32unP
						DISMISSKBD32unP
     L overloadedkey
	= 0 to @ $((was_e0))	
	= @ $((keyvent)) A to A
	ANDtest -1 with @ $((numlock))
		when	not	zero	nonumlock
	= 2 to @ $keyspam
     L nonumlock
        = A to D
        RINGKEY32unP
        	DISMISSKBD32unP



# beam
  L plainkey				
	= A to D
	RINGKEY32unP
				DISMISSKBD32unP

# beam
  L do_e0			# set a switch, no save on this trip
	= -1 to @ $was_e0
				DISMISSKBD32unP



# beam
  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
        RINGKEY32unP
        = $((114+128)) to A
        = A to D
        RINGKEY32unP
			DISMISSKBD32unP


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




strand keyring 128 1



L keyvent
#	0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f

ab 	0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   # 0
ab	0   0   0   0   0   0   0   0   0   0   0   0   96  97  0   0
ab	0   0   0   0   0   0   0   0   0   0   98  0   0   0   0   0
ab	0   0   0   0   0   99	0   0   100 0   0   0   0   0   0   0   # 3
ab	0   0   0   0   0   0   0   101 102 103 0   104 0   105 0   106
ab	107 108 109 110 0   0   0   0   0   0   0   111 112 113 0   0 
ab      0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   # 6
ab      0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   # 7
ab      0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   # 8
ab      0   0   0   0   0   0   0   0   0   0   0   0   224 225 0   0
ab      0   0   0   0   0   0   0   0   0   0   226 0   0   0   0   0
ab      0   0   0   0   0   227 0   0   228 0   0   0   0   0   0   0   # b
ab      0   0   0   0   0   0   0   229 230 231 0   232 0   233 0   234
ab      235 236 237 238 0   0   0   0   0   0   0   239 240 241 0   0
ab      0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   #
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.

We uniquely ID all keys by the second byte recieved. We 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, and save the A and D of the interrupted
thread of course.




" > /dev/null

