Heap: Protect multiboot module command line
[snowy-minesweeper.git] / kbd.c
blobdd5a552f428bb716356d84ddf6cf46aa819e29f0
1 #include "kbd.h"
2 #include "console.h"
3 #include "io.h"
5 #define KBD_DATA 0x60
6 #define KBD_STATUS 0x64
8 #define KBD_BUF_SIZE 16
9 static int kbd_buf[KBD_BUF_SIZE];
10 static int kbd_buf_head, kbd_buf_tail;
12 void kbd_cmd(unsigned char cmd)
14 while (inb(KBD_STATUS) & 0x2);
15 outb(KBD_DATA, cmd);
17 while ((inb(KBD_STATUS) & 0x1) == 0);
18 inb(KBD_DATA);
21 void kbd_init(void)
23 while (inb(KBD_STATUS) & 0x1) {
24 inb(KBD_DATA);
27 kbd_cmd(0xf4);
30 static void kbd_queue_key(int scancode)
32 if ((kbd_buf_head + 1) % KBD_BUF_SIZE == kbd_buf_tail) {
33 /* Buffer full, ignore keypress */
34 return;
37 kbd_buf[kbd_buf_head] = scancode;
38 kbd_buf_head = (kbd_buf_head + 1) % KBD_BUF_SIZE;
41 int kbd_wait_key(void)
43 int ret;
45 while (kbd_buf_head == kbd_buf_tail) {
46 asm volatile("hlt");
49 ret = kbd_buf[kbd_buf_tail];
50 kbd_buf_tail = (kbd_buf_tail + 1) % KBD_BUF_SIZE;
51 return ret;
54 void kbd_intr(void)
56 static enum {
57 KBD_STATE_NORMAL,
58 KBD_STATE_E0,
59 } kbd_state = KBD_STATE_NORMAL;
61 int scancode = inb(KBD_DATA);
63 switch (kbd_state) {
64 case KBD_STATE_NORMAL:
65 if (scancode == 0xe0) {
66 kbd_state = KBD_STATE_E0;
67 return;
69 if (scancode & 0x80) {
70 /* Ignore break codes */
71 return;
73 kbd_queue_key(scancode);
74 break;
76 case KBD_STATE_E0:
77 kbd_state = KBD_STATE_NORMAL;
78 if (scancode & 0x80) {
79 /* Ignore break codes */
80 return;
82 kbd_queue_key(0x100 | scancode);
83 break;