Add preliminary PS/2 keyboard support
diff --git a/src/Makefile b/src/Makefile
index b9f1708..a1527de 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -10,7 +10,8 @@
 			pic.o \
 			timer.o \
 			paging.o \
-			switch_table.o
+			switch_table.o \
+			scan_codes.o
 CFLAGS = -nostdlib -nostdinc -fno-builtin -fno-stack-protector -ffreestanding -m32 -O2 -g
 LDFLAGS = -Tlink.ld -melf_i386
 ASMFLAGS = -felf
@@ -34,6 +35,9 @@
 qemu-iso: install
 	qemu-system-i386 $(QEMUFLAGS) -monitor stdio ../bin/bluejay.iso
 
+scan_codes.c: gen_scan_codes.py scan_codes.tsv 
+	python3 $< > $@
+
 .s.o:
 	nasm $(ASMFLAGS) $<
 
diff --git a/src/gen_scan_codes.py b/src/gen_scan_codes.py
new file mode 100644
index 0000000..6bf68c9
--- /dev/null
+++ b/src/gen_scan_codes.py
@@ -0,0 +1,48 @@
+# Generate scan_codes.h from scan_codes.tsv
+
+from functools import reduce
+
+def symbolify(s):
+    if not s.startswith("'"):
+        return s.replace('+', 'PLUS').replace('*', 'TIMES').replace('/', 'DIV').replace('-', 'MINUS').replace('.', 'DOT')
+    else: return s
+
+def gen_set_entry(set, line):
+    parts = line.split('\t')
+
+    make_break = parts[set]
+    [make, brk] = [[int(y, 16) for y in x.split(' ')] for x in make_break.replace('(base)', '').strip().split('/')]
+    brk_pfx = brk[0]
+    if not set == 1:
+        brk = brk[1:]
+
+    if make[0] == 0xe0 or make[0] == 0xe1:
+        return
+
+    [make, brk] = [reduce(lambda o, n: o << 8 | n, x, 0) for x in [make, brk]]
+
+    ascii = str(parts[6] == 'yes').lower()
+    symbol = symbolify(parts[7])
+    upper_symbol = symbolify(parts[8])
+    
+    print(f"""\t[{make}] = {'{'} .ascii = {ascii}, .symbol = {symbol},
+\t\t.up_symbol = {upper_symbol}, .prefix = {brk_pfx} {'}'},""")
+
+    if set == 1:
+        print(f"""\t[{brk}] = {'{'} .ascii = {ascii}, .symbol = {symbol},
+\t\t.up_symbol = {upper_symbol}, .prefix = {brk_pfx}, .brk = true {'}'},""")
+
+def gen_set(lines, set):
+    # NOTE will only work with scan code set 3
+    print("const struct kbd_scan_codes scan_code_set_" + str(set) + "[0xff] =\n{")
+    for l in lines:
+        gen_set_entry(set, l)
+    print("};")
+
+with open('scan_codes.tsv', 'r') as f:
+    lines = f.read().split('\n')[1:]
+    print('#include "kbd.h"\n\n')
+    gen_set(lines, 1)
+    print('\n')
+    gen_set(lines, 3)
+
diff --git a/src/io.c b/src/io.c
index 52e5d04..55bf7a7 100644
--- a/src/io.c
+++ b/src/io.c
@@ -1,4 +1,17 @@
 #include "io.h"
+#include "kbd.h"
+#include "log.h"
+#include "pic.h"
+
+bool pressed_keys[LAST_KBD_KEY];
+char special_key_mappings[LAST_KBD_KEY - FIRST_KBD_KEY] =
+{
+	[KBD_ENTER - FIRST_KBD_KEY] = '\n',
+	[KBD_SPACEBAR - FIRST_KBD_KEY] = ' ',
+	[KBD_TAB - FIRST_KBD_KEY] = '\t',
+	[KBD_BACKSPACE - FIRST_KBD_KEY] = '\b',
+	0
+};
 
 void outb(ushort port, uchar val)
 {
@@ -41,3 +54,38 @@
 {
 	asm volatile("outb %0, $0x80" ::"a"(0));
 }
+
+uchar kbd_scan_code()
+{
+	return inb(KBD_DATA_PORT);
+}
+
+static bool kbd_shift_pressed()
+{
+	return pressed_keys[KBD_LEFT_SHIFT] || pressed_keys[KBD_RIGHT_SHIFT] ||
+		   pressed_keys[KBD_CAPS_LOCK];
+}
+
+void kbd_handle_input(struct registers *registers)
+{
+	uchar byte = kbd_scan_code();
+
+	struct kbd_scan_codes code = scan_code_set_1[byte];
+
+	if (code.ascii && !code.brk)
+	{
+		kprintf("%c", kbd_shift_pressed() && code.up_symbol ? code.up_symbol
+															: code.symbol);
+	}
+	else if (!code.brk && special_key_mappings[code.symbol - FIRST_KBD_KEY])
+	{
+		kprintf("%c", special_key_mappings[code.symbol - FIRST_KBD_KEY]);
+	}
+	pressed_keys[code.symbol] = !code.brk;
+}
+
+void init_kbd()
+{
+	memset(pressed_keys, 0, LAST_KBD_KEY);
+	add_interrupt_handler(33, kbd_handle_input);
+}
diff --git a/src/io.h b/src/io.h
index ab5ce4a..28af387 100644
--- a/src/io.h
+++ b/src/io.h
@@ -1,6 +1,19 @@
 #pragma once
 
 #include "kint.h"
+#include "registers.h"
+
+#define KBD_CMD_PORT 0x64
+#define KBD_DATA_PORT 0x60
+
+struct kbd_scan_code_info
+{
+	bool pressed;
+	bool escape;
+	char key;
+};
+
+extern struct kbd_scan_code_info scan_code_table[0xff];
 
 void outb(ushort port, uchar val);
 uchar inb(ushort port);
@@ -10,3 +23,7 @@
 void *memcpy(void *dest, const void *src, size_t n);
 
 void io_wait();
+
+uchar kbd_scan_code();
+void kbd_handle_input(struct registers *registers);
+void init_kbd();
diff --git a/src/kbd.h b/src/kbd.h
new file mode 100644
index 0000000..98d6fd7
--- /dev/null
+++ b/src/kbd.h
@@ -0,0 +1,77 @@
+#pragma once
+
+#include "kint.h"
+
+struct kbd_scan_codes
+{
+	bool ascii;
+	int symbol;
+	int up_symbol;
+	uchar prefix;
+	bool brk;
+};
+
+enum kbd_keys
+{
+	FIRST_KBD_KEY = 129,
+	KBD_BACKSPACE = 129,
+	KBD_TAB,
+	KBD_CAPS_LOCK,
+	KBD_ENTER,
+	KBD_LEFT_SHIFT,
+	KBD_RIGHT_SHIFT,
+	KBD_LEFT_CTRL,
+	KBD_LEFT_ALT,
+	KBD_SPACEBAR,
+	KBD_RIGHT_ALT,
+	KBD_RIGHT_CTRL,
+	KBD_INSERT,
+	KBD_DELETE,
+	KBD_LEFT_ARROW,
+	KBD_HOME,
+	KBD_END,
+	KBD_UP_ARROW,
+	KBD_DOWN_ARROW,
+	KBD_RIGHT_ARROW,
+	KBD_NUM_LOCK,
+	KBD_KEYPAD_0,
+	KBD_KEYPAD_1,
+	KBD_KEYPAD_2,
+	KBD_KEYPAD_3,
+	KBD_KEYPAD_4,
+	KBD_KEYPAD_5,
+	KBD_KEYPAD_6,
+	KBD_KEYPAD_7,
+	KBD_KEYPAD_8,
+	KBD_KEYPAD_9,
+	KBD_KEYPAD_DOT,
+	KBD_KEYPAD_PLUS,
+	KBD_KEYPAD_MINUS,
+	KBD_KEYPAD_TIMES,
+	KBD_KEYPAD_DIV,
+	KBD_KEYPAD_ENTER,
+	KBD_ESC,
+	KBD_F1,
+	KBD_F2,
+	KBD_F3,
+	KBD_F4,
+	KBD_F5,
+	KBD_F6,
+	KBD_F7,
+	KBD_F8,
+	KBD_F9,
+	KBD_F10,
+	KBD_F11,
+	KBD_F12,
+	KBD_PRINT_SCREEN,
+	KBD_SCROLL_LOCK,
+	KBD_PAUSE_BREAK,
+	KBD_PAGE_UP,
+	KBD_PAGE_DOWN,
+	LAST_KBD_KEY,
+};
+
+extern const struct kbd_scan_codes scan_code_set_3[0xff];
+extern const struct kbd_scan_codes scan_code_set_1[0xff];
+extern bool pressed_keys[LAST_KBD_KEY];
+extern char special_key_mappings[LAST_KBD_KEY - FIRST_KBD_KEY];
diff --git a/src/kint.h b/src/kint.h
index abe7660..44b9bfd 100644
--- a/src/kint.h
+++ b/src/kint.h
@@ -15,4 +15,4 @@
 	true,
 };
 
