aboutsummaryrefslogtreecommitdiff
path: root/kernel/io
diff options
context:
space:
mode:
authorJames Barnett <noreply@jamesbarnett.xyz>2019-05-25 20:11:52 +0100
committerJames Barnett <noreply@jamesbarnett.xyz>2019-05-25 20:11:52 +0100
commit506f1691f1ca7b562d82ab6f2280b87d0e4af84c (patch)
treebdb403c000cd15ab29cbce8b3bcec5077d6f9655 /kernel/io
parentc1d948ce1973d9be37a43718f548776a0061807b (diff)
downloadtinyOS-506f1691f1ca7b562d82ab6f2280b87d0e4af84c.tar.xz
tinyOS-506f1691f1ca7b562d82ab6f2280b87d0e4af84c.zip
Add keyboard support
Diffstat (limited to 'kernel/io')
-rw-r--r--kernel/io/keyboard/keyboard_handler.c73
-rw-r--r--kernel/io/keyboard/keyboard_handler.h1
-rw-r--r--kernel/io/keyboard/scancode_map.h93
-rw-r--r--kernel/io/vga/text_mode_diplay.h4
-rw-r--r--kernel/io/vga/text_mode_display.c6
-rw-r--r--kernel/io/vga/text_mode_display.h5
6 files changed, 178 insertions, 4 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);
+ }
+
+}
diff --git a/kernel/io/keyboard/keyboard_handler.h b/kernel/io/keyboard/keyboard_handler.h
new file mode 100644
index 0000000..f56f4f2
--- /dev/null
+++ b/kernel/io/keyboard/keyboard_handler.h
@@ -0,0 +1 @@
+void init_keyboard_handler(); \ No newline at end of file
diff --git a/kernel/io/keyboard/scancode_map.h b/kernel/io/keyboard/scancode_map.h
new file mode 100644
index 0000000..e48a1f6
--- /dev/null
+++ b/kernel/io/keyboard/scancode_map.h
@@ -0,0 +1,93 @@
+char scancode_map[128] =
+{
+ 0xFF, // Keyboard error code
+ 0, // Esc
+ '1',
+ '2',
+ '3',
+ '4',
+ '5',
+ '6',
+ '7',
+ '8',
+ '9',
+ '0',
+ '-',
+ '=',
+ '\b', // Backspace
+ '\t', // Tab
+ 'q',
+ 'w',
+ 'e',
+ 'r',
+ 't',
+ 'y',
+ 'u',
+ 'i',
+ 'o',
+ 'p',
+ '[',
+ ']',
+ '\n', // Enter
+ 0, // Ctrl
+ 'a',
+ 's',
+ 'd',
+ 'f',
+ 'g',
+ 'h',
+ 'j',
+ 'k',
+ 'l',
+ ';',
+ '\'',
+ '`',
+ 0, // Left Shift
+ '\\',
+ 'z',
+ 'x',
+ 'c',
+ 'v',
+ 'b',
+ 'n',
+ 'm',
+ ',',
+ '.',
+ '/',
+ 0, // Right shift
+ '*',
+ 0, // Alt
+ ' ', // Space
+ 0, // Caps
+ 0, // F1 ...
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, // F10
+ 0, // Numlock
+ 0, // Scroll lock
+ 0, // Home
+ 0, // Up
+ 0, // PgUp
+ '-',
+ 0, // Left
+ 0, // Numpad 5
+ 0, // Right
+ '+',
+ 0, // End
+ 0, // Down
+ 0, // PgDown
+ 0, // Ins
+ 0, // Del
+ 0, // Alt-Sysrq
+ 0, // n/a
+ 0, // n/a
+ 0, // F11
+ 0, // F12
+ 0, // Others are undefined
+}; \ No newline at end of file
diff --git a/kernel/io/vga/text_mode_diplay.h b/kernel/io/vga/text_mode_diplay.h
deleted file mode 100644
index 9441925..0000000
--- a/kernel/io/vga/text_mode_diplay.h
+++ /dev/null
@@ -1,4 +0,0 @@
-void vga_clear_screen();
-void vga_print(char *msg);
-void vga_print_ln(char *msg);
-void vga_set_text_colour(int foreground, int background); \ No newline at end of file
diff --git a/kernel/io/vga/text_mode_display.c b/kernel/io/vga/text_mode_display.c
index 4844524..bfee909 100644
--- a/kernel/io/vga/text_mode_display.c
+++ b/kernel/io/vga/text_mode_display.c
@@ -39,4 +39,10 @@ void vga_print_ln(char *msg)
void vga_set_text_colour(int foreground, int background)
{
char_attribute_byte = (background << 4) | foreground;
+}
+
+void vga_print_raw(unsigned char byte)
+{
+ video_ram[cursor_pos++] = byte;
+ video_ram[cursor_pos++] = char_attribute_byte;
} \ No newline at end of file
diff --git a/kernel/io/vga/text_mode_display.h b/kernel/io/vga/text_mode_display.h
new file mode 100644
index 0000000..48bae85
--- /dev/null
+++ b/kernel/io/vga/text_mode_display.h
@@ -0,0 +1,5 @@
+void vga_clear_screen();
+void vga_print(char *msg);
+void vga_print_ln(char *msg);
+void vga_set_text_colour(int foreground, int background);
+void vga_print_raw(unsigned char byte); \ No newline at end of file