summaryrefslogtreecommitdiff
path: root/kbd.c
diff options
context:
space:
mode:
authorrsc <rsc>2007-08-28 03:28:13 +0000
committerrsc <rsc>2007-08-28 03:28:13 +0000
commitf0d11fea8251ef959cf1197b62e523922855df3a (patch)
treec1ac5b50ec8cffb2e46636a6b5569f758dcaf8ae /kbd.c
parentc1bfbfa2f7b995ee38ef138ca3250274213dc010 (diff)
downloadxv6-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.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/kbd.c b/kbd.c
new file mode 100644
index 0000000..a4dd381
--- /dev/null
+++ b/kbd.c
@@ -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);
+}
+