-#define NULL ((void *)0)
+#define NULL 0
diff --git a/src/log.c b/src/log.c
index 0766a60..ac49971 100644
--- a/src/log.c
+++ b/src/log.c
@@ -34,6 +34,12 @@
 				vga_write(s);
 				break;
 			}
+
+			case 'c': {
+				char s = va_arg(args, int);
+				vga_put(s);
+				break;
+			}
 			}
 			format++;
 		}
diff --git a/src/main.c b/src/main.c
index 84f5a79..15b6c09 100644
--- a/src/main.c
+++ b/src/main.c
@@ -21,6 +21,7 @@
 	init_timer(20);
 
 	initialize_paging();
+	init_kbd();
 	asm volatile("sti");
 
 
diff --git a/src/scan_codes.c b/src/scan_codes.c
new file mode 100644
index 0000000..530fd91
--- /dev/null
+++ b/src/scan_codes.c
@@ -0,0 +1,553 @@
+#include "kbd.h"
+
+
+const struct kbd_scan_codes scan_code_set_1[0xff] =
+{
+	[41] = { .ascii = true, .symbol = '`',
+		.up_symbol = '~', .prefix = 169 },
+	[169] = { .ascii = true, .symbol = '`',
+		.up_symbol = '~', .prefix = 169, .brk = true },
+	[2] = { .ascii = true, .symbol = '1',
+		.up_symbol = '!', .prefix = 130 },
+	[130] = { .ascii = true, .symbol = '1',
+		.up_symbol = '!', .prefix = 130, .brk = true },
+	[3] = { .ascii = true, .symbol = '2',
+		.up_symbol = '@', .prefix = 131 },
+	[131] = { .ascii = true, .symbol = '2',
+		.up_symbol = '@', .prefix = 131, .brk = true },
+	[4] = { .ascii = true, .symbol = '3',
+		.up_symbol = '#', .prefix = 132 },
+	[132] = { .ascii = true, .symbol = '3',
+		.up_symbol = '#', .prefix = 132, .brk = true },
+	[5] = { .ascii = true, .symbol = '4',
+		.up_symbol = '$', .prefix = 133 },
+	[133] = { .ascii = true, .symbol = '4',
+		.up_symbol = '$', .prefix = 133, .brk = true },
+	[6] = { .ascii = true, .symbol = '5',
+		.up_symbol = '%', .prefix = 134 },
+	[134] = { .ascii = true, .symbol = '5',
+		.up_symbol = '%', .prefix = 134, .brk = true },
+	[7] = { .ascii = true, .symbol = '6',
+		.up_symbol = '^', .prefix = 135 },
+	[135] = { .ascii = true, .symbol = '6',
+		.up_symbol = '^', .prefix = 135, .brk = true },
+	[8] = { .ascii = true, .symbol = '7',
+		.up_symbol = '&', .prefix = 136 },
+	[136] = { .ascii = true, .symbol = '7',
+		.up_symbol = '&', .prefix = 136, .brk = true },
+	[9] = { .ascii = true, .symbol = '8',
+		.up_symbol = '*', .prefix = 137 },
+	[137] = { .ascii = true, .symbol = '8',
+		.up_symbol = '*', .prefix = 137, .brk = true },
+	[10] = { .ascii = true, .symbol = '9',
+		.up_symbol = '(', .prefix = 138 },
+	[138] = { .ascii = true, .symbol = '9',
+		.up_symbol = '(', .prefix = 138, .brk = true },
+	[11] = { .ascii = true, .symbol = '0',
+		.up_symbol = ')', .prefix = 139 },
+	[139] = { .ascii = true, .symbol = '0',
+		.up_symbol = ')', .prefix = 139, .brk = true },
+	[12] = { .ascii = true, .symbol = '-',
+		.up_symbol = '_', .prefix = 140 },
+	[140] = { .ascii = true, .symbol = '-',
+		.up_symbol = '_', .prefix = 140, .brk = true },
+	[13] = { .ascii = true, .symbol = '=',
+		.up_symbol = '+', .prefix = 141 },
+	[141] = { .ascii = true, .symbol = '=',
+		.up_symbol = '+', .prefix = 141, .brk = true },
+	[14] = { .ascii = false, .symbol = KBD_BACKSPACE,
+		.up_symbol = NULL, .prefix = 142 },
+	[142] = { .ascii = false, .symbol = KBD_BACKSPACE,
+		.up_symbol = NULL, .prefix = 142, .brk = true },
+	[15] = { .ascii = false, .symbol = KBD_TAB,
+		.up_symbol = NULL, .prefix = 143 },
+	[143] = { .ascii = false, .symbol = KBD_TAB,
+		.up_symbol = NULL, .prefix = 143, .brk = true },
+	[16] = { .ascii = true, .symbol = 'q',
+		.up_symbol = 'Q', .prefix = 144 },
+	[144] = { .ascii = true, .symbol = 'q',
+		.up_symbol = 'Q', .prefix = 144, .brk = true },
+	[17] = { .ascii = true, .symbol = 'w',
+		.up_symbol = 'W', .prefix = 145 },
+	[145] = { .ascii = true, .symbol = 'w',
+		.up_symbol = 'W', .prefix = 145, .brk = true },
+	[18] = { .ascii = true, .symbol = 'e',
+		.up_symbol = 'E', .prefix = 146 },
+	[146] = { .ascii = true, .symbol = 'e',
+		.up_symbol = 'E', .prefix = 146, .brk = true },
+	[19] = { .ascii = true, .symbol = 'r',
+		.up_symbol = 'R', .prefix = 147 },
+	[147] = { .ascii = true, .symbol = 'r',
+		.up_symbol = 'R', .prefix = 147, .brk = true },
+	[20] = { .ascii = true, .symbol = 't',
+		.up_symbol = 'T', .prefix = 148 },
+	[148] = { .ascii = true, .symbol = 't',
+		.up_symbol = 'T', .prefix = 148, .brk = true },
+	[21] = { .ascii = true, .symbol = 'y',
+		.up_symbol = 'Y', .prefix = 149 },
+	[149] = { .ascii = true, .symbol = 'y',
+		.up_symbol = 'Y', .prefix = 149, .brk = true },
+	[22] = { .ascii = true, .symbol = 'u',
+		.up_symbol = 'U', .prefix = 150 },
+	[150] = { .ascii = true, .symbol = 'u',
+		.up_symbol = 'U', .prefix = 150, .brk = true },
+	[23] = { .ascii = true, .symbol = 'i',
+		.up_symbol = 'I', .prefix = 151 },
+	[151] = { .ascii = true, .symbol = 'i',
+		.up_symbol = 'I', .prefix = 151, .brk = true },
+	[24] = { .ascii = true, .symbol = 'o',
+		.up_symbol = 'O', .prefix = 152 },
+	[152] = { .ascii = true, .symbol = 'o',
+		.up_symbol = 'O', .prefix = 152, .brk = true },
+	[25] = { .ascii = true, .symbol = 'p',
+		.up_symbol = 'P', .prefix = 153 },
+	[153] = { .ascii = true, .symbol = 'p',
+		.up_symbol = 'P', .prefix = 153, .brk = true },
+	[26] = { .ascii = true, .symbol = '[',
+		.up_symbol = '{', .prefix = 154 },
+	[154] = { .ascii = true, .symbol = '[',
+		.up_symbol = '{', .prefix = 154, .brk = true },
+	[27] = { .ascii = true, .symbol = ']',
+		.up_symbol = '}', .prefix = 155 },
+	[155] = { .ascii = true, .symbol = ']',
+		.up_symbol = '}', .prefix = 155, .brk = true },
+	[58] = { .ascii = false, .symbol = KBD_CAPS_LOCK,
+		.up_symbol = NULL, .prefix = 186 },
+	[186] = { .ascii = false, .symbol = KBD_CAPS_LOCK,
+		.up_symbol = NULL, .prefix = 186, .brk = true },
+	[30] = { .ascii = true, .symbol = 'a',
+		.up_symbol = 'A', .prefix = 158 },
+	[158] = { .ascii = true, .symbol = 'a',
+		.up_symbol = 'A', .prefix = 158, .brk = true },
+	[31] = { .ascii = true, .symbol = 's',
+		.up_symbol = 'S', .prefix = 159 },
+	[159] = { .ascii = true, .symbol = 's',
+		.up_symbol = 'S', .prefix = 159, .brk = true },
+	[32] = { .ascii = true, .symbol = 'd',
+		.up_symbol = 'D', .prefix = 160 },
+	[160] = { .ascii = true, .symbol = 'd',
+		.up_symbol = 'D', .prefix = 160, .brk = true },
+	[33] = { .ascii = true, .symbol = 'f',
+		.up_symbol = 'F', .prefix = 161 },
+	[161] = { .ascii = true, .symbol = 'f',
+		.up_symbol = 'F', .prefix = 161, .brk = true },
+	[34] = { .ascii = true, .symbol = 'g',
+		.up_symbol = 'G', .prefix = 162 },
+	[162] = { .ascii = true, .symbol = 'g',
+		.up_symbol = 'G', .prefix = 162, .brk = true },
+	[35] = { .ascii = true, .symbol = 'h',
+		.up_symbol = 'H', .prefix = 163 },
+	[163] = { .ascii = true, .symbol = 'h',
+		.up_symbol = 'H', .prefix = 163, .brk = true },
+	[36] = { .ascii = true, .symbol = 'j',
+		.up_symbol = 'J', .prefix = 164 },
+	[164] = { .ascii = true, .symbol = 'j',
+		.up_symbol = 'J', .prefix = 164, .brk = true },
+	[37] = { .ascii = true, .symbol = 'k',
+		.up_symbol = 'K', .prefix = 165 },
+	[165] = { .ascii = true, .symbol = 'k',
+		.up_symbol = 'K', .prefix = 165, .brk = true },
+	[38] = { .ascii = true, .symbol = 'l',
+		.up_symbol = 'L', .prefix = 166 },
+	[166] = { .ascii = true, .symbol = 'l',
+		.up_symbol = 'L', .prefix = 166, .brk = true },
+	[39] = { .ascii = true, .symbol = ';',
+		.up_symbol = ':', .prefix = 167 },
+	[167] = { .ascii = true, .symbol = ';',
+		.up_symbol = ':', .prefix = 167, .brk = true },
+	[40] = { .ascii = true, .symbol = '\'',
+		.up_symbol = '"', .prefix = 168 },
+	[168] = { .ascii = true, .symbol = '\'',
+		.up_symbol = '"', .prefix = 168, .brk = true },
+	[28] = { .ascii = false, .symbol = KBD_ENTER,
+		.up_symbol = NULL, .prefix = 156 },
+	[156] = { .ascii = false, .symbol = KBD_ENTER,
+		.up_symbol = NULL, .prefix = 156, .brk = true },
+	[42] = { .ascii = false, .symbol = KBD_LEFT_SHIFT,
+		.up_symbol = NULL, .prefix = 170 },
+	[170] = { .ascii = false, .symbol = KBD_LEFT_SHIFT,
+		.up_symbol = NULL, .prefix = 170, .brk = true },
+	[44] = { .ascii = true, .symbol = 'z',
+		.up_symbol = 'Z', .prefix = 172 },
+	[172] = { .ascii = true, .symbol = 'z',
+		.up_symbol = 'Z', .prefix = 172, .brk = true },
+	[45] = { .ascii = true, .symbol = 'x',
+		.up_symbol = 'X', .prefix = 173 },
+	[173] = { .ascii = true, .symbol = 'x',
+		.up_symbol = 'X', .prefix = 173, .brk = true },
+	[46] = { .ascii = true, .symbol = 'c',
+		.up_symbol = 'C', .prefix = 174 },
+	[174] = { .ascii = true, .symbol = 'c',
+		.up_symbol = 'C', .prefix = 174, .brk = true },
+	[47] = { .ascii = true, .symbol = 'v',
+		.up_symbol = 'V', .prefix = 175 },
+	[175] = { .ascii = true, .symbol = 'v',
+		.up_symbol = 'V', .prefix = 175, .brk = true },
+	[48] = { .ascii = true, .symbol = 'b',
+		.up_symbol = 'B', .prefix = 176 },
+	[176] = { .ascii = true, .symbol = 'b',
+		.up_symbol = 'B', .prefix = 176, .brk = true },
+	[49] = { .ascii = true, .symbol = 'n',
+		.up_symbol = 'N', .prefix = 177 },
+	[177] = { .ascii = true, .symbol = 'n',
+		.up_symbol = 'N', .prefix = 177, .brk = true },
+	[50] = { .ascii = true, .symbol = 'm',
+		.up_symbol = 'M', .prefix = 178 },
+	[178] = { .ascii = true, .symbol = 'm',
+		.up_symbol = 'M', .prefix = 178, .brk = true },
+	[51] = { .ascii = true, .symbol = ',',
+		.up_symbol = '<', .prefix = 179 },
+	[179] = { .ascii = true, .symbol = ',',
+		.up_symbol = '<', .prefix = 179, .brk = true },
+	[52] = { .ascii = true, .symbol = '.',
+		.up_symbol = '>', .prefix = 180 },
+	[180] = { .ascii = true, .symbol = '.',
+		.up_symbol = '>', .prefix = 180, .brk = true },
+	[53] = { .ascii = true, .symbol = '/',
+		.up_symbol = '?', .prefix = 181 },
+	[181] = { .ascii = true, .symbol = '/',
+		.up_symbol = '?', .prefix = 181, .brk = true },
+	[54] = { .ascii = false, .symbol = KBD_RIGHT_SHIFT,
+		.up_symbol = NULL, .prefix = 182 },
+	[182] = { .ascii = false, .symbol = KBD_RIGHT_SHIFT,
+		.up_symbol = NULL, .prefix = 182, .brk = true },
+	[29] = { .ascii = false, .symbol = KBD_LEFT_CTRL,
+		.up_symbol = NULL, .prefix = 157 },
+	[157] = { .ascii = false, .symbol = KBD_LEFT_CTRL,
+		.up_symbol = NULL, .prefix = 157, .brk = true },
+	[56] = { .ascii = false, .symbol = KBD_LEFT_ALT,
+		.up_symbol = NULL, .prefix = 184 },
+	[184] = { .ascii = false, .symbol = KBD_LEFT_ALT,
+		.up_symbol = NULL, .prefix = 184, .brk = true },
+	[57] = { .ascii = false, .symbol = KBD_SPACEBAR,
+		.up_symbol = NULL, .prefix = 185 },
+	[185] = { .ascii = false, .symbol = KBD_SPACEBAR,
+		.up_symbol = NULL, .prefix = 185, .brk = true },
+	[69] = { .ascii = false, .symbol = KBD_NUM_LOCK,
+		.up_symbol = NULL, .prefix = 197 },
+	[197] = { .ascii = false, .symbol = KBD_NUM_LOCK,
+		.up_symbol = NULL, .prefix = 197, .brk = true },
+	[71] = { .ascii = false, .symbol = KBD_KEYPAD_7,
+		.up_symbol = NULL, .prefix = 199 },
+	[199] = { .ascii = false, .symbol = KBD_KEYPAD_7,
+		.up_symbol = NULL, .prefix = 199, .brk = true },
+	[75] = { .ascii = false, .symbol = KBD_KEYPAD_4,
+		.up_symbol = NULL, .prefix = 203 },
+	[203] = { .ascii = false, .symbol = KBD_KEYPAD_4,
+		.up_symbol = NULL, .prefix = 203, .brk = true },
+	[79] = { .ascii = false, .symbol = KBD_KEYPAD_1,
+		.up_symbol = NULL, .prefix = 207 },
+	[207] = { .ascii = false, .symbol = KBD_KEYPAD_1,
+		.up_symbol = NULL, .prefix = 207, .brk = true },
+	[72] = { .ascii = false, .symbol = KBD_KEYPAD_8,
+		.up_symbol = NULL, .prefix = 200 },
+	[200] = { .ascii = false, .symbol = KBD_KEYPAD_8,
+		.up_symbol = NULL, .prefix = 200, .brk = true },
+	[76] = { .ascii = false, .symbol = KBD_KEYPAD_5,
+		.up_symbol = NULL, .prefix = 204 },
+	[204] = { .ascii = false, .symbol = KBD_KEYPAD_5,
+		.up_symbol = NULL, .prefix = 204, .brk = true },
+	[80] = { .ascii = false, .symbol = KBD_KEYPAD_2,
+		.up_symbol = NULL, .prefix = 208 },
+	[208] = { .ascii = false, .symbol = KBD_KEYPAD_2,
+		.up_symbol = NULL, .prefix = 208, .brk = true },
+	[82] = { .ascii = false, .symbol = KBD_KEYPAD_0,
+		.up_symbol = NULL, .prefix = 210 },
+	[210] = { .ascii = false, .symbol = KBD_KEYPAD_0,
+		.up_symbol = NULL, .prefix = 210, .brk = true },
+	[55] = { .ascii = false, .symbol = KBD_KEYPAD_TIMES,
+		.up_symbol = NULL, .prefix = 183 },
+	[183] = { .ascii = false, .symbol = KBD_KEYPAD_TIMES,
+		.up_symbol = NULL, .prefix = 183, .brk = true },
+	[73] = { .ascii = false, .symbol = KBD_KEYPAD_9,
+		.up_symbol = NULL, .prefix = 201 },
+	[201] = { .ascii = false, .symbol = KBD_KEYPAD_9,
+		.up_symbol = NULL, .prefix = 201, .brk = true },
+	[77] = { .ascii = false, .symbol = KBD_KEYPAD_6,
+		.up_symbol = NULL, .prefix = 205 },
+	[205] = { .ascii = false, .symbol = KBD_KEYPAD_6,
+		.up_symbol = NULL, .prefix = 205, .brk = true },
+	[81] = { .ascii = false, .symbol = KBD_KEYPAD_3,
+		.up_symbol = NULL, .prefix = 209 },
+	[209] = { .ascii = false, .symbol = KBD_KEYPAD_3,
+		.up_symbol = NULL, .prefix = 209, .brk = true },
+	[83] = { .ascii = false, .symbol = KBD_KEYPAD_DOT,
+		.up_symbol = NULL, .prefix = 211 },
+	[211] = { .ascii = false, .symbol = KBD_KEYPAD_DOT,
+		.up_symbol = NULL, .prefix = 211, .brk = true },
+	[74] = { .ascii = false, .symbol = KBD_KEYPAD_MINUS,
+		.up_symbol = NULL, .prefix = 202 },
+	[202] = { .ascii = false, .symbol = KBD_KEYPAD_MINUS,
+		.up_symbol = NULL, .prefix = 202, .brk = true },
+	[78] = { .ascii = false, .symbol = KBD_KEYPAD_PLUS,
+		.up_symbol = NULL, .prefix = 206 },
+	[206] = { .ascii = false, .symbol = KBD_KEYPAD_PLUS,
+		.up_symbol = NULL, .prefix = 206, .brk = true },
+	[1] = { .ascii = false, .symbol = KBD_ESC,
+		.up_symbol = NULL, .prefix = 129 },
+	[129] = { .ascii = false, .symbol = KBD_ESC,
+		.up_symbol = NULL, .prefix = 129, .brk = true },
+	[59] = { .ascii = false, .symbol = KBD_F1,
+		.up_symbol = NULL, .prefix = 187 },
+	[187] = { .ascii = false, .symbol = KBD_F1,
+		.up_symbol = NULL, .prefix = 187, .brk = true },
+	[60] = { .ascii = false, .symbol = KBD_F2,
+		.up_symbol = NULL, .prefix = 188 },
+	[188] = { .ascii = false, .symbol = KBD_F2,
+		.up_symbol = NULL, .prefix = 188, .brk = true },
+	[61] = { .ascii = false, .symbol = KBD_F3,
+		.up_symbol = NULL, .prefix = 189 },
+	[189] = { .ascii = false, .symbol = KBD_F3,
+		.up_symbol = NULL, .prefix = 189, .brk = true },
+	[62] = { .ascii = false, .symbol = KBD_F4,
+		.up_symbol = NULL, .prefix = 190 },
+	[190] = { .ascii = false, .symbol = KBD_F4,
+		.up_symbol = NULL, .prefix = 190, .brk = true },
+	[63] = { .ascii = false, .symbol = KBD_F5,
+		.up_symbol = NULL, .prefix = 191 },
+	[191] = { .ascii = false, .symbol = KBD_F5,
+		.up_symbol = NULL, .prefix = 191, .brk = true },
+	[64] = { .ascii = false, .symbol = KBD_F6,
+		.up_symbol = NULL, .prefix = 192 },
+	[192] = { .ascii = false, .symbol = KBD_F6,
+		.up_symbol = NULL, .prefix = 192, .brk = true },
+	[65] = { .ascii = false, .symbol = KBD_F7,
+		.up_symbol = NULL, .prefix = 193 },
+	[193] = { .ascii = false, .symbol = KBD_F7,
+		.up_symbol = NULL, .prefix = 193, .brk = true },
+	[66] = { .ascii = false, .symbol = KBD_F8,
+		.up_symbol = NULL, .prefix = 194 },
+	[194] = { .ascii = false, .symbol = KBD_F8,
+		.up_symbol = NULL, .prefix = 194, .brk = true },
+	[67] = { .ascii = false, .symbol = KBD_F9,
+		.up_symbol = NULL, .prefix = 195 },
+	[195] = { .ascii = false, .symbol = KBD_F9,
+		.up_symbol = NULL, .prefix = 195, .brk = true },
+	[68] = { .ascii = false, .symbol = KBD_F10,
+		.up_symbol = NULL, .prefix = 196 },
+	[196] = { .ascii = false, .symbol = KBD_F10,
+		.up_symbol = NULL, .prefix = 196, .brk = true },
+	[87] = { .ascii = false, .symbol = KBD_F11,
+		.up_symbol = NULL, .prefix = 215 },
+	[215] = { .ascii = false, .symbol = KBD_F11,
+		.up_symbol = NULL, .prefix = 215, .brk = true },
+	[88] = { .ascii = false, .symbol = KBD_F12,
+		.up_symbol = NULL, .prefix = 216 },
+	[216] = { .ascii = false, .symbol = KBD_F12,
+		.up_symbol = NULL, .prefix = 216, .brk = true },
+	[70] = { .ascii = false, .symbol = KBD_SCROLL_LOCK,
+		.up_symbol = NULL, .prefix = 198 },
+	[198] = { .ascii = false, .symbol = KBD_SCROLL_LOCK,
+		.up_symbol = NULL, .prefix = 198, .brk = true },
+	[43] = { .ascii = true, .symbol = '\\',
+		.up_symbol = '|', .prefix = 171 },
+	[171] = { .ascii = true, .symbol = '\\',
+		.up_symbol = '|', .prefix = 171, .brk = true },
+};
+
+
+const struct kbd_scan_codes scan_code_set_3[0xff] =
+{
+	[14] = { .ascii = true, .symbol = '`',
+		.up_symbol = '~', .prefix = 240 },
+	[22] = { .ascii = true, .symbol = '1',
+		.up_symbol = '!', .prefix = 240 },
+	[30] = { .ascii = true, .symbol = '2',
+		.up_symbol = '@', .prefix = 240 },
+	[38] = { .ascii = true, .symbol = '3',
+		.up_symbol = '#', .prefix = 240 },
+	[37] = { .ascii = true, .symbol = '4',
+		.up_symbol = '$', .prefix = 240 },
+	[46] = { .ascii = true, .symbol = '5',
+		.up_symbol = '%', .prefix = 240 },
+	[54] = { .ascii = true, .symbol = '6',
+		.up_symbol = '^', .prefix = 240 },
+	[61] = { .ascii = true, .symbol = '7',
+		.up_symbol = '&', .prefix = 240 },
+	[62] = { .ascii = true, .symbol = '8',
+		.up_symbol = '*', .prefix = 240 },
+	[70] = { .ascii = true, .symbol = '9',
+		.up_symbol = '(', .prefix = 240 },
+	[69] = { .ascii = true, .symbol = '0',
+		.up_symbol = ')', .prefix = 240 },
+	[78] = { .ascii = true, .symbol = '-',
+		.up_symbol = '_', .prefix = 240 },
+	[85] = { .ascii = true, .symbol = '=',
+		.up_symbol = '+', .prefix = 240 },
+	[102] = { .ascii = false, .symbol = KBD_BACKSPACE,
+		.up_symbol = NULL, .prefix = 240 },
+	[13] = { .ascii = false, .symbol = KBD_TAB,
+		.up_symbol = NULL, .prefix = 240 },
+	[21] = { .ascii = true, .symbol = 'q',
+		.up_symbol = 'Q', .prefix = 240 },
+	[29] = { .ascii = true, .symbol = 'w',
+		.up_symbol = 'W', .prefix = 240 },
+	[36] = { .ascii = true, .symbol = 'e',
+		.up_symbol = 'E', .prefix = 240 },
+	[45] = { .ascii = true, .symbol = 'r',
+		.up_symbol = 'R', .prefix = 240 },
+	[44] = { .ascii = true, .symbol = 't',
+		.up_symbol = 'T', .prefix = 240 },
+	[53] = { .ascii = true, .symbol = 'y',
+		.up_symbol = 'Y', .prefix = 240 },
+	[60] = { .ascii = true, .symbol = 'u',
+		.up_symbol = 'U', .prefix = 240 },
+	[67] = { .ascii = true, .symbol = 'i',
+		.up_symbol = 'I', .prefix = 240 },
+	[68] = { .ascii = true, .symbol = 'o',
+		.up_symbol = 'O', .prefix = 240 },
+	[77] = { .ascii = true, .symbol = 'p',
+		.up_symbol = 'P', .prefix = 240 },
+	[84] = { .ascii = true, .symbol = '[',
+		.up_symbol = '{', .prefix = 240 },
+	[91] = { .ascii = true, .symbol = ']',
+		.up_symbol = '}', .prefix = 240 },
+	[88] = { .ascii = false, .symbol = KBD_CAPS_LOCK,
+		.up_symbol = NULL, .prefix = 240 },
+	[28] = { .ascii = true, .symbol = 'a',
+		.up_symbol = 'A', .prefix = 240 },
+	[27] = { .ascii = true, .symbol = 's',
+		.up_symbol = 'S', .prefix = 240 },
+	[35] = { .ascii = true, .symbol = 'd',
+		.up_symbol = 'D', .prefix = 240 },
+	[43] = { .ascii = true, .symbol = 'f',
+		.up_symbol = 'F', .prefix = 240 },
+	[52] = { .ascii = true, .symbol = 'g',
+		.up_symbol = 'G', .prefix = 240 },
+	[51] = { .ascii = true, .symbol = 'h',
+		.up_symbol = 'H', .prefix = 240 },
+	[59] = { .ascii = true, .symbol = 'j',
+		.up_symbol = 'J', .prefix = 240 },
+	[66] = { .ascii = true, .symbol = 'k',
+		.up_symbol = 'K', .prefix = 240 },
+	[75] = { .ascii = true, .symbol = 'l',
+		.up_symbol = 'L', .prefix = 240 },
+	[76] = { .ascii = true, .symbol = ';',
+		.up_symbol = ':', .prefix = 240 },
+	[82] = { .ascii = true, .symbol = '\'',
+		.up_symbol = '"', .prefix = 240 },
+	[90] = { .ascii = false, .symbol = KBD_ENTER,
+		.up_symbol = NULL, .prefix = 240 },
+	[18] = { .ascii = false, .symbol = KBD_LEFT_SHIFT,
+		.up_symbol = NULL, .prefix = 240 },
+	[26] = { .ascii = true, .symbol = 'z',
+		.up_symbol = 'Z', .prefix = 240 },
+	[34] = { .ascii = true, .symbol = 'x',
+		.up_symbol = 'X', .prefix = 240 },
+	[33] = { .ascii = true, .symbol = 'c',
+		.up_symbol = 'C', .prefix = 240 },
+	[42] = { .ascii = true, .symbol = 'v',
+		.up_symbol = 'V', .prefix = 240 },
+	[50] = { .ascii = true, .symbol = 'b',
+		.up_symbol = 'B', .prefix = 240 },
+	[49] = { .ascii = true, .symbol = 'n',
+		.up_symbol = 'N', .prefix = 240 },
+	[58] = { .ascii = true, .symbol = 'm',
+		.up_symbol = 'M', .prefix = 240 },
+	[65] = { .ascii = true, .symbol = ',',
+		.up_symbol = '<', .prefix = 240 },
+	[73] = { .ascii = true, .symbol = '.',
+		.up_symbol = '>', .prefix = 240 },
+	[74] = { .ascii = true, .symbol = '/',
+		.up_symbol = '?', .prefix = 240 },
+	[89] = { .ascii = false, .symbol = KBD_RIGHT_SHIFT,
+		.up_symbol = NULL, .prefix = 240 },
+	[17] = { .ascii = false, .symbol = KBD_LEFT_CTRL,
+		.up_symbol = NULL, .prefix = 240 },
+	[25] = { .ascii = false, .symbol = KBD_LEFT_ALT,
+		.up_symbol = NULL, .prefix = 240 },
+	[41] = { .ascii = false, .symbol = KBD_SPACEBAR,
+		.up_symbol = NULL, .prefix = 240 },
+	[57] = { .ascii = false, .symbol = KBD_RIGHT_ALT,
+		.up_symbol = NULL, .prefix = 240 },
+	[88] = { .ascii = false, .symbol = KBD_RIGHT_CTRL,
+		.up_symbol = NULL, .prefix = 240 },
+	[103] = { .ascii = false, .symbol = KBD_INSERT,
+		.up_symbol = NULL, .prefix = 240 },
+	[100] = { .ascii = false, .symbol = KBD_DELETE,
+		.up_symbol = NULL, .prefix = 240 },
+	[97] = { .ascii = false, .symbol = KBD_LEFT_ARROW,
+		.up_symbol = NULL, .prefix = 240 },
+	[110] = { .ascii = false, .symbol = KBD_HOME,
+		.up_symbol = NULL, .prefix = 240 },
+	[101] = { .ascii = false, .symbol = KBD_END,
+		.up_symbol = NULL, .prefix = 240 },
+	[99] = { .ascii = false, .symbol = KBD_UP_ARROW,
+		.up_symbol = NULL, .prefix = 240 },
+	[96] = { .ascii = false, .symbol = KBD_DOWN_ARROW,
+		.up_symbol = NULL, .prefix = 240 },
+	[111] = { .ascii = false, .symbol = KBD_PAGE_UP,
+		.up_symbol = NULL, .prefix = 240 },
+	[109] = { .ascii = false, .symbol = KBD_PAGE_DOWN,
+		.up_symbol = NULL, .prefix = 240 },
+	[106] = { .ascii = false, .symbol = KBD_RIGHT_ARROW,
+		.up_symbol = NULL, .prefix = 240 },
+	[118] = { .ascii = false, .symbol = KBD_NUM_LOCK,
+		.up_symbol = NULL, .prefix = 240 },
+	[108] = { .ascii = false, .symbol = KBD_KEYPAD_7,
+		.up_symbol = NULL, .prefix = 240 },
+	[107] = { .ascii = false, .symbol = KBD_KEYPAD_4,
+		.up_symbol = NULL, .prefix = 240 },
+	[105] = { .ascii = false, .symbol = KBD_KEYPAD_1,
+		.up_symbol = NULL, .prefix = 240 },
+	[119] = { .ascii = false, .symbol = KBD_KEYPAD_DIV,
+		.up_symbol = NULL, .prefix = 240 },
+	[117] = { .ascii = false, .symbol = KBD_KEYPAD_8,
+		.up_symbol = NULL, .prefix = 240 },
+	[115] = { .ascii = false, .symbol = KBD_KEYPAD_5,
+		.up_symbol = NULL, .prefix = 240 },
+	[114] = { .ascii = false, .symbol = KBD_KEYPAD_2,
+		.up_symbol = NULL, .prefix = 240 },
+	[112] = { .ascii = false, .symbol = KBD_KEYPAD_0,
+		.up_symbol = NULL, .prefix = 240 },
+	[126] = { .ascii = false, .symbol = KBD_KEYPAD_TIMES,
+		.up_symbol = NULL, .prefix = 240 },
+	[125] = { .ascii = false, .symbol = KBD_KEYPAD_9,
+		.up_symbol = NULL, .prefix = 240 },
+	[116] = { .ascii = false, .symbol = KBD_KEYPAD_6,
+		.up_symbol = NULL, .prefix = 240 },
+	[122] = { .ascii = false, .symbol = KBD_KEYPAD_3,
+		.up_symbol = NULL, .prefix = 240 },
+	[113] = { .ascii = false, .symbol = KBD_KEYPAD_DOT,
+		.up_symbol = NULL, .prefix = 240 },
+	[132] = { .ascii = false, .symbol = KBD_KEYPAD_MINUS,
+		.up_symbol = NULL, .prefix = 240 },
+	[124] = { .ascii = false, .symbol = KBD_KEYPAD_PLUS,
+		.up_symbol = NULL, .prefix = 240 },
+	[121] = { .ascii = false, .symbol = KBD_KEYPAD_ENTER,
+		.up_symbol = NULL, .prefix = 240 },
+	[8] = { .ascii = false, .symbol = KBD_ESC,
+		.up_symbol = NULL, .prefix = 240 },
+	[7] = { .ascii = false, .symbol = KBD_F1,
+		.up_symbol = NULL, .prefix = 240 },
+	[15] = { .ascii = false, .symbol = KBD_F2,
+		.up_symbol = NULL, .prefix = 240 },
+	[23] = { .ascii = false, .symbol = KBD_F3,
+		.up_symbol = NULL, .prefix = 240 },
+	[31] = { .ascii = false, .symbol = KBD_F4,
+		.up_symbol = NULL, .prefix = 240 },
+	[39] = { .ascii = false, .symbol = KBD_F5,
+		.up_symbol = NULL, .prefix = 240 },
+	[47] = { .ascii = false, .symbol = KBD_F6,
+		.up_symbol = NULL, .prefix = 240 },
+	[55] = { .ascii = false, .symbol = KBD_F7,
+		.up_symbol = NULL, .prefix = 240 },
+	[63] = { .ascii = false, .symbol = KBD_F8,
+		.up_symbol = NULL, .prefix = 240 },
+	[71] = { .ascii = false, .symbol = KBD_F9,
+		.up_symbol = NULL, .prefix = 240 },
+	[79] = { .ascii = false, .symbol = KBD_F10,
+		.up_symbol = NULL, .prefix = 240 },
+	[86] = { .ascii = false, .symbol = KBD_F11,
+		.up_symbol = NULL, .prefix = 240 },
+	[94] = { .ascii = false, .symbol = KBD_F12,
+		.up_symbol = NULL, .prefix = 240 },
+	[87] = { .ascii = false, .symbol = KBD_PRINT_SCREEN,
+		.up_symbol = NULL, .prefix = 240 },
+	[95] = { .ascii = false, .symbol = KBD_SCROLL_LOCK,
+		.up_symbol = NULL, .prefix = 240 },
+	[98] = { .ascii = false, .symbol = KBD_PAUSE_BREAK,
+		.up_symbol = NULL, .prefix = 240 },
+	[92] = { .ascii = true, .symbol = '\\',
+		.up_symbol = '|', .prefix = 240 },
+};
diff --git a/src/scan_codes.tsv b/src/scan_codes.tsv
new file mode 100644
index 0000000..d036329
--- /dev/null
+++ b/src/scan_codes.tsv
@@ -0,0 +1,102 @@
+IBM Key No.	Set 1 Make/Break	Set 2 Make/Break	Set 3 Make/Break	Base Case	Upper Case	Is ASCII char	Symbol	Uppercase Symbol

