OSDN Git Service

svn rev.329より移動。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_010 / chnos / keyboard.c
diff --git a/CHNOSProject/chnos/tolset_chn_000/chnos_010/chnos/keyboard.c b/CHNOSProject/chnos/tolset_chn_000/chnos_010/chnos/keyboard.c
new file mode 100644 (file)
index 0000000..07c4ba6
--- /dev/null
@@ -0,0 +1,615 @@
+\r
+#include "core.h"\r
+\r
+uint kbd_data0;\r
+DATA_FIFO32 *kbd_fifo;\r
+\r
+union  STATE_KEYLOCK {\r
+       uchar keylock;\r
+       struct STATE_KEYLOCK_KEY {\r
+               unsigned scroll : 1;\r
+               unsigned num : 1;\r
+               unsigned caps : 1;\r
+       } key;\r
+} state_keylock;\r
+\r
+union  STATE_KEYSHIFT {\r
+       uchar keyshift;\r
+       struct STATE_KEYSHIFT_KEY {\r
+               unsigned L : 1;\r
+               unsigned R : 1;\r
+       } key;\r
+} state_keyshift;\r
+\r
+union  STATE_KEYCTRL {\r
+       uchar keyctrl;\r
+       struct STATE_KEYCTRL_KEY {\r
+               unsigned L : 1;\r
+               unsigned R : 1;\r
+       } key;\r
+} state_keyctrl;\r
+\r
+union  STATE_KEYALT {\r
+       uchar keyalt;\r
+       struct STATE_KEYALT_KEY {\r
+               unsigned L : 1;\r
+               unsigned R : 1;\r
+       } key;\r
+} state_keyalt;\r
+\r
+ushort state_shift;\r
+\r
+uint key_decode_phase;\r
+uchar key_decode_buf[4];\r
+uchar kbc_retv;\r
+\r
+/*\83L\81[\83R\81[\83h\95Ï\8a·\83e\81[\83u\83\8b*/\r
+ushort Keyboard_KeyCodeTable[0x80] = {\r
+       KEYID_MASK_EXTENDED | KEYID_KBD_ERROR,\r
+       KEYID_MASK_EXTENDED | KEYID_ESC,\r
+       '1',\r
+       '2',\r
+       '3',\r
+       '4',\r
+       '5',\r
+       '6',\r
+       '7',\r
+       '8',\r
+       '9',\r
+       '0',\r
+       '-',\r
+       '^',\r
+       KEYID_MASK_EXTENDED | KEYID_BACKSPACE,\r
+       KEYID_MASK_EXTENDED | KEYID_TAB,\r
+/*0x10*/\r
+       'Q',\r
+       'W',\r
+       'E',\r
+       'R',\r
+       'T',\r
+       'Y',\r
+       'U',\r
+       'I',\r
+       'O',\r
+       'P',\r
+       '@',\r
+       '[',\r
+       KEYID_MASK_EXTENDED | KEYID_ENTER,\r
+       KEYID_MASK_EXTENDED | KEYID_CTRL_L,\r
+       'A',\r
+       'S',\r
+/*0x20*/\r
+       'D',\r
+       'F',\r
+       'G',\r
+       'H',\r
+       'J',\r
+       'K',\r
+       'L',\r
+       ';',\r
+       ':',\r
+       KEYID_MASK_EXTENDED | KEYID_KANJI,\r
+       KEYID_MASK_EXTENDED | KEYID_SHIFT_L,\r
+       ']',\r
+       'Z',\r
+       'X',\r
+       'C',\r
+       'V',\r
+/*0x30*/\r
+       'B',\r
+       'N',\r
+       'M',\r
+       ',',\r
+       '.',\r
+       '/',\r
+       KEYID_MASK_EXTENDED | KEYID_SHIFT_R,\r
+       KEYID_MASK_TENKEY | '*',\r
+       KEYID_MASK_EXTENDED | KEYID_ALT_L,\r
+       ' ',\r
+       KEYID_MASK_EXTENDED | KEYID_LOCK_CAPS,\r
+       KEYID_MASK_EXTENDED | KEYID_F1,\r
+       KEYID_MASK_EXTENDED | KEYID_F2,\r
+       KEYID_MASK_EXTENDED | KEYID_F3,\r
+       KEYID_MASK_EXTENDED | KEYID_F4,\r
+       KEYID_MASK_EXTENDED | KEYID_F5,\r
+/*0x40*/\r
+       KEYID_MASK_EXTENDED | KEYID_F6,\r
+       KEYID_MASK_EXTENDED | KEYID_F7,\r
+       KEYID_MASK_EXTENDED | KEYID_F8,\r
+       KEYID_MASK_EXTENDED | KEYID_F9,\r
+       KEYID_MASK_EXTENDED | KEYID_F10,\r
+       KEYID_MASK_EXTENDED | KEYID_LOCK_NUM,\r
+       KEYID_MASK_EXTENDED | KEYID_LOCK_SCROOL,\r
+       KEYID_MASK_TENKEY | '7',\r
+       KEYID_MASK_TENKEY | '8',\r
+       KEYID_MASK_TENKEY | '9',\r
+       KEYID_MASK_TENKEY | '-',\r
+       KEYID_MASK_TENKEY | '4',\r
+       KEYID_MASK_TENKEY | '5',\r
+       KEYID_MASK_TENKEY | '6',\r
+       KEYID_MASK_TENKEY | '+',\r
+       KEYID_MASK_TENKEY | '1',\r
+/*0x50*/\r
+       KEYID_MASK_TENKEY | '2',\r
+       KEYID_MASK_TENKEY | '3',\r
+       KEYID_MASK_TENKEY | '0',\r
+       KEYID_MASK_TENKEY | '.',\r
+       KEYID_MASK_EXTENDED | KEYID_SYS_RQ,\r
+       0x0000,\r
+       0x0000,\r
+       KEYID_MASK_EXTENDED | KEYID_F11,\r
+       KEYID_MASK_EXTENDED | KEYID_F12,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+/*0x60*/\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+/*0x70*/\r
+       KEYID_MASK_EXTENDED | KEYID_HIRAGANA,\r
+       0x0000,\r
+       0x0000,\r
+       '_',\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       0x0000,\r
+       KEYID_MASK_EXTENDED | KEYID_HENKAN,\r
+       0x0000,\r
+       KEYID_MASK_EXTENDED | KEYID_MUHENKAN,\r
+       0x0000,\r
+       '\\',\r
+//     0x5c,   // ='\' for mikan-trap.\r
+       0x0000,\r
+       0x0000\r
+};\r
+\r
+//\83[\83\8d\82Ì\8f\8a\82Í\83V\83t\83g\95\8e\9a\82ª\96³\82¢\82Ì\82Å\81A\83e\81[\83u\83\8b0\82ð\8eQ\8fÆ\r
+uchar Keyboard_KeyCodeTable_Shift[0x80] = {\r
+       0x00,\r
+       0x00,\r
+       '!',\r
+       0x22,   //double quote\r
+       '#',\r
+       '$',\r
+       '%',\r
+       '&',\r
+       0x27,   //single quote\r
+       '(',\r
+       ')',\r
+       '~',\r
+       '=',\r
+       '~',\r
+       0x00,\r
+       0x00,\r
+/*0x10*/\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       '`',\r
+       '{',\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+/*0x20*/\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       '+',\r
+       '*',\r
+       0x00,\r
+       0x00,\r
+       '}',\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+/*0x30*/\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       '<',\r
+       '>',\r
+       '?',\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+/*0x40*/\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+/*0x50*/\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+/*0x60*/\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+/*0x70*/\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       '_',\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       0x00,\r
+       '|',\r
+       0x00,\r
+       0x00\r
+};\r
+\r
+void Initialize_Keyboard(void)\r
+{\r
+       System_GateDescriptor_Set(0x21, (uint)asm_InterruptHandler21, 0x02, AR_INTGATE32);\r
+       ProgrammableInterruptController_InterruptMask_Clear(0x01);\r
+       kbd_data0 = 0;\r
+       kbd_fifo = 0;\r
+       state_keylock.keylock = 0;\r
+       state_keyshift.keyshift = 0;\r
+       state_keyctrl.keyctrl = 0;\r
+       state_keyalt.keyalt = 0;\r
+       key_decode_phase = 0;\r
+\r
+       KeyboardController_Wait_SendReady();\r
+       IO_Out8(PORT_KEYCMD, KEYCMD_WRITE_8042_MODE_REG);\r
+       KeyboardController_Wait_SendReady();\r
+       IO_Out8(PORT_KEYDATA, KBC_MODE);\r
+\r
+       return;\r
+}\r
+\r
+void InterruptHandler21(uint *esp)\r
+{\r
+       uint data;\r
+\r
+       data = IO_In8(PORT_KEYDATA);\r
+\r
+       ProgrammableInterruptController_InterruptRequest_Complete(0x01);\r
+\r
+       if(kbd_fifo != 0){\r
+               FIFO32_Put(kbd_fifo, data + kbd_data0);\r
+       }\r
+\r
+       if(data == KEYDATA_ACK || data == KEYDATA_RESEND){\r
+               kbc_retv = data;\r
+       }\r
+\r
+       return;\r
+}\r
+\r
+void Keyboard_Set_ReceiveFIFO(DATA_FIFO32 *fifo, uint data0)\r
+{\r
+       kbd_data0 = data0;\r
+       kbd_fifo = fifo;\r
+\r
+       return; \r
+}\r
+\r
+ushort Keyboard_Decode_KeyCode(uchar keycode)\r
+{\r
+       ushort keyid;\r
+       ushort table;\r
+       keyid = 0;\r
+       table = 0;\r
+\r
+       if(keycode == KEYDATA_ACK || keycode == KEYDATA_RESEND){\r
+               return 0;\r
+       }\r
+\r
+       key_decode_buf[key_decode_phase] = keycode;\r
+\r
+       switch(key_decode_phase){\r
+               case 0:\r
+\r
+                       if(key_decode_buf[0] == 0xe0){\r
+                               key_decode_phase = 1;\r
+                               break;\r
+                       } else if(key_decode_buf[0] == 0xe1){\r
+                               key_decode_phase = 2;\r
+                               break;\r
+                       } else{\r
+                               if(state_keylock.key.caps){\r
+                                       if(!state_keyshift.keyshift){\r
+                                               table = 1;\r
+                                       }\r
+                               } else{\r
+                                       if(state_keyshift.keyshift){\r
+                                               table = 1;\r
+                                       }\r
+                               }\r
+\r
+                               if(state_keyshift.keyshift){\r
+                                       keyid = Keyboard_KeyCodeTable_Shift[(key_decode_buf[0] & KEYID_MASK_ID)];\r
+                                       if(keyid == 0){\r
+                                               keyid = Keyboard_KeyCodeTable[(key_decode_buf[0] & KEYID_MASK_ID)];\r
+                                       }\r
+                               } else{\r
+                                       keyid = Keyboard_KeyCodeTable[(key_decode_buf[0] & KEYID_MASK_ID)];\r
+                               }\r
+\r
+                               if(!table && ('A' <= keyid && keyid <= 'Z')){\r
+                                       keyid += 0x20;\r
+                               }\r
+\r
+                               if(keyid & KEYID_MASK_EXTENDED){\r
+                                       if(keyid == (KEYID_MASK_EXTENDED | KEYID_CTRL_L)){\r
+                                               if((key_decode_buf[0] & KEYID_MASK_BREAK)){\r
+                                                       state_keyctrl.key.L = False;\r
+                                               } else{\r
+                                                       state_keyctrl.key.L = True;\r
+                                               }\r
+                                       } else if(keyid == (KEYID_MASK_EXTENDED | KEYID_SHIFT_L)){\r
+                                               if((key_decode_buf[0] & KEYID_MASK_BREAK)){\r
+                                                       state_keyshift.key.L = False;\r
+                                               } else{\r
+                                                       state_keyshift.key.L = True;\r
+                                               }\r
+                                       } else if(keyid == (KEYID_MASK_EXTENDED | KEYID_SHIFT_R)){\r
+                                               if((key_decode_buf[0] & KEYID_MASK_BREAK)){\r
+                                                       state_keyshift.key.R = False;\r
+                                               } else{\r
+                                                       state_keyshift.key.R = True;\r
+                                               }\r
+                                       } else if(keyid == (KEYID_MASK_EXTENDED | KEYID_ALT_L)){\r
+                                               if((key_decode_buf[0] & KEYID_MASK_BREAK)){\r
+                                                       state_keyalt.key.L = False;\r
+                                               } else{\r
+                                                       state_keyalt.key.L = True;\r
+                                               }\r
+                                       } else if(keyid == (KEYID_MASK_EXTENDED | KEYID_LOCK_CAPS)){\r
+                                               if(!(key_decode_buf[0] & KEYID_MASK_BREAK)){\r
+                                                       if(state_keylock.key.caps){\r
+                                                               state_keylock.key.caps = False;\r
+                                                       } else{\r
+                                                               state_keylock.key.caps = True;\r
+                                                       }\r
+                                                       KeyboardController_SetLED(state_keylock.keylock);\r
+                                               }\r
+                                       } else if(keyid == (KEYID_MASK_EXTENDED | KEYID_LOCK_NUM)){\r
+                                               if(!(key_decode_buf[0] & KEYID_MASK_BREAK)){\r
+                                                       if(state_keylock.key.num){\r
+                                                               state_keylock.key.num = False;\r
+                                                       } else{\r
+                                                               state_keylock.key.num = True;\r
+                                                       }\r
+                                                       KeyboardController_SetLED(state_keylock.keylock);\r
+                                               }\r
+                                       } else if(keyid == (KEYID_MASK_EXTENDED | KEYID_LOCK_SCROOL)){\r
+                                               if(!(key_decode_buf[0] & KEYID_MASK_BREAK)){\r
+                                                       if(state_keylock.key.scroll){\r
+                                                               state_keylock.key.scroll = False;\r
+                                                       } else{\r
+                                                               state_keylock.key.scroll = True;\r
+                                                       }\r
+                                                       KeyboardController_SetLED(state_keylock.keylock);\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               if(keyid != 0 && (key_decode_buf[0] & KEYID_MASK_BREAK)){\r
+                                       keyid |= KEYID_MASK_BREAK;\r
+                               }\r
+\r
+                       }\r
+                       key_decode_phase = 0;\r
+                       break;\r
+               case 1: //E0\8ag\92£\83L\81[\83R\81[\83h\r
+                       if((key_decode_buf[1] & KEYID_MASK_ID) == 0x1c){\r
+                               keyid |= KEYID_MASK_TENKEY | KEYID_ENTER;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x1d){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_CTRL_R;\r
+                               if((key_decode_buf[1] & KEYID_MASK_BREAK)){\r
+                                       state_keyctrl.key.R = False;\r
+                               } else{\r
+                                       state_keyctrl.key.R = True;\r
+                               }\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x35){\r
+                               keyid |= KEYID_MASK_TENKEY | '/';\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x37){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_PRINT_SCREEN;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x38){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_ALT_R;\r
+                               if((key_decode_buf[1] & KEYID_MASK_BREAK)){\r
+                                       state_keyalt.key.R = False;\r
+                               } else{\r
+                                       state_keyalt.key.R = True;\r
+                               }\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x46){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_BREAK;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x47){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_HOME;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x48){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_CURSOR_U;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x49){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_PAGE_UP;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x4b){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_CURSOR_L;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x4d){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_CURSOR_R;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x4f){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_END;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x50){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_CURSOR_D;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x51){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_PAGE_DOWN;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x52){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_INSERT;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x53){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_DELETE;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x5b){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_ICON_L;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x5c){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_ICON_R;\r
+                       } else if((key_decode_buf[1] & KEYID_MASK_ID) == 0x5d){\r
+                               keyid |= KEYID_MASK_EXTENDED | KEYID_MENU;\r
+                       }\r
+\r
+                       if(keyid != 0 && (key_decode_buf[1] & KEYID_MASK_BREAK)){\r
+                               keyid |= KEYID_MASK_BREAK;\r
+                       }\r
+\r
+                       key_decode_phase = 0;\r
+                       break;\r
+               case 2: //E1\8ag\92£\83L\81[\83R\81[\83h\83t\83F\81[\83Y0\r
+                       key_decode_phase = 3;\r
+                       break;\r
+               case 3: //E1\8ag\92£\83L\81[\83R\81[\83h\83t\83F\81[\83Y1\r
+                       if((key_decode_buf[1] == 0x1d) && (key_decode_buf[2] == 0x45)){ //Pause-Key Make\r
+                               keyid = KEYID_MASK_EXTENDED | KEYID_PAUSE;\r
+                       } else if((key_decode_buf[1] == 0x9d) && (key_decode_buf[2] == 0xc5)){  //Pause-Key Break\r
+                               keyid = KEYID_MASK_EXTENDED | KEYID_MASK_BREAK | KEYID_PAUSE;\r
+                       }\r
+                       key_decode_phase = 0;\r
+                       break;\r
+       }\r
+\r
+       if(keyid != 0){\r
+               if(state_keyshift.keyshift){\r
+                       keyid |= KEYID_MASK_STATE_SHIFT;\r
+               }\r
+               if(state_keyctrl.keyctrl){\r
+                       keyid |= KEYID_MASK_STATE_CTRL;\r
+               }\r
+               if(state_keyalt.keyalt){\r
+                       keyid |= KEYID_MASK_STATE_ALT;\r
+               }\r
+               keyid |= ((ushort)state_keylock.keylock << 12);\r
+       }\r
+\r
+       return keyid;\r
+}\r
+\r
+void KeyboardController_SetLED(uchar leds)\r
+{\r
+       KeyboardController_SendData(KEYCMD_LED);\r
+       KeyboardController_SendData(leds);\r
+       return;\r
+}\r
+\r
+void KeyboardController_Wait_SendReady(void)\r
+{\r
+       for(;;){\r
+               if((IO_In8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) {\r
+                       break;\r
+               }\r
+       }\r
+       return;\r
+}\r
+\r
+void KeyboardController_SendData(uchar data)\r
+{\r
+       for(;;){\r
+               kbc_retv = 0;\r
+               KeyboardController_Wait_SendReady();\r
+               IO_Out8(PORT_KEYDATA, data);\r
+               for(;;){\r
+                       if(kbc_retv == KEYDATA_ACK){\r
+                               return;\r
+                       }\r
+                       if(kbc_retv == KEYDATA_RESEND){\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+void KeyboardController_SendCommand(uchar cmd)\r
+{\r
+       for(;;){\r
+               kbc_retv = 0;\r
+               KeyboardController_Wait_SendReady();\r
+               IO_Out8(PORT_KEYCMD, cmd);\r
+               for(;;){\r
+                       if(kbc_retv == KEYDATA_ACK){\r
+                               return;\r
+                       }\r
+                       if(kbc_retv == KEYDATA_RESEND){\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+}\r