diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2015-02-18 12:49:58 -0500 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2015-02-18 12:49:58 -0500 |
| commit | 9defae4d6f7b30d844447549fadffea4eab5a0dd (patch) | |
| tree | 2c44f6fb193d9b3f7487714e7dfa3903bedb932d /drivers/ps2kbd.c | |
| parent | 1d3537f33d793e2cabe53e72f0e0ead911fcc870 (diff) | |
| download | kappa-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.c | 104 |
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(); +} |