OSDN Git Service

[INITIAL] Import 20141226 version of http://homepage3.nifty.com/takeda-toshiya/common...
[csp-qt/common_source_project-fm7.git] / source / src / vm / jx / keyboard.cpp
diff --git a/source/src/vm/jx/keyboard.cpp b/source/src/vm/jx/keyboard.cpp
new file mode 100644 (file)
index 0000000..35fa219
--- /dev/null
@@ -0,0 +1,194 @@
+/*\r
+       IBM Japan Ltd PC/JX Emulator 'eJX'\r
+\r
+       Author : Takeda.Toshiya\r
+       Date   : 2011.05.10-\r
+\r
+       [ keyboard ]\r
+*/\r
+\r
+#include "keyboard.h"\r
+#include "../i8253.h"\r
+#include "../i8255.h"\r
+#include "../../fifo.h"\r
+\r
+static const int key_table[256] = {\r
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00,\r
+       0x2a, 0x1d, 0x38, 0x46, 0x3a, 0x6f, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x01, 0x6d, 0x6c, 0x00, 0x00,\r
+       0x39, 0x4f, 0x5e, 0x54, 0x47, 0x4b, 0x48, 0x4d, 0x50, 0x00, 0x00, 0x00, 0x00, 0x52, 0x53, 0x00,\r
+       0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+       0x00, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18,\r
+       0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+       0x70, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x4e, 0x00, 0x4a, 0x71, 0x7c,\r
+       0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00,\r
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x27, 0x33, 0x0c, 0x34, 0x35,\r
+       0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x6A, 0x29, 0x0d, 0x00,\r
+       0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+};\r
+\r
+#define EVENT_SEND     0\r
+#define EVENT_TIMER    1\r
+\r
+void KEYBOARD::initialize()\r
+{\r
+       key_buf = new FIFO(8);\r
+       \r
+#ifdef KEYBOARD_HACK\r
+       register_event(this, EVENT_SEND, 440 * 21, true, NULL);\r
+#else\r
+       register_event(this, EVENT_SEND, 220, true, NULL);\r
+#endif\r
+#ifndef TIMER_HACK\r
+       register_event_by_clock(this, EVENT_TIMER, 4, true, NULL);\r
+#endif\r
+}\r
+\r
+void KEYBOARD::release()\r
+{\r
+       key_buf->release();\r
+       delete key_buf;\r
+}\r
+\r
+void KEYBOARD::reset()\r
+{\r
+       key_buf->clear();\r
+#ifndef KEYBOARD_HACK\r
+       send_count = 0;\r
+#endif\r
+       key_latched = false;\r
+       \r
+       d_pio->write_signal(SIG_I8255_PORT_C, 0x00, 0x01); // clear keyboard latched\r
+       d_pio->write_signal(SIG_I8255_PORT_C, 0x00, 0x40); // set stop bit\r
+       \r
+       nmi_reg = 0;\r
+}\r
+\r
+void KEYBOARD::write_io8(uint32 addr, uint32 data)\r
+{\r
+       switch(addr) {\r
+       case 0xa0:\r
+               nmi_reg = data;\r
+               break;\r
+       }\r
+}\r
+\r
+uint32 KEYBOARD::read_io8(uint32 addr)\r
+{\r
+       switch(addr) {\r
+       case 0xa0:\r
+               d_pio->write_signal(SIG_I8255_PORT_C, 0x00, 0x01);\r
+               key_latched = false;\r
+               return nmi_reg; // ???\r
+#ifdef KEYBOARD_HACK\r
+       case 0xa1:\r
+               if(!key_buf->empty()) {\r
+                       return key_buf->read();\r
+               }\r
+               break;\r
+#endif\r
+       }\r
+       return 0xff;\r
+}\r
+\r
+void KEYBOARD::event_callback(int id, int err)\r
+{\r
+       if(id == EVENT_SEND) {\r
+#ifdef KEYBOARD_HACK\r
+               if(!key_buf->empty()) {\r
+                       // rising edge\r
+                       if(nmi_reg & 0x80) {\r
+                               d_cpu->write_signal(SIG_CPU_NMI, 1, 1);\r
+                       }\r
+                       d_pio->write_signal(SIG_I8255_PORT_C, 0x01, 0x01);\r
+                       key_latched = true;\r
+               }\r
+#else\r
+               if(send_count == 0 && !key_buf->empty()) {\r
+                       int code = key_buf->read();\r
+                       int parity = 1;\r
+                       uint64 bit = 1;\r
+                       \r
+                       for(int i = 0; i < 8; i++) {\r
+                               if(code & (1 << i)) {\r
+                                       parity++;\r
+                               }\r
+                       }\r
+                       send_data = 0;\r
+                       \r
+                       #define SET_HALF_BIT(v) { \\r
+                               if(v) { \\r
+                                       send_data |= bit; \\r
+                               } \\r
+                               bit <<= 1; \\r
+                       }\r
+                       #define SET_BIT(v) { \\r
+                               if(v) { \\r
+                                       SET_HALF_BIT(1); \\r
+                                       SET_HALF_BIT(0); \\r
+                               } else { \\r
+                                       SET_HALF_BIT(0); \\r
+                                       SET_HALF_BIT(1); \\r
+                               } \\r
+                       }\r
+                       \r
+                       SET_BIT(1);     // start bit\r
+                       for(int i = 0; i < 8; i++) {\r
+                               SET_BIT(code & (1 << i));\r
+                       }\r
+                       SET_BIT(parity & 1);\r
+                       send_count = 42;\r
+               }\r
+               if(send_count) {\r
+                       if(send_count == 42 && !key_latched) {\r
+                               // rising edge\r
+                               if(nmi_reg & 0x80) {\r
+                                       d_cpu->write_signal(SIG_CPU_NMI, 1, 1);\r
+                               }\r
+                               d_pio->write_signal(SIG_I8255_PORT_C, 0x01, 0x01);\r
+                               key_latched = true;\r
+                       }\r
+                       d_pio->write_signal(SIG_I8255_PORT_C, (send_data & 1) ? 0x40 : 0, 0x40);\r
+                       send_data >>= 1;\r
+                       send_count--;\r
+               }\r
+#endif\r
+#ifndef TIMER_HACK\r
+       } else if(id == EVENT_TIMER) {\r
+               if(!(nmi_reg & 0x20)) {\r
+                       d_pit->write_signal(SIG_I8253_CLOCK_1, 1, 1);\r
+                       d_pit->write_signal(SIG_I8253_CLOCK_1, 0, 0);\r
+               }\r
+#endif\r
+       }\r
+}\r
+\r
+void KEYBOARD::write_signal(int id, uint32 data, uint32 mask)\r
+{\r
+#ifndef TIMER_HACK\r
+       if(id == SIG_KEYBOARD_TIMER) {\r
+               if(nmi_reg & 0x20) {\r
+                       d_pit->write_signal(SIG_I8253_CLOCK_1, data, mask);\r
+               }\r
+       }\r
+#endif\r
+}\r
+\r
+void KEYBOARD::key_down(int code)\r
+{\r
+       if(key_table[code]) {\r
+               key_buf->write(key_table[code]);\r
+       }\r
+}\r
+\r
+void KEYBOARD::key_up(int code)\r
+{\r
+       if(key_table[code]) {\r
+               key_buf->write(key_table[code] | 0x80);\r
+       }\r
+}\r
+\r