📄 kbdriver.c
字号:
saw_break_code = 0;
return -1;
}
/* it's a make code: check the "meta" keys, as above */
if(code == RAW1_LEFT_ALT || code == RAW1_RIGHT_ALT)
{
kbd_status |= KBD_META_ALT;
return -1;
}
if(code == RAW1_LEFT_CTRL || code == RAW1_RIGHT_CTRL)
{
kbd_status |= KBD_META_CTRL;
return -1;
}
if(code == RAW1_LEFT_SHIFT || code == RAW1_RIGHT_SHIFT)
{
kbd_status |= KBD_META_SHIFT;
return -1;
}
/* Scroll Lock, Num Lock, and Caps Lock set the LEDs. These keys
have on-off (toggle or XOR) action, instead of momentary action */
if(code == RAW1_SCROLL_LOCK)
{
kbd_status ^= KBD_META_SCRL;
goto LEDS;
}
if(code == RAW1_NUM_LOCK)
{
kbd_status ^= KBD_META_NUM;
goto LEDS;
}
if(code == RAW1_CAPS_LOCK)
{
kbd_status ^= KBD_META_CAPS;
LEDS: write_kbd(0x60, 0xED); /* "set LEDs" command */
temp = 0;
if(kbd_status & KBD_META_SCRL)
temp |= 1;
if(kbd_status & KBD_META_NUM)
temp |= 2;
if(kbd_status & KBD_META_CAPS)
temp |= 4;
write_kbd(0x60, temp); /* bottom 3 bits set LEDs */
return -1;
}
/* no conversion if Alt pressed */
if(kbd_status & KBD_META_ALT)
return code;
/* convert A-Z[\]^_ to control chars */
if(kbd_status & KBD_META_CTRL)
{
if(code >= sizeof(map) / sizeof(map[0]))
return -1;
temp = map[code];
if(temp >= 'a' && temp <= 'z')
return temp - 'a';
if(temp >= '[' && temp <= '_')
return temp - '[' + 0x1B;
return -1;
}
/* convert raw scancode to ASCII */
if(kbd_status & KBD_META_SHIFT)
{
/* ignore invalid scan codes */
if(code >= sizeof(shift_map) / sizeof(shift_map[0]))
return -1;
temp = shift_map[code];
/* defective keyboard? non-US keyboard? more than 104 keys? */
if(temp == 0)
return -1;
/* caps lock? */
if(kbd_status & KBD_META_CAPS)
{
if(temp >= 'A' && temp <= 'Z')
temp = map[code];
}
}
else
{
if(code >= sizeof(map) / sizeof(map[0]))
return -1;
temp = map[code];
if(temp == 0)
return -1;
if(kbd_status & KBD_META_CAPS)
{
if(temp >= 'a' && temp <= 'z')
temp = shift_map[code];
}
}
return temp;
}
/*****************************************************************************
*****************************************************************************/
#define RAW3_LEFT_CTRL 0x11
#define RAW3_LEFT_SHIFT 0x12
#define RAW3_CAPS_LOCK 0x14
#define RAW3_LEFT_ALT 0x19
#define RAW3_RIGHT_ALT 0x39
#define RAW3_RIGHT_CTRL 0x58
#define RAW3_RIGHT_SHIFT 0x59
#define RAW3_SCROLL_LOCK 0x5F
#define RAW3_NUM_LOCK 0x76
#define RAW3_DEL 0x64
static int set3_scancode_to_ascii(unsigned code)
{
static const unsigned char map[] =
{
/* 00 */0, 0, 0, 0, 0, 0, 0, KEY_F1,
/* 08 */0x1B, 0, 0, 0, 0, 0x09, '~', KEY_F2,
/* 11 is left Ctrl; 12 is left Shift; 14 is CapsLock */
/* 10 */0, 0, 0, 0, 0, 'q', '!', KEY_F3,
/* 19 is left Alt */
/* 18 */0, 0, 'z', 's', 'a', 'w', '@', KEY_F4,
/* 20 */0, 'c', 'x', 'd', 'e', '$', '#', KEY_F5,
/* 28 */0, ' ', 'v', 'f', 't', 'r', '%', KEY_F6,
/* 30 */0, 'n', 'b', 'h', 'g', 'y', '^', KEY_F7,
/* 39 is right Alt */
/* 38 */0, 0, 'm', 'j', 'u', '&', '*', KEY_F8,
/* 40 */0, '<', 'k', 'i', 'o', ')', '(', KEY_F9,
/* 48 */0, '>', '?', 'l', ':', 'p', '_', KEY_F10,
/* 50 */0, 0, '"', 0, '{', '+', KEY_F11,KEY_PRNT,
/* 58 is right Ctrl; 59 is right Shift; 5F is Scroll Lock */
/* 58 */0, 0, 0x0D, '}', '|', 0, KEY_F12,0,
/* 60 */KEY_DN, KEY_LFT,KEY_PAUSE,KEY_UP,KEY_DEL,KEY_END,0x08, KEY_INS,
/* 68 */0, '1', KEY_RT, '4', '7', KEY_PGDN,KEY_HOME,KEY_PGUP,
/* 76 is Num Lock */
/* 70 */'0', '.', '2', '5', '6', '8', 0, '/',
/* 78 */0, 0x0D, '3', 0, '+', '9', '*', 0,
/* 80 */0, 0, 0, 0, '-', 0, 0, 0,
/* 88 */0, 0, 0, KEY_LWIN,KEY_RWIN,KEY_MENU,0, 0
};
static const unsigned char shift_map[] =
{
/* 00 */0, 0, 0, 0, 0, 0, 0, KEY_F1,
/* 08 */0x1B, 0, 0, 0, 0, 0x09, '`', KEY_F2,
/* 10 */0, 0, 0, 0, 0, 'Q', '1', KEY_F3,
/* 18 */0, 0, 'Z', 'S', 'A', 'W', '2', KEY_F4,
/* 20 */0, 'C', 'X', 'D', 'E', '4', '3', KEY_F5,
/* 28 */0, ' ', 'V', 'F', 'T', 'R', '5', KEY_F6,
/* 30 */0, 'N', 'B', 'H', 'G', 'Y', '6', KEY_F7,
/* 38 */0, 0, 'M', 'J', 'U', '7', '8', KEY_F8,
/* 40 */0, ',', 'K', 'I', 'O', '0', '9', KEY_F9,
/* 48 */0, '.', '/', 'L', ';', 'P', '-', KEY_F10,
/* 50 */0, 0, '\'', 0, '[', '=', KEY_F11,KEY_PRNT,
/* 58 */0, 0, 0x0D, ']', '\\', 0, KEY_F12,0,
/* 60 */KEY_DN, KEY_LFT,KEY_PAUSE,KEY_UP,KEY_DEL,KEY_END,0x08, KEY_INS,
/* 68 */0, KEY_END,KEY_RT, KEY_LFT,KEY_HOME,KEY_PGDN,KEY_HOME,KEY_PGUP,
/* 70 */KEY_INS,KEY_DEL,KEY_DN, '5', KEY_RT, KEY_UP, 0, '/',
/* 78 */0, 0x0D, KEY_PGDN,0, '+', KEY_PGUP,'*', 0,
/* 80 */0, 0, 0, 0, '-', 0, 0, 0,
/* 88 */0, 0, 0, KEY_LWIN,KEY_RWIN,KEY_MENU,0, 0
};
static unsigned saw_break_code, kbd_status;
/**/
unsigned temp;
/* check for break code (i.e. a key is released) */
if(code == 0xF0)
{
saw_break_code = 1;
return -1;
}
/* the only break codes we're interested in are Shift, Ctrl, Alt */
if(saw_break_code)
{
if(code == RAW3_LEFT_ALT || code == RAW3_RIGHT_ALT)
kbd_status &= ~KBD_META_ALT;
else if(code == RAW3_LEFT_CTRL || code == RAW3_RIGHT_CTRL)
kbd_status &= ~KBD_META_CTRL;
else if(code == RAW3_LEFT_SHIFT || code == RAW3_RIGHT_SHIFT)
kbd_status &= ~KBD_META_SHIFT;
saw_break_code = 0;
return -1;
}
/* it's a make code: check the "meta" keys, as above */
if(code == RAW3_LEFT_ALT || code == RAW3_RIGHT_ALT)
{
kbd_status |= KBD_META_ALT;
return -1;
}
if(code == RAW3_LEFT_CTRL || code == RAW3_RIGHT_CTRL)
{
kbd_status |= KBD_META_CTRL;
return -1;
}
if(code == RAW3_LEFT_SHIFT || code == RAW3_RIGHT_SHIFT)
{
kbd_status |= KBD_META_SHIFT;
return -1;
}
/* Scroll Lock, Num Lock, and Caps Lock set the LEDs. These keys
have on-off (toggle or XOR) action, instead of momentary action */
if(code == RAW3_SCROLL_LOCK)
{
kbd_status ^= KBD_META_SCRL;
goto LEDS;
}
if(code == RAW3_NUM_LOCK)
{
kbd_status ^= KBD_META_NUM;
goto LEDS;
}
if(code == RAW3_CAPS_LOCK)
{
kbd_status ^= KBD_META_CAPS;
LEDS: write_kbd(0x60, 0xED); /* "set LEDs" command */
temp = 0;
if(kbd_status & KBD_META_SCRL)
temp |= 1;
if(kbd_status & KBD_META_NUM)
temp |= 2;
if(kbd_status & KBD_META_CAPS)
temp |= 4;
write_kbd(0x60, temp); /* bottom 3 bits set LEDs */
return -1;
}
/* no conversion if Alt pressed */
if(kbd_status & KBD_META_ALT)
return code;
/* convert A-Z[\]^_ to control chars */
if(kbd_status & KBD_META_CTRL)
{
if(code >= sizeof(map) / sizeof(map[0]))
return -1;
temp = map[code];
if(temp >= 'a' && temp <= 'z')
return temp - 'a';
if(temp >= '[' && temp <= '_')
return temp - '[' + 0x1B;
return -1;
}
/* convert raw scancode to ASCII */
if(kbd_status & KBD_META_SHIFT)
{
/* ignore invalid scan codes */
if(code >= sizeof(shift_map) / sizeof(shift_map[0]))
return -1;
temp = shift_map[code];
/* defective keyboard? non-US keyboard? more than 104 keys? */
if(temp == 0)
return -1;
/* caps lock? */
if(kbd_status & KBD_META_CAPS)
{
if(temp >= 'A' && temp <= 'Z')
temp = map[code];
}
}
else
{
if(code >= sizeof(map) / sizeof(map[0]))
return -1;
temp = map[code];
if(temp == 0)
return -1;
if(kbd_status & KBD_META_CAPS)
{
if(temp >= 'a' && temp <= 'z')
temp = shift_map[code];
}
}
return temp;
}
/*****************************************************************************
*****************************************************************************/
void kbd_main(void)
{
unsigned /* windows,*/ ss = 1;
unsigned char scancode;
int c;
if(ss < 1 || ss > 3)
{
kprintf("scancode set (%u) must be 1-3"); newline();
return ;
}
//init 有问题
//init low repeate and wait long
//kb_wait();
//if(init_kbd(ss, 0x34, 0) != 0)
// kprintf("kbd init fail"); newline();
kprintf("\r\nPress Esc to end");
linehome();
/* main loop */
do
{
readit:
//kb_wait();
kbd_irq();
juge:
/* wait for keyboard interrupt to put scancode in queue */
if(empty(&g_queue)) goto readit;
/* get scancode */
if(deq(&g_queue, &scancode) < 0)
break; /* should not happen */
/* process scancodes into ASCII and display them */
#if 1
switch(ss)
{
case 1:
c = set1_scancode_to_ascii(scancode);
break;
case 3:
c = set3_scancode_to_ascii(scancode);
break;
default:
c = -1;
break;
}
if(c != -1)
kputc( c, g_color, g_row,g_col); //no g_col ++
cursor((ushort)g_row,(ushort) g_col);
if(scancode != 1 ) //set 1 // && scancode != 0x76 && scancode != 8)
goto juge;
break;
/* display raw scancodes in hex */
#else
//kprintf("%02X ", scancode);
#endif
/* until Esc pressed
} while(scancode != esc_make_code[ss]); */
} while(scancode != 1 && scancode != 0x76 && scancode != 8);
newline();
//END:
/* set scancode set 1, set FAST repeat/SHORT delay, no AT-to-XT translation */
//if(!windows)
//init_kbd(1, 0, 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -