aboutsummaryrefslogtreecommitdiff
path: root/kernel/io/keyboard/keyboard_handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/io/keyboard/keyboard_handler.c')
-rw-r--r--kernel/io/keyboard/keyboard_handler.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/kernel/io/keyboard/keyboard_handler.c b/kernel/io/keyboard/keyboard_handler.c
new file mode 100644
index 0000000..86a50a7
--- /dev/null
+++ b/kernel/io/keyboard/keyboard_handler.c
@@ -0,0 +1,73 @@
+#include "../../interrupt_descriptor_table.h"
+#include "../vga/text_mode_display.h"
+#include "scancode_map.h"
+
+extern void keyboard_handler(void);
+extern char read_port(unsigned short port);
+extern void write_port(unsigned short port, unsigned char data);
+extern void load_idt(unsigned long *idt_ptr);
+
+struct idt_entry keyboard_idt[256];
+
+void init_keyboard_idt()
+{
+ unsigned long keyboard_address;
+ unsigned long idt_address;
+ unsigned long idt_ptr[2];
+
+ // Build IDT entry
+ keyboard_address = (unsigned long) keyboard_handler;
+
+ keyboard_idt[0x21].offset_lowerbits = keyboard_address & 0xffff;
+ keyboard_idt[0x21].selector = 0x08; // Offset by 0x08
+ keyboard_idt[0x21].zero = 0;
+ keyboard_idt[0x21].type_attr = 0x8E; // Interrupt gate addr
+ keyboard_idt[0x21].offset_higherbits = (keyboard_address & 0xffff0000) >> 16;
+
+ idt_address = (unsigned long) keyboard_idt;
+ idt_ptr[0] = (sizeof(struct idt_entry) * 256) + ((idt_address & 0xffff) << 16);
+ idt_ptr[1] = idt_address >> 16;
+
+ // Init PIC 1 @ 0x20
+ write_port(0x20, 0x11);
+ write_port(0x21, 0x20);
+ write_port(0x21, 0x00);
+ write_port(0x21, 0x01);
+ write_port(0x21, 0xff);
+
+ // PIC 2 @ 0xA0
+ write_port(0xA0, 0x11);
+ write_port(0xA1, 0x28);
+ write_port(0xA1, 0x00);
+ write_port(0xA1, 0x01);
+ write_port(0xA1, 0xff);
+
+ load_idt(idt_ptr);
+}
+
+void init_keyboard_handler()
+{
+ init_keyboard_idt();
+
+ write_port(0x21, 0xFD);
+}
+
+int isKeyup(int scancode)
+{
+ return scancode & 0x80;
+}
+
+void handle_keypress() {
+
+ // Ack the interrupt
+ write_port(0x20, 0x20);
+
+ unsigned char scancode = read_port(0x60);
+
+ if(!isKeyup(scancode))
+ {
+ char pressed_key = scancode_map[scancode];
+ vga_print_raw(pressed_key);
+ }
+
+}