Skip to content

Commit

Permalink
Impl PS/2 keyboard driver (not completed, but it works)
Browse files Browse the repository at this point in the history
  • Loading branch information
hikalium committed Jan 11, 2019
1 parent 80474aa commit e9af482
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 123 deletions.
238 changes: 117 additions & 121 deletions src/keyboard.cc
Original file line number Diff line number Diff line change
@@ -1,153 +1,149 @@
#include "liumos.h"

#define KEYID_MASK_ID 0x007f
#define KEYID_MASK_BREAK 0x0080
#define KEYID_MASK_BREAK KEYCODE_MASK_BREAK
#define KEYID_MASK_TENKEY 0x0100
#define KEYID_MASK_STATE_SHIFT 0x0200
#define KEYID_MASK_STATE_CTRL 0x0400
#define KEYID_MASK_STATE_ALT 0x0800
#define KEYID_MASK_STATE_LOCK_SCROOL 0x1000
#define KEYID_MASK_STATE_LOCK_NUM 0x2000
#define KEYID_MASK_STATE_LOCK_CAPS 0x4000
#define KEYID_MASK_EXTENDED 0x8000

#define KEYID_ASCII_NUL 0x0000
#define KEYID_ASCII_SOH 0x0001
#define KEYID_ASCII_STX 0x0002
#define KEYID_ASCII_ETX 0x0003
#define KEYID_ASCII_EOT 0x0004
#define KEYID_ASCII_ENQ 0x0005
#define KEYID_ASCII_ACK 0x0006
#define KEYID_ASCII_BEL 0x0007
#define KEYID_ASCII_BS 0x0008 /*0x0e*/
#define KEYID_ASCII_HT 0x0009 /*0x0f*/
#define KEYID_ASCII_LF 0x000a /*0x1c*/
#define KEYID_ASCII_VT 0x000b
#define KEYID_ASCII_FF 0x000c
#define KEYID_ASCII_CR 0x000d
#define KEYID_ASCII_SO 0x000e
#define KEYID_ASCII_SI 0x000f
#define KEYID_ASCII_DLE 0x0010
#define KEYID_ASCII_DC1 0x0011
#define KEYID_ASCII_DC2 0x0012
#define KEYID_ASCII_DC3 0x0013
#define KEYID_ASCII_DC4 0x0014
#define KEYID_ASCII_NAK 0x0015
#define KEYID_ASCII_SYN 0x0016
#define KEYID_ASCII_ETB 0x0017
#define KEYID_ASCII_CAN 0x0018
#define KEYID_ASCII_EM 0x0019
#define KEYID_ASCII_SUB 0x001a
#define KEYID_ASCII_ESC 0x001b
#define KEYID_ASCII_FS 0x001c
#define KEYID_ASCII_GS 0x001d
#define KEYID_ASCII_RS 0x001e
#define KEYID_ASCII_US 0x001f
#define KEYID_ASCII_CHAR_START 0x0020
#define KEYID_ASCII_CHAR_END 0x007e
#define KEYID_ASCII_DEL 0x007f
#define KEYID_ESC (kKeyIDMaskExtended | 0x0000)
#define KEYID_F1 (kKeyIDMaskExtended | 0x0001)
#define KEYID_F2 (kKeyIDMaskExtended | 0x0002)
#define KEYID_F3 (kKeyIDMaskExtended | 0x0003)
#define KEYID_F4 (kKeyIDMaskExtended | 0x0004)
#define KEYID_F5 (kKeyIDMaskExtended | 0x0005)
#define KEYID_F6 (kKeyIDMaskExtended | 0x0006)
#define KEYID_F7 (kKeyIDMaskExtended | 0x0007)
#define KEYID_F8 (kKeyIDMaskExtended | 0x0008)
#define KEYID_F9 (kKeyIDMaskExtended | 0x0009)
#define KEYID_F10 (kKeyIDMaskExtended | 0x000a)
#define KEYID_F11 (kKeyIDMaskExtended | 0x000b)
#define KEYID_F12 (kKeyIDMaskExtended | 0x000c)
#define KEYID_LOCK_NUM (kKeyIDMaskExtended | 0x000d)
#define KEYID_LOCK_SCROOL (kKeyIDMaskExtended | 0x000e)
#define KEYID_LOCK_CAPS (kKeyIDMaskExtended | 0x000f)
#define KEYID_SHIFT_L (kKeyIDMaskExtended | 0x0010)
#define KEYID_SHIFT_R (kKeyIDMaskExtended | 0x0011)
#define KEYID_CTRL_L (kKeyIDMaskExtended | 0x0012)
#define KEYID_CTRL_R (kKeyIDMaskExtended | 0x0013)
#define KEYID_ALT_L (kKeyIDMaskExtended | 0x0014)
#define KEYID_ALT_R (kKeyIDMaskExtended | 0x0015)
#define KEYID_DELETE (kKeyIDMaskExtended | 0x0016)
#define KEYID_INSERT (kKeyIDMaskExtended | 0x0017)
#define KEYID_PAUSE (kKeyIDMaskExtended | 0x0018)
#define KEYID_BREAK (kKeyIDMaskExtended | 0x0019)
#define KEYID_PRINT_SCREEN (kKeyIDMaskExtended | 0x001a)
#define KEYID_SYS_RQ (kKeyIDMaskExtended | 0x001b)
#define KEYID_CURSOR_U (kKeyIDMaskExtended | 0x001c)
#define KEYID_CURSOR_D (kKeyIDMaskExtended | 0x001d)
#define KEYID_CURSOR_L (kKeyIDMaskExtended | 0x001e)
#define KEYID_CURSOR_R (kKeyIDMaskExtended | 0x001f)
#define KEYID_PAGE_UP (kKeyIDMaskExtended | 0x0020)
#define KEYID_PAGE_DOWN (kKeyIDMaskExtended | 0x0021)
#define KEYID_HOME (kKeyIDMaskExtended | 0x0022)
#define KEYID_END (kKeyIDMaskExtended | 0x0023)
#define KEYID_ICON_L (kKeyIDMaskExtended | 0x0024)
#define KEYID_ICON_R (kKeyIDMaskExtended | 0x0025)
#define KEYID_MENU (kKeyIDMaskExtended | 0x0026)
#define KEYID_KANJI (kKeyIDMaskExtended | 0x0027)
#define KEYID_HIRAGANA (kKeyIDMaskExtended | 0x0028)
#define KEYID_HENKAN (kKeyIDMaskExtended | 0x0029)
#define KEYID_MUHENKAN (kKeyIDMaskExtended | 0x002a)

