diff options
author | rsc <rsc> | 2007-08-28 03:28:13 +0000 |
---|---|---|
committer | rsc <rsc> | 2007-08-28 03:28:13 +0000 |
commit | f0d11fea8251ef959cf1197b62e523922855df3a (patch) | |
tree | c1ac5b50ec8cffb2e46636a6b5569f758dcaf8ae /kbd.c | |
parent | c1bfbfa2f7b995ee38ef138ca3250274213dc010 (diff) | |
download | xv6-labs-f0d11fea8251ef959cf1197b62e523922855df3a.tar.gz xv6-labs-f0d11fea8251ef959cf1197b62e523922855df3a.tar.bz2 xv6-labs-f0d11fea8251ef959cf1197b62e523922855df3a.zip |
Move keyboard code into kbd.c; add backspace handling.
Diffstat (limited to 'kbd.c')
-rw-r--r-- | kbd.c | 51 |
1 files changed, 51 insertions, 0 deletions
@@ -0,0 +1,51 @@ +#include "types.h" +#include "x86.h" +#include "defs.h" +#include "kbd.h" + +int +kbd_getc(void) +{ + static uint shift; + static uchar *charcode[4] = { + normalmap, shiftmap, ctlmap, ctlmap + }; + uint st, data, c; + + st = inb(KBSTATP); + if((st & KBS_DIB) == 0) + return -1; + data = inb(KBDATAP); + + if(data == 0xE0) { + shift |= E0ESC; + return 0; + } else if(data & 0x80) { + // Key released + data = (shift & E0ESC ? data : data & 0x7F); + shift &= ~(shiftcode[data] | E0ESC); + return 0; + } else if(shift & E0ESC) { + // Last character was an E0 escape; or with 0x80 + data |= 0x80; + shift &= ~E0ESC; + } + + shift |= shiftcode[data]; + shift ^= togglecode[data]; + c = charcode[shift & (CTL | SHIFT)][data]; + if(shift & CAPSLOCK) { + if('a' <= c && c <= 'z') + c += 'A' - 'a'; + else if('A' <= c && c <= 'Z') + c += 'a' - 'A'; + } + return c; +} + +void +kbd_intr(void) +{ + console_intr(kbd_getc); +} + |