+1	29/A9	0E/F0 0E	0E/F0 0E	`	~	yes	'`'	'~'

+2	02/82	16/F0 16	16/F0 16	1	!	yes	'1'	'!'

+3	03/83	1E/F0 1E	1E/F0 1E	2	@	yes	'2'	'@'

+4	04/84	26/F0 26	26/F0 26	3	#	yes	'3'	'#'

+5	05/85	25/F0 25	25/F0 25	4	$	yes	'4'	'$'

+6	06/86	2E/F0 2E	2E/F0 2E	5	%	yes	'5'	'%'

+7	07/87	36/F0 36	36/F0 36	6	^	yes	'6'	'^'

+8	08/88	3D/F0 3D	3D/F0 3D	7	&	yes	'7'	'&'

+9	09/89	3E/F0 3E	3E/F0 3E	8	*	yes	'8'	'*'

+10	0A/8A	46/F0 46	46/F0 46	9	(	yes	'9'	'('

+11	0B/8B	45/F0 45	45/F0 45	0	)	yes	'0'	')'

+12	0C/8C	4E/F0 4E	4E/F0 4E	-	_	yes	'-'	'_'

+13	0D/8D	55/F0 55	55/F0 55	=	+	yes	'='	'+'

+15	0E/8E	66/F0 66	66/F0 66	Backspace		no	KBD_BACKSPACE	NULL