#define KEYID_ESC 0x0000
#define KEYID_F1 0x0001
#define KEYID_F2 0x0002
#define KEYID_F3 0x0003
#define KEYID_F4 0x0004
#define KEYID_F5 0x0005
#define KEYID_F6 0x0006
#define KEYID_F7 0x0007
#define KEYID_F8 0x0008
#define KEYID_F9 0x0009
#define KEYID_F10 0x000a
#define KEYID_F11 0x000b
#define KEYID_F12 0x000c
#define KEYID_LOCK_NUM 0x000d
#define KEYID_LOCK_SCROOL 0x000e
#define KEYID_LOCK_CAPS 0x000f
#define KEYID_SHIFT_L 0x0010
#define KEYID_SHIFT_R 0x0011
#define KEYID_CTRL_L 0x0012
#define KEYID_CTRL_R 0x0013
#define KEYID_ALT_L 0x0014
#define KEYID_ALT_R 0x0015
#define KEYID_DELETE 0x0016
#define KEYID_INSERT 0x0017
#define KEYID_PAUSE 0x0018
#define KEYID_BREAK 0x0019
#define KEYID_PRINT_SCREEN 0x001a
#define KEYID_SYS_RQ 0x001b
#define KEYID_CURSOR_U 0x001c
#define KEYID_CURSOR_D 0x001d
#define KEYID_CURSOR_L 0x001e
#define KEYID_CURSOR_R 0x001f
#define KEYID_PAGE_UP 0x0020
#define KEYID_PAGE_DOWN 0x0021
#define KEYID_HOME 0x0022
#define KEYID_END 0x0023
#define KEYID_ICON_L 0x0024
#define KEYID_ICON_R 0x0025
#define KEYID_MENU 0x0026
#define KEYID_KANJI 0x0027
#define KEYID_HIRAGANA 0x0028
#define KEYID_HENKAN 0x0029
#define KEYID_MUHENKAN 0x002a
#define KEYID_BACKSPACE (kKeyIDMaskExtended | 0x0040)
#define KEYID_TAB (kKeyIDMaskExtended | 0x0041)
#define KEYID_ENTER (kKeyIDMaskExtended | 0x0042)

