From 2591ad735d1b1c87facd251239141158f273b48c Mon Sep 17 00:00:00 2001 From: Nathan Wagner Date: Mon, 24 Oct 2016 20:33:22 -0500 Subject: [PATCH] keyboard interrupt handling --- kbd.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ kbd.h | 1 + 2 files changed, 84 insertions(+) create mode 100644 kbd.c create mode 100644 kbd.h diff --git a/kbd.c b/kbd.c new file mode 100644 index 0000000..cf62b72 --- /dev/null +++ b/kbd.c @@ -0,0 +1,83 @@ +#include + +#include "kernel.h" +#include "kbd.h" +#include "interrupt.h" +#include "tty.h" +#include "pic.h" +#include "ioport.h" + +static struct interrupt_handler keyboard; + +static unsigned char keymap[128] = { + 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', + 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', + 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, + '*', '0', ' ', 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static unsigned char keymap_shift[128] = { + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', + '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', + 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', + 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0, + '*', '0', ' ', 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static unsigned int kbd_state = 0; + +static unsigned char keyboard_decode(unsigned char scancode) { + if (scancode & 0x80) { + /* break */ + scancode = scancode & 0x7F; + if (scancode == 0x2A || scancode == 0x36) { + /* left or right shift */ + kbd_state = 0; + } + return 0; + } else { + if (scancode == 0x2A || scancode == 0x36) { + kbd_state = 1; + return 0; + } + + if (kbd_state == 1) { + return keymap_shift[scancode]; + } else { + return keymap[scancode]; + } + } +} + +static void keyboard_handler(struct interrupt_context *c, void *unused) { + unsigned char code; + unsigned char scancode; + + scancode = inport8(0x60); + + code = keyboard_decode(scancode); + + /* TODO deliver to process with console open */ + /* will need a notion of 'foreground' and 'background' processes */ + /* might make sense to just hand it off to whatever terminal it is + * attached to + */ + if(code) { + printk("%c", code); + } + code = scancode; +} + +void init_keyboard() { + keyboard.handler = keyboard_handler; + keyboard.context = 0; + + interrupt_add_handler(IRQ1, &keyboard); +} diff --git a/kbd.h b/kbd.h new file mode 100644 index 0000000..64c0482 --- /dev/null +++ b/kbd.h @@ -0,0 +1 @@ +void init_keyboard(); -- 2.40.0