Structure of a key handler: The handler starts with the following structure: +0: Offset to simple translation table +4: Number of entries in simple translation table +8: Offset to internal key mapping (-ve INKEY) table +12: Offset to list of shifting keys +16: Offset to list of special keys +20: Offset to list of special key code entries +24: Offset to initialisation entry point +28: Offset to pending Alt code routine +32: Optional flags word (present if bit 31 of +4 is set) KeyBdStatus is a bitfield: Bit 0: KBStat_PendingAlt 1: KBStat_ScrollLack 2: KBStat_NoNumLock 3: KBStat_ShiftEngaged 4: KBStat_CapsLock 5: KBStat_NoShiftLock 6: KBStat_CtrlEngaged 7: KBStat_ShiftEnable This is the byte referenced by OS_Byte 202. PendingAltType is a byte that is conventionally used to store information about pending conditions (eg dead accents). Initialisation entry point -------------------------- In: R0->handler R1=keyboard ID R5=KeyBdStatus R7=PendingAltType R12->fixed workspace (allocated by kernel) - approx 170 bytes, not aligned Out: All registers preserved, except R5 and R7 can be updated, R8 corrupted. This is called once on initialisation of the keyboard driver. Simple translation table ------------------------ This is a table of bytes. When a key is pressed, the kernel looks up byte (low-level key number)*4 + (1 if shift enabled) + (2 if ctrl enabled). If the byte read is FF, or the key number is outside the table, then the key is decided to be "special" and looked up in the special table. Otherwise the key is modified by the kernel for caps lock (if it decides it is alphanumeric), and inserted into the keyboard buffer. Hence bytes 80-FE are interpreted as function keys. Autorepeat and debounce are handled automatically in this case. If the key is outside this list or is special (all four bytes &FF) and is on the shifting list (see below) the kernel will not autorepeat it and will not perform rollover. The special code (if any) will be called for both up and down. This is intended for Shift,Ctrl,Alt,mouse buttons etc. Internal key mapping -------------------- This is a table of words. Word N-&80 corresponds to OS_Byte 129 N 255 (ie internal key number 128-N). Each word is treated as four bytes - each byte corresponding to a low-level key number that corresponds to this INKEY- number, or &FF. For example, the entry for INKEY-1 is &FFFF4C58, meaning that low level keys &4C and &58 make INKEY-1 return true. This table is normally constant across all keyboards. Shifting key list ----------------- Byte 0: Number of entries (n) Bytes 1-n: Low level key numbers This table is a list of modifier keys. Typically this comprises: Left Shift, Right Shift, Left Ctrl, Right Ctrl, Left Alt, Right Alt, Select, Menu, Adjust Special key list ---------------- Byte 0: Number of entries (n) Bytes 1-n: Low level key numbers This lists the keys that have special handler code. This gets invoked if the simple table contains FF (see above). Special key code list --------------------- Word 0: Offset to handler for first special key (from start of list) ... This lists the handler routines for each special key. Calling environment: In: R0->handler R1=action (shifting key:0,1=up,down; non-shifting:2=first,3=autorepeat) R2=low-level key number R3->table of exit points R4=special key number (eg 1 for first special key) R5=KeyBdStatus R6->a zero byte (so left unmodified -> no output) R7=PendingAltType R12->fixed workspace (allocated by kernel) - approx 170 bytes, not aligned Out: R0-R4 preserved R5 updated R6->output (first byte=length, subsequent bytes to insert into buffer) R7 updated R8 corrupted Alternative exits can be taken by branching to: R3+0:MouseButtonChange With R0 = new mouse button state (bits 0,1,2 = Adjust,Menu,Select) R3+4:DoBreakKey Registers as passed in to the special key handler Pending Alt Code ---------------- In: R0->handler R1=action (2=first,3=autorepeat) R2=low-level key number R3=character that would normally be generated (from the simple table) R5=KeyBdStatus R6->a zero byte (so left unmodified -> no output) R7=PendingAltType R12->fixed workspace (allocated by kernel) - approx 170 bytes, not aligned Out: R0-R4 preserved R5 updated R6->output (first byte=length, subsequent bytes to insert into buffer) R7 updated R8 corrupted This code is called if a simple key is pressed while the PendingAlt bit is set, instead of the character in the simple table being generated. Flags word ---------- Bit Meaning 0 Key handler uses wide (16 bit) key numbers Wide key numbers ---------------- If wide key numbers are in use, the following changes to the key handler format are in effect: * The simple translation table contains 16 bit entries, not 8 bit. &FF still corresponds to "no mapping" * The internal key mapping table has 2x16 bit entries per key, not 4x8 bit entries. &FF still corresponds to "no mapping" * The shifting key list & special key list contain 16 bit entries, not 8 bit. The entry count is also a 16 bit value.