OSDN Git Service

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