aboutsummaryrefslogtreecommitdiff
path: root/drivers/ps2kbd.c
diff options
context:
space:
mode:
authorFranklin Wei <frankhwei536@gmail.com>2015-02-18 12:49:58 -0500
committerFranklin Wei <frankhwei536@gmail.com>2015-02-18 12:49:58 -0500
commit9defae4d6f7b30d844447549fadffea4eab5a0dd (patch)
tree2c44f6fb193d9b3f7487714e7dfa3903bedb932d /drivers/ps2kbd.c
parent1d3537f33d793e2cabe53e72f0e0ead911fcc870 (diff)
downloadkappa-9defae4d6f7b30d844447549fadffea4eab5a0dd.zip
kappa-9defae4d6f7b30d844447549fadffea4eab5a0dd.tar.gz
kappa-9defae4d6f7b30d844447549fadffea4eab5a0dd.tar.bz2
kappa-9defae4d6f7b30d844447549fadffea4eab5a0dd.tar.xz
support keyboard io
Diffstat (limited to 'drivers/ps2kbd.c')
-rw-r--r--drivers/ps2kbd.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/drivers/ps2kbd.c b/drivers/ps2kbd.c
new file mode 100644
index 0000000..5aa9d2a
--- /dev/null
+++ b/drivers/ps2kbd.c
@@ -0,0 +1,104 @@
+/* this is both a PS/2 keyboard driver */
+#include <stdint.h>
+#include <stdio.h>
+#include "io.h"
+#include "isr.h"
+#include "ps2kbd.h"
+#include "ps2_keymaps.h"
+
+static void ps2_wait(void)
+{
+ /* wait for the keyboard */
+ while(1)
+ if ((inb(0x64) & 2) == 0) break;
+}
+
+void ps2kbd_set_leds(uint8_t status)
+{
+ ps2_wait();
+ outb(0x60, 0xED);
+ outb(0x60, status);
+}
+
+#define IDX_UP 0
+#define IDX_LEFT 1
+#define IDX_DOWN 2
+#define IDX_RIGHT 3
+
+static uint8_t ps2_arrowkeys[4];
+
+uint8_t ps2kbd_button_get(void)
+{
+ uint8_t ret = 0;
+ if(ps2_arrowkeys[IDX_UP])
+ ret |= BUTTON_UP;
+ if(ps2_arrowkeys[IDX_LEFT])
+ ret |= BUTTON_LEFT;
+ if(ps2_arrowkeys[IDX_DOWN])
+ ret |= BUTTON_DOWN;
+ if(ps2_arrowkeys[IDX_RIGHT])
+ ret |= BUTTON_RIGHT;
+ return ret;
+}
+
+static void key_handler(struct regs_t *regs)
+{
+ (void) regs;
+ uint8_t scancode = inb(0x60);
+ switch(scancode)
+ {
+ /* ... the only one we care about! */
+ case 0xE0:
+ {
+ uint8_t spec = inb(0x60);
+ switch(spec)
+ {
+ case 0x48:
+ ps2_arrowkeys[IDX_UP] = 1;
+ break;
+ case 0x4B:
+ ps2_arrowkeys[IDX_LEFT] = 1;
+ break;
+ case 0x50:
+ ps2_arrowkeys[IDX_DOWN] = 1;
+ break;
+ case 0x4D:
+ ps2_arrowkeys[IDX_RIGHT] = 1;
+ break;
+ case 0xC8:
+ ps2_arrowkeys[IDX_UP] = 0;
+ break;
+ case 0xCB:
+ ps2_arrowkeys[IDX_LEFT] = 0;
+ break;
+ case 0xD0:
+ ps2_arrowkeys[IDX_DOWN] = 0;
+ break;
+ case 0xCD:
+ ps2_arrowkeys[IDX_RIGHT] = 0;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void ps2_set_scancode_set(uint8_t set)
+{
+ ps2_wait();
+ outb(0x60, 0xF0);
+ outb(0x60, set);
+}
+
+static void keyboard_init(void)
+{
+ set_interrupt_handler(IRQ(1), key_handler);
+ ps2_set_scancode_set(1);
+}
+
+void ps2kbd_init(void)
+{
+ keyboard_init();
+}