]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
feat: /dev/kbd raw scancode device for game input (DOOM)
authorTulio A M Mendes <[email protected]>
Thu, 12 Feb 2026 07:32:51 +0000 (04:32 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 02:44:55 +0000 (23:44 -0300)
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.

include/hal/keyboard.h
include/keyboard.h
src/drivers/keyboard.c
src/hal/x86/keyboard.c
src/kernel/init.c

index a2cc84c164f0b1d52945879ef2e508ae5024f56c..7dfe025a2adbeda9c467ce3e27c38828c2d97571 100644 (file)
@@ -1,8 +1,12 @@
 #ifndef HAL_KEYBOARD_H
 #define HAL_KEYBOARD_H
 
+#include <stdint.h>
+
 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
index 31cc0418b6eeebc54e82df31758fac25d1a9ea6b..41f11e3cdcca357ad74714eb675006c5d788da73 100644 (file)
@@ -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);
index 4357aad32229f44939b887b371446bf0c56a18d7..7142a51f32e5dda85a896d7152cc5f3748153058 100644 (file)
@@ -1,4 +1,5 @@
 #include "keyboard.h"
+#include "devfs.h"
 #include "uart_console.h"
 #include <stddef.h>
 
@@ -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) {
index 9f39e2e24251044a5688e4db3718463aab5cff80..546e1eb525b1910853e0be73bbb9d015a735fc53 100644 (file)
@@ -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
index 2ef9cfaa31a3253da6b4f0232d7ce4cb8f8b74dc..632d773e3328af5cbde279e867e2766e66631a28 100644 (file)
@@ -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) {