david/ipxe
Archived
1
0
This repository has been archived on 2020-12-06. You can view files and clone it, but cannot push or open issues or pull requests.
ipxe/src/core/pc_kbd.c
Michael Brown 8406115834 [build] Rename gPXE to iPXE
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>
2010-04-19 23:43:39 +01:00

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,
};