00001 /* Minimal polling PC keyboard driver 00002 * - No interrupt 00003 * - No LED 00004 * - No special keys 00005 * 00006 * still Enough For Me to type a filename. 00007 * 00008 * 2003-07 by SONE Takesh 00009 * 2004-04 moved by LYH From filo to Etherboot 00010 * yhlu@tyan.com 00011 */ 00012 00013 #include <gpxe/io.h> 00014 #include "console.h" 00015 00016 static char key_map[][128] = { 00017 { 00018 "\0\x1b""1234567890-=\b\t" 00019 "qwertyuiop[]\r\0as" 00020 "dfghjkl;'`\0\\zxcv" 00021 "bnm,./\0*\0 \0\0\0\0\0\0" 00022 "\0\0\0\0\0\0\0""789-456+1" 00023 "230." 00024 },{ 00025 "\0\x1b""!@#$%^&*()_+\b\t" 00026 "QWERTYUIOP{}\r\0AS" 00027 "DFGHJKL:\"~\0|ZXCV" 00028 "BNM<>?\0\0\0 \0\0\0\0\0\0" 00029 "\0\0\0\0\0\0\0""789-456+1" 00030 "230." 00031 } 00032 }; 00033 00034 static int cur_scan; 00035 static unsigned int shift_state; 00036 #define SHIFT 1 00037 #define CONTROL 2 00038 #define CAPS 4 00039 00040 static int get_scancode(void) 00041 { 00042 int scan; 00043 00044 if ((inb(0x64) & 1) == 0) 00045 return 0; 00046 scan = inb(0x60); 00047 00048 switch (scan) { 00049 case 0x2a: 00050 case 0x36: 00051 shift_state |= SHIFT; 00052 break; 00053 case 0xaa: 00054 case 0xb6: 00055 shift_state &= ~SHIFT; 00056 break; 00057 case 0x1d: 00058 shift_state |= CONTROL; 00059 break; 00060 case 0x9d: 00061 shift_state &= ~CONTROL; 00062 break; 00063 case 0x3a: 00064 shift_state ^= CAPS; 00065 break; 00066 } 00067 00068 if (scan & 0x80) 00069 return 0; /* ignore break code or 0xe0 etc! */ 00070 return scan; 00071 } 00072 00073 static int kbd_havekey(void) 00074 { 00075 if (!cur_scan) 00076 cur_scan = get_scancode(); 00077 return cur_scan != 0; 00078 } 00079 00080 static int kbd_ischar(void) 00081 { 00082 if (!kbd_havekey()) 00083 return 0; 00084 if (!key_map[shift_state & SHIFT][cur_scan]) { 00085 cur_scan = 0; 00086 return 0; 00087 } 00088 return 1; 00089 } 00090 00091 static int kbd_getc(void) 00092 { 00093 int c; 00094 00095 while (!kbd_ischar()) 00096 ; 00097 c = key_map[shift_state & SHIFT][cur_scan]; 00098 if (shift_state & (CONTROL | CAPS)) { 00099 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { 00100 if (shift_state & CONTROL) 00101 c &= 0x1f; 00102 else if (shift_state & CAPS) 00103 c ^= ('A' ^ 'a'); 00104 } 00105 } 00106 cur_scan = 0; 00107 return c; 00108 } 00109 00110 struct console_driver pc_kbd_console __console_driver = { 00111 .getchar = kbd_getc, 00112 };
1.5.7.1