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