You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pc_kbd.c 1.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. #include <ipxe/io.h>
  13. #include <ipxe/console.h>
  14. static char key_map[][128] = {
  15. {
  16. "\0\x1b""1234567890-=\b\t"
  17. "qwertyuiop[]\r\0as"
  18. "dfghjkl;'`\0\\zxcv"
  19. "bnm,./\0*\0 \0\0\0\0\0\0"
  20. "\0\0\0\0\0\0\0""789-456+1"
  21. "230."
  22. },{
  23. "\0\x1b""!@#$%^&*()_+\b\t"
  24. "QWERTYUIOP{}\r\0AS"
  25. "DFGHJKL:\"~\0|ZXCV"
  26. "BNM<>?\0\0\0 \0\0\0\0\0\0"
  27. "\0\0\0\0\0\0\0""789-456+1"
  28. "230."
  29. }
  30. };
  31. static int cur_scan;
  32. static unsigned int shift_state;
  33. #define SHIFT 1
  34. #define CONTROL 2
  35. #define CAPS 4
  36. static int get_scancode(void)
  37. {
  38. int scan;
  39. if ((inb(0x64) & 1) == 0)
  40. return 0;
  41. scan = inb(0x60);
  42. switch (scan) {
  43. case 0x2a:
  44. case 0x36:
  45. shift_state |= SHIFT;
  46. break;
  47. case 0xaa:
  48. case 0xb6:
  49. shift_state &= ~SHIFT;
  50. break;
  51. case 0x1d:
  52. shift_state |= CONTROL;
  53. break;
  54. case 0x9d:
  55. shift_state &= ~CONTROL;
  56. break;
  57. case 0x3a:
  58. shift_state ^= CAPS;
  59. break;
  60. }
  61. if (scan & 0x80)
  62. return 0; /* ignore break code or 0xe0 etc! */
  63. return scan;
  64. }
  65. static int kbd_havekey(void)
  66. {
  67. if (!cur_scan)
  68. cur_scan = get_scancode();
  69. return cur_scan != 0;
  70. }
  71. static int kbd_ischar(void)
  72. {
  73. if (!kbd_havekey())
  74. return 0;
  75. if (!key_map[shift_state & SHIFT][cur_scan]) {
  76. cur_scan = 0;
  77. return 0;
  78. }
  79. return 1;
  80. }
  81. static int kbd_getc(void)
  82. {
  83. int c;
  84. while (!kbd_ischar())
  85. ;
  86. c = key_map[shift_state & SHIFT][cur_scan];
  87. if (shift_state & (CONTROL | CAPS)) {
  88. if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
  89. if (shift_state & CONTROL)
  90. c &= 0x1f;
  91. else if (shift_state & CAPS)
  92. c ^= ('A' ^ 'a');
  93. }
  94. }
  95. cur_scan = 0;
  96. return c;
  97. }
  98. struct console_driver pc_kbd_console __console_driver = {
  99. .getchar = kbd_getc,
  100. };