#define KEYID_BACKSPACE 0x0040
#define KEYID_TAB 0x0041
#define KEYID_ENTER 0x0042

#define KEYID_KBD_ERROR 0x007e
#define KEYID_UNKNOWN 0x007f
#define KEYID_KBD_ERROR (kKeyIDMaskExtended | 0x007e)
#define KEYID_UNKNOWN (kKeyIDMaskExtended | 0x007f)

static const uint16_t kKeyCodeTable[0x80] = {
KEYID_MASK_EXTENDED | KEYID_KBD_ERROR, KEYID_MASK_EXTENDED | KEYID_ESC, '1',
'2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^',
KEYID_MASK_EXTENDED | KEYID_BACKSPACE, KEYID_MASK_EXTENDED | KEYID_TAB,
0, KEYID_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^',
KEYID_BACKSPACE, KEYID_TAB,
/*0x10*/
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[',
KEYID_MASK_EXTENDED | KEYID_ENTER, KEYID_MASK_EXTENDED | KEYID_CTRL_L, 'A',
'S',
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', KEYID_ENTER,
KEYID_CTRL_L, 'A', 'S',
/*0x20*/
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':',
KEYID_MASK_EXTENDED | KEYID_KANJI, KEYID_MASK_EXTENDED | KEYID_SHIFT_L, ']',
'Z', 'X', 'C', 'V',
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', KEYID_KANJI, KEYID_SHIFT_L,
']', 'Z', 'X', 'C', 'V',
/*0x30*/
'B', 'N', 'M', ',', '.', '/', KEYID_MASK_EXTENDED | KEYID_SHIFT_R,
KEYID_MASK_TENKEY | '*', KEYID_MASK_EXTENDED | KEYID_ALT_L, ' ',
KEYID_MASK_EXTENDED | KEYID_LOCK_CAPS, KEYID_MASK_EXTENDED | KEYID_F1,
KEYID_MASK_EXTENDED | KEYID_F2, KEYID_MASK_EXTENDED | KEYID_F3,
KEYID_MASK_EXTENDED | KEYID_F4, KEYID_MASK_EXTENDED | KEYID_F5,
'B', 'N', 'M', ',', '.', '/', KEYID_SHIFT_R, KEYID_MASK_TENKEY | '*',
KEYID_ALT_L, ' ', KEYID_LOCK_CAPS, KEYID_F1, KEYID_F2, KEYID_F3, KEYID_F4,
KEYID_F5,
/*0x40*/
KEYID_MASK_EXTENDED | KEYID_F6, KEYID_MASK_EXTENDED | KEYID_F7,
KEYID_MASK_EXTENDED | KEYID_F8, KEYID_MASK_EXTENDED | KEYID_F9,
KEYID_MASK_EXTENDED | KEYID_F10, KEYID_MASK_EXTENDED | KEYID_LOCK_NUM,
KEYID_MASK_EXTENDED | KEYID_LOCK_SCROOL, KEYID_MASK_TENKEY | '7',
KEYID_MASK_TENKEY | '8', KEYID_MASK_TENKEY | '9', KEYID_MASK_TENKEY | '-',
KEYID_MASK_TENKEY | '4', KEYID_MASK_TENKEY | '5', KEYID_MASK_TENKEY | '6',
KEYID_MASK_TENKEY | '+', KEYID_MASK_TENKEY | '1',
KEYID_F6, KEYID_F7, KEYID_F8, KEYID_F9, KEYID_F10, KEYID_LOCK_NUM,
KEYID_LOCK_SCROOL, KEYID_MASK_TENKEY | '7', KEYID_MASK_TENKEY | '8',
KEYID_MASK_TENKEY | '9', KEYID_MASK_TENKEY | '-', KEYID_MASK_TENKEY | '4',
KEYID_MASK_TENKEY | '5', KEYID_MASK_TENKEY | '6', KEYID_MASK_TENKEY | '+',
KEYID_MASK_TENKEY | '1',
/*0x50*/
KEYID_MASK_TENKEY | '2', KEYID_MASK_TENKEY | '3', KEYID_MASK_TENKEY | '0',
KEYID_MASK_TENKEY | '.', KEYID_MASK_EXTENDED | KEYID_SYS_RQ, 0x0000, 0x0000,
KEYID_MASK_EXTENDED | KEYID_F11, KEYID_MASK_EXTENDED | KEYID_F12, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
KEYID_MASK_TENKEY | '.', KEYID_SYS_RQ, 0x0000, 0x0000, KEYID_F11, KEYID_F12,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/*0x60*/
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/*0x70*/
KEYID_MASK_EXTENDED | KEYID_HIRAGANA, 0x0000, 0x0000, '_', 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, KEYID_MASK_EXTENDED | KEYID_HENKAN, 0x0000,
KEYID_MASK_EXTENDED | KEYID_MUHENKAN, 0x0000, '\\',
KEYID_HIRAGANA, 0x0000, 0x0000, '_', 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
KEYID_HENKAN, 0x0000, KEYID_MUHENKAN, 0x0000, '\\',
// 0x5c, // ='\' for mikan-trap.
0x0000, 0x0000};

static const uint16_t kKeyCodeTableWithShift[0x80] = {
0x00, 0x00, '!', '"', '#', '$', '%', '&', '\'', '(', ')', '~', '=', '~',
0x00, 0x00,
/*0x10*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, '`', '{', 0x00,
0x00, 0x00, 0x00,
/*0x20*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, '+', '*', 0x00, 0x00, '}', 0x00,
0x00, 0x00, 0x00,
/*0x30*/
0x00, 0x00, 0x00, '<', '>', '?', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
/*0x40*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
/*0x50*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
/*0x60*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
/*0x70*/
0x00, 0x00, 0x00, '_', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
'|', 0x00, 0x00};

static bool state_shift;

constexpr uint16_t kKeyScanCodeMaskBreak = 0x80;

uint16_t ParseKeyCode(uint8_t keycode) {
if (keycode & 0x80) {
PutStringAndHex("break:", keycode);
uint16_t keyid;
if (state_shift) {
keyid = kKeyCodeTableWithShift[keycode];
if (!keyid)
keyid = kKeyCodeTable[keycode];
} else {
keyid = kKeyCodeTable[keycode];
}

if ('A' <= keyid && keyid <= 'Z' && !state_shift)
keyid += 0x20;
if (!keyid)
return 0;

if (keycode & kKeyScanCodeMaskBreak) {
if (keyid == KEYID_SHIFT_L || keyid == KEYID_SHIFT_R)
state_shift = false;
keyid |= kKeyIDMaskBreak;
} else {
if (keyid == KEYID_SHIFT_L || keyid == KEYID_SHIFT_R)
state_shift = true;
}
uint16_t keyid = kKeyCodeTable[keycode];
char s[2];
s[0] = keyid;
s[1] = 0;
PutStringAndHex(s, keyid);
return 0;
return keyid;
}
5 changes: 4 additions & 1 deletion src/liumos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,10 @@ void MainForBootProcessor(void* image_handle, EFISystemTable* system_table) {
ClearIntFlag();
while (!keycode_buffer.IsEmpty()) {
uint8_t keycode = keycode_buffer.Pop();
ParseKeyCode(keycode);
uint16_t keyid = ParseKeyCode(keycode);
if (!(keyid & kKeyIDMaskBreak) && !(keyid & kKeyIDMaskExtended)) {
PutChar(keyid);
}
}
// PutStringAndHex("RootContext", count += 2);
}
Expand Down
5 changes: 4 additions & 1 deletion src/liumos.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ void DrawRect(int px, int py, int w, int h, uint32_t col);
void BlockTransfer(int to_x, int to_y, int from_x, int from_y, int w, int h);

// @keyboard.cc
const uint16_t kIOPortKeyboardData = 0x0060;
constexpr uint16_t kIOPortKeyboardData = 0x0060;

constexpr uint16_t kKeyIDMaskBreak = 0x80;
constexpr uint16_t kKeyIDMaskExtended = 0x8000;

// @liumos.c
[[noreturn]] void Panic(const char* s);
Expand Down

0 comments on commit e9af482

Please sign in to comment.