]> pd.if.org Git - zos/commitdiff
keyboard interrupt handling
authorNathan Wagner <nw@hydaspes.if.org>
Tue, 25 Oct 2016 01:33:22 +0000 (20:33 -0500)
committerNathan Wagner <nw@hydaspes.if.org>
Tue, 25 Oct 2016 04:00:24 +0000 (23:00 -0500)
kbd.c [new file with mode: 0644]
kbd.h [new file with mode: 0644]

diff --git a/kbd.c b/kbd.c
new file mode 100644 (file)
index 0000000..cf62b72
--- /dev/null
+++ b/kbd.c
@@ -0,0 +1,83 @@
+#include <stdint.h>
+
+#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 (file)
index 0000000..64c0482
--- /dev/null
+++ b/kbd.h
@@ -0,0 +1 @@
+void init_keyboard();