mirror of
https://github.com/ipxe/ipxe
synced 2025-12-20 20:10:18 +03:00
Initial revision
This commit is contained in:
108
src/core/pc_kbd.c
Normal file
108
src/core/pc_kbd.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/* 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
|
||||
*/
|
||||
#ifdef CONSOLE_PC_KBD
|
||||
#include "etherboot.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;
|
||||
}
|
||||
|
||||
int kbd_havekey(void)
|
||||
{
|
||||
if (!cur_scan)
|
||||
cur_scan = get_scancode();
|
||||
return cur_scan != 0;
|
||||
}
|
||||
|
||||
int kbd_ischar(void)
|
||||
{
|
||||
if (!kbd_havekey())
|
||||
return 0;
|
||||
if (!key_map[shift_state & SHIFT][cur_scan]) {
|
||||
cur_scan = 0;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user