iPXE
pc_kbd.c
Go to the documentation of this file.
1 /* Minimal polling PC keyboard driver
2  * - No interrupt
3  * - No LED
4  * - No special keys
5  *
6  * still Enough For Me to type a filename.
7  *
8  * 2003-07 by SONE Takesh
9  * 2004-04 moved by LYH From filo to Etherboot
10  * yhlu@tyan.com
11  */
12 
13 #include <ipxe/io.h>
14 #include <ipxe/console.h>
15 
16 static char key_map[][128] = {
17  {
18  "\0\x1b""1234567890-=\b\t"
19  "qwertyuiop[]\r\0as"
20  "dfghjkl;'`\0\\zxcv"
21  "bnm,./\0*\0 \0\0\0\0\0\0"
22  "\0\0\0\0\0\0\0""789-456+1"
23  "230."
24  },{
25  "\0\x1b""!@#$%^&*()_+\b\t"
26  "QWERTYUIOP{}\r\0AS"
27  "DFGHJKL:\"~\0|ZXCV"
28  "BNM<>?\0\0\0 \0\0\0\0\0\0"
29  "\0\0\0\0\0\0\0""789-456+1"
30  "230."
31  }
32 };
33 
34 static int cur_scan;
35 static unsigned int shift_state;
36 #define SHIFT 1
37 #define CONTROL 2
38 #define CAPS 4
39 
40 static int get_scancode(void)
41 {
42  int scan;
43 
44  if ((inb(0x64) & 1) == 0)
45  return 0;
46  scan = inb(0x60);
47 
48  switch (scan) {
49  case 0x2a:
50  case 0x36:
51  shift_state |= SHIFT;
52  break;
53  case 0xaa:
54  case 0xb6:
55  shift_state &= ~SHIFT;
56  break;
57  case 0x1d:
59  break;
60  case 0x9d:
61  shift_state &= ~CONTROL;
62  break;
63  case 0x3a:
64  shift_state ^= CAPS;
65  break;
66  }
67 
68  if (scan & 0x80)
69  return 0; /* ignore break code or 0xe0 etc! */
70  return scan;
71 }
72 
73 static int kbd_havekey(void)
74 {
75  if (!cur_scan)
77  return cur_scan != 0;
78 }
79 
80 static int kbd_ischar(void)
81 {
82  if (!kbd_havekey())
83  return 0;
84  if (!key_map[shift_state & SHIFT][cur_scan]) {
85  cur_scan = 0;
86  return 0;
87  }
88  return 1;
89 }
90 
91 static int kbd_getc(void)
92 {
93  int c;
94 
95  while (!kbd_ischar())
96  ;
98  if (shift_state & (CONTROL | CAPS)) {
99  if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
100  if (shift_state & CONTROL)
101  c &= 0x1f;
102  else if (shift_state & CAPS)
103  c ^= ('A' ^ 'a');
104  }
105  }
106  cur_scan = 0;
107  return c;
108 }
109 
110 struct console_driver pc_kbd_console __console_driver = {
111  .getchar = kbd_getc,
112 };
uint32_t c
Definition: md4.c:30
static int kbd_havekey(void)
Definition: pc_kbd.c:73
iPXE I/O API
struct console_driver pc_kbd_console __console_driver
Definition: pc_kbd.c:110
#define SHIFT
Definition: pc_kbd.c:36
static char key_map[][128]
Definition: pc_kbd.c:16
static int get_scancode(void)
Definition: pc_kbd.c:40
User interaction.
static int kbd_ischar(void)
Definition: pc_kbd.c:80
uint8_t inb(volatile uint8_t *io_addr)
Read byte from I/O-mapped device.
#define CONTROL
Definition: pc_kbd.c:37
static unsigned int shift_state
Definition: pc_kbd.c:35
#define CAPS
Definition: pc_kbd.c:38
A console driver.
Definition: console.h:55
static int kbd_getc(void)
Definition: pc_kbd.c:91
int(* getchar)(void)
Read a character from the console.
Definition: console.h:78
static int cur_scan
Definition: pc_kbd.c:34