OSDN Git Service

69ae962c592aba7d0359c9b867fb07ed5686691b
[csp-qt/common_source_project-fm7.git] / source / src / vm / tk80bs / keyboard.cpp
1 /*
2         NEC TK-80BS (COMPO BS/80) Emulator 'eTK-80BS'
3         NEC TK-80 Emulator 'eTK-80'
4         NEC TK-85 Emulator 'eTK-85'
5
6         Author : Takeda.Toshiya
7         Date   : 2008.08.26 -
8
9         [ keyboard ]
10 */
11
12 #include "keyboard.h"
13 #include "../i8255.h"
14
15 #if defined(_TK80BS)
16 static const uint8_t matrix[256] = {
17         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,
18         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19         0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,
20         0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x00,0x00,0x00,0x00,0x00,0x00,
21         0x00,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
22         0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x00,0x00,0x00,0x00,0x00,
23         0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2a,0x2b,0x00,0x2d,0x2e,0x2f,
24         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
25         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
26         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
27         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
28         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3a,0x3b,0x2c,0x2d,0x2e,0x2f,
29         0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
30         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0x5c,0x5d,0x5e,0x00,
31         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
32         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
33 };
34
35 static const uint8_t matrix_s[256] = {
36         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,
37         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
38         0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,
39         0x00,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x00,0x00,0x00,0x00,0x00,0x00,
40         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
41         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42 //      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
43         0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2a,0x2b,0x00,0x2d,0x2e,0x2f,
44         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
45         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
46         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
47         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
48         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0x2b,0x3c,0x3d,0x3e,0x3f,
49         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
50         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
51         0x00,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
52         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
53 };
54
55 static const uint8_t matrix_k[256] = {
56         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,
57         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
58         0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,
59         0xdc,0xc7,0xcc,0xb1,0xb3,0xb4,0xb5,0xd4,0xd5,0xd6,0x00,0x00,0x00,0x00,0x00,0x00,
60         0x00,0xc1,0xba,0xbf,0xbc,0xb2,0xca,0xb7,0xb8,0xc6,0xcf,0xc9,0xd8,0xd3,0xd0,0xd7,
61         0xbe,0xc0,0xbd,0xc4,0xb6,0xc5,0xcb,0xc3,0xbb,0xdd,0xc2,0x00,0x00,0x00,0x00,0x00,
62 //      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
63         0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2a,0x2b,0x00,0x2d,0x2e,0x2f,
64         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
65         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
66         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
67         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
68         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb9,0xda,0xc8,0xce,0xd9,0xd2,
69         0xde,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
70         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xb0,0xd1,0xcd,0x00,
71         0x00,0x00,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
72         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
73 };
74
75 static const uint8_t matrix_ks[256] = {
76         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,
77         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
78         0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,
79         0xa6,0x00,0x00,0xa7,0xa9,0xaa,0xab,0xac,0xad,0xae,0x00,0x00,0x00,0x00,0x00,0x00,
80         0x00,0x00,0x00,0x00,0x00,0xa8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
81         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x00,0x00,0x00,0x00,0x00,
82 //      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
83         0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2a,0x2b,0x00,0x2d,0x2e,0x2f,
84         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
85         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
86         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
87         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
88         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa4,0x00,0xa1,0xa5,
89         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
90         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x00,0xa3,0x00,0x00,
91         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
92         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
93 };
94 #endif
95
96 void KEYBOARD::initialize()
97 {
98         key_stat = emu->get_key_buffer();
99 #if defined(_TK80BS)
100         kb_type = 3;
101 #endif
102 }
103
104 void KEYBOARD::reset()
105 {
106 #if defined(_TK80BS)
107         prev_type = prev_brk = prev_kana = 0;
108         kana_lock = false;
109 #endif
110         column = 0xff;
111 }
112
113 void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
114 {
115         // update TK-80 keyboard
116         column = data & mask;
117         update_tk80();
118 }
119
120 void KEYBOARD::key_down(int code)
121 {
122 #if defined(_TK80BS)
123         // get special key
124         bool hit_type = (key_stat[0x1b] && !prev_type); // ESC
125         bool hit_brk = (key_stat[0x13] && !prev_brk);   // PAUSE/BREAK
126         bool hit_kana = (key_stat[0x15] && !prev_kana); // KANA
127         prev_type = key_stat[0x1b];
128         prev_brk = key_stat[0x13];
129         prev_kana = key_stat[0x15];
130         
131         // check keyboard focus
132         if(hit_type) {
133                 // 1 ... TK80BS
134                 // 2 ... TK80
135                 // 3 ... BOTH
136                 if(++kb_type == 4) {
137                         kb_type = 1;
138                 }
139                 if(kb_type == 1){
140                         emu->out_message(_T("BS Full Keyboard"));
141                 } else if(kb_type == 2){
142                         emu->out_message(_T("On-Board Buttons"));
143                 } else if(kb_type == 3){
144                         emu->out_message(_T("Both On-Board Buttons and BS Full Keyboard"));
145                 }
146         }
147         
148         // update TK-80BS keyboard
149         if(kb_type & 1) {
150                 // break
151                 if(hit_brk) {
152                         d_cpu->set_intr_line(true, true, 0);
153                 }
154                 
155                 // kana lock
156                 if(hit_kana) {
157                         kana_lock = !kana_lock;
158                 }
159                 
160                 // send keycode
161                 if(kana_lock) {
162                         if(key_stat[0x10]) {
163                                 code = matrix_ks[code & 0xff];
164                         } else {
165                                 code = matrix_k[code & 0xff];
166                         }
167                 } else {
168                         if(key_stat[0x10]) {
169                                 code = matrix_s[code & 0xff];
170                         } else {
171                                 code = matrix[code & 0xff];
172                         }
173                 }
174                 if(code) {
175                         d_pio_b->write_signal(SIG_I8255_PORT_A, code, 0xff);
176                 }
177         }
178 #endif
179         
180         // update TK-80 keyboard
181         update_tk80();
182 }
183
184 void KEYBOARD::key_up(int code)
185 {
186 #if defined(_TK80BS)
187         prev_type = key_stat[0x1b];
188         prev_brk = key_stat[0x13];
189         prev_kana = key_stat[0x15];
190 #endif
191         
192         // update TK-80 keyboard
193         update_tk80();
194 }
195
196 uint32_t KEYBOARD::get_intr_ack()
197 {
198         // RST 7
199         return 0xff;
200 }
201
202 void KEYBOARD::update_tk80()
203 {
204 /*      [RET] [RUN] [STO] [LOA] [RES]
205         [ C ] [ D ] [ E ] [ F ] [ADR]
206         [ 8 ] [ 9 ] [ A ] [ B ] [RD+]
207         [ 4 ] [ 5 ] [ 6 ] [ 7 ] [RD-]
208         [ 0 ] [ 1 ] [ 2 ] [ 3 ] [WR+]
209 */
210         uint32_t val = 0xff;
211         
212         // keyboard
213 #if defined(_TK80BS)
214         if(kb_type & 2) {
215 #endif
216                 if(!(column & 0x10)) {
217                         if(key_stat[0x30] || key_stat[0x60]) val &= ~0x01;      // 0
218                         if(key_stat[0x31] || key_stat[0x61]) val &= ~0x02;      // 1
219                         if(key_stat[0x32] || key_stat[0x62]) val &= ~0x04;      // 2
220                         if(key_stat[0x33] || key_stat[0x63]) val &= ~0x08;      // 3
221                         if(key_stat[0x34] || key_stat[0x64]) val &= ~0x10;      // 4
222                         if(key_stat[0x35] || key_stat[0x65]) val &= ~0x20;      // 5
223                         if(key_stat[0x36] || key_stat[0x66]) val &= ~0x40;      // 6
224                         if(key_stat[0x37] || key_stat[0x67]) val &= ~0x80;      // 7
225                 }
226                 if(!(column & 0x20)) {
227                         if(key_stat[0x38] || key_stat[0x68]) val &= ~0x01;      // 8
228                         if(key_stat[0x39] || key_stat[0x69]) val &= ~0x02;      // 9
229                         if(key_stat[0x41]                  ) val &= ~0x04;      // A
230                         if(key_stat[0x42]                  ) val &= ~0x08;      // B
231                         if(key_stat[0x43]                  ) val &= ~0x10;      // C
232                         if(key_stat[0x44]                  ) val &= ~0x20;      // D
233                         if(key_stat[0x45]                  ) val &= ~0x40;      // E
234                         if(key_stat[0x46]                  ) val &= ~0x80;      // F
235                 }
236                 if(!(column & 0x40)) {
237                         if(key_stat[0x71]                  ) val &= ~0x01;      // RUN          F2
238                         if(key_stat[0x70]                  ) val &= ~0x02;      // RET          F1
239                         if(key_stat[0x74]                  ) val &= ~0x04;      // ADRS SET     F5
240                         if(key_stat[0x76] || key_stat[0x22]) val &= ~0x08;      // READ DECR    F7 or PgDn
241                         if(key_stat[0x75] || key_stat[0x21]) val &= ~0x10;      // READ INCR    F6 or PgUp
242                         if(key_stat[0x77] || key_stat[0x0d]) val &= ~0x20;      // WRITE INCR   F8 or Enter
243                         if(key_stat[0x72]                  ) val &= ~0x40;      // STORE DATA   F3
244                         if(key_stat[0x73]                  ) val &= ~0x80;      // LOAD DATA    F4
245                 }
246 #if defined(_TK80BS)
247         }
248 #endif
249         
250         // graphical buffons
251         if(!(column & 0x10)) {
252                 if(key_stat[0x80]) val &= ~0x01;        // 0
253                 if(key_stat[0x81]) val &= ~0x02;        // 1
254                 if(key_stat[0x82]) val &= ~0x04;        // 2
255                 if(key_stat[0x83]) val &= ~0x08;        // 3
256                 if(key_stat[0x84]) val &= ~0x10;        // 4
257                 if(key_stat[0x85]) val &= ~0x20;        // 5
258                 if(key_stat[0x86]) val &= ~0x40;        // 6
259                 if(key_stat[0x87]) val &= ~0x80;        // 7
260         }
261         if(!(column & 0x20)) {
262                 if(key_stat[0x88]) val &= ~0x01;        // 8
263                 if(key_stat[0x89]) val &= ~0x02;        // 9
264                 if(key_stat[0x8a]) val &= ~0x04;        // A
265                 if(key_stat[0x8b]) val &= ~0x08;        // B
266                 if(key_stat[0x8c]) val &= ~0x10;        // C
267                 if(key_stat[0x8d]) val &= ~0x20;        // D
268                 if(key_stat[0x8e]) val &= ~0x40;        // E
269                 if(key_stat[0x8f]) val &= ~0x80;        // F
270         }
271         if(!(column & 0x40)) {
272                 if(key_stat[0x99]) val &= ~0x01;        // RUN
273                 if(key_stat[0x98]) val &= ~0x02;        // RET
274                 if(key_stat[0x9c]) val &= ~0x04;        // ADRS SET
275                 if(key_stat[0x9e]) val &= ~0x08;        // READ DECR
276                 if(key_stat[0x9d]) val &= ~0x10;        // READ INCR
277                 if(key_stat[0x9f]) val &= ~0x20;        // WRITE INCR
278                 if(key_stat[0x9a]) val &= ~0x40;        // STORE DATA
279                 if(key_stat[0x9b]) val &= ~0x80;        // LOAD DATA
280         }
281         d_pio_t->write_signal(SIG_I8255_PORT_A, val, 0xff);
282 }
283
284 #define STATE_VERSION   2
285
286 #include "../../statesub.h"
287
288 void KEYBOARD::decl_state()
289 {
290         enter_decl_state(STATE_VERSION);
291
292 #if defined(_TK80BS)
293         DECL_STATE_ENTRY_UINT8(prev_type);
294         DECL_STATE_ENTRY_UINT8(prev_brk);
295         DECL_STATE_ENTRY_UINT8(prev_kana);
296         DECL_STATE_ENTRY_BOOL(kana_lock);
297         DECL_STATE_ENTRY_UINT32(kb_type);
298 #endif
299         DECL_STATE_ENTRY_UINT32(column);
300         
301         leave_decl_state();
302 }
303
304 void KEYBOARD::save_state(FILEIO* state_fio)
305 {
306         if(state_entry != NULL) {
307                 state_entry->save_state(state_fio);
308         }
309 //      state_fio->FputUint32(STATE_VERSION);
310 //      state_fio->FputInt32(this_device_id);
311         
312 //#if defined(_TK80BS)
313 //      state_fio->FputUint8(prev_type);
314 //      state_fio->FputUint8(prev_brk);
315 //      state_fio->FputUint8(prev_kana);
316 //      state_fio->FputBool(kana_lock);
317 //      state_fio->FputUint32(kb_type);
318 //#endif
319 //      state_fio->FputUint32(column);
320 }
321
322 bool KEYBOARD::load_state(FILEIO* state_fio)
323 {
324         bool mb = false;
325         if(state_entry != NULL) {
326                 mb = state_entry->load_state(state_fio);
327         }
328         if(!mb) {
329                 return false;
330         }
331 //      if(state_fio->FgetUint32() != STATE_VERSION) {
332 //              return false;
333 //      }
334 //      if(state_fio->FgetInt32() != this_device_id) {
335 //              return false;
336 //      }
337 //#if defined(_TK80BS)
338 //      prev_type = state_fio->FgetUint8();
339 //      prev_brk = state_fio->FgetUint8();
340 //      prev_kana = state_fio->FgetUint8();
341 //      kana_lock = state_fio->FgetBool();
342 //      kb_type = state_fio->FgetUint32();
343 //#endif
344 //      column = state_fio->FgetUint32();
345         return true;
346 }
347
348 bool KEYBOARD::process_state(FILEIO* state_fio, bool loading)
349 {
350         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
351                 return false;
352         }
353         if(!state_fio->StateCheckInt32(this_device_id)) {
354                 return false;
355         }
356 #if defined(_TK80BS)
357         state_fio->StateUint8(prev_type);
358         state_fio->StateUint8(prev_brk);
359         state_fio->StateUint8(prev_kana);
360         state_fio->StateBool(kana_lock);
361         state_fio->StateUint32(kb_type);
362 #endif
363         state_fio->StateUint32(column);
364         return true;
365 }