OSDN Git Service

f75ec30b37ce15608697b52c607411337ffbf0a1
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz3500 / keyboard.cpp
1 /*
2         SHARP MZ-5500 Emulator 'EmuZ-5500'
3
4         Author : Takeda.Toshiya
5         Date   : 2008.04.10 -
6
7         [ keyboard ]
8 */
9
10 #include "keyboard.h"
11 #include "../ls244.h"
12 #include "../../fifo.h"
13
14 #define PHASE_RESET             -1
15 #define PHASE_IDLE              0
16 #define PHASE_SEND_START_H      1
17 #define PHASE_SEND_START_L      2
18 #define PHASE_SEND_BIT_7_H      3
19 #define PHASE_SEND_BIT_7_L      4
20 #define PHASE_SEND_BIT_6_H      5
21 #define PHASE_SEND_BIT_6_L      6
22 #define PHASE_SEND_BIT_5_H      7
23 #define PHASE_SEND_BIT_5_L      8
24 #define PHASE_SEND_BIT_4_H      9
25 #define PHASE_SEND_BIT_4_L      10
26 #define PHASE_SEND_BIT_3_H      11
27 #define PHASE_SEND_BIT_3_L      12
28 #define PHASE_SEND_BIT_2_H      13
29 #define PHASE_SEND_BIT_2_L      14
30 #define PHASE_SEND_BIT_1_H      15
31 #define PHASE_SEND_BIT_1_L      16
32 #define PHASE_SEND_BIT_0_H      17
33 #define PHASE_SEND_BIT_0_L      18
34 #define PHASE_SEND_COMMAND_H    19
35 #define PHASE_SEND_COMMAND_L    20
36 #define PHASE_SEND_PARITY_H     21
37 #define PHASE_SEND_PARITY_L     22
38 #define PHASE_SEND_FINISH       23
39 #define PHASE_SEND_WAIT_ACK     24
40 #define PHASE_RECV_START        30
41 #define PHASE_RECV_BIT_2        31
42 #define PHASE_RECV_BIT_1        32
43 #define PHASE_RECV_BIT_0        33
44 #define PHASE_RECV_PARITY       34
45 #define PHASE_RECV_ACK_H        35
46 #define PHASE_RECV_ACK_L        36
47
48 #define EVENT_DRIVE             0
49 #define EVENT_DATA              1
50 #define EVENT_ACK               2
51
52 // http://www.8bity.cz/2013/adapter-pro-pripojeni-ps2-klavesnice-k-sharp-mz-3500/
53
54 // CMD          Escape or Kanji
55 // CL           Back Space
56 // 00           Alt + 0 or Num0
57 // RUN          Alt + F1
58 // EDIT         End
59 // DEB          F11
60 // CONT         F12
61 // PRO          Page Up
62 // OP           Page Down
63
64 static const uint16_t key_table[256] = {
65         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
66         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0fe, 0x000, 0x0fe, 0x000, 0x000, 0x000, 0x000,
67         0x020, 0x000, 0x000, 0x1f7, 0x00b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
68         0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
69         0x000, 0x041, 0x042, 0x043, 0x044, 0x045, 0x046, 0x047, 0x048, 0x049, 0x04a, 0x04b, 0x04c, 0x04d, 0x04e, 0x04f,
70         0x050, 0x051, 0x052, 0x053, 0x054, 0x055, 0x056, 0x057, 0x058, 0x059, 0x05a, 0x000, 0x000, 0x000, 0x000, 0x000,
71         0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
72         0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 0x009, 0x00a, 0x1f5, 0x1fb, 0x000, 0x000, 0x000, 0x000,
73         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
74         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
75         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
76         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x03a, 0x03b, 0x02c, 0x02d, 0x02e, 0x02f,
77         0x040, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
78         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x05b, 0x05c, 0x05d, 0x05e, 0x000,
79         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
80         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
81 };
82
83 static const uint16_t key_shift_table[256] = {
84         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
85         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0fe, 0x000, 0x0fe, 0x000, 0x000, 0x000, 0x000,
86         0x020, 0x000, 0x000, 0x000, 0x00b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
87         0x000, 0x021, 0x022, 0x1f7, 0x024, 0x025, 0x026, 0x027, 0x028, 0x029, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
88         0x000, 0x061, 0x062, 0x063, 0x064, 0x065, 0x066, 0x067, 0x068, 0x069, 0x06a, 0x06b, 0x06c, 0x06d, 0x06e, 0x06f,
89         0x070, 0x071, 0x072, 0x073, 0x074, 0x075, 0x076, 0x077, 0x078, 0x079, 0x07a, 0x000, 0x000, 0x000, 0x000, 0x000,
90         0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
91         0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 0x009, 0x00a, 0x1f5, 0x1fb, 0x000, 0x000, 0x000, 0x000,
92         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
93         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
94         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
95         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x02a, 0x02b, 0x03c, 0x03d, 0x03e, 0x03f,
96         0x060, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
97         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x07b, 0x07c, 0x07d, 0x07e, 0x000,
98         0x000, 0x000, 0x05f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
99         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
100 };
101
102 static const uint16_t key_ctrl_table[256] = {
103         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
104         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x1fc, 0x000, 0x1fc, 0x000, 0x000, 0x000, 0x000,
105         0x020, 0x000, 0x000, 0x1f7, 0x01b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
106         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
107         0x000, 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087, 0x088, 0x089, 0x08a, 0x08b, 0x08c, 0x08d, 0x08e, 0x08f,
108         0x090, 0x091, 0x092, 0x093, 0x094, 0x095, 0x096, 0x097, 0x098, 0x099, 0x09a, 0x000, 0x000, 0x000, 0x000, 0x000,
109         0x190, 0x191, 0x192, 0x193, 0x194, 0x195, 0x196, 0x197, 0x198, 0x199, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
110         0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017, 0x018, 0x019, 0x01a, 0x1f6, 0x1f3, 0x000, 0x000, 0x000, 0x000,
111         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
112         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
113         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
114         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
115         0x080, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
116         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x09b, 0x09c, 0x09d, 0x09e, 0x000,
117         0x000, 0x000, 0x09f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
118         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
119 };
120
121 static const uint16_t key_ctrl_shift_table[256] = {
122         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
123         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x1fc, 0x000, 0x1fc, 0x000, 0x000, 0x000, 0x000,
124         0x020, 0x000, 0x000, 0x1f7, 0x01b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
125         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
126         0x000, 0x0e1, 0x0e2, 0x0e3, 0x0e4, 0x0e5, 0x0e6, 0x0e7, 0x0e8, 0x0e9, 0x0ea, 0x0eb, 0x0ec, 0x0ed, 0x0ee, 0x0ef,
127         0x0f0, 0x0f1, 0x0f2, 0x0f3, 0x0f4, 0x0f5, 0x0f6, 0x0f7, 0x0f8, 0x0f9, 0x0fa, 0x000, 0x000, 0x000, 0x000, 0x000,
128         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
129         0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017, 0x018, 0x019, 0x01a, 0x1f6, 0x1f3, 0x000, 0x000, 0x000, 0x000,
130         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
131         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
132         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
133         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
134         0x0e0, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
135         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0fb, 0x000, 0x000, 0x000, 0x000,
136         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
137         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
138 };
139
140 static const uint16_t key_kana_table[256] = {
141         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
142         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0fe, 0x000, 0x0fe, 0x000, 0x000, 0x000, 0x000,
143         0x020, 0x000, 0x000, 0x1f7, 0x00b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
144         0x0dc, 0x0c7, 0x0cc, 0x0b1, 0x0b3, 0x0b4, 0x0b5, 0x0d4, 0x0d5, 0x0d6, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
145         0x000, 0x0c1, 0x0ba, 0x0bf, 0x0bc, 0x0b2, 0x0ca, 0x0b7, 0x0b8, 0x0c6, 0x0cf, 0x0c9, 0x0d8, 0x0d3, 0x0d0, 0x0d7,
146         0x0be, 0x0c0, 0x0bd, 0x0c4, 0x0b6, 0x0c5, 0x0cb, 0x0c3, 0x0bb, 0x0dd, 0x0c2, 0x000, 0x000, 0x000, 0x000, 0x000,
147         0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
148         0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 0x009, 0x00a, 0x1f5, 0x1fb, 0x000, 0x000, 0x000, 0x000,
149         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
150         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
151         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
152         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0b9, 0x0da, 0x0c8, 0x0ce, 0x0d9, 0x0d2,
153         0x0de, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
154         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0df, 0x0b0, 0x0d1, 0x0cd, 0x000,
155         0x000, 0x000, 0x0db, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
156         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
157 };
158
159 static const uint16_t key_kana_shift_table[256] = {
160         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
161         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0fe, 0x000, 0x0fe, 0x000, 0x000, 0x000, 0x000,
162         0x020, 0x000, 0x000, 0x1f7, 0x00b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
163         0x0a6, 0x000, 0x000, 0x0a7, 0x0a9, 0x0aa, 0x0ab, 0x0ac, 0x0ad, 0x0ae, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
164         0x000, 0x000, 0x000, 0x000, 0x000, 0x0a8, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
165         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0af, 0x000, 0x000, 0x000, 0x000, 0x000,
166         0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
167         0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 0x009, 0x00a, 0x1f5, 0x1fb, 0x000, 0x000, 0x000, 0x000,
168         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
169         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
170         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
171         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0a4, 0x000, 0x0a1, 0x0a5,
172         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
173         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0a2, 0x000, 0x0a3, 0x000, 0x000,
174         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
175         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
176 };
177
178 void KEYBOARD::initialize()
179 {
180         key_stat = emu->get_key_buffer();
181         key_buf = new FIFO(64);
182         
183         caps = kana = false;
184         pro_mode = true;
185         
186         register_frame_event(this);
187 }
188
189 void KEYBOARD::release()
190 {
191         key_buf->release();
192         delete key_buf;
193 }
194
195 void KEYBOARD::reset()
196 {
197         key_buf->clear();
198         emu->out_message(pro_mode ? _T("PRO mode") : _T("OP mode"));
199         key_buf->write(pro_mode ? 0x1f2 : 0x1f0);
200         
201         phase = PHASE_RESET;
202         drive();
203         
204         stc_clock = get_current_clock();
205         stc = dc = false;
206 }
207
208 void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
209 {
210         if(id == SIG_KEYBOARD_ACKC) {
211                 if(data & mask) {
212                         if(phase == PHASE_SEND_WAIT_ACK) {
213                                 key_buf->read();
214                         }
215                 }
216         } else if(id == SIG_KEYBOARD_STC) {
217                 bool old = stc;
218                 stc = ((data & mask) != 0);
219                 if(old && !stc) {
220                         stc_clock = get_current_clock();
221                 } else if(!old && stc) {
222                         switch(phase) {
223                         case PHASE_RESET:
224                                 phase = PHASE_IDLE;
225                                 drive();
226                                 break;
227                         case PHASE_IDLE:
228                                 if(get_passed_usec(stc_clock) < 7.5) {
229                                         phase = PHASE_IDLE;
230                                 } else {
231                                         phase = PHASE_RECV_START;
232                                 }
233                                 drive();
234                                 break;
235                         case PHASE_RECV_BIT_2:
236                         case PHASE_RECV_BIT_1:
237                         case PHASE_RECV_BIT_0:
238                         case PHASE_RECV_PARITY:
239                                 if(get_passed_usec(stc_clock) < 17.5) {
240                                         phase = PHASE_IDLE;
241                                 }
242                                 drive();
243                                 break;
244                         }
245                 }
246         } else if(id == SIG_KEYBOARD_DC) {
247                 dc = ((data & mask) != 0);
248         }
249 }
250
251 void KEYBOARD::event_callback(int event_id, int err)
252 {
253         if(event_id == EVENT_DRIVE) {
254                 drive();
255         } else if(event_id == EVENT_DATA) {
256                 set_dk((send_data & 0x200) != 0);
257                 send_data <<= 1;
258         } else if(event_id == EVENT_ACK) {
259                 set_dk(recv_ok);
260         }
261 }
262
263 void KEYBOARD::event_frame()
264 {
265         if(phase == PHASE_IDLE) {
266                 if(!key_buf->empty()) {
267                         send_data = (uint16_t)key_buf->read_not_remove(0);
268                         send_data = ((send_data & 0xff) << 2) | ((send_data & 0x100) >> 7);
269                         int parity = 0;//1;
270                         if(send_data & 0x200) parity++;
271                         if(send_data & 0x100) parity++;
272                         if(send_data & 0x080) parity++;
273                         if(send_data & 0x040) parity++;
274                         if(send_data & 0x020) parity++;
275                         if(send_data & 0x010) parity++;
276                         if(send_data & 0x008) parity++;
277                         if(send_data & 0x004) parity++;
278                         if(send_data & 0x002) parity++;
279                         send_data |= (parity & 1);
280                         phase = PHASE_SEND_START_H;
281                         drive();
282                 }
283         }
284 }
285
286 void KEYBOARD::drive()
287 {
288         switch(phase) {
289         case PHASE_RESET:
290         case PHASE_IDLE:
291                 set_dk(false);
292                 set_stk(false);
293                 break;
294         case PHASE_SEND_START_H:
295                 set_dk(false);
296                 set_stk(true);
297                 phase++;
298                 register_event(this, EVENT_DRIVE, 12.5, false, NULL);
299                 break;
300         case PHASE_SEND_START_L:
301                 set_stk(false);
302                 phase++;
303                 register_event(this, EVENT_DATA, 32.0, false, NULL);
304                 register_event(this, EVENT_DRIVE, 32.5, false, NULL);
305                 break;
306         case PHASE_SEND_BIT_7_H:
307         case PHASE_SEND_BIT_6_H:
308         case PHASE_SEND_BIT_5_H:
309         case PHASE_SEND_BIT_4_H:
310         case PHASE_SEND_BIT_3_H:
311         case PHASE_SEND_BIT_2_H:
312         case PHASE_SEND_BIT_1_H:
313         case PHASE_SEND_BIT_0_H:
314         case PHASE_SEND_COMMAND_H:
315         case PHASE_SEND_PARITY_H:
316                 set_stk(true);
317                 phase++;
318                 register_event(this, EVENT_DRIVE, 17.5, false, NULL);
319                 break;
320         case PHASE_SEND_BIT_7_L:
321         case PHASE_SEND_BIT_6_L:
322         case PHASE_SEND_BIT_5_L:
323         case PHASE_SEND_BIT_4_L:
324         case PHASE_SEND_BIT_3_L:
325         case PHASE_SEND_BIT_2_L:
326         case PHASE_SEND_BIT_1_L:
327         case PHASE_SEND_BIT_0_L:
328         case PHASE_SEND_COMMAND_L:
329                 set_stk(false);
330                 phase++;
331                 register_event(this, EVENT_DATA, 49.5, false, NULL);
332                 register_event(this, EVENT_DRIVE, 50.0, false, NULL);
333                 break;
334         case PHASE_SEND_PARITY_L:
335                 set_stk(false);
336                 phase++;
337                 register_event(this, EVENT_DRIVE, 50.0, false, NULL);
338                 break;
339         case PHASE_SEND_FINISH:
340                 set_dk(false);
341                 phase++;
342                 register_event(this, EVENT_DRIVE, 300.0, false, NULL);
343                 break;
344         case PHASE_SEND_WAIT_ACK:
345                 phase = PHASE_IDLE;
346                 break;
347         case PHASE_RECV_START:
348                 recv_data = 0;
349                 phase++;
350                 break;
351         case PHASE_RECV_BIT_2:
352                 recv_data |= dc ? 4 : 0;
353                 phase++;
354                 break;
355         case PHASE_RECV_BIT_1:
356                 recv_data |= dc ? 2 : 0;
357                 phase++;
358                 break;
359         case PHASE_RECV_BIT_0:
360                 recv_data |= dc ? 1 : 0;
361                 phase++;
362                 break;
363         case PHASE_RECV_PARITY:
364                 {
365                         int parity = 0;//1;
366                         if(recv_data & 4) parity++;
367                         if(recv_data & 2) parity++;
368                         if(recv_data & 1) parity++;
369                         recv_ok = ((parity & 1) == (dc ? 1 : 0));
370                         phase++;
371                         register_event(this, EVENT_ACK, 69.5, false, NULL);
372                         register_event(this, EVENT_DRIVE, 70.0, false, NULL);
373                 }
374                 break;
375         case PHASE_RECV_ACK_H:
376                 set_stk(true);
377                 phase++;
378                 register_event(this, EVENT_DRIVE, 17.5, false, NULL);
379                 break;
380         case PHASE_RECV_ACK_L:
381                 set_dk(false);
382                 set_stk(false);
383                 phase = PHASE_IDLE;
384                 break;
385         }
386 }
387
388 void KEYBOARD::key_down(int code)
389 {
390         bool shift = (key_stat[0x10] != 0);
391         bool ctrl = (key_stat[0x11] != 0);
392         bool alt = (key_stat[0x12] != 0);
393         
394         if(code == 0x14) {
395                 caps = !caps;
396                 return;
397         } else if(code == 0x15) {
398                 kana = !kana;
399                 return;
400         } else if(code == 0x21) {
401                 if(!pro_mode) {
402                         pro_mode = true;
403                         emu->out_message(_T("PRO mode"));
404                         key_buf->write(0x1f2);
405                 }
406                 return;
407         } else if(code == 0x22) {
408                 if(pro_mode) {
409                         pro_mode = false;
410                         emu->out_message(_T("OP mode"));
411                         key_buf->write(0x1f0);
412                 }
413                 return;
414         } else if(code == 0x70 && alt) {
415                 // ALT + F11 -> RUN
416                 key_buf->write(0x1fa);
417                 return;
418         } else if((code == 0x30 || code == 0x60) && alt) {
419                 // Alt + 0 -> 00
420                 key_buf->write(0x0fc);
421                 return;
422         }
423         if(ctrl && shift) {
424                 code = key_ctrl_shift_table[code];
425         } else if(ctrl) {
426                 code = key_ctrl_table[code];
427         } else if(kana && shift) {
428                 code = key_kana_shift_table[code];
429         } else if(kana) {
430                 code = key_kana_table[code];
431         } else if(shift) {
432                 code = key_shift_table[code];
433         } else {
434                 code = key_table[code];
435         }
436         if(code != 0) {
437                 if(caps) {
438                         if(code >= 'a' && code <= 'z') {
439                                 code += 'A' - 'a';
440                         } else if(code >= 'A' && code <= 'Z') {
441                                 code += 'a' - 'A';
442                         }
443                 }
444                 key_buf->write(code);
445         }
446 }
447
448 void KEYBOARD::key_up(int code)
449 {
450 }
451
452 void KEYBOARD::set_stk(bool value)
453 {
454         d_ls244->write_signal(SIG_LS244_INPUT, value ? 0xffffffff : 0, 0x40);
455         d_subcpu->write_signal(SIG_CPU_IRQ, value ? 0xffffffff : 0, 1);
456 }
457
458 void KEYBOARD::set_dk(bool value)
459 {
460         d_ls244->write_signal(SIG_LS244_INPUT, value ? 0xffffffff : 0, 0x20);
461 }
462
463 #define STATE_VERSION   3
464
465 #include "../../statesub.h"
466
467 void KEYBOARD::decl_state()
468 {
469         enter_decl_state(STATE_VERSION);
470
471         DECL_STATE_ENTRY_FIFO(key_buf);
472         DECL_STATE_ENTRY_INT32(phase);
473         DECL_STATE_ENTRY_UINT16(send_data);
474         DECL_STATE_ENTRY_UINT32(stc_clock);
475         DECL_STATE_ENTRY_UINT8(recv_data);
476         DECL_STATE_ENTRY_BOOL(recv_ok);
477         DECL_STATE_ENTRY_BOOL(stc);
478         DECL_STATE_ENTRY_BOOL(dc);
479         DECL_STATE_ENTRY_BOOL(caps);
480         DECL_STATE_ENTRY_BOOL(kana);
481         DECL_STATE_ENTRY_BOOL(pro_mode);
482         
483         leave_decl_state();
484 }
485
486 void KEYBOARD::save_state(FILEIO* state_fio)
487 {
488         if(state_entry != NULL) {
489                 state_entry->save_state(state_fio);
490         }
491 //      state_fio->FputUint32(STATE_VERSION);
492 //      state_fio->FputInt32(this_device_id);
493         
494 //      key_buf->save_state((void *)state_fio);
495 //      state_fio->FputInt32(phase);
496 //      state_fio->FputUint16(send_data);
497 //      state_fio->FputUint32(stc_clock);
498 //      state_fio->FputUint8(recv_data);
499 //      state_fio->FputBool(recv_ok);
500 //      state_fio->FputBool(stc);
501 //      state_fio->FputBool(dc);
502 //      state_fio->FputBool(caps);
503 //      state_fio->FputBool(kana);
504 //      state_fio->FputBool(pro_mode);
505 }
506
507 bool KEYBOARD::load_state(FILEIO* state_fio)
508 {
509         bool mb = false;
510         if(state_entry != NULL) {
511                 mb = state_entry->load_state(state_fio);
512         }
513         if(!mb) {
514                 return false;
515         }
516 //      if(state_fio->FgetUint32() != STATE_VERSION) {
517 //              return false;
518 //      }
519 //      if(state_fio->FgetInt32() != this_device_id) {
520 //              return false;
521 //      }
522 //      if(!key_buf->load_state((void *)state_fio)) {
523 //              return false;
524 //      }
525 //      phase = state_fio->FgetInt32();
526 //      send_data = state_fio->FgetUint16();
527 //      stc_clock = state_fio->FgetUint32();
528 //      recv_data = state_fio->FgetUint8();
529 //      recv_ok = state_fio->FgetBool();
530 //      stc = state_fio->FgetBool();
531 //      dc = state_fio->FgetBool();
532 //      caps = state_fio->FgetBool();
533 //      kana = state_fio->FgetBool();
534 //      pro_mode = state_fio->FgetBool();
535         return true;
536 }
537
538 bool KEYBOARD::process_state(FILEIO* state_fio, bool loading)
539 {
540         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
541                 return false;
542         }
543         if(!state_fio->StateCheckInt32(this_device_id)) {
544                 return false;
545         }
546         if(!key_buf->process_state((void *)state_fio, loading)) {
547                 return false;
548         }
549         state_fio->StateInt32(phase);
550         state_fio->StateUint16(send_data);
551         state_fio->StateUint32(stc_clock);
552         state_fio->StateUint8(recv_data);
553         state_fio->StateBool(recv_ok);
554         state_fio->StateBool(stc);
555         state_fio->StateBool(dc);
556         state_fio->StateBool(caps);
557         state_fio->StateBool(kana);
558         state_fio->StateBool(pro_mode);
559         return true;
560 }