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