+16	0F/8F	0D/F0 0D	0D/F0 0D	Tab		no	KBD_TAB	NULL

+17	10/90	15/F0 15	15/F0 15	q	Q	yes	'q'	'Q'

+18	11/91	1D/F0 1D	1D/F0 1D	w	W	yes	'w'	'W'

+19	12/92	24/F0 24	24/F0 24	e	E	yes	'e'	'E'

+20	13/93	2D/F0 2D	2D/F0 2D	r	R	yes	'r'	'R'

+21	14/94	2C/F0 2C	2C/F0 2C	t	T	yes	't'	'T'

+22	15/95	35/F0 35	35/F0 35	y	Y	yes	'y'	'Y'

+23	16/96	3C/F0 3C	3C/F0 3C	u	U	yes	'u'	'U'

+24	17/97	43/F0 43	43/F0 43	i	I	yes	'i'	'I'

+25	18/98	44/F0 44	44/F0 44	o	O	yes	'o'	'O'

+26	19/99	4D/F0 4D	4D/F0 4D	p	P	yes	'p'	'P'

+27	1A/9A	54/F0 54	54/F0 54	[	{	yes	'['	'{'

+28	1B/9B	5B/F0 5B	5B/F0 5B	]	}	yes	']'	'}'

+30	3A/BA	58/F0 58	58/F0 58	Caps Lock		no	KBD_CAPS_LOCK	NULL

