keyboard.c

Commit: d8432d7b Author: jokerz Raw Copy
1
/* ============================================================================
2
 * Pactor64 — PS/2 Keyboard Driver (x86-64)
3
 * IRQ1 (INT 0x21), scancode set 1, circular buffer
4
 * ============================================================================ */
5
#include "../include/pactor64.h"
6
7
/* === Scancode → ASCII lookup (scancode set 1) === */
8
static const char sc1_to_ascii[128] = {
9
    0,   0,  '1', '2', '3', '4', '5', '6',   /* 0x00-0x07 */
10
   '7', '8', '9', '0', '-', '=', '\b', '\t',  /* 0x08-0x0F */
11
   'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',   /* 0x10-0x17 */
12
   'o', 'p', '[', ']', '\n',  0,  'a', 's',   /* 0x18-0x1F */
13
   'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',   /* 0x20-0x27 */
14
   '\'', '`',  0, '\\', 'z', 'x', 'c', 'v',  /* 0x28-0x2F */
15
   'b', 'n', 'm', ',', '.', '/',  0,  '*',    /* 0x30-0x37 */
16
    0,  ' ',  0,   0,   0,   0,   0,   0,     /* 0x38-0x3F */
17
    0,   0,   0,   0,   0,   0,   0,   0,     /* 0x40-0x47 */
18
    0,   0,  '-',  0,   0,   0,  '+',  0,     /* 0x48-0x4F */
19
    0,   0,   0,   0,   0,   0,   0,   0,     /* 0x50-0x57 */
20
    0,   0,   0,   0,   0,   0,   0,   0,     /* 0x58-0x5F */
21
    0,   0,   0,   0,   0,   0,   0,   0,     /* 0x60-0x67 */
22
    0,   0,   0,   0,   0,   0,   0,   0,     /* 0x68-0x6F */
23
    0,   0,   0,   0,   0,   0,   0,   0,     /* 0x70-0x77 */
24
    0,   0,   0,   0,   0,   0,   0,   0      /* 0x78-0x7F */
25
};
26
27
/* === Circular scancode buffer === */
28
#define KBD_BUF_SIZE 256
29
static volatile char    kbd_buf[KBD_BUF_SIZE];
30
static volatile int     kbd_buf_head = 0;
31
static volatile int     kbd_buf_tail = 0;
32
33
/* Forward declaration */
34
extern void irq_install(int irq, void (*handler)(registers_t *regs));
35
36
/* === Keyboard ISR (IRQ1) === */
37
static void keyboard_isr(registers_t *regs) {
38
    (void)regs;
39
    uint8_t scancode = inb(KBD_DATA_PORT);
40
41
    /* Ignore key releases (bit 7 set) */
42
    if (scancode & 0x80) return;
43
44
    char c = sc1_to_ascii[scancode];
45
    if (c == 0) return;
46
47
    /* Insert into circular buffer */
48
    int next = (kbd_buf_head + 1) % KBD_BUF_SIZE;
49
    if (next != kbd_buf_tail) {
50
        kbd_buf[kbd_buf_head] = c;
51
        kbd_buf_head = next;
52
    }
53
}
54
55
/* === Initialize keyboard === */
56
void keyboard_init(void) {
57
    kbd_buf_head = 0;
58
    kbd_buf_tail = 0;
59
60
    /* Drain any pending data */
61
    while (inb(KBD_STATUS_PORT) & 0x01) {
62
        inb(KBD_DATA_PORT);
63
    }
64
65
    irq_install(0x21, keyboard_isr);
66
    pic_unmask_irq(1);
67
}
68
69
/* === Read a character from keyboard buffer (non-blocking, returns -1 if empty) === */
70
int keyboard_getchar(void) {
71
    if (kbd_buf_head == kbd_buf_tail) return -1;
72
    char c = kbd_buf[kbd_buf_tail];
73
    kbd_buf_tail = (kbd_buf_tail + 1) % KBD_BUF_SIZE;
74
    return c;
75
}
76