From: Tulio A M Mendes Date: Thu, 12 Feb 2026 07:32:51 +0000 (-0300) Subject: feat: /dev/kbd raw scancode device for game input (DOOM) X-Git-Url: https://projects.tadryanom.me/docs/static/git-logo.png?a=commitdiff_plain;h=584b03329012fbfbe8fcaae35d727577032fd794;p=AdrOS.git feat: /dev/kbd raw scancode device for game input (DOOM) Added raw scancode ring buffer to the keyboard driver. The HAL keyboard layer now fires a second callback with the unprocessed scancode byte (both key-press and key-release events). - hal/keyboard.h: added hal_keyboard_scan_cb_t and setter - hal/x86/keyboard.c: fires g_scan_cb before ASCII translation - drivers/keyboard.c: raw scancode buffer + /dev/kbd device node registered via devfs (non-blocking read returns raw scancodes) - init.c: calls keyboard_register_devfs() after devfs is mounted DOOM can now open /dev/kbd and read raw PS/2 scancodes to detect key press/release events without TTY line buffering. --- diff --git a/include/hal/keyboard.h b/include/hal/keyboard.h index a2cc84c..7dfe025 100644 --- a/include/hal/keyboard.h +++ b/include/hal/keyboard.h @@ -1,8 +1,12 @@ #ifndef HAL_KEYBOARD_H #define HAL_KEYBOARD_H +#include + typedef void (*hal_keyboard_char_cb_t)(char c); +typedef void (*hal_keyboard_scan_cb_t)(uint8_t scancode); void hal_keyboard_init(hal_keyboard_char_cb_t cb); +void hal_keyboard_set_scancode_cb(hal_keyboard_scan_cb_t cb); #endif diff --git a/include/keyboard.h b/include/keyboard.h index 31cc041..41f11e3 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -7,6 +7,7 @@ typedef void (*keyboard_callback_t)(char); void keyboard_init(void); +void keyboard_register_devfs(void); void keyboard_set_callback(keyboard_callback_t callback); int keyboard_read_nonblock(char* out, uint32_t max_len); diff --git a/src/drivers/keyboard.c b/src/drivers/keyboard.c index 4357aad..7142a51 100644 --- a/src/drivers/keyboard.c +++ b/src/drivers/keyboard.c @@ -1,4 +1,5 @@ #include "keyboard.h" +#include "devfs.h" #include "uart_console.h" #include @@ -46,13 +47,65 @@ static void hal_kbd_bridge(char c) { } } +/* --- Raw scancode ring buffer for /dev/kbd --- */ + +#define SCAN_BUF_SIZE 256 +static volatile uint32_t scan_head = 0; +static volatile uint32_t scan_tail = 0; +static uint8_t scan_buf[SCAN_BUF_SIZE]; +static spinlock_t scan_lock = {0}; + +static void scan_push(uint8_t sc) { + uint32_t next = (scan_head + 1U) % SCAN_BUF_SIZE; + if (next == scan_tail) { + scan_tail = (scan_tail + 1U) % SCAN_BUF_SIZE; + } + scan_buf[scan_head] = sc; + scan_head = next; +} + +static void hal_scan_bridge(uint8_t scancode) { + uintptr_t flags = spin_lock_irqsave(&scan_lock); + scan_push(scancode); + spin_unlock_irqrestore(&scan_lock, flags); +} + +static uint32_t kbd_dev_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) { + (void)node; (void)offset; + if (!buffer || size == 0) return 0; + + uintptr_t flags = spin_lock_irqsave(&scan_lock); + uint32_t count = 0; + while (count < size && scan_tail != scan_head) { + buffer[count++] = scan_buf[scan_tail]; + scan_tail = (scan_tail + 1U) % SCAN_BUF_SIZE; + } + spin_unlock_irqrestore(&scan_lock, flags); + return count; +} + +static fs_node_t g_dev_kbd_node; + void keyboard_init(void) { uart_print("[KBD] Initializing Keyboard Driver...\n"); spinlock_init(&kbd_lock); + spinlock_init(&scan_lock); kbd_head = 0; kbd_tail = 0; + scan_head = 0; + scan_tail = 0; kbd_waiter = NULL; hal_keyboard_init(hal_kbd_bridge); + hal_keyboard_set_scancode_cb(hal_scan_bridge); +} + +void keyboard_register_devfs(void) { + memset(&g_dev_kbd_node, 0, sizeof(g_dev_kbd_node)); + strcpy(g_dev_kbd_node.name, "kbd"); + g_dev_kbd_node.flags = FS_CHARDEVICE; + g_dev_kbd_node.inode = 21; + g_dev_kbd_node.read = &kbd_dev_read; + devfs_register_device(&g_dev_kbd_node); } void keyboard_set_callback(keyboard_callback_t callback) { diff --git a/src/hal/x86/keyboard.c b/src/hal/x86/keyboard.c index 9f39e2e..546e1eb 100644 --- a/src/hal/x86/keyboard.c +++ b/src/hal/x86/keyboard.c @@ -5,6 +5,7 @@ #include "io.h" static hal_keyboard_char_cb_t g_cb = 0; +static hal_keyboard_scan_cb_t g_scan_cb = 0; static char scancode_map[128] = { 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', @@ -51,6 +52,11 @@ static void kbd_irq(struct registers* regs) { if (status & 0x01) { uint8_t scancode = inb(0x60); + /* Raw scancode callback (key press and release) */ + if (g_scan_cb) { + g_scan_cb(scancode); + } + if (!(scancode & 0x80)) { if (scancode < 128) { char c = scancode_map[scancode]; @@ -66,8 +72,16 @@ void hal_keyboard_init(hal_keyboard_char_cb_t cb) { g_cb = cb; register_interrupt_handler(33, kbd_irq); } + +void hal_keyboard_set_scancode_cb(hal_keyboard_scan_cb_t cb) { + g_scan_cb = cb; +} #else void hal_keyboard_init(hal_keyboard_char_cb_t cb) { (void)cb; } + +void hal_keyboard_set_scancode_cb(hal_keyboard_scan_cb_t cb) { + (void)cb; +} #endif diff --git a/src/kernel/init.c b/src/kernel/init.c index 2ef9cfa..632d773 100644 --- a/src/kernel/init.c +++ b/src/kernel/init.c @@ -86,6 +86,7 @@ int init_start(const struct boot_info* bi) { } vbe_register_devfs(); + keyboard_register_devfs(); fs_node_t* persist = persistfs_create_root(); if (persist) {