+31	1E/9E	1C/F0 1C	1C/F0 1C	a	A	yes	'a'	'A'

+32	1F/9F	1B/F0 1B	1B/F0 1B	s	S	yes	's'	'S'

+33	20/A0	23/F0 23	23/F0 23	d	D	yes	'd'	'D'

+34	21/A1	2B/F0 2B	2B/F0 2B	f	F	yes	'f'	'F'

+35	22/A2	34/F0 34	34/F0 34	g	G	yes	'g'	'G'

+36	23/A3	33/F0 33	33/F0 33	h	H	yes	'h'	'H'

+37	24/A4	3B/F0 3B	3B/F0 3B	j	J	yes	'j'	'J'

+38	25/A5	42/F0 42	42/F0 42	k	K	yes	'k'	'K'

+39	26/A6	4B/F0 4B	4B/F0 4B	l	L	yes	'l'	'L'

+40	27/A7	4C/F0 4C	4C/F0 4C	;	:	yes	';'	':'

+41	28/A8	52/F0 52	52/F0 52	'	"	yes	'\''	'"'

+43	1C/9C	5A/F0 5A	5A/F0 5A	Enter	Enter	no	KBD_ENTER	NULL

+44	2A/AA	12/F0 12	12/F0 12	Left Shift		no	KBD_LEFT_SHIFT	NULL

