static int kbd_get(int ms) { int status, data; while(1) { status = kbd_inb(KBD_STATUS_REG); if (status & KBD_STAT_OBF) { data = kbd_inb(KBD_DATA_REG); if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) return -1; else return data; } if (--ms < 0) return -1; #ifdef __BOOT__ boot_udelay(1000); #else rtems_bsp_delay(1000); #endif } }
static void kbd_put(u_char c, int ms, int port) { while (kbd_inb(KBD_STATUS_REG) & KBD_STAT_IBF) { if (--ms < 0) return; #ifdef __BOOT__ boot_udelay(1000); #else rtems_bsp_delay(1000); #endif } kbd_outb(port, c); }
int kbd_tstc(void) { return ((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) != 0); }
/* Keyboard support */ static int kbd_getc(void) { unsigned char dt, brk, val; unsigned code; loop: while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ; dt = kbd_inb(KBD_DATA_REG); brk = dt & 0x80; /* brk == 1 on key release */ dt = dt & 0x7f; /* keycode */ if (console_global_data.shfts) code = shift_map[dt]; else if (console_global_data.ctls) code = ctrl_map[dt]; else code = plain_map[dt]; val = KVAL(code); switch (KTYP(code) & 0x0f) { case KT_LATIN: if (brk) break; if (console_global_data.alts) val |= 0x80; if (val == 0x7f) /* map delete to backspace */ val = '\b'; return val; case KT_LETTER: if (brk) break; if (console_global_data.caps) val -= 'a'-'A'; return val; case KT_SPEC: if (brk) break; if (val == KVAL(K_CAPS)) console_global_data.caps = !console_global_data.caps; else if (val == KVAL(K_ENTER)) { enter: /* Wait for key up */ while (1) { while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ; dt = kbd_inb(KBD_DATA_REG); if (dt & 0x80) /* key up */ break; } return 10; } break; case KT_PAD: if (brk) break; if (val < 10) return val; if (val == KVAL(K_PENTER)) goto enter; break; case KT_SHIFT: switch (val) { case KG_SHIFT: case KG_SHIFTL: case KG_SHIFTR: console_global_data.shfts = brk ? 0 : 1; break; case KG_ALT: case KG_ALTGR: console_global_data.alts = brk ? 0 : 1; break; case KG_CTRL: case KG_CTRLL: case KG_CTRLR: console_global_data.ctls = brk ? 0 : 1; break; } break; case KT_LOCK: switch (val) { case KG_SHIFT: case KG_SHIFTL: case KG_SHIFTR: if (brk) console_global_data.shfts = !console_global_data.shfts; break; case KG_ALT: case KG_ALTGR: if (brk) console_global_data.alts = !console_global_data.alts; break; case KG_CTRL: case KG_CTRLL: case KG_CTRLR: if (brk) console_global_data.ctls = !console_global_data.ctls; break; } break; } /* if (brk) return (0); */ /* Ignore initial 'key up' codes */ goto loop; }
/*-------------------------------------------------------------------------+ | Function: _IBMPC_scankey | Description: This function can be called during a poll for input, or by | an ISR. Basically any time you want to process a keypress. | Global Variables: key_map, shift_map. | Arguments: outChar - character read in case of a valid reading, | otherwise unchanged. | Returns: true in case a valid character has been read, | false otherwise. +--------------------------------------------------------------------------*/ bool _IBMPC_scankey(char *outChar) { unsigned char inChar; static int alt_pressed = 0; static int ctrl_pressed = 0; static int shift_pressed = 0; static int caps_pressed = 0; static int extended = 0; *outChar = 0; /* default value if we return false */ /* Read keyboard controller, toggle enable */ inChar=kbd_inb(KBD_CTL); kbd_outb(KBD_CTL, inChar & ~0x80); kbd_outb(KBD_CTL, inChar | 0x80); kbd_outb(KBD_CTL, inChar & ~0x80); /* See if it has data */ inChar=kbd_inb(KBD_STATUS); if ((inChar & 0x01) == 0) return false; /* Read the data. Handle nonsense with shift, control, etc. */ inChar=kbd_inb(KBD_DATA); if (extended) extended--; switch (inChar) { case 0xe0: extended = 2; return false; break; case 0x38: alt_pressed = 1; return false; break; case 0xb8: alt_pressed = 0; return false; break; case 0x1d: ctrl_pressed = 1; return false; break; case 0x9d: ctrl_pressed = 0; return false; break; case 0x2a: if (extended) return false; case 0x36: shift_pressed = 1; return false; break; case 0xaa: if (extended) return false; case 0xb6: shift_pressed = 0; return false; break; case 0x3a: caps_pressed = 1; return false; break; case 0xba: caps_pressed = 0; return false; break; case 0x53: if (ctrl_pressed && alt_pressed) bsp_reset(); /* ctrl+alt+del -> reboot */ break; /* * Ignore unrecognized keys--usually arrow and such */ default: if ((inChar & 0x80) || (inChar > 0x39)) /* High-bit on means key is being released, not pressed */ return false; break; } /* switch */ /* Strip high bit, look up in our map */ inChar &= 0x7f; if (ctrl_pressed) { *outChar = key_map[inChar]; *outChar &= 037; } else { *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar]; if (caps_pressed) { if (*outChar >= 'A' && *outChar <= 'Z') *outChar += 'a' - 'A'; else if (*outChar >= 'a' && *outChar <= 'z') *outChar -= 'a' - 'A'; } } return true; } /* _IBMPC_scankey */