OSDN Git Service

[VM][STATE] Use namespace {VMNAME} to separate per VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz5500 / 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 "../i8255.h"
12 #include "../i8259.h"
13 #include "../../fifo.h"
14
15 #define BIT_DK  0x08
16 #define BIT_SRK 0x10
17 #define BIT_DC  0x01
18 #define BIT_STC 0x02
19
20 #define PHASE_IDLE      0
21
22 #define PHASE_SEND_EB_L 11
23 #define PHASE_SEND_D7_H 12
24 #define PHASE_SEND_D7_L 13
25 #define PHASE_SEND_D6_H 14
26 #define PHASE_SEND_D6_L 15
27 #define PHASE_SEND_D5_H 16
28 #define PHASE_SEND_D5_L 17
29 #define PHASE_SEND_D4_H 18
30 #define PHASE_SEND_D4_L 19
31 #define PHASE_SEND_D3_H 20
32 #define PHASE_SEND_D3_L 21
33 #define PHASE_SEND_D2_H 22
34 #define PHASE_SEND_D2_L 23
35 #define PHASE_SEND_D1_H 24
36 #define PHASE_SEND_D1_L 25
37 #define PHASE_SEND_D0_H 26
38 #define PHASE_SEND_D0_L 27
39 #define PHASE_SEND_PB_H 28
40 #define PHASE_SEND_PB_L 29
41 #define PHASE_SEND_RE_H 30
42 #define PHASE_SEND_RE_L 31
43 #define PHASE_SEND_END  32
44
45 #define PHASE_RECV_D4_H 41
46 #define PHASE_RECV_D4_L 42
47 #define PHASE_RECV_D3_H 43
48 #define PHASE_RECV_D3_L 44
49 #define PHASE_RECV_D2_H 45
50 #define PHASE_RECV_D2_L 46
51 #define PHASE_RECV_D1_H 47
52 #define PHASE_RECV_D1_L 48
53 #define PHASE_RECV_D0_H 49
54 #define PHASE_RECV_D0_L 50
55 #define PHASE_RECV_PB_H 51
56 #define PHASE_RECV_PB_L 52
57 #define PHASE_RECV_RE_H 53
58 #define PHASE_RECV_RE_L 54
59 #define PHASE_RECV_END  55
60
61 #define TIMEOUT_500MSEC 30
62 #define TIMEOUT_100MSEC 6
63
64 namespace MZ5500 {
65
66 static const int key_table[256] = {
67         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x008,0x009,0x000,0x000,0x000,0x00d,0x000,0x000,
68         0x000,0x000,0x000,0x006,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x01b,0x000,0x000,0x000,0x000,
69         0x020,0x080,0x090,0x018,0x08f,0x01f,0x01c,0x01e,0x01d,0x000,0x000,0x000,0x000,0x00b,0x07f,0x000,
70         0x030,0x031,0x032,0x033,0x034,0x035,0x036,0x037,0x038,0x039,0x000,0x000,0x000,0x000,0x000,0x000,
71         0x000,0x061,0x062,0x063,0x064,0x065,0x066,0x067,0x068,0x069,0x06a,0x06b,0x06c,0x06d,0x06e,0x06f,
72         0x070,0x071,0x072,0x073,0x074,0x075,0x076,0x077,0x078,0x079,0x07a,0x000,0x000,0x000,0x000,0x000,
73         0x0f0,0x0f1,0x0f2,0x0f3,0x0f4,0x0f5,0x0f6,0x0f7,0x0f8,0x0f9,0x0ea,0x0eb,0x0ec,0x0ed,0x0ee,0x0ef,
74         0x081,0x082,0x083,0x084,0x085,0x086,0x087,0x088,0x089,0x08a,0x00e,0x00f,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,0x05f,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 int key_table_shift[256] = {
86         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x019,0x000,0x000,0x000,0x000,0x000,0x000,
87         0x000,0x000,0x000,0x007,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
88         0x020,0x090,0x080,0x000,0x09f,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x00c,0x01a,0x000,
89         0x000,0x021,0x022,0x023,0x024,0x025,0x026,0x027,0x028,0x029,0x000,0x000,0x000,0x000,0x000,0x000,
90         0x000,0x041,0x042,0x043,0x044,0x045,0x046,0x047,0x048,0x049,0x04a,0x04b,0x04c,0x04d,0x04e,0x04f,
91         0x050,0x051,0x052,0x053,0x054,0x055,0x056,0x057,0x058,0x059,0x05a,0x000,0x000,0x000,0x000,0x000,
92         0x0e0,0x0e1,0x0e2,0x0e3,0x0e4,0x0e5,0x0e6,0x0e7,0x0e8,0x0e9,0x000,0x000,0x000,0x000,0x000,0x000,
93         0x091,0x092,0x093,0x094,0x095,0x096,0x097,0x098,0x099,0x09a,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,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 int key_table_kana[256] = {
105         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x008,0x009,0x000,0x000,0x000,0x00d,0x000,0x000,
106         0x000,0x000,0x000,0x006,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x01b,0x000,0x000,0x000,0x000,
107         0x020,0x080,0x090,0x018,0x08f,0x01f,0x01c,0x01e,0x01d,0x000,0x000,0x000,0x000,0x00b,0x07f,0x000,
108         0x0dc,0x0c7,0x0cc,0x0b1,0x0b3,0x0b4,0x0b5,0x0d4,0x0d5,0x0d6,0x000,0x000,0x000,0x000,0x000,0x000,
109         0x000,0x0c1,0x0ba,0x0bf,0x0bc,0x0b2,0x0ca,0x0b7,0x0b8,0x0c6,0x0cf,0x0c9,0x0d8,0x0d3,0x0d0,0x0d7,
110         0x0be,0x0c0,0x0bd,0x0c4,0x0b6,0x0c5,0x0cb,0x0c3,0x0bb,0x0dd,0x0c2,0x000,0x000,0x000,0x000,0x000,
111         0x0f0,0x0f1,0x0f2,0x0f3,0x0f4,0x0f5,0x0f6,0x0f7,0x0f8,0x0f9,0x0ea,0x0eb,0x0ec,0x0ed,0x0ee,0x0ef,
112         0x081,0x082,0x083,0x084,0x085,0x086,0x087,0x088,0x089,0x08a,0x00e,0x00f,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,0x0b9,0x0da,0x0c8,0x0ce,0x0d9,0x0d2,
117         0x0de,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,0x0df,0x0b0,0x0d1,0x0cd,0x000,
119         0x000,0x000,0x0db,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 int key_table_kana_shift[256] = {
124         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x019,0x000,0x000,0x000,0x000,0x000,0x000,
125         0x000,0x000,0x000,0x007,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
126         0x020,0x090,0x080,0x000,0x09f,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x00c,0x01a,0x000,
127         0x0a6,0x000,0x000,0x0a7,0x0a9,0x0aa,0x0ab,0x0ac,0x0ad,0x0ae,0x000,0x000,0x000,0x000,0x000,0x000,
128         0x000,0x000,0x000,0x000,0x000,0x0a8,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
129         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x0af,0x000,0x000,0x000,0x000,0x000,
130         0x0e0,0x0e1,0x0e2,0x0e3,0x0e4,0x0e5,0x0e6,0x0e7,0x0e8,0x0e9,0x000,0x000,0x000,0x000,0x000,0x000,
131         0x091,0x092,0x093,0x094,0x095,0x096,0x097,0x098,0x099,0x09a,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         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,0x0a4,0x000,0x0a1,0x0a5,
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,0x0a2,0x000,0x0a3,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 int key_table_graph[256] = {
143         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x008,0x009,0x000,0x000,0x000,0x00d,0x000,0x000,
144         0x000,0x000,0x000,0x006,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x01b,0x000,0x000,0x000,0x000,
145         0x020,0x080,0x090,0x018,0x1a0,0x1a5,0x1a2,0x1a4,0x1a3,0x000,0x000,0x000,0x000,0x00b,0x07f,0x000,
146         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
147         0x000,0x181,0x182,0x183,0x184,0x185,0x186,0x187,0x188,0x189,0x18a,0x18b,0x18c,0x18d,0x18e,0x18f,
148         0x190,0x191,0x192,0x193,0x194,0x195,0x196,0x197,0x198,0x199,0x19a,0x000,0x000,0x000,0x000,0x000,
149         0x0f0,0x0f1,0x0f2,0x0f3,0x0f4,0x0f5,0x0f6,0x0f7,0x0f8,0x0f9,0x0ea,0x0eb,0x0ec,0x0ed,0x0ee,0x0ef,
150         0x081,0x082,0x083,0x084,0x085,0x086,0x087,0x088,0x089,0x08a,0x00e,0x00f,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,0x000,0x000,0x000,0x000,0x000,0x000,
155         0x180,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,0x19b,0x19c,0x19d,0x19e,0x000,
157         0x000,0x000,0x19f,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 int key_table_graph_shift[256] = {
162         0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x019,0x000,0x000,0x000,0x000,0x000,0x000,
163         0x000,0x000,0x000,0x007,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
164         0x020,0x090,0x080,0x000,0x1fb,0x1a5,0x1a2,0x1a4,0x1a3,0x000,0x000,0x000,0x000,0x00c,0x01a,0x000,
165         0x1d0,0x1d1,0x1d2,0x1d3,0x1d4,0x1d5,0x1d6,0x1d7,0x1d8,0x1d9,0x000,0x000,0x000,0x000,0x000,0x000,
166         0x000,0x1e1,0x1e2,0x1e3,0x1e4,0x1e5,0x1e6,0x1e7,0x1e8,0x1e9,0x1ea,0x1eb,0x1ec,0x1ed,0x1ee,0x1ef,
167         0x1f0,0x1f1,0x1f2,0x1f3,0x1f4,0x1f5,0x1f6,0x1f7,0x1f8,0x1f9,0x1fa,0x000,0x000,0x000,0x000,0x000,
168         0x0e0,0x0e1,0x0e2,0x0e3,0x0e4,0x0e5,0x0e6,0x0e7,0x0e8,0x0e9,0x000,0x000,0x000,0x000,0x000,0x000,
169         0x091,0x092,0x093,0x094,0x095,0x096,0x097,0x098,0x099,0x09a,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,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,0x000,0x000,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         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 #define SET_DK(v) { \
181         d_pio->write_signal(SIG_I8255_PORT_B, (dk = (v) ? 1 : 0) ? 0 : BIT_DK, BIT_DK); \
182 }
183 #define SET_SRK(v) { \
184         d_pio->write_signal(SIG_I8255_PORT_B, (srk = (v) ? 1 : 0) ? 0 : BIT_SRK, BIT_SRK); \
185         d_pic->write_signal(SIG_I8259_IR3 | SIG_I8259_CHIP0, srk ? 0 : 1, 1); \
186 }
187
188 void KEYBOARD::initialize()
189 {
190         key_stat = emu->get_key_buffer();
191         mouse_stat = emu->get_mouse_buffer();
192         key_buf = new FIFO(64);
193         rsp_buf = new FIFO(16);
194         caps = kana = graph = false;
195         
196         register_frame_event(this);
197 }
198
199 void KEYBOARD::release()
200 {
201         key_buf->release();
202         delete key_buf;
203         rsp_buf->release();
204         delete rsp_buf;
205 }
206
207 void KEYBOARD::reset()
208 {
209         key_buf->clear();
210         rsp_buf->clear();
211         SET_DK(1);
212         SET_SRK(1);
213         dc = stc = 1;
214         phase = PHASE_IDLE;
215         timeout = 0;
216 }
217
218 void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
219 {
220         // from 8255 port c
221         dc = (data & BIT_DC) ? 0 : 1;
222         stc = (data & BIT_STC) ? 0 : 1;
223         drive();
224 }
225
226 void KEYBOARD::event_frame()
227 {
228         if(timeout > 0) {
229                 timeout--;
230         }
231         drive();
232 }
233
234 void KEYBOARD::key_down(int code)
235 {
236         if(code == 0x1d) {
237                 // muhenkan->graph
238                 if(graph) {
239                         graph = false;
240                 } else {
241                         graph = true;
242                         kana = false;
243                 }
244                 return;
245         } else if(code == 0x14) {
246                 // caps
247                 caps = !caps;
248                 return;
249         } else if(code == 0x15) {
250                 // kana
251                 if(kana) {
252                         kana = false;
253                 } else {
254                         kana = true;
255                         graph = false;
256                 }
257                 return;
258         }
259         int shift = key_stat[0x10];
260         int ctrl = key_stat[0x11];
261         int algo = key_stat[0x12];
262         
263         if(kana) {
264                 if(shift) {
265                         code = key_table_kana_shift[code];
266                 } else {
267                         code = key_table_kana[code];
268                 }
269         } else if(graph) {
270                 if(shift) {
271                         code = key_table_graph_shift[code];
272                 } else {
273                         code = key_table_graph[code];
274                 }
275         } else {
276                 if(shift) {
277                         code = key_table_shift[code];
278                 } else {
279                         code = key_table[code];
280                 }
281         }
282         if(!code) {
283                 return;
284         }
285         if(caps) {
286                 if(0x41 <= code && code <= 0x5a) {
287                         code += 0x20;
288                 } else if(0x61 <= code && code <= 0x7a) {
289                         code -= 0x20;
290                 }
291         }
292         if(ctrl) {
293                 key_buf->write(2);
294         } else if(algo) {
295                 key_buf->write(4);
296         }
297         key_buf->write(code);
298 //      drive();
299 }
300
301 void KEYBOARD::key_up(int code)
302 {
303         // dont check key break
304 }
305
306 #define NEXTPHASE() { \
307         phase++; \
308         timeout = TIMEOUT_100MSEC; \
309 }
310
311 void KEYBOARD::drive()
312 {
313         switch(phase) {
314         case PHASE_IDLE:
315                 if(dc && (!key_buf->empty() || !rsp_buf->empty())) {
316                         if(!rsp_buf->empty()) {
317                                 send = rsp_buf->read();
318                         } else {
319                                 send = key_buf->read();
320                         }
321                         send = ~send & 0x1ff;
322                         int parity = 0;
323                         for(int i = 0; i < 9; i++) {
324                                 parity += (send & (1 << i)) ? 1 : 0;
325                         }
326                         send = (send << 1) | (parity & 1);
327                         
328                         SET_DK(0);
329                         SET_SRK(0);
330                         phase = PHASE_SEND_EB_L;
331                         // 500msec
332                         timeout = TIMEOUT_500MSEC;
333                 } else if(!dc && !stc) {
334                         recv = 0;
335                         SET_DK(0);
336                         phase = PHASE_RECV_D4_H;
337                         // 500msec
338                         timeout = TIMEOUT_500MSEC;
339                 }
340                 break;
341         case PHASE_SEND_EB_L:
342                 if(!stc) {
343                         SET_DK(send & 0x200);
344                         SET_SRK(1);
345                         NEXTPHASE();
346                 }
347                 break;
348         case PHASE_SEND_D7_H:
349         case PHASE_SEND_D6_H:
350         case PHASE_SEND_D5_H:
351         case PHASE_SEND_D4_H:
352         case PHASE_SEND_D3_H:
353         case PHASE_SEND_D2_H:
354         case PHASE_SEND_D1_H:
355         case PHASE_SEND_D0_H:
356         case PHASE_SEND_PB_H:
357                 if(stc) {
358                         SET_DK(send & 0x100);
359                         send <<= 1;
360                         NEXTPHASE();
361                 }
362                 break;
363         case PHASE_SEND_D7_L:
364         case PHASE_SEND_D6_L:
365         case PHASE_SEND_D5_L:
366         case PHASE_SEND_D4_L:
367         case PHASE_SEND_D3_L:
368         case PHASE_SEND_D2_L:
369         case PHASE_SEND_D1_L:
370         case PHASE_SEND_D0_L:
371         case PHASE_SEND_PB_L:
372                 if(!stc) {
373                         NEXTPHASE();
374                 }
375                 break;
376         case PHASE_SEND_RE_H:
377                 if(stc) {
378                         SET_DK(0);
379                         NEXTPHASE();
380                 }
381                 break;
382         case PHASE_SEND_RE_L:
383                 if(!stc) {
384                         NEXTPHASE();
385                 }
386                 break;
387         case PHASE_SEND_END:
388                 if(stc) {
389                         SET_DK(1);
390                         phase = PHASE_IDLE;
391                 }
392                 break;
393         case PHASE_RECV_D4_H:
394         case PHASE_RECV_D3_H:
395         case PHASE_RECV_D2_H:
396         case PHASE_RECV_D1_H:
397         case PHASE_RECV_D0_H:
398         case PHASE_RECV_PB_H:
399                 if(stc) {
400                         NEXTPHASE();
401                 }
402                 break;
403         case PHASE_RECV_D4_L:
404         case PHASE_RECV_D3_L:
405         case PHASE_RECV_D2_L:
406         case PHASE_RECV_D1_L:
407         case PHASE_RECV_D0_L:
408         case PHASE_RECV_PB_L:
409                 if(!stc) {
410                         recv = (recv << 1) | (dc ? 1 : 0);
411                         NEXTPHASE();
412                 }
413                 break;
414         case PHASE_RECV_RE_H:
415                 if(stc) {
416                         SET_DK(1);
417                         NEXTPHASE();
418                 }
419                 break;
420         case PHASE_RECV_RE_L:
421                 if(!stc) {
422                         NEXTPHASE();
423                 }
424                 break;
425         case PHASE_RECV_END:
426                 if(stc) {
427                         recv >>= 1;
428                         recv = ~recv & 0x1f;
429                         process(recv);
430                         phase = PHASE_IDLE;
431                 }
432                 break;
433         }
434         
435         // timeout
436         if(phase != PHASE_IDLE && !(timeout > 0)) {
437                 SET_DK(1);
438                 SET_SRK(1);
439                 phase = PHASE_IDLE;
440         }
441 }
442
443 void KEYBOARD::process(int cmd)
444 {
445         int mx, my, mb;
446         
447         switch(cmd) {
448         case 1:
449                 // mouse ???
450                 mx = mouse_stat[0]; mx = (mx > 126) ? 126 : (mx < -128) ? -128 : mx;
451                 my = mouse_stat[1]; my = (my > 126) ? 126 : (my < -128) ? -128 : my;
452                 mb = mouse_stat[2];
453 //              rsp_buf->clear();
454                 rsp_buf->write(0x140 | (mx & 0x3f));
455                 rsp_buf->write(0x140 | (my & 0x3f));
456                 rsp_buf->write(0x140 | ((my >> 2) & 0x30) | ((mx >> 4) & 0xc) | (mb & 3));
457                 break;
458         case 25:
459                 // clear buffer ?
460 //              key_buf->clear();
461                 break;
462         case 30:
463                 // version ???
464 //              rsp_buf->write(0x110);
465                 break;
466         }
467 }
468
469 #define STATE_VERSION   1
470
471 bool KEYBOARD::process_state(FILEIO* state_fio, bool loading)
472 {
473         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
474                 return false;
475         }
476         if(!state_fio->StateCheckInt32(this_device_id)) {
477                 return false;
478         }
479         if(!key_buf->process_state((void *)state_fio, loading)) {
480                 return false;
481         }
482         if(!rsp_buf->process_state((void *)state_fio, loading)) {
483                 return false;
484         }
485         state_fio->StateBool(caps);
486         state_fio->StateBool(kana);
487         state_fio->StateBool(graph);
488         state_fio->StateInt32(dk);
489         state_fio->StateInt32(srk);
490         state_fio->StateInt32(dc);
491         state_fio->StateInt32(stc);
492         state_fio->StateInt32(send);
493         state_fio->StateInt32(recv);
494         state_fio->StateInt32(phase);
495         state_fio->StateInt32(timeout);
496         return true;
497 }
498
499 }