+46	2C/AC	1A/F0 1A	1A/F0 1A	z	Z	yes	'z'	'Z'

+47	2D/AD	22/F0 22	22/F0 22	x	X	yes	'x'	'X'

+48	2E/AE	21/F0 21	21/F0 21	c	C	yes	'c'	'C'

+49	2F/AF	2A/F0 2A	2A/F0 2A	v	V	yes	'v'	'V'

+50	30/B0	32/F0 32	32/F0 32	b	B	yes	'b'	'B'

+51	31/B1	31/F0 31	31/F0 31	n	N	yes	'n'	'N'

+52	32/B2	3A/F0 3A	3A/F0 3A	m	M	yes	'm'	'M'

+53	33/B3	41/F0 41	41/F0 41	,	<	yes	','	'<'

+54	34/B4	49/F0 49	49/F0 49	.	>	yes	'.'	'>'

+55	35/B5	4A/F0 4A	4A/F0 4A	/	?	yes	'/'	'?'

+57	36/B6	59/F0 59	59/F0 59	Right Shift		no	KBD_RIGHT_SHIFT	NULL

+58	1D/9D	14/F0 14	11/F0 11	Left Ctrl		no	KBD_LEFT_CTRL	NULL

+60	38/B8	11/F0 11	19/F0 19	Left Alt		no	KBD_LEFT_ALT	NULL

