/* StarForth — Steady-State Virtual Machine Runtime Copyright (c) 2023–2025 Robert A. James All rights reserved. Licensed under the StarForth License, Version 1.0 */ /* keyboard_words.c — raw scancode-ring diagnostic word (FABRIC.md item * 4.3.5). Kernel-only, amd64-only; no-op elsewhere. */ #include "include/keyboard_words.h" #include "../../include/word_registry.h" #if defined(__STARKERNEL__) && defined(ARCH_AMD64) #include "starkernel/i8042.h" #endif #if defined(__STARKERNEL__) && defined(ARCH_RISCV64) #include "starkernel/virtio_input.h" #endif /* KBD-SCAN ( -- c -1 | 0 ) */ static void kbw_scan(VM *vm) { #if defined(__STARKERNEL__) && defined(ARCH_AMD64) uint8_t sc; if (i8042_pop_scancode(&sc)) { vm_push(vm, (cell_t)sc); vm_push(vm, -1); } else { vm_push(vm, 0); } #else vm_push(vm, 0); #endif } /* KBD-DEBUG ( -- isr_count spurious_count ): cheap standing diagnostic, * not scaffolding -- confirms the interrupt path is alive (isr_count) and * flags the failure mode item 4.3.5 found (a real IRQ misreported as * spurious) without needing a live debugger. */ extern volatile uint32_t g_i8042_isr_count; extern volatile uint32_t g_spurious_count; static void kbw_debug(VM *vm) { #if defined(__STARKERNEL__) && defined(ARCH_AMD64) vm_push(vm, (cell_t)g_i8042_isr_count); vm_push(vm, (cell_t)g_spurious_count); #else vm_push(vm, 0); vm_push(vm, 0); #endif } /* VKBD-EVENT ( -- code value -1 | 0 ): item 4.3.5c, riscv64 virtio-input. * Pop one decoded EV_KEY event off the interrupt-fed ring buffer. Pushes * code and value and -1 (true) if one was available, or just 0 (false) if * the buffer was empty. Distinct word from KBD-SCAN rather than a shared * one: different device, different event shape (Linux-style code/value * pair vs. a raw XT scancode byte) -- convergence onto one interface is * item 4.3.5f's explicit job, not this one's. */ static void kbw_vevent(VM *vm) { #if defined(__STARKERNEL__) && defined(ARCH_RISCV64) 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); vm_push(vm, -1); } else { vm_push(vm, 0); } #else vm_push(vm, 0); #endif } /* VKBD-DEBUG ( -- isr_count ): standing diagnostic, same shape as * KBD-DEBUG -- confirms the virtio-input interrupt path is alive. */ extern volatile uint32_t g_virtio_input_isr_count; static void kbw_vdebug(VM *vm) { #if defined(__STARKERNEL__) && defined(ARCH_RISCV64) vm_push(vm, (cell_t)g_virtio_input_isr_count); #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); }