OSDN Git Service

[VM][STATE] Use namespace {VMNAME} to separate per VMs.
[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 namespace MZ3500 {
65
66 static const uint16_t key_table[256] = {
67         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
68         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0fe, 0x000, 0x0fe, 0x000, 0x000, 0x000, 0x000,
69         0x020, 0x000, 0x000, 0x1f7, 0x00b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
70         0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
71         0x000, 0x041, 0x042, 0x043, 0x044, 0x045, 0x046, 0x047, 0x048, 0x049, 0x04a, 0x04b, 0x04c, 0x04d, 0x04e, 0x04f,
72         0x050, 0x051, 0x052, 0x053, 0x054, 0x055, 0x056, 0x057, 0x058, 0x059, 0x05a, 0x000, 0x000, 0x000, 0x000, 0x000,
73         0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
74         0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 0x009, 0x00a, 0x1f5, 0x1fb, 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, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
77         0x000, 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, 0x03a, 0x03b, 0x02c, 0x02d, 0x02e, 0x02f,
79         0x040, 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, 0x05b, 0x05c, 0x05d, 0x05e, 0x000,
81         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
82         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
83 };
84
85 static const uint16_t key_shift_table[256] = {
86         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
87         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0fe, 0x000, 0x0fe, 0x000, 0x000, 0x000, 0x000,
88         0x020, 0x000, 0x000, 0x000, 0x00b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
89         0x000, 0x021, 0x022, 0x1f7, 0x024, 0x025, 0x026, 0x027, 0x028, 0x029, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
90         0x000, 0x061, 0x062, 0x063, 0x064, 0x065, 0x066, 0x067, 0x068, 0x069, 0x06a, 0x06b, 0x06c, 0x06d, 0x06e, 0x06f,
91         0x070, 0x071, 0x072, 0x073, 0x074, 0x075, 0x076, 0x077, 0x078, 0x079, 0x07a, 0x000, 0x000, 0x000, 0x000, 0x000,
92         0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
93         0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 0x009, 0x00a, 0x1f5, 0x1fb, 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, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
96         0x000, 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, 0x02a, 0x02b, 0x03c, 0x03d, 0x03e, 0x03f,
98         0x060, 0x000, 0x000, 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, 0x07b, 0x07c, 0x07d, 0x07e, 0x000,
100         0x000, 0x000, 0x05f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
101         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
102 };
103
104 static const uint16_t key_ctrl_table[256] = {
105         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
106         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x1fc, 0x000, 0x1fc, 0x000, 0x000, 0x000, 0x000,
107         0x020, 0x000, 0x000, 0x1f7, 0x01b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
108         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
109         0x000, 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087, 0x088, 0x089, 0x08a, 0x08b, 0x08c, 0x08d, 0x08e, 0x08f,
110         0x090, 0x091, 0x092, 0x093, 0x094, 0x095, 0x096, 0x097, 0x098, 0x099, 0x09a, 0x000, 0x000, 0x000, 0x000, 0x000,
111         0x190, 0x191, 0x192, 0x193, 0x194, 0x195, 0x196, 0x197, 0x198, 0x199, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
112         0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017, 0x018, 0x019, 0x01a, 0x1f6, 0x1f3, 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         0x000, 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, 0x000, 0x000, 0x000, 0x000, 0x000,
117         0x080, 0x000, 0x000, 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, 0x09b, 0x09c, 0x09d, 0x09e, 0x000,
119         0x000, 0x000, 0x09f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
120         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
121 };
122
123 static const uint16_t key_ctrl_shift_table[256] = {
124         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
125         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x1fc, 0x000, 0x1fc, 0x000, 0x000, 0x000, 0x000,
126         0x020, 0x000, 0x000, 0x1f7, 0x01b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
127         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
128         0x000, 0x0e1, 0x0e2, 0x0e3, 0x0e4, 0x0e5, 0x0e6, 0x0e7, 0x0e8, 0x0e9, 0x0ea, 0x0eb, 0x0ec, 0x0ed, 0x0ee, 0x0ef,
129         0x0f0, 0x0f1, 0x0f2, 0x0f3, 0x0f4, 0x0f5, 0x0f6, 0x0f7, 0x0f8, 0x0f9, 0x0fa, 0x000, 0x000, 0x000, 0x000, 0x000,
130         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
131         0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017, 0x018, 0x019, 0x01a, 0x1f6, 0x1f3, 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         0x000, 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, 0x000, 0x000, 0x000, 0x000, 0x000,
136         0x0e0, 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, 0x0fb, 0x000, 0x000, 0x000, 0x000,
138         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
139         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
140 };
141
142 static const uint16_t key_kana_table[256] = {
143         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
144         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0fe, 0x000, 0x0fe, 0x000, 0x000, 0x000, 0x000,
145         0x020, 0x000, 0x000, 0x1f7, 0x00b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
146         0x0dc, 0x0c7, 0x0cc, 0x0b1, 0x0b3, 0x0b4, 0x0b5, 0x0d4, 0x0d5, 0x0d6, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
147         0x000, 0x0c1, 0x0ba, 0x0bf, 0x0bc, 0x0b2, 0x0ca, 0x0b7, 0x0b8, 0x0c6, 0x0cf, 0x0c9, 0x0d8, 0x0d3, 0x0d0, 0x0d7,
148         0x0be, 0x0c0, 0x0bd, 0x0c4, 0x0b6, 0x0c5, 0x0cb, 0x0c3, 0x0bb, 0x0dd, 0x0c2, 0x000, 0x000, 0x000, 0x000, 0x000,
149         0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
150         0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 0x009, 0x00a, 0x1f5, 0x1fb, 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, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
153         0x000, 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, 0x0b9, 0x0da, 0x0c8, 0x0ce, 0x0d9, 0x0d2,
155         0x0de, 0x000, 0x000, 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, 0x0df, 0x0b0, 0x0d1, 0x0cd, 0x000,
157         0x000, 0x000, 0x0db, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
158         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
159 };
160
161 static const uint16_t key_kana_shift_table[256] = {
162         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00f, 0x1f4, 0x000, 0x000, 0x000, 0x00d, 0x000, 0x000,
163         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0fe, 0x000, 0x0fe, 0x000, 0x000, 0x000, 0x000,
164         0x020, 0x000, 0x000, 0x1f7, 0x00b, 0x01f, 0x01c, 0x01e, 0x01d, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
165         0x0a6, 0x000, 0x000, 0x0a7, 0x0a9, 0x0aa, 0x0ab, 0x0ac, 0x0ad, 0x0ae, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
166         0x000, 0x000, 0x000, 0x000, 0x000, 0x0a8, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x1f9, 0x1f8, 0x000,
167         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x0af, 0x000, 0x000, 0x000, 0x000, 0x000,
168         0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x02a, 0x02b, 0x02c, 0x02d, 0x0fd, 0x02f,
169         0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 0x009, 0x00a, 0x1f5, 0x1fb, 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, 0x000, 0x000, 0x000, 0x000,
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, 0x000, 0x0a4, 0x000, 0x0a1, 0x0a5,
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, 0x0a2, 0x000, 0x0a3, 0x000, 0x000,
176         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
177         0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
178 };
179
180 void KEYBOARD::initialize()
181 {
182         key_stat = emu->get_key_buffer();
183         key_buf = new FIFO(64);
184         
185         caps = kana = false;
186         pro_mode = true;
187         
188         register_frame_event(this);
189 }
190
191 void KEYBOARD::release()
192 {
193         key_buf->release();
194         delete key_buf;
195 }
196
197 void KEYBOARD::reset()
198 {
199         key_buf->clear();
200         emu->out_message(pro_mode ? _T("PRO mode") : _T("OP mode"));
201         key_buf->write(pro_mode ? 0x1f2 : 0x1f0);
202         
203         phase = PHASE_RESET;
204         drive();
205         
206         stc_clock = get_current_clock();
207         stc = dc = false;
208 }
209
210 void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
211 {
212         if(id == SIG_KEYBOARD_ACKC) {
213                 if(data & mask) {
214                         if(phase == PHASE_SEND_WAIT_ACK) {
215                                 key_buf->read();
216                         }
217                 }
218         } else if(id == SIG_KEYBOARD_STC) {
219                 bool old = stc;
220                 stc = ((data & mask) != 0);
221                 if(old && !stc) {
222                         stc_clock = get_current_clock();
223                 } else if(!old && stc) {
224                         switch(phase) {
225                         case PHASE_RESET:
226                                 phase = PHASE_IDLE;
227                                 drive();
228                                 break;
229                         case PHASE_IDLE:
230                                 if(get_passed_usec(stc_clock) < 7.5) {
231                                         phase = PHASE_IDLE;
232                                 } else {
233                                         phase = PHASE_RECV_START;
234                                 }
235                                 drive();
236                                 break;
237                         case PHASE_RECV_BIT_2:
238                         case PHASE_RECV_BIT_1:
239                         case PHASE_RECV_BIT_0:
240                         case PHASE_RECV_PARITY:
241                                 if(get_passed_usec(stc_clock) < 17.5) {
242                                         phase = PHASE_IDLE;
243                                 }
244                                 drive();
245                                 break;
246                         }
247                 }
248         } else if(id == SIG_KEYBOARD_DC) {
249                 dc = ((data & mask) != 0);
250         }
251 }
252
253 void KEYBOARD::event_callback(int event_id, int err)
254 {
255         if(event_id == EVENT_DRIVE) {
256                 drive();
257         } else if(event_id == EVENT_DATA) {
258                 set_dk((send_data & 0x200) != 0);
259                 send_data <<= 1;
260         } else if(event_id == EVENT_ACK) {
261                 set_dk(recv_ok);
262         }
263 }
264
265 void KEYBOARD::event_frame()
266 {
267         if(phase == PHASE_IDLE) {
268                 if(!key_buf->empty()) {
269                         send_data = (uint16_t)key_buf->read_not_remove(0);
270                         send_data = ((send_data & 0xff) << 2) | ((send_data & 0x100) >> 7);
271                         int parity = 0;//1;
272                         if(send_data & 0x200) parity++;
273                         if(send_data & 0x100) parity++;
274                         if(send_data & 0x080) parity++;
275                         if(send_data & 0x040) parity++;
276                         if(send_data & 0x020) parity++;
277                         if(send_data & 0x010) parity++;
278                         if(send_data & 0x008) parity++;
279                         if(send_data & 0x004) parity++;
280                         if(send_data & 0x002) parity++;
281                         send_data |= (parity & 1);
282                         phase = PHASE_SEND_START_H;
283                         drive();
284                 }
285         }
286 }
287
288 void KEYBOARD::drive()
289 {
290         switch(phase) {
291         case PHASE_RESET:
292         case PHASE_IDLE:
293                 set_dk(false);
294                 set_stk(false);
295                 break;
296         case PHASE_SEND_START_H:
297                 set_dk(false);
298                 set_stk(true);
299                 phase++;
300                 register_event(this, EVENT_DRIVE, 12.5, false, NULL);
301                 break;
302         case PHASE_SEND_START_L:
303                 set_stk(false);
304                 phase++;
305                 register_event(this, EVENT_DATA, 32.0, false, NULL);
306                 register_event(this, EVENT_DRIVE, 32.5, false, NULL);
307                 break;
308         case PHASE_SEND_BIT_7_H:
309         case PHASE_SEND_BIT_6_H:
310         case PHASE_SEND_BIT_5_H:
311         case PHASE_SEND_BIT_4_H:
312         case PHASE_SEND_BIT_3_H:
313         case PHASE_SEND_BIT_2_H:
314         case PHASE_SEND_BIT_1_H:
315         case PHASE_SEND_BIT_0_H:
316         case PHASE_SEND_COMMAND_H:
317         case PHASE_SEND_PARITY_H:
318                 set_stk(true);
319                 phase++;
320                 register_event(this, EVENT_DRIVE, 17.5, false, NULL);
321                 break;
322         case PHASE_SEND_BIT_7_L:
323         case PHASE_SEND_BIT_6_L:
324         case PHASE_SEND_BIT_5_L:
325         case PHASE_SEND_BIT_4_L:
326         case PHASE_SEND_BIT_3_L:
327         case PHASE_SEND_BIT_2_L:
328         case PHASE_SEND_BIT_1_L:
329         case PHASE_SEND_BIT_0_L:
330         case PHASE_SEND_COMMAND_L:
331                 set_stk(false);
332                 phase++;
333                 register_event(this, EVENT_DATA, 49.5, false, NULL);
334                 register_event(this, EVENT_DRIVE, 50.0, false, NULL);
335                 break;
336         case PHASE_SEND_PARITY_L:
337                 set_stk(false);
338                 phase++;
339                 register_event(this, EVENT_DRIVE, 50.0, false, NULL);
340                 break;
341         case PHASE_SEND_FINISH:
342                 set_dk(false);
343                 phase++;
344                 register_event(this, EVENT_DRIVE, 300.0, false, NULL);
345                 break;
346         case PHASE_SEND_WAIT_ACK:
347                 phase = PHASE_IDLE;
348                 break;
349         case PHASE_RECV_START:
350                 recv_data = 0;
351                 phase++;
352                 break;
353         case PHASE_RECV_BIT_2:
354                 recv_data |= dc ? 4 : 0;
355                 phase++;
356                 break;
357         case PHASE_RECV_BIT_1:
358                 recv_data |= dc ? 2 : 0;
359                 phase++;
360                 break;
361         case PHASE_RECV_BIT_0:
362                 recv_data |= dc ? 1 : 0;
363                 phase++;
364                 break;
365         case PHASE_RECV_PARITY:
366                 {
367                         int parity = 0;//1;
368                         if(recv_data & 4) parity++;
369                         if(recv_data & 2) parity++;
370                         if(recv_data & 1) parity++;
371                         recv_ok = ((parity & 1) == (dc ? 1 : 0));
372                         phase++;
373                         register_event(this, EVENT_ACK, 69.5, false, NULL);
374                         register_event(this, EVENT_DRIVE, 70.0, false, NULL);
375                 }
376                 break;
377         case PHASE_RECV_ACK_H:
378                 set_stk(true);
379                 phase++;
380                 register_event(this, EVENT_DRIVE, 17.5, false, NULL);
381                 break;
382         case PHASE_RECV_ACK_L:
383                 set_dk(false);
384                 set_stk(false);
385                 phase = PHASE_IDLE;
386                 break;
387         }
388 }
389
390 void KEYBOARD::key_down(int code)
391 {
392         bool shift = (key_stat[0x10] != 0);
393         bool ctrl = (key_stat[0x11] != 0);
394         bool alt = (key_stat[0x12] != 0);
395         
396         if(code == 0x14) {
397                 caps = !caps;
398                 return;
399         } else if(code == 0x15) {
400                 kana = !kana;
401                 return;
402         } else if(code == 0x21) {
403                 if(!pro_mode) {
404                         pro_mode = true;
405                         emu->out_message(_T("PRO mode"));
406                         key_buf->write(0x1f2);
407                 }
408                 return;
409         } else if(code == 0x22) {
410                 if(pro_mode) {
411                         pro_mode = false;
412                         emu->out_message(_T("OP mode"));
413                         key_buf->write(0x1f0);
414                 }
415                 return;
416         } else if(code == 0x70 && alt) {
417                 // ALT + F11 -> RUN
418                 key_buf->write(0x1fa);
419                 return;
420         } else if((code == 0x30 || code == 0x60) && alt) {
421                 // Alt + 0 -> 00
422                 key_buf->write(0x0fc);
423                 return;
424         }
425         if(ctrl && shift) {
426                 code = key_ctrl_shift_table[code];
427         } else if(ctrl) {
428                 code = key_ctrl_table[code];
429         } else if(kana && shift) {
430                 code = key_kana_shift_table[code];
431         } else if(kana) {
432                 code = key_kana_table[code];
433         } else if(shift) {
434                 code = key_shift_table[code];
435         } else {
436                 code = key_table[code];
437         }
438         if(code != 0) {
439                 if(caps) {
440                         if(code >= 'a' && code <= 'z') {
441                                 code += 'A' - 'a';
442                         } else if(code >= 'A' && code <= 'Z') {
443                                 code += 'a' - 'A';
444                         }
445                 }
446                 key_buf->write(code);
447         }
448 }
449
450 void KEYBOARD::key_up(int code)
451 {
452 }
453
454 void KEYBOARD::set_stk(bool value)
455 {
456         d_ls244->write_signal(SIG_LS244_INPUT, value ? 0xffffffff : 0, 0x40);
457         d_subcpu->write_signal(SIG_CPU_IRQ, value ? 0xffffffff : 0, 1);
458 }
459
460 void KEYBOARD::set_dk(bool value)
461 {
462         d_ls244->write_signal(SIG_LS244_INPUT, value ? 0xffffffff : 0, 0x20);
463 }
464
465 #define STATE_VERSION   3
466
467 bool KEYBOARD::process_state(FILEIO* state_fio, bool loading)
468 {
469         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
470                 return false;
471         }
472         if(!state_fio->StateCheckInt32(this_device_id)) {
473                 return false;
474         }
475         if(!key_buf->process_state((void *)state_fio, loading)) {
476                 return false;
477         }
478         state_fio->StateInt32(phase);
479         state_fio->StateUint16(send_data);
480         state_fio->StateUint32(stc_clock);
481         state_fio->StateUint8(recv_data);
482         state_fio->StateBool(recv_ok);
483         state_fio->StateBool(stc);
484         state_fio->StateBool(dc);
485         state_fio->StateBool(caps);
486         state_fio->StateBool(kana);
487         state_fio->StateBool(pro_mode);
488         return true;
489 }
490
491 }