+61	39/B9	29/F0 29	29/F0 29	Spacebar		no	KBD_SPACEBAR	NULL

+62	E0 38/E0 B8	E0 11/E0 F0 11	39/F0 39	Right Alt		no	KBD_RIGHT_ALT	NULL

+64	E0 1D/E0 9D	E0 14/E0 F0 14	58/F0 58	Right Ctrl		no	KBD_RIGHT_CTRL	NULL

+75	E0 52/E0 D2 (base)	E0 70/E0 F0 70 (base)	67/F0 67	Insert		no	KBD_INSERT	NULL

+76	E0 4B/E0 CB (base)	E0 71/E0 F0 71 (base)	64/F0 64	Delete		no	KBD_DELETE	NULL

+79	E0 4B/E0 CB (base)	E0 6B/E0 F0 6B (base)	61/F0 61	Left Arrow		no	KBD_LEFT_ARROW	NULL

+80	E0 47/E0 C7 (base)	E0 6C/E0 F0 6C (base)	6E/F0 6E	Home		no	KBD_HOME	NULL

+81	E0 4F/E0 CF (base)	E0 69/E0 F0 69 (base)	65/F0 65	End		no	KBD_END	NULL

+83	E0 48/E0 C8 (base)	E0 75/E0 F0 75 (base)	63/F0 63	Up Arrow		no	KBD_UP_ARROW	NULL

