FORTH: KEY-EVENT unified keyboard interface, closes 4.3.5-4.3.5f (item 4.3.5f)

Punch list §25 item 4.3.5f complete. Keyboard-input slice done.

New KEY-EVENT ( -- keycode pressed -1 | 0 ) converges amd64's i8042,
riscv64's and aarch64's virtio-keyboard-pci behind one shape. Translation
needed is minimal: XT Set-1 make codes and Linux input keycodes are
numerically identical across the standard 84-key block (a documented
historical property of the Linux input subsystem, confirmed against this
host's own headers and this tree's own prior live observations), so amd64
needs two lines, riscv64/aarch64 need none. Verified live with a real
keypress on all three architectures: identical "-1 1 30" output everywhere.
Three-arch acceptance boot clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-08 12:48:05 -04:00
co-authored by Claude Sonnet 5
parent a373c9124a
commit d0835c674b
17 changed files with 108582 additions and 75 deletions
+9
View File
@@ -41,6 +41,15 @@
*
* @par VKBD-DEBUG ( -- isr_count )
* Standing diagnostic: count of virtio-input ISR invocations since boot.
*
* @par KEY-EVENT ( -- keycode pressed -1 | 0 )
* Item 4.3.5f convergence checkpoint. One shared event shape across all
* three architectures: keycode in the Linux input keycode namespace
* (identical numbering to amd64's raw XT Set-1 scancode for the
* non-extended key range, by historical design, not translated arbitrarily
* -- see the implementation's own doc comment), pressed is 1 or 0. This is
* the word the later REPL keyboard-input work (M8) is expected to build
* on; KBD-SCAN/VKBD-EVENT remain as lower-level per-device diagnostics.
* @}
*/
+53
View File
@@ -91,10 +91,63 @@ static void kbw_vdebug(VM *vm)
#endif
}
/* KEY-EVENT ( -- keycode pressed -1 | 0 ): item 4.3.5f convergence
* checkpoint. One shared shape across all three architectures instead of
* KBD-SCAN's raw XT scancode byte or VKBD-EVENT's Linux code/value pair.
* keycode is the Linux input keycode namespace (linux/input-event-codes.h);
* pressed is 1 (press) or 0 (release).
*
* amd64 needs a real translation, not an invented one: XT Set-1's make
* code for a key and Linux's keycode for that same key are the *same
* number*, confirmed against this build host's own
* /usr/include/linux/input-event-codes.h and against this tree's own
* live-observed values (item 4.3.5's done note: 'a' -> 30, 'b' -> 48,
* matching KEY_A=30/KEY_B=48 exactly) -- not a coincidence, a documented
* historical property of how the Linux input keycode numbering was
* originally defined around the AT/XT scancode set. Break codes set XT's
* bit 7 (make|0x80) rather than carrying a separate press/release field,
* so `keycode = sc & 0x7F, pressed = !(sc & 0x80)` is the whole
* translation for the entire non-extended key range. Extended
* (0xE0-prefixed) scancodes are not decoded here -- this checkpoint needs
* one shared shape proven live per architecture, not full keyboard
* coverage; that belongs to the REPL wiring item (M8) this checkpoint
* unblocks.
*
* riscv64/aarch64 need no translation at all -- virtio-input's `code`
* field already lives in the same Linux keycode namespace; `value` is
* mapped 1:1 except autorepeat (value=2), folded into "still pressed"
* here since this checkpoint's shape only distinguishes press/release. */
static void kbw_key_event(VM *vm)
{
#if defined(__STARKERNEL__) && defined(ARCH_AMD64)
uint8_t sc;
if (i8042_pop_scancode(&sc)) {
vm_push(vm, (cell_t)(sc & 0x7Fu));
vm_push(vm, (cell_t)((sc & 0x80u) ? 0 : 1));
vm_push(vm, -1);
} else {
vm_push(vm, 0);
}
#elif defined(__STARKERNEL__) && (defined(ARCH_RISCV64) || defined(ARCH_AARCH64))
uint16_t code;
uint32_t value;
if (virtio_input_pop_event(&code, &value)) {
vm_push(vm, (cell_t)code);
vm_push(vm, (cell_t)(value == 0u ? 0 : 1));
vm_push(vm, -1);
} else {
vm_push(vm, 0);
}
#else
vm_push(vm, 0);
#endif
}
void register_keyboard_words(VM *vm)
{
register_word(vm, "KBD-SCAN", kbw_scan);
register_word(vm, "KBD-DEBUG", kbw_debug);
register_word(vm, "VKBD-EVENT", kbw_vevent);
register_word(vm, "VKBD-DEBUG", kbw_vdebug);
register_word(vm, "KEY-EVENT", kbw_key_event);
}