4 * Implementation for PC keyboards.
14 K_RDWR = 0x60, /* keyboard data & cmds (read/write) */
15 K_STATUS = 0x64, /* keybd status (read-only) */
16 K_CMD = 0x64, /* keybd ctlr command (write-only) */
19 * Bit definitions for K_STATUS port.
21 K_OBUF_FUL = 0x01, /* output (from keybd) buffer full */
22 K_IBUF_FUL = 0x02, /* input (to keybd) buffer full */
23 K_SYSFLAG = 0x04, /* "System Flag" */
24 K_CMD_DATA = 0x08, /* 1 = input buf has cmd, 0 = data */
25 K_KBD_INHIBIT = 0x10, /* 0 if keyboard inhibited */
26 K_AUX_OBUF_FUL = 0x20, /* 1 = obuf holds aux device data */
27 K_TIMEOUT = 0x40, /* timout error flag */
28 K_PARITY_ERROR = 0x80, /* parity error flag */
31 * Keyboard controller commands (sent to K_CMD port).
33 KC_CMD_READ = 0x20, /* read controller command byte */
34 KC_CMD_WRITE = 0x60, /* write controller command byte */
35 KC_CMD_DIS_AUX = 0xa7, /* disable auxiliary device */
36 KC_CMD_ENB_AUX = 0xa8, /* enable auxiliary device */
37 KC_CMD_TEST_AUX = 0xa9, /* test auxiliary device interface */
38 KC_CMD_SELFTEST = 0xaa, /* keyboard controller self-test */
39 KC_CMD_TEST = 0xab, /* test keyboard interface */
40 KC_CMD_DUMP = 0xac, /* diagnostic dump */
41 KC_CMD_DISABLE = 0xad, /* disable keyboard */
42 KC_CMD_ENABLE = 0xae, /* enable keyboard */
43 KC_CMD_RDKBD = 0xc4, /* read keyboard ID */
44 KC_CMD_WIN = 0xd0, /* read output port */
45 KC_CMD_WOUT = 0xd1, /* write output port */
46 KC_CMD_ECHO = 0xee, /* used for diagnostic testing */
47 KC_CMD_PULSE = 0xff, /* pulse bits 3-0 based on low nybble */
50 * Keyboard commands (send to K_RDWR).
52 K_CMD_LEDS = 0xed, /* set status LEDs (caps lock, etc.) */
55 * Bit definitions for controller command byte (sent following
56 * K_CMD_WRITE command).
58 K_CB_ENBLIRQ = 0x01, /* enable data-ready intrpt */
59 K_CB_SETSYSF = 0x04, /* Set System Flag */
60 K_CB_INHBOVR = 0x08, /* Inhibit Override */
61 K_CB_DISBLE = 0x10, /* disable keyboard */
64 * Bit definitions for "Indicator Status Byte" (sent after a
65 * K_CMD_LEDS command). If the bit is on, the LED is on. Undefined
66 * bit positions must be 0.
68 K_LED_SCRLLK = 0x1, /* scroll lock */
69 K_LED_NUMLK = 0x2, /* num lock */
70 K_LED_CAPSLK = 0x4, /* caps lock */
73 * Bit definitions for "Miscellaneous port B" (K_PORTB).
76 K_ENABLETMR2 = 0x01, /* enable output from timer 2 */
77 K_SPKRDATA = 0x02, /* direct input to speaker */
78 K_ENABLEPRTB = 0x04, /* "enable" port B */
79 K_EIOPRTB = 0x08, /* enable NMI on parity error */
81 K_REFRESHB = 0x10, /* refresh flag from INLTCONT PAL */
82 K_OUT2B = 0x20, /* timer 2 output */
83 K_ICKB = 0x40, /* I/O channel check (parity error) */
86 * Bit definitions for the keyboard controller's output port.
88 KO_SYSRESET = 0x01, /* processor reset */
89 KO_GATE20 = 0x02, /* A20 address line enable */
90 KO_AUX_DATA_OUT = 0x04, /* output data to auxiliary device */
91 KO_AUX_CLOCK = 0x08, /* auxiliary device clock */
92 KO_OBUF_FUL = 0x10, /* keyboard output buffer full */
93 KO_AUX_OBUF_FUL = 0x20, /* aux device output buffer full */
94 KO_CLOCK = 0x40, /* keyboard clock */
95 KO_DATA_OUT = 0x80, /* output data to keyboard */
101 #include "processor.h"
108 static unsigned char keymap[][2] = {
110 {27, 27 }, /* 1 - ESC */
123 {8, 8 }, /* 14 - Backspace */
124 {'\t','\t'}, /* 15 */
137 {'\r','\r'}, /* 28 - Enter */
138 {0, 0 }, /* 29 - Ctrl */
151 {SHIFT, SHIFT}, /* 42 - Left Shift */
163 {SHIFT, SHIFT}, /* 54 - Right Shift */
164 {0, 0}, /* 55 - Print Screen */
165 {0, 0}, /* 56 - Alt */
166 {' ',' '}, /* 57 - Space bar */
167 {0, 0}, /* 58 - Caps Lock */
168 {0, 0}, /* 59 - F1 */
169 {0, 0}, /* 60 - F2 */
170 {0, 0}, /* 61 - F3 */
171 {0, 0}, /* 62 - F4 */
172 {0, 0}, /* 63 - F5 */
173 {0, 0}, /* 64 - F6 */
174 {0, 0}, /* 65 - F7 */
175 {0, 0}, /* 66 - F8 */
176 {0, 0}, /* 67 - F9 */
177 {0, 0}, /* 68 - F10 */
178 {0, 0}, /* 69 - Num Lock */
179 {0, 0}, /* 70 - Scroll Lock */
180 {0xb7,0xb7}, /* 71 - Numeric keypad 7 */
181 {0xb8,0xb8}, /* 72 - Numeric keypad 8 */
182 {0xb9,0xb9}, /* 73 - Numeric keypad 9 */
183 {'-', '-'}, /* 74 - Numeric keypad '-' */
184 {0xb4,0xb4}, /* 75 - Numeric keypad 4 */
185 {0xb5,0xb5}, /* 76 - Numeric keypad 5 */
186 {0xb6,0xb6}, /* 77 - Numeric keypad 6 */
187 {'+', '+'}, /* 78 - Numeric keypad '+' */
188 {0xb1,0xb1}, /* 79 - Numeric keypad 1 */
189 {0xb2,0xb2}, /* 80 - Numeric keypad 2 */
190 {0xb3,0xb3}, /* 81 - Numeric keypad 3 */
191 {0xb0,0xb0}, /* 82 - Numeric keypad 0 */
192 {0xae,0xae}, /* 83 - Numeric keypad '.' */
197 Keyb::set_keymap(Keyb::Keymap km)
199 // This is a one-time switch over only.
202 // Simple patch to german layout
217 keymap[43][1] = '\'';
228 int Keyb::getchar(bool wait)
230 static unsigned shift_state;
231 unsigned status, scan_code, ch;
232 Proc::Status old_s = Proc::cli_save();
236 /* Wait until a scan code is ready and read it. */
237 status = Io::in8(0x64);
238 if ((status & K_OBUF_FUL) == 0)
242 Proc::sti_restore(old_s);
245 scan_code = Io::in8(0x60);
247 /* Drop mouse events */
248 if ((status & K_AUX_OBUF_FUL) != 0)
252 Proc::sti_restore(old_s);
256 if ((scan_code & 0x7f) >= sizeof(keymap)/sizeof(keymap[0]))
259 /* Handle key releases - only release of SHIFT is important. */
260 if (scan_code & 0x80)
263 if (keymap[scan_code][0] == SHIFT)
268 /* Translate the character through the keymap. */
269 ch = keymap[scan_code][shift_state];
270 if (ch == (unsigned)SHIFT)
278 Proc::sti_restore(old_s);