+84	E0 50/E0 D0 (base)	E0 72/E0 F0 72 (base)	60/F0 60	Down Arrow		no	KBD_DOWN_ARROW	NULL

+85	E0 49/E0 C9 (base)	E0 7D/E0 F0 7D (base)	6F/F0 6F	Page Up		no	KBD_PAGE_UP	NULL

+86	E0 51/E0 D1 (base)	E0 7A/E0 F0 7A (base)	6D/F0 6D	Page Down		no	KBD_PAGE_DOWN	NULL

+89	E0 4D/E0 CD (base)	E0 74/E0 F0 74 (base)	6A/F0 6A	Right Arrow		no	KBD_RIGHT_ARROW	NULL

+90	45/C5	77/F0 77	76/F0 76	Num Lock		no	KBD_NUM_LOCK	NULL

+91	47/C7	6C/F0 6C	6C/F0 6C	Keypad 7		no	KBD_KEYPAD_7	NULL

+92	4B/CB	6B/F0 6B	6B/F0 6B	Keypad 4		no	KBD_KEYPAD_4	NULL

+93	4F/CF	69/F0 69	69/F0 69	Keypad 1		no	KBD_KEYPAD_1	NULL

+95	E0 35/E0 B5 (base)	E0 4A/E0 F0 4A (base)	77/F0 77	Keypad /		no	KBD_KEYPAD_/	NULL

+96	48/C8	75/F0 75	75/F0 75	Keypad 8		no	KBD_KEYPAD_8	NULL

+97	4C/CC	73/F0 73	73/F0 73	Keypad 5		no	KBD_KEYPAD_5	NULL

+98	50/D0	72/F0 72	72/F0 72	Keypad 2		no	KBD_KEYPAD_2	NULL

+99	52/D2	70/F0 70	70/F0 70	Keypad 0		no	KBD_KEYPAD_0	NULL

+100	37/B7	7C/F0 7C	7E/F0 7E	Keypad *		no	KBD_KEYPAD_*	NULL

+101	49/C9	7D/F0 7D	7D/F0 7D	Keypad 9		no	KBD_KEYPAD_9	NULL

+102	4D/CD	74/F0 74	74/F0 74	Keypad 6		no	KBD_KEYPAD_6	NULL

+103	51/D1	7A/F0 7A	7A/F0 7A	Keypad 3		no	KBD_KEYPAD_3	NULL

+104	53/D3	71/F0 71	71/F0 71	Keypad .		no	KBD_KEYPAD_.	NULL

+105	4A/CA	7B/F0 7B	84/F0 84	Keypad -		no	KBD_KEYPAD_-	NULL

+106	4E/CE	79/F0 79	7C/F0 7C	Keypad +		no	KBD_KEYPAD_+	NULL

+108	E0 1C/E0 9C	E0 5A/E0 F0 5A	79/F0 79	Keypad Enter		no	KBD_KEYPAD_ENTER	NULL

+110	01/81	76/F0 76	08/F0 08	Esc		no	KBD_ESC	NULL

+112	3B/BB	05/F0 05	07/F0 07	F1		no	KBD_F1	NULL

+113	3C/BC	06/F0 06	0F/F0 0F	F2		no	KBD_F2	NULL

+114	3D/BD	04/F0 04	17/F0 17	F3		no	KBD_F3	NULL

+115	3E/BE	0C/F0 0C	1F/F0 1F	F4		no	KBD_F4	NULL

+116	3F/BF	03/F0 03	27/F0 27	F5		no	KBD_F5	NULL

+117	40/C0	0B/F0 0B	2F/F0 2F	F6		no	KBD_F6	NULL

+118	41/C1	83/F0 83	37/F0 37	F7		no	KBD_F7	NULL

+119	42/C2	0A/F0 0A	3F/F0 3F	F8		no	KBD_F8	NULL

+120	43/C3	01/F0 01	47/F0 47	F9		no	KBD_F9	NULL

+121	44/C4	09/F0 09	4F/F0 4F	F10		no	KBD_F10	NULL

+122	57/D7	78/F0 78	56/F0 56	F11		no	KBD_F11	NULL

+123	58/D8	07/F0 07	5E/F0 5E	F12		no	KBD_F12	NULL

+124	E0 2A E0 37/E0 B7 E0 AA	E0 12 E0 7C/E0 F0 7C E0 F0 12	57/F0 57	Print Screen		no	KBD_PRINT_SCREEN	NULL

+125	46/C6	7E/F0 7E	5F/F0 5F	Scroll Lock		no	KBD_SCROLL_LOCK	NULL

+126	E1 1D 45/E1 9D C5	E1 14 77 E1/F0 14 F0 77	62/F0 62	Pause Break		no	KBD_PAUSE_BREAK	NULL

+29	2B/AB	5D/F0 5D	5C/F0 5C	\	|	yes	'\\'	'|'
\ No newline at end of file
diff --git a/src/timer.c b/src/timer.c
index 4227949..145f8f8 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -6,10 +6,9 @@
 
 static ulong tick = 0;
 
-static void timer_cb(struct registers regs)
+static void timer_cb(struct registers *regs)
 {
-	if (++tick % 100 == 0)
-		kprintf("Timer tick %d\n", tick);
+	// do nothing :)
 }
 
 void init_timer(uint hz)
diff --git a/src/vga.c b/src/vga.c
index b6edbb0..bfd13e0 100644
--- a/src/vga.c
+++ b/src/vga.c
@@ -49,6 +49,7 @@
 	case '\b':
 		if (cursor_x > 0)
 			cursor_x--;
+		fb[cursor_y * 80 + cursor_x] = ' ' | (color << 8);
 		break;
 	case '\t':
 		cursor_x = (cursor_x + 8) & ~7;
@@ -59,8 +60,8 @@
 		cursor_x = 0;
 		break;
 	default:
-		cursor_x++;
 		fb[cursor_y * 80 + cursor_x] = c | (color << 8);
+		cursor_x++;
 	}
 
 	if (cursor_x >= 80) // off screen