8406115834
Access to the gpxe.org and etherboot.org domains and associated resources has been revoked by the registrant of the domain. Work around this problem by renaming project from gPXE to iPXE, and updating URLs to match. Also update README, LOG and COPYRIGHTS to remove obsolete information. Signed-off-by: Michael Brown <mcb30@ipxe.org>
113 lines
1.9 KiB
C
113 lines
1.9 KiB
C
/* Minimal polling PC keyboard driver
|
|
* - No interrupt
|
|
* - No LED
|
|
* - No special keys
|
|
*
|
|
* still Enough For Me to type a filename.
|
|
*
|
|
* 2003-07 by SONE Takesh
|
|
* 2004-04 moved by LYH From filo to Etherboot
|
|
* yhlu@tyan.com
|
|
*/
|
|
|
|
#include <ipxe/io.h>
|
|
#include "console.h"
|
|
|
|
static char key_map[][128] = {
|
|
{
|
|
"\0\x1b""1234567890-=\b\t"
|
|
"qwertyuiop[]\r\0as"
|
|
"dfghjkl;'`\0\\zxcv"
|
|
"bnm,./\0*\0 \0\0\0\0\0\0"
|
|
"\0\0\0\0\0\0\0""789-456+1"
|
|
"230."
|
|
},{
|
|
"\0\x1b""!@#$%^&*()_+\b\t"
|
|
"QWERTYUIOP{}\r\0AS"
|
|
"DFGHJKL:\"~\0|ZXCV"
|
|
"BNM<>?\0\0\0 \0\0\0\0\0\0"
|
|
"\0\0\0\0\0\0\0""789-456+1"
|
|
"230."
|
|
}
|
|
};
|
|
|
|
static int cur_scan;
|
|
static unsigned int shift_state;
|
|
#define SHIFT 1
|
|
#define CONTROL 2
|
|
#define CAPS 4
|
|
|
|
static int get_scancode(void)
|
|
{
|
|
int scan;
|
|
|
|
if ((inb(0x64) & 1) == 0)
|
|
return 0;
|
|
scan = inb(0x60);
|
|
|
|
switch (scan) {
|
|
case 0x2a:
|
|
case 0x36:
|
|
shift_state |= SHIFT;
|
|
break;
|
|
case 0xaa:
|
|
case 0xb6:
|
|
shift_state &= ~SHIFT;
|
|
break;
|
|
case 0x1d:
|
|
shift_state |= CONTROL;
|
|
break;
|
|
case 0x9d:
|
|
shift_state &= ~CONTROL;
|
|
break;
|
|
case 0x3a:
|
|
shift_state ^= CAPS;
|
|
break;
|
|
}
|
|
|
|
if (scan & 0x80)
|
|
return 0; /* ignore break code or 0xe0 etc! */
|
|
return scan;
|
|
}
|
|
|
|
static int kbd_havekey(void)
|
|
{
|
|
if (!cur_scan)
|
|
cur_scan = get_scancode();
|
|
return cur_scan != 0;
|
|
}
|
|
|
|
static int kbd_ischar(void)
|
|
{
|
|
if (!kbd_havekey())
|
|
return 0;
|
|
if (!key_map[shift_state & SHIFT][cur_scan]) {
|
|
cur_scan = 0;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int kbd_getc(void)
|
|
{
|
|
int c;
|
|
|
|
while (!kbd_ischar())
|
|
;
|
|
c = key_map[shift_state & SHIFT][cur_scan];
|
|
if (shift_state & (CONTROL | CAPS)) {
|
|
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
|
|
if (shift_state & CONTROL)
|
|
c &= 0x1f;
|
|
else if (shift_state & CAPS)
|
|
c ^= ('A' ^ 'a');
|
|
}
|
|
}
|
|
cur_scan = 0;
|
|
return c;
|
|
}
|
|
|
|
struct console_driver pc_kbd_console __console_driver = {
|
|
.getchar = kbd_getc,
|
|
};
|