/* ============================================================================ * Pactor64 — PS/2 Keyboard Driver (x86-64) * IRQ1 (INT 0x21), scancode set 1, circular buffer * ============================================================================ */ #include "../include/pactor64.h" /* === Scancode → ASCII lookup (scancode set 1) === */ static const char sc1_to_ascii[128] = { 0, 0, '1', '2', '3', '4', '5', '6', /* 0x00-0x07 */ '7', '8', '9', '0', '-', '=', '\b', '\t', /* 0x08-0x0F */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 0x10-0x17 */ 'o', 'p', '[', ']', '\n', 0, 'a', 's', /* 0x18-0x1F */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 0x20-0x27 */ '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', /* 0x28-0x2F */ 'b', 'n', 'm', ',', '.', '/', 0, '*', /* 0x30-0x37 */ 0, ' ', 0, 0, 0, 0, 0, 0, /* 0x38-0x3F */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x47 */ 0, 0, '-', 0, 0, 0, '+', 0, /* 0x48-0x4F */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x57 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x58-0x5F */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x68-0x6F */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */ 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7F */ }; /* === Circular scancode buffer === */ #define KBD_BUF_SIZE 256 static volatile char kbd_buf[KBD_BUF_SIZE]; static volatile int kbd_buf_head = 0; static volatile int kbd_buf_tail = 0; /* Forward declaration */ extern void irq_install(int irq, void (*handler)(registers_t *regs)); /* === Keyboard ISR (IRQ1) === */ static void keyboard_isr(registers_t *regs) { (void)regs; uint8_t scancode = inb(KBD_DATA_PORT); /* Ignore key releases (bit 7 set) */ if (scancode & 0x80) return; char c = sc1_to_ascii[scancode]; if (c == 0) return; /* Insert into circular buffer */ int next = (kbd_buf_head + 1) % KBD_BUF_SIZE; if (next != kbd_buf_tail) { kbd_buf[kbd_buf_head] = c; kbd_buf_head = next; } } /* === Initialize keyboard === */ void keyboard_init(void) { kbd_buf_head = 0; kbd_buf_tail = 0; /* Drain any pending data */ while (inb(KBD_STATUS_PORT) & 0x01) { inb(KBD_DATA_PORT); } irq_install(0x21, keyboard_isr); pic_unmask_irq(1); } /* === Read a character from keyboard buffer (non-blocking, returns -1 if empty) === */ int keyboard_getchar(void) { if (kbd_buf_head == kbd_buf_tail) return -1; char c = kbd_buf[kbd_buf_tail]; kbd_buf_tail = (kbd_buf_tail + 1) % KBD_BUF_SIZE; return c; }