static void matrix_make(uint8_t code);
static void matrix_break(uint8_t code);
-static void matrix_clear(void);
-#ifdef MATRIX_HAS_GHOST
-static bool matrix_has_ghost_in_row(uint8_t row);
-#endif
static uint8_t matrix[MATRIX_ROWS];
#define ROW(code) (code>>3)
#define COL(code) (code&0x07)
-// matrix positions for exceptional keys
-#define PRINT_SCREEN (0x7C)
-#define PAUSE (0x7D)
-
-static bool is_modified = false;
-
-
-inline
-uint8_t matrix_rows(void)
-{
- return MATRIX_ROWS;
-}
-
-inline
-uint8_t matrix_cols(void)
-{
- return MATRIX_COLS;
-}
void matrix_init(void)
{
return;
}
-static uint8_t move_codes(uint8_t code) {
+// convert E0-escaped codes into unused area
+static uint8_t move_e0code(uint8_t code) {
switch(code) {
- case 0x10:
- code += 0x5E;
- break;
- case 0x19:
- code += 0x41;
- break;
- case 0x1C:
- case 0x1D:
- code += 0x38;
- break;
- case 0x20:
- case 0x21:
- case 0x22:
- case 0x24:
- code += 0x40;
- break;
- case 0x2E:
- case 0x30:
- case 0x32:
- code += 0x44;
- break;
- case 0x35:
- case 0x38:
- code += 0x21;
- break;
- case 0x47:
- case 0x48:
- case 0x49:
- case 0x4B:
- case 0x4D:
- case 0x4F:
- case 0x50:
- case 0x51:
- case 0x52:
- case 0x53:
- code += 0x28;
- break;
+ // Original IBM XT keyboard doesn't use E0-codes probably
+ // Some XT compatilble keyobards need these keys?
+ // http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
+ // https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
+ case 0x37: return 0x54; // Print Screen
+ case 0x46: return 0x55; // Ctrl + Pause
+ case 0x1C: return 0x6F; // Keypad Enter
+ case 0x35: return 0x7F; // Keypad /
+ case 0x5B: return 0x5A; // Left GUI
+ case 0x5C: return 0x5B; // Right GUI
+ case 0x5D: return 0x5C; // Application
+ case 0x5E: return 0x5D; // Power(not used)
+ case 0x5F: return 0x5E; // Sleep(not used)
+ case 0x63: return 0x5F; // Wake (not used)
+ case 0x48: return 0x60; // Up
+ case 0x4B: return 0x61; // Left
+ case 0x50: return 0x62; // Down
+ case 0x4D: return 0x63; // Right
+ case 0x52: return 0x71; // Insert
+ case 0x53: return 0x72; // Delete
+ case 0x47: return 0x74; // Home
+ case 0x4F: return 0x75; // End
+ case 0x49: return 0x77; // Home
+ case 0x51: return 0x78; // End
+ case 0x1D: return 0x7A; // Right Ctrl
+ case 0x38: return 0x7C; // Right Alt
}
- return code;
+ return 0x00;
}
uint8_t matrix_scan(void)
{
-
- // scan code reading states
static enum {
INIT,
E0,
- E0_2A,
- E0_2A_E0,
- E0_B7,
- E0_B7_E0,
-
- // print screen
+ // Pause: E1 1D 45, E1 9D C5
E1,
E1_1D,
- E1_1D_45,
- E1_1D_45_E1,
- E1_1D_45_E1_9D,
- // pause
+ E1_9D,
} state = INIT;
-
- is_modified = false;
-
- // 'pseudo break code' hack
- if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) {
- matrix_break(PAUSE);
- }
-
uint8_t code = xt_host_recv();
- if (code) xprintf("%X\r\n", code);
+ if (!code) return 0;
+ dprintf("%02X ", code);
switch (state) {
case INIT:
switch (code) {
case 0xE1:
state = E1;
break;
- case 0x00:
- break;
- default: // normal key make
- if (code < 0x80) {
- xprintf("make: %X\r\n", code);
+ default:
+ if (code < 0x80)
matrix_make(code);
- } else if (code > 0x80 && code < 0xFF) {
- xprintf("break %X\r\n", code);
- matrix_break(code - 0x80);
- } else {
- matrix_clear();
- clear_keyboard();
- xprintf("unexpected scan code at INIT: %02X\n", code);
- }
- state = INIT;
- }
- break;
- case E0: // E0-Prefixed
- switch (code) { //move these codes to unused places on the matrix
- case 0x2A:
- state = E0_2A;
- break;
- case 0xB7:
- state = E0_B7;
- break;
- case 0x00:
- state = INIT;
+ else
+ matrix_break(code & 0x7F);
break;
- default:
- if (code < 0x80) {
- matrix_make(move_codes(code));
- } else if (code > 0x80 && code < 0xFF) {
- matrix_break(move_codes(code - 0x80));
- } else {
- matrix_clear();
- clear_keyboard();
- xprintf("unexpected scan code at E0: %02X\n", code);
- }
- state = INIT;
}
break;
- case E0_2A:
+ case E0:
switch (code) {
- case 0xE0:
- state = E0_2A_E0;
- break;
- default:
+ case 0x2A:
+ case 0xAA:
+ case 0x36:
+ case 0xB6:
+ //ignore fake shift
state = INIT;
- }
- break;
- case E0_2A_E0:
- switch (code) {
- case 0x37:
- matrix_make(PRINT_SCREEN);
break;
default:
+ if (code < 0x80)
+ matrix_make(move_e0code(code));
+ else
+ matrix_break(move_e0code(code & 0x7F));
state = INIT;
- }
- break;
- case E0_B7:
- switch (code) {
- case 0xE0:
- state = E0_B7;
break;
- default:
- state = INIT;
}
break;
- case E0_B7_E0:
- switch (code) {
- case 0xAA:
- matrix_break(PRINT_SCREEN);
- break;
- default:
- state = INIT;
- }
- break;
case E1:
switch (code) {
case 0x1D:
state = E1_1D;
break;
+ case 0x9D:
+ state = E1_9D;
+ break;
default:
state = INIT;
+ break;
}
break;
case E1_1D:
switch (code) {
case 0x45:
- state = E1_1D_45;
+ matrix_make(0x55);
break;
default:
state = INIT;
- }
- break;
- case E1_1D_45:
- switch (code) {
- case 0xE1:
- state = E1_1D_45_E1;
break;
- default:
- state = INIT;
}
break;
- case E1_1D_45_E1:
+ case E1_9D:
switch (code) {
- case 0x9D:
- state = E1_1D_45_E1_9D;
+ case 0x45:
+ matrix_break(0x55);
break;
default:
state = INIT;
- }
- break;
- case E1_1D_45_E1_9D:
- switch (code) {
- case 0xC5:
- matrix_make(PAUSE);
break;
- default:
- state = INIT;
}
break;
default:
state = INIT;
}
-
- // TODO: request RESEND when error occurs?
-/*
- if (PS2_IS_FAILED(ps2_error)) {
- uint8_t ret = ps2_host_send(PS2_RESEND);
- xprintf("Resend: %02X\n", ret);
- }
-*/
return 1;
}
-bool matrix_is_modified(void)
-{
- return is_modified;
-}
-
-inline
-bool matrix_has_ghost(void)
-{
-#ifdef MATRIX_HAS_GHOST
- for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
- if (matrix_has_ghost_in_row(i))
- return true;
- }
-#endif
- return false;
-}
-
-inline
-bool matrix_is_on(uint8_t row, uint8_t col)
-{
- return (matrix[row] & (1<<col));
-}
-
inline
uint8_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
-void matrix_print(void)
-{
- print("\nr/c 01234567\n");
- for (uint8_t row = 0; row < matrix_rows(); row++) {
- phex(row); print(": ");
- pbin_reverse(matrix_get_row(row));
-#ifdef MATRIX_HAS_GHOST
- if (matrix_has_ghost_in_row(row)) {
- print(" <ghost");
- }
-#endif
- print("\n");
- }
-}
-
-uint8_t matrix_key_count(void)
-{
- uint8_t count = 0;
- for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
- count += bitpop(matrix[i]);
- }
- return count;
-}
-
-#ifdef MATRIX_HAS_GHOST
-inline
-static bool matrix_has_ghost_in_row(uint8_t row)
-{
- // no ghost exists in case less than 2 keys on
- if (((matrix[row] - 1) & matrix[row]) == 0)
- return false;
-
- // ghost exists in case same state as other row
- for (uint8_t i=0; i < MATRIX_ROWS; i++) {
- if (i != row && (matrix[i] & matrix[row]) == matrix[row])
- return true;
- }
- return false;
-}
-#endif
-
-
inline
static void matrix_make(uint8_t code)
{
if (!matrix_is_on(ROW(code), COL(code))) {
matrix[ROW(code)] |= 1<<COL(code);
- is_modified = true;
}
}
{
if (matrix_is_on(ROW(code), COL(code))) {
matrix[ROW(code)] &= ~(1<<COL(code));
- is_modified = true;
}
}
-inline
-static void matrix_clear(void)
+void matrix_clear(void)
{
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
}
+
+/*
+XT Scancodes
+============
+- http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
+- https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
+
+01-53: Normal codes used in original XT keyboard
+54-7F: Not used in original XT keyboard
+
+ 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 50 - - - - * * x x x x * * * o o o
+ 60 * * * * x x x x x x x x x x x *
+ 70 x * * x * * x * * x * x * x x *
+
+-: codes existed in original XT keyboard
+*: E0-escaped codes converted into unused code area(internal use in TMK)
+x: Non-espcaped codes(not used in real keyboards probably, for CodeSet2-CodeSet1 translation purpose)
+o: reserved
+
+Usage in TMK:
+
+ 00 (reserved) DO NOT USE
+ 54 PrintScr*
+ 55 Pause*
+ 56 Euro2
+ 57 F11
+ 58 F12
+ 59 Keypad =
+ 5A LGUI*
+ 5B RGUI*
+ 5C APP*
+ 5D (reserved)
+ 5E (reserved)
+ 5F (reserved)
+ 60 cursor*
+ 61 cursor*
+ 62 cursor*
+ 63 cursor*
+ 64 F13
+ 65 F14
+ 66 F15
+ 67 F16
+ 68 F17
+ 69 F18
+ 6A F19
+ 6B F20
+ 6C F21
+ 6D F22
+ 6E F23
+ 6F Keypad Enter*
+ 70 KANA
+ 71 nav*
+ 72 nav*
+ 73 RO
+ 74 nav*
+ 75 nav*
+ 76 F24
+ 77 nav*
+ 78 nav*
+ 79 HENKAN
+ 7A RCTL*
+ 7B MUHENKAN
+ 7C RALT*
+ 7D JPY
+ 7E Keypad ,
+ 7F Keypad / *
+
+*/