xref: /xv6-public/kbd.c (revision f0d11fea)
1*f0d11feaSrsc #include "types.h"
2*f0d11feaSrsc #include "x86.h"
3*f0d11feaSrsc #include "defs.h"
4*f0d11feaSrsc #include "kbd.h"
5*f0d11feaSrsc 
6*f0d11feaSrsc int
7*f0d11feaSrsc kbd_getc(void)
8*f0d11feaSrsc {
9*f0d11feaSrsc   static uint shift;
10*f0d11feaSrsc   static uchar *charcode[4] = {
11*f0d11feaSrsc     normalmap, shiftmap, ctlmap, ctlmap
12*f0d11feaSrsc   };
13*f0d11feaSrsc   uint st, data, c;
14*f0d11feaSrsc 
15*f0d11feaSrsc   st = inb(KBSTATP);
16*f0d11feaSrsc   if((st & KBS_DIB) == 0)
17*f0d11feaSrsc     return -1;
18*f0d11feaSrsc   data = inb(KBDATAP);
19*f0d11feaSrsc 
20*f0d11feaSrsc   if(data == 0xE0) {
21*f0d11feaSrsc     shift |= E0ESC;
22*f0d11feaSrsc     return 0;
23*f0d11feaSrsc   } else if(data & 0x80) {
24*f0d11feaSrsc     // Key released
25*f0d11feaSrsc     data = (shift & E0ESC ? data : data & 0x7F);
26*f0d11feaSrsc     shift &= ~(shiftcode[data] | E0ESC);
27*f0d11feaSrsc     return 0;
28*f0d11feaSrsc   } else if(shift & E0ESC) {
29*f0d11feaSrsc     // Last character was an E0 escape; or with 0x80
30*f0d11feaSrsc     data |= 0x80;
31*f0d11feaSrsc     shift &= ~E0ESC;
32*f0d11feaSrsc   }
33*f0d11feaSrsc 
34*f0d11feaSrsc   shift |= shiftcode[data];
35*f0d11feaSrsc   shift ^= togglecode[data];
36*f0d11feaSrsc   c = charcode[shift & (CTL | SHIFT)][data];
37*f0d11feaSrsc   if(shift & CAPSLOCK) {
38*f0d11feaSrsc     if('a' <= c && c <= 'z')
39*f0d11feaSrsc       c += 'A' - 'a';
40*f0d11feaSrsc     else if('A' <= c && c <= 'Z')
41*f0d11feaSrsc       c += 'a' - 'A';
42*f0d11feaSrsc   }
43*f0d11feaSrsc   return c;
44*f0d11feaSrsc }
45*f0d11feaSrsc 
46*f0d11feaSrsc void
47*f0d11feaSrsc kbd_intr(void)
48*f0d11feaSrsc {
49*f0d11feaSrsc   console_intr(kbd_getc);
50*f0d11feaSrsc }
51*f0d11feaSrsc 
52