OSDN Git Service

6c068eecbb6a0332ec2f30ebac33f671cbdaac62
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / keyboard.cpp
1 /*
2  * Common Source code Project -> VM -> FM-7/77AV -> Keyboard
3  * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
4  * Licence: GPLv2
5  * History : 
6  *  Feb 12, 2015 : Initial 
7  */
8
9 #include "vm.h"
10 #include "emu.h"
11 #include "../../fifo.h"
12 #include "../device.h"
13 #include "fm7_keyboard.h"
14 #include "keyboard_tables.h"
15
16 #if defined(_FM77AV_VARIANTS)
17 #include "../beep.h"
18 #include "fm77av_hidden_message_keyboard.h"
19 #endif
20 enum {
21         ID_KEYBOARD_RXRDY_OK = 1,
22         ID_KEYBOARD_ACK,
23         ID_KEYBOARD_RXRDY_BUSY,
24         ID_KEYBOARD_RTC_COUNTUP,
25         ID_KEYBOARD_INT,
26         ID_KEYBOARD_AUTOREPEAT_FIRST,
27         ID_KEYBOARD_AUTOREPEAT,
28         ID_KEYBOARD_HIDDENMESSAGE_AV,
29         ID_KEYBOARD_HIDDEN_BEEP_ON,
30         ID_KEYBOARD_HIDDEN_BEEP_OFF,
31         ID_KEYBOARD_AUTO_8KEY_START,
32         ID_KEYBOARD_AUTO_8KEY_END,
33         ID_KEYBOARD_AUTO_5KEY_START,
34         ID_KEYBOARD_AUTO_5KEY_END,
35         ID_KEYBOARD_BREAK_ONESHOT,
36 };
37
38 //
39 /*
40  * I/O API (subio)
41  */
42 // 0xd400(SUB) or 0xfd00(MAIN)
43 uint8_t KEYBOARD::get_keycode_high(void)
44 {
45         uint8_t data = 0x00;
46         if((keycode_7 & 0x0100) != 0) data = 0x80;
47         return data;
48 }
49
50 // 0xd401(SUB) or 0xfd01(MAIN)
51 uint8_t KEYBOARD::get_keycode_low(void)
52 {
53         uint8_t data = keycode_7 & 0xff;
54         this->write_signals(&int_line, 0x00000000);
55         return data;
56 }
57
58 // 0xd40d : R
59 void KEYBOARD::turn_on_ins_led(void)
60 {
61         ins_led_status = true;
62 }
63
64 // 0xd40d : W
65 void KEYBOARD::turn_off_ins_led(void)
66 {
67         ins_led_status = false;
68 }
69
70 // UI Handler. 
71 uint16_t KEYBOARD::vk2scancode(uint32_t vk)
72 {
73         uint16_t i;
74         i = 0;
75         if(vk == VK_PAUSE) vk = VK_KANJI; // Workaround some desktop environments for [ESC].
76         do {
77                 if(vk_matrix_106[i] == vk) return i;
78                 i++;
79         } while(vk_matrix_106[i] != 0xffff);
80         return 0x0000;
81 }
82
83 bool KEYBOARD::isModifier(uint8_t sc)
84 {
85         if(((sc >= 0x52) && (sc <= 0x56)) || // CTRL LSHIFT RSHIFT CAPS GRPH
86                 (sc == 0x5a) || (sc == 0x5c)) { // KANA BREAK
87                 return true;
88         }
89         return false;
90 }
91
92 void KEYBOARD::set_modifiers(uint8_t sc, bool flag)
93 {
94         if(sc == 0x52) { // CTRL
95                 ctrl_pressed = flag; 
96         } else if(sc == 0x53) { // LSHIFT
97                 lshift_pressed = flag;
98                 shift_pressed = lshift_pressed | rshift_pressed;
99                 //printf("LSHIFT : %d\n", flag ? 1 : 0);
100         } else if(sc == 0x54) { // RSHIFT
101                 rshift_pressed = flag;
102                 shift_pressed = lshift_pressed | rshift_pressed;
103                 //printf("RSHIFT : %d\n", flag ? 1 : 0);
104         } else if(sc == 0x56) { // GRPH
105                 graph_pressed = flag;
106         } else if(sc == 0x55) { // CAPS
107                 // Toggle on press.
108                 if(flag) {
109                         if(caps_pressed) {
110                                 caps_pressed = false;
111                         } else {
112                                 caps_pressed = true;
113                         }
114                         if(keymode == KEYMODE_STANDARD) caps_led_status = caps_pressed;
115                 }
116         } else if(sc == 0x5a) { // KANA
117                 // Toggle on press.
118                 if(flag) {
119                         if(kana_pressed) {
120                                 kana_pressed = false;
121                         } else {
122                                 kana_pressed = true;
123                         }
124                         if(keymode == KEYMODE_STANDARD) kana_led_status = kana_pressed;
125                 }
126         } else if(sc == 0x5c) { // Break
127                 if(!override_break_key) {
128                         break_pressed = flag;
129                 }
130         }
131 }
132
133 uint16_t KEYBOARD::scan2fmkeycode(uint8_t sc)
134 {
135         const struct key_tbl_t *keyptr = NULL;
136         bool stdkey = false;
137         int i;
138         uint16_t retval;
139         
140         if((sc == 0) || (sc >= 0x67)) return 0xffff;
141         // Set repeat flag(s)
142         if(shift_pressed && ctrl_pressed) {
143                 switch(sc) {
144                         case 0x02: // 1
145                         case 0x42: // 1
146                                 repeat_mode = true;
147                                 return 0xffff;
148                                 break;
149                         case 0x0b: // 0
150                         case 0x46: // 0
151                                 repeat_mode = false;
152                                 return 0xffff;
153                                 break;
154                 }
155         }
156         if(keymode == KEYMODE_STANDARD) {
157                 if(ctrl_pressed) {
158                         if(shift_pressed) {
159                                 keyptr = ctrl_shift_key;
160                         } else {
161                                 keyptr = ctrl_key;
162                         }
163                 } else if(graph_pressed) {
164                         if(shift_pressed) {
165                                 keyptr = graph_shift_key;
166                         } else {
167                                 keyptr = graph_key;
168                         }
169                 } else if(kana_pressed) {
170                         if(shift_pressed) {
171                                 keyptr = kana_shift_key;
172                         } else {
173                                 keyptr = kana_key;
174                         }
175                 } else { // Standard
176                         stdkey = true;
177                         if(shift_pressed) {
178                                 keyptr = standard_shift_key;
179                         } else {
180                                 keyptr = standard_key;
181                         }
182                 }
183         }
184 #if defined(_FM77AV_VARIANTS)
185         else    if(shift_pressed) {
186           // DO super-impose mode:
187           // F7 : PC
188           // F8 : IMPOSE (High brightness)
189           // F9 : IMPOSE (Low brightness)
190           // F10: TV
191         }
192         if(keymode == KEYMODE_SCAN) {
193                 retval = (uint16_t)sc;
194                 return retval;
195         } else if(keymode == KEYMODE_16BETA) { // Will Implement
196                 if(ctrl_pressed) {
197                         if(shift_pressed) {
198                                 keyptr = ctrl_shift_key_16beta;
199                         } else {
200                                 keyptr = ctrl_key_16beta;
201                         }
202                 } else if(graph_pressed) {
203                         if(shift_pressed) {
204                                 keyptr = graph_shift_key_16beta;
205                         } else {
206                                 keyptr = graph_key_16beta;
207                         }
208                 } else if(kana_pressed) {
209                         if(shift_pressed) {
210                                 keyptr = kana_shift_key_16beta;
211                         } else {
212                                 keyptr = kana_key_16beta;
213                         }
214                 } else { // Standard
215                         stdkey = true;
216                         if(shift_pressed) {
217                                 keyptr = standard_shift_key_16beta;
218                         } else {
219                                 keyptr = standard_key_16beta;
220                         }
221                 }
222         }
223 #endif //_FM77AV_VARIANTS       
224         i = 0;
225         retval = 0xffff;
226         if (keyptr == NULL) return 0xffff;
227         do {
228                 if(keyptr[i].phy == (uint16_t)sc) {
229                         retval = keyptr[i].code;
230                         break;
231                 }
232                 i++;
233         } while(keyptr[i].phy != 0xffff);
234         if(keyptr[i].phy == 0xffff) return 0x00;
235         if(stdkey) {
236                 if((retval >= 'A') && (retval <= 'Z')) {
237                         if(caps_pressed) {
238                                 retval += 0x20;
239                         }
240                 } else if((retval >= 'a') && (retval <= 'z')) {
241                         if(caps_pressed) {
242                                 retval -= 0x20;
243                         }
244                 }
245         }
246         return retval;
247 }
248
249 void KEYBOARD::key_up_main(uint8_t bak_scancode)
250 {
251         bool stat_break = break_pressed;
252         older_vk = 0;
253         if(bak_scancode == 0) return;
254         if((event_keyrepeat >= 0) && (repeat_keycode == bak_scancode)) { // Not Break
255                 cancel_event(this, event_keyrepeat);
256                 event_keyrepeat = -1;
257                 repeat_keycode = 0;
258         }
259         if(keymode != KEYMODE_SCAN) {
260                 if(this->isModifier(bak_scancode)) {
261                         set_modifiers(bak_scancode, false);
262                         if(break_pressed != stat_break) { // Break key UP.
263                                 this->write_signals(&break_line, 0x00);
264                         }
265                 }
266                 if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
267                         if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
268                                 switch(bak_scancode) {
269                                         case 0x42: // 1
270                                         case 0x43: // 2
271                                         case 0x44: // 3
272                                         case 0x3f: // 5
273                                         case 0x46: // 0
274                                                 register_event(this,
275                                                                            ID_KEYBOARD_AUTO_8KEY_START,
276                                                                            10.0 * 1000.0, false, NULL);
277                                                 break;
278                                         default:
279                                                 if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
280                                                 break;
281                                 }
282                         } else { // Auto 5
283                                 switch(bak_scancode) {
284                                         case 0x42: // 1
285                                         case 0x43: // 2
286                                         case 0x44: // 3
287                                         case 0x3e: // 4
288                                         case 0x40: // 6
289                                         case 0x3a: // 7
290                                         case 0x3b: // 8
291                                         case 0x3c: // 9
292                                                 register_event(this,
293                                                                            ID_KEYBOARD_AUTO_5KEY_START,
294                                                                            10.0 * 1000.0, false, NULL);
295                                                 break;
296                                         default:
297                                                 if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
298                                                 break;
299                                 }
300                         }                               
301                 }
302         } else {
303                 //scancode = 0;
304                 if(bak_scancode != 0) { // Notify even key-up, when using SCAN mode.
305                         uint8_t code = (bak_scancode & 0x7f) | 0x80;
306                         if(this->isModifier(bak_scancode)) {
307                                 set_modifiers(bak_scancode, false);
308                         }
309 #if defined(_FM77AV_VARIANTS)      
310                         if(bak_scancode != 0x5c) {
311                                 if(beep_phase == 1) {
312                                         if(break_pressed) this->write_signals(&break_line, 0x00);
313                                         break_pressed = false;
314                                         beep_phase++;
315                                         bak_scancode = 0x7f;
316                                         code = 0xff;
317                                 } else if(beep_phase == 2) {
318                                         beep_phase = 0;
319                                         register_event(this,
320                                                                    ID_KEYBOARD_HIDDEN_BEEP_ON,
321                                                                    100.0, false, NULL); // 100.0 us is dummy.
322                                         bak_scancode = 0x7f;
323                                         code = 0xff;
324                                 }
325                         } else { // 0x5c : BREAK is up.
326                                 beep_phase = 0;
327                                 if(stat_break) this->write_signals(&break_line, 0x00);
328                         }
329 #endif             
330                         if(code != 0x80) {
331                                 key_fifo->write(code);
332                                 scancode = bak_scancode;
333                         }
334                 }
335         }
336 }
337
338 void KEYBOARD::key_up(uint32_t vk)
339 {
340         uint8_t bak_scancode = (uint8_t)(vk2scancode(vk) & 0x00ff);
341         key_up_main(bak_scancode);
342 }
343
344 void KEYBOARD::key_down(uint32_t vk)
345 {
346         if(older_vk == vk) return;
347         older_vk = vk;
348         
349         scancode = (uint8_t)vk2scancode(vk);
350 #if defined(_FM77AV_VARIANTS)
351         // Below are FM-77AV's hidden message , see :
352         // https://twitter.com/maruan/status/499558392092831745
353         //if(caps_pressed && kana_pressed) {
354         //      if(ctrl_pressed && lshift_pressed && rshift_pressed && graph_pressed) {
355         if(caps_pressed && kana_pressed && graph_pressed && shift_pressed && ctrl_pressed && !did_hidden_message_av_1) { // IT's deprecated key pressing
356                 if(scancode == 0x15) { // "T"
357                         if(event_hidden1_av < 0) {
358                                 hidden1_ptr = 0;
359                                 did_hidden_message_av_1 = true;
360                                 register_event(this,
361                                                 ID_KEYBOARD_HIDDENMESSAGE_AV,
362                                                 130.0 * 1000, true, &event_hidden1_av);
363                         }
364                         return;
365                 }
366         }
367 #endif 
368         key_down_main(true);
369 }
370
371 void KEYBOARD::key_down_main(bool repeat_auto_key)
372 {
373         bool stat_break = break_pressed;
374         uint32_t code;
375         if(scancode == 0) return;
376         if(keymode == KEYMODE_SCAN) {
377                 code = scancode & 0x7f;
378                 if(this->isModifier(scancode)) {  // modifiers
379                         set_modifiers(scancode, true);
380                 }
381 #if defined(_FM77AV_VARIANTS)
382                 if(break_pressed) {
383                         if(!stat_break) {
384                                 beep_phase = 1;
385                                 // It's dirty hack for AMNORK ; Set dead zone for FIRQ to 0.25sec.
386                                 // I wish to replace this solution to more simple. 
387                                 register_event(this,
388                                                            ID_KEYBOARD_BREAK_ONESHOT,
389                                                            250.0 * 1000.0, false, NULL);
390                         } else if(beep_phase == 1) {
391                                 if(code != 0x5c) {
392                                         if(break_pressed) this->write_signals(&break_line, 0x00);
393                                         break_pressed = false;
394                                         beep_phase++;
395                                         code = 0x7f; // Special
396                                         scancode = 0x7f;        
397                                 }
398                         }
399                 }
400 #endif
401
402                 if(code != 0) {
403                         key_fifo->write(code);
404                         // NOTE: With scan key code mode, auto repeat seems to be not effectable.
405                         // See : http://hanabi.2ch.net/test/read.cgi/i4004/1430836648/607
406                         // 20160409 K.Ohta
407                 }
408         } else {
409                 if(this->isModifier(scancode)) {  // modifiers
410                         set_modifiers(scancode, true);
411                         if(break_pressed != stat_break) { // Break key Down.
412                                 this->write_signals(&break_line, 0xff);
413                         }
414                         return;
415                 }
416                 code = scan2fmkeycode(scancode);
417                 if((code > 0x3ff) || (code == 0)) return;
418                 if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
419                         if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
420                                 switch(scancode) {
421                                         case 0x42: // 1
422                                         case 0x43: // 2
423                                         case 0x44: // 3
424                                         case 0x3f: // 5
425                                         case 0x46: // 0
426                                                 autokey_backup = scancode;
427                                                 break;
428                                 }
429                         } else { // Auto 5
430                                 switch(scancode) {
431                                         case 0x42: // 1
432                                         case 0x43: // 2
433                                         case 0x44: // 3
434                                         case 0x3e: // 4
435                                         case 0x40: // 6
436                                         case 0x3a: // 7
437                                         case 0x3b: // 8
438                                         case 0x3c: // 9
439                                                 autokey_backup = scancode;
440                                                 break;
441                                 }
442                         }                               
443                 } else {
444                         autokey_backup = 0x00;
445                 }
446                 if(code != 0) {
447                         key_fifo->write(code);
448                         if((scancode < 0x5c) && repeat_auto_key) {
449                                 double usec = (double)repeat_time_long * 1000.0;
450                                 if((repeat_keycode == 0) && repeat_mode) {
451                                         if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
452                                         event_keyrepeat = -1;
453                                         register_event(this,
454                                                                    ID_KEYBOARD_AUTOREPEAT_FIRST,
455                                                                    usec, false, &event_keyrepeat);
456                                 }
457                                 repeat_keycode = scancode;
458                         }
459                 }
460         }
461 }
462
463 #if defined(_FM77AV_VARIANTS)
464 void KEYBOARD::adjust_rtc(void)
465 {
466         get_host_time(&cur_time);
467         rtc_yy = cur_time.year % 100;
468         rtc_mm = cur_time.month;
469         rtc_dd = cur_time.day;
470
471         rtc_dayofweek = cur_time.day_of_week;
472         if(rtc_count24h) {
473                 rtc_ispm = (cur_time.hour >= 12) ? true : false;
474                 rtc_hour = cur_time.hour % 12;
475         } else {
476                 rtc_ispm = false;
477                 rtc_hour = cur_time.hour;
478         }
479         rtc_minute = cur_time.minute;
480         rtc_sec = cur_time.second;
481         if(event_key_rtc >= 0) {
482                 cancel_event(this, event_key_rtc);
483         }
484         register_event(this, ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
485 }
486 #endif
487
488 void KEYBOARD::do_repeatkey(uint8_t sc)
489 {
490         uint16_t code;
491         if((sc == 0) || (sc >= 0x5c)) return; // scancode overrun.
492         if(!repeat_mode) {
493                 if(event_keyrepeat >= 0) {
494                         cancel_event(this, event_keyrepeat);
495                         event_keyrepeat = -1;
496                 }
497                 return;
498         }
499         if(keymode == KEYMODE_SCAN) {
500                 code = (uint16_t)(sc & 0x7f);
501                 key_fifo->write((uint32_t)code); // Make
502                 //key_fifo->write((uint32_t)(code | 0x80)); // Break
503         } else {
504                 code = scan2fmkeycode(sc);
505                 if(code < 0x400) {
506                         key_fifo->write((uint32_t)code);
507                 }
508         }
509 }
510
511 void KEYBOARD::event_callback(int event_id, int err)
512 {
513 #if defined(_FM77AV_VARIANTS)
514         if(event_id == ID_KEYBOARD_RXRDY_OK) {
515                 rxrdy_status = true;
516                 write_signals(&rxrdy, 0xff);
517         } else if(event_id == ID_KEYBOARD_RXRDY_BUSY) {
518                 rxrdy_status = false;
519                 write_signals(&rxrdy, 0x00);
520         } else if(event_id == ID_KEYBOARD_ACK) {
521                 key_ack_status = true;
522                 write_signals(&key_ack, 0xff);
523         } else if(event_id == ID_KEYBOARD_RTC_COUNTUP) {
524                 rtc_count();
525         } else if(event_id == ID_KEYBOARD_HIDDENMESSAGE_AV) {
526                 if(hidden_message_77av_1[hidden1_ptr] == 0x00) {
527                         cancel_event(this, event_hidden1_av);
528                         event_hidden1_av = -1;
529                         hidden1_ptr = 0;
530                 } else {
531                         key_fifo->write(hidden_message_77av_1[hidden1_ptr++]);
532                 }
533                 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
534                 beep->write_signal(SIG_BEEP_ON, 1, 1);
535                 register_event(this,
536                        ID_KEYBOARD_HIDDEN_BEEP_OFF,
537                        25.0 * 1000.0, false, NULL);
538         } else  if(event_id == ID_KEYBOARD_HIDDEN_BEEP_ON) {
539                 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
540                 beep->write_signal(SIG_BEEP_ON, 1, 1);
541                 register_event(this,
542                        ID_KEYBOARD_HIDDEN_BEEP_OFF,
543                        25.0 * 1000.0, false, NULL);
544
545         } else  if(event_id == ID_KEYBOARD_HIDDEN_BEEP_OFF) {
546                 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
547                 beep->write_signal(SIG_BEEP_ON, 0, 1);
548         } else if(event_id == ID_KEYBOARD_BREAK_ONESHOT) {
549                 if(break_pressed) this->write_signals(&break_line, 0xff);
550         } else
551 #endif
552         if(event_id == ID_KEYBOARD_AUTOREPEAT_FIRST) {
553                 double usec = (double)repeat_time_short * 1000.0;
554
555                 do_repeatkey(repeat_keycode);
556                 register_event(this,
557                                ID_KEYBOARD_AUTOREPEAT,
558                                usec, true, &event_keyrepeat);
559                 // Key repeat.
560         } else if(event_id == ID_KEYBOARD_AUTOREPEAT){
561                 if(repeat_keycode != 0) {
562                         do_repeatkey(repeat_keycode);
563                 } else {
564                         cancel_event(this, event_keyrepeat);
565                         event_keyrepeat = -1;
566                 }
567         } else if(event_id == ID_KEYBOARD_INT) {
568                 if(!(key_fifo->empty())) {
569                         keycode_7 = key_fifo->read();
570                         this->write_signals(&int_line, 0xffffffff);
571                 }
572         } else if(event_id == ID_KEYBOARD_AUTO_8KEY_START) {
573                 if(keymode != KEYMODE_SCAN) {
574                         scancode = 0x3b; // 8
575                         autokey_backup = 0x00;
576                         key_down_main(false);
577                         register_event(this,
578                                                    ID_KEYBOARD_AUTO_8KEY_END,
579                                                    50.0 * 1000.0, false, NULL);
580                 }
581         } else if(event_id == ID_KEYBOARD_AUTO_8KEY_END) {
582                 key_up_main(0x3b); // 8
583         } else if(event_id == ID_KEYBOARD_AUTO_5KEY_START) {
584                 if(keymode != KEYMODE_SCAN) {
585                         scancode = 0x3f; // 5
586                         autokey_backup = 0x00;
587                         key_down_main(false);
588                         register_event(this,
589                                                    ID_KEYBOARD_AUTO_5KEY_END,
590                                                    50.0 * 1000.0, false, NULL);
591                 }
592         } else if(event_id == ID_KEYBOARD_AUTO_5KEY_END) {
593                 key_up_main(0x3f); // 5
594         }
595 }
596
597 // Commands
598 void KEYBOARD::reset_unchange_mode(void)
599 {
600         repeat_time_short = 70; // mS
601         repeat_time_long = 700; // mS
602         repeat_mode = true;
603         older_vk = 0;
604
605         lshift_pressed = false;
606         rshift_pressed = false;
607         shift_pressed = false;
608         ctrl_pressed   = false;
609         graph_pressed = false;
610         kana_pressed = false;
611         caps_pressed = false;
612         ins_led_status = false;
613         kana_led_status = false;
614         caps_led_status = false;
615         datareg = 0x00;
616         repeat_keycode = 0x00;
617         autokey_backup = 0x00;
618
619         if(override_break_key) write_signals(&break_line, (break_pressed) ? 0xff : 0);
620         key_fifo->clear();
621 #if defined(_FM77AV_VARIANTS)
622         cmd_fifo->clear();
623         data_fifo->clear();
624         if(event_key_rtc >= 0) {
625                 cancel_event(this, event_key_rtc);
626         }
627         register_event(this,ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
628
629         cmd_phase = 0;
630         if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
631         event_keyrepeat = -1;
632    
633         if(event_hidden1_av >= 0) cancel_event(this, event_hidden1_av);
634         event_hidden1_av = -1;
635         hidden1_ptr = 0;
636 #endif
637         // Bus
638         this->write_signals(&break_line, 0x00);
639 #if defined(_FM77AV_VARIANTS)
640         rxrdy_status = false;
641         key_ack_status = true;
642         this->write_signals(&rxrdy, 0x00);                
643         this->write_signals(&key_ack, 0xff);              
644 #endif
645 }
646
647
648 void KEYBOARD::reset(void)
649 {
650         keymode = KEYMODE_STANDARD;
651         scancode = 0x00;
652
653         keycode_7 = 0xffffffff; 
654         //keycode_7 = 0; 
655         reset_unchange_mode();
656         this->write_signals(&int_line, 0x00000000);
657
658 #if defined(_FM77AV_VARIANTS)  
659         adjust_rtc();
660         did_hidden_message_av_1 = false;
661         beep_phase = 0;
662 #endif
663
664         if(override_break_key) write_signals(&break_line, (break_pressed) ? 0xff : 0);
665
666         if(event_int >= 0) cancel_event(this, event_int);
667         register_event(this,
668                                    ID_KEYBOARD_INT,
669                                    20000.0, true, &event_int);
670 }
671
672
673 #if defined(_FM77AV_VARIANTS)  
674 // 0xd431 : Read
675 uint8_t KEYBOARD::read_data_reg(void)
676 {
677         if(!data_fifo->empty()) {
678                 datareg = data_fifo->read() & 0xff;
679         }
680         if(!data_fifo->empty()) {
681                 rxrdy_status = true;
682                 write_signals(&rxrdy, 0xff);
683         } else {
684                 rxrdy_status = false;
685                 write_signals(&rxrdy, 0x00);
686         }
687         return datareg;
688 }
689
690 // 0xd432
691 uint8_t KEYBOARD::read_stat_reg(void)
692 {
693         uint8_t data = 0xff;
694         if(rxrdy_status) {
695                 data &= 0x7f;
696         }
697         if(!key_ack_status) {
698                 data &= 0xfe;
699         }
700         // Digityze : bit0 = '0' when waiting,
701         return data;
702 }
703
704 void KEYBOARD::set_mode(void)
705 {
706         int count = cmd_fifo->count();
707         int cmd;
708         int mode;
709         if(count < 2) return;
710         cmd = cmd_fifo->read();
711         mode = cmd_fifo->read();
712         if(mode <= KEYMODE_SCAN) {
713                 keymode = mode;
714                 //printf("Keymode : %d\n", keymode);
715                 //reset_unchange_mode();
716                 beep_phase = 0;
717                 autokey_backup = 0x00;
718                 this->write_signals(&break_line, 0x00);
719                 if(scancode != 0) key_down_main(true); 
720         }
721         cmd_fifo->clear();
722         data_fifo->clear(); // right?
723         rxrdy_status = false;
724         write_signals(&rxrdy, 0x00);
725 }
726
727 void KEYBOARD::get_mode(void)
728 {
729         int cmd;
730         int dummy;
731         cmd = cmd_fifo->read();
732         if(data_fifo->full()) {
733                 dummy = data_fifo->read();
734         }
735         data_fifo->write(keymode);
736         rxrdy_status = true;
737         write_signals(&rxrdy, 0xff);
738 }
739
740 void KEYBOARD::set_leds(void)
741 {
742         int count = cmd_fifo->count();
743         int cmd;
744         int ledvar;
745         if(count < 2) return;
746         cmd = cmd_fifo->read();
747         ledvar = cmd_fifo->read();
748         if(ledvar < 4) {
749                 if((ledvar & 0x02) != 0) {
750                         // Kana
751                         kana_pressed = ((ledvar & 0x01) == 0);
752                         kana_led_status = kana_pressed;
753                 } else {
754                         // Caps
755                         caps_pressed = ((ledvar & 0x01) == 0);
756                         caps_led_status = caps_pressed;
757                 }
758         }
759         cmd_fifo->clear();
760         data_fifo->clear(); // right?
761         rxrdy_status = false;
762         write_signals(&rxrdy, 0x00);
763 }
764
765 void KEYBOARD::get_leds(void)
766 {
767         uint8_t ledvar = 0x00;
768         data_fifo->clear();
769         ledvar |= caps_pressed ? 0x01 : 0x00;
770         ledvar |= kana_pressed ? 0x02 : 0x00;
771         data_fifo->write(ledvar);
772         cmd_fifo->clear();
773         rxrdy_status = true;
774         write_signals(&rxrdy, 0xff);
775 }
776
777 void KEYBOARD::set_repeat_type(void)
778 {
779         int cmd;
780         int modeval;
781
782         cmd = cmd_fifo->read();
783         if(!cmd_fifo->empty()) {
784                 modeval = cmd_fifo->read();
785                 if((modeval < 2) && (modeval >= 0)) {
786                         repeat_mode = (modeval == 0);
787                         if(repeat_mode) {
788                                 //scancode = 0x00;
789                                 //keycode_7 = 0x00;
790                                 key_fifo->clear();
791                         }
792                 }
793         }
794         data_fifo->clear();
795         cmd_fifo->clear();
796         rxrdy_status = false;
797         write_signals(&rxrdy, 0x00);
798 }
799
800 void KEYBOARD::set_repeat_time(void)
801 {
802         int cmd;
803         uint32_t time_high = 0;
804         uint32_t time_low = 0;
805         cmd = cmd_fifo->read();
806         if(cmd_fifo->empty()) goto _end;
807         time_high = cmd_fifo->read();
808         if(cmd_fifo->empty()) goto _end;
809         time_low = cmd_fifo->read();
810 _end:
811         if((time_high == 0) || (time_low == 0)) {
812                 repeat_time_long = 700;
813                 repeat_time_short = 70;
814         } else {
815                 repeat_time_long = (int)time_high * 10;
816                 repeat_time_short = (int)time_low * 10;
817         }
818         data_fifo->clear();
819         cmd_fifo->clear();
820         rxrdy_status = false;
821         write_signals(&rxrdy, 0x00);
822 }
823
824 void KEYBOARD::set_rtc(void)
825 {
826         int cmd;
827         int tmp;
828         int localcmd;
829         if(cmd_fifo->count() < 9) return;
830         cmd = cmd_fifo->read();
831         localcmd = cmd_fifo->read();
832         // YY
833         tmp = cmd_fifo->read();
834         rtc_yy = ((tmp >> 4) * 10) | (tmp & 0x0f);
835         // MM
836         tmp = cmd_fifo->read();
837         rtc_mm = ((tmp >> 4) * 10) | (tmp & 0x0f);
838         // DD
839         tmp = cmd_fifo->read();
840         rtc_dd = (((tmp & 0x30) >> 4) * 10) | (tmp & 0x0f);
841         // DayOfWeek + Hour
842         tmp = cmd_fifo->read();
843         rtc_count24h = ((tmp & 0x08) != 0);
844         if(!rtc_count24h) {
845                 rtc_ispm = ((tmp & 0x04) != 0);
846         }
847         rtc_dayofweek = (tmp >> 4) % 0x07;
848         rtc_hour = ((tmp & 0x03) * 10);
849         // Low
850         tmp = cmd_fifo->read();
851         rtc_hour = rtc_hour | (tmp >> 4);
852         if(rtc_count24h) {
853           rtc_ispm = (rtc_hour >= 12);
854         }
855         rtc_minute = (tmp & 0x0f) * 10;
856         
857         tmp = cmd_fifo->read();
858         rtc_minute = rtc_minute | (tmp >> 4);
859         rtc_sec = (tmp & 0x0f) * 10;
860         
861         tmp = cmd_fifo->read();
862         rtc_sec = rtc_sec | (tmp >> 4);
863         
864         data_fifo->clear();
865         cmd_fifo->clear();
866         if(event_key_rtc >= 0) {
867                 cancel_event(this, event_key_rtc);
868         }
869         register_event(this, ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
870         rxrdy_status = false;
871         write_signals(&rxrdy, 0x00);
872 }
873
874 void KEYBOARD::get_rtc(void)
875 {
876         int tmp;
877         data_fifo->clear();
878         // YY
879         tmp = ((rtc_yy / 10) << 4) | (rtc_yy % 10);
880         data_fifo->write(tmp);
881         // MM
882         tmp = ((rtc_mm / 10) << 4) | (rtc_mm % 10);
883         data_fifo->write(tmp);
884         // DD
885         tmp = ((rtc_dd / 10) << 4) | (rtc_dd % 10);
886         tmp = tmp | (0 << 6); // leap
887         data_fifo->write(tmp);
888         // DayOfWeek + Hour
889         tmp = rtc_dayofweek << 4;
890         tmp = tmp | (rtc_hour / 10);
891         if(rtc_count24h) {
892           tmp = tmp | 0x08;
893         } else {
894           if(rtc_ispm) {
895             tmp = tmp | 0x04;
896           }
897         }
898         data_fifo->write(tmp);
899         // Low
900         tmp = (rtc_hour % 10) << 4;
901         tmp = tmp | (rtc_minute / 10);
902         data_fifo->write(tmp);
903         
904         tmp = (rtc_minute % 10) << 4;
905         tmp = tmp | (rtc_sec / 10);
906         data_fifo->write(tmp);
907         
908         tmp = (rtc_sec % 10) << 4;
909         data_fifo->write(tmp);
910         
911         cmd_fifo->clear();
912         rxrdy_status = true;
913         write_signals(&rxrdy, 0xff);
914 }
915
916 const int rtc_month_days[12] = {
917         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
918 };
919
920 void KEYBOARD::rtc_count(void)
921 {
922         // count per 1sec
923         rtc_sec++;
924         if(rtc_sec >= 60) {
925                 rtc_sec = 0;
926                 rtc_minute++;
927                 if(rtc_minute >= 60) {
928                         rtc_minute = 0;
929                         rtc_hour++;
930                         if(rtc_count24h) {
931                                 rtc_ispm = (rtc_hour >= 12);
932                                 if(rtc_hour < 24) return;
933                         } else {
934                                 if(rtc_ispm) {
935                                         if(rtc_hour < 12) return;
936                                 } else {
937                                         if(rtc_hour < 12) return;
938                                         rtc_ispm = true;
939                                         rtc_hour = 0;
940                                         return;
941                                 }
942                         }
943                         // Day count up
944                         rtc_hour = 0;
945                         rtc_dd++;
946                         rtc_dayofweek++;
947                         if(rtc_dayofweek >= 7) rtc_dayofweek = 0;
948                         if(rtc_dd > rtc_month_days[rtc_mm]){
949                                 if((rtc_mm ==1) && (rtc_dd == 29)) {
950                                         if((rtc_yy % 4) == 0) return;
951                                 }
952                                 rtc_dd = 1;
953                                 rtc_mm++;
954                                 if(rtc_mm >= 12) {
955                                         rtc_yy++;
956                                         rtc_mm = 0;
957                                         if(rtc_yy >= 100) rtc_yy = 0;
958                                 }
959                         }
960                 }
961         }
962 }
963 #endif // FM77AV_VARIANTS
964
965 uint32_t KEYBOARD::read_signal(int id)
966 {
967         if(id == SIG_FM7KEY_BREAK_KEY) {
968                 return break_pressed ? 0xfffffff : 0x00000000;
969         } else if(id == SIG_FM7KEY_LED_STATUS) {
970                 uint32_t _l;
971                 _l  = (ins_led_status) ? 0x00000001 : 0;
972                 _l |= (kana_led_status) ? 0x00000002 : 0;
973                 _l |= (caps_led_status) ? 0x00000004 : 0;
974                 return _l;
975         }
976         return 0;
977 }
978
979
980 void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
981 {
982         if(id == SIG_FM7KEY_SET_INSLED) {
983                 ins_led_status = ((data & mask) != 0);
984         } else if(id == SIG_FM7KEY_OVERRIDE_PRESS_BREAK) {
985                 override_break_key = ((data & mask) != 0);
986         }
987 #if defined(_FM77AV_VARIANTS)  
988          else if(id == SIG_FM7KEY_PUSH_TO_ENCODER) {
989                 /*
990                  * I refered XM7's sourcecode : VM/keyboard.c act of key-encoder.
991                  * Thanks to Ryu.Takegami and PI.
992                  */
993                 int count;
994                 if(!key_ack_status) return; // If (not(ACK)) noop.
995
996                 if(cmd_fifo->full()) {
997                         cmd_fifo->clear();
998                 }
999                 if(cmd_fifo->empty()) {
1000                         cmd_phase = data & 0xff;
1001                 }
1002                 
1003                 cmd_fifo->write(data & 0xff);
1004                 count = cmd_fifo->count();
1005                 
1006                 rxrdy_status = false;
1007                 key_ack_status = false;
1008                 write_signals(&key_ack, 0x00);
1009                 write_signals(&rxrdy, 0x00);
1010             
1011                 switch(cmd_phase) {
1012                         case 0: // Set mode
1013                                 if(count >= 2) {
1014                                         set_mode();
1015                                         if(keymode == KEYMODE_SCAN) key_down_main(true);
1016                                         cmd_phase = -1;
1017                                         cmd_fifo->clear();
1018                                 }
1019                                 break;
1020                         case 1: // Get mode
1021                                 get_mode();
1022                                 cmd_fifo->clear();
1023                                 cmd_phase = -1;
1024                                 break;
1025                         case 2: // Set LED Phase
1026                                 if(count >= 2) {
1027                                         set_leds();
1028                                         if(keymode == KEYMODE_SCAN) key_down_main(true);
1029                                         cmd_phase = -1;
1030                                         cmd_fifo->clear();
1031                                 }
1032                                 break;
1033                         case 3: // Get LED Phase
1034                                 get_leds();
1035                                 cmd_phase = -1;
1036                                 cmd_fifo->clear();
1037                                 break;
1038                         case 4:
1039                                 if(count >= 2) {
1040                                         set_repeat_type();
1041                                         cmd_phase = -1;
1042                                         cmd_fifo->clear();
1043                                 }
1044                                 break;
1045                         case 5:
1046                                 if(count >= 3) {
1047                                         set_repeat_time();
1048                                         cmd_phase = -1;
1049                                         cmd_fifo->clear();
1050                                 }
1051                                 break;
1052                         case 0x80: // Communicate to/from RTC.
1053                                 if(count == 1) {
1054                                         rtc_set = false;
1055                                 }
1056                                 if(count == 2) {
1057                                         if((data & 0xff) == 0) { // Get
1058                                                 get_rtc();
1059                                                 cmd_phase = -1;
1060                                                 cmd_fifo->clear();
1061                                         } else if((data & 0xff) == 1) { // Set
1062                                                 rtc_set_flag = true;
1063                                         } else { // Illegal
1064                                                 cmd_fifo->clear();
1065                                                 cmd_phase = -1;
1066                                         }
1067                                 }
1068                                 if(rtc_set_flag) {
1069                                         if(count >= 9) {
1070                                                 set_rtc();
1071                                                 cmd_fifo->clear();
1072                                                 cmd_phase = -1;
1073                                         }
1074                                 }
1075                                 break;
1076                         case 0x81: // Digitize.
1077                                 if(count >= 2) {
1078                                         do_digitize(); // WILL Implement?
1079                                         cmd_fifo->clear();
1080                                         cmd_phase = -1;
1081                                 }
1082                                 break;
1083                         case 0x82:
1084                                 if(count >= 2) {
1085                                         set_screen_mode(); // WILL Implement?
1086                                         cmd_fifo->clear();
1087                                         cmd_phase = -1;
1088                                 }
1089                                 break;
1090                         case 0x83:
1091                                 get_screen_mode(); // WILL Implement?
1092                                 cmd_fifo->clear();
1093                                 cmd_phase = -1;
1094                                 break;
1095                         case 0x84:
1096                                 if(count >= 2) {
1097                                         set_brightness(); // WILL Implement?
1098                                         cmd_fifo->clear();
1099                                         cmd_phase = -1;
1100                                 }
1101                                 break;
1102                         default:
1103                                 cmd_fifo->clear();
1104                                 cmd_phase = -1;
1105                                 break;
1106                 }
1107                 register_event(this, ID_KEYBOARD_ACK, 5, false, NULL); // Delay 5us until ACK is up.
1108         } else if(id == SIG_FM7KEY_RXRDY) {
1109                 rxrdy_status = ((data & mask) != 0);
1110                 //write_signals(&rxrdy, (rxrdy_status) ? 0xffffffff : 0x00000000);
1111         } else if(id == SIG_FM7KEY_ACK) {
1112                 key_ack_status = ((data & mask) != 0);
1113                 //write_signals(&key_ack, (key_ack_status) ? 0xffffffff : 0x00000000);
1114         }
1115
1116 #endif
1117 }
1118
1119 uint32_t KEYBOARD::read_data8(uint32_t addr)
1120 {
1121         uint32_t retval = 0xff;
1122         switch(addr) {
1123                 case 0x00:
1124                         retval = get_keycode_high();
1125                         break;
1126                 case 0x01:
1127                         retval = get_keycode_low();
1128                         break;
1129 #if defined(_FM77AV_VARIANTS)                   
1130                 case 0x31:
1131                         retval = read_data_reg();
1132                         break;
1133                 case 0x32:
1134                         retval = read_stat_reg();
1135                         break;
1136 #endif
1137                 default:
1138                         break;
1139         }
1140         return retval;
1141 }
1142
1143 void KEYBOARD::write_data8(uint32_t addr, uint32_t data)
1144 {
1145         switch(addr) {
1146 #if defined(_FM77AV_VARIANTS)                   
1147                 case 0x31:
1148                         this->write_signal(SIG_FM7KEY_PUSH_TO_ENCODER, data, 0x000000ff);
1149                         break;
1150 #endif
1151         }
1152 }
1153
1154 KEYBOARD::KEYBOARD(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
1155 {
1156 #if defined(_FM77AV_VARIANTS)
1157         beep = NULL;
1158 #endif  
1159         keycode_7 = 0xffffffff;
1160    
1161         ctrl_pressed = false; 
1162         lshift_pressed = false; 
1163         rshift_pressed = false; 
1164         shift_pressed = false; 
1165         graph_pressed = false;
1166         caps_pressed = false;
1167         kana_pressed = false;
1168         break_pressed = false;
1169         event_keyrepeat = -1;
1170         autokey_backup = 0x00;
1171
1172         keymode = KEYMODE_STANDARD;
1173         override_break_key = false;
1174 #if defined(_FM77AV_VARIANTS)
1175         cmd_fifo = new FIFO(16);
1176         data_fifo = new FIFO(16);
1177         rxrdy_status = true;
1178         key_ack_status = false;
1179         initialize_output_signals(&rxrdy);
1180         initialize_output_signals(&key_ack);
1181         
1182         rtc_count24h = false;
1183         rtc_dayofweek = 0;
1184         rtc_ispm = false;
1185         rtc_set = false;
1186         rtc_set_flag = false;
1187         rtc_yy = 0;
1188         rtc_mm = 0;
1189         rtc_dd = 0;
1190         rtc_hour = 0;
1191         rtc_minute = 0;
1192         rtc_sec = 0;
1193         event_key_rtc = -1;
1194         event_hidden1_av = -1;
1195         hidden1_ptr = 0;
1196 #endif
1197         key_fifo = new FIFO(512);
1198         event_int = -1;
1199         
1200         initialize_output_signals(&break_line);
1201         initialize_output_signals(&int_line);
1202         
1203         ins_led_status = false;
1204         kana_led_status = false;
1205         caps_led_status = false;
1206         set_device_name(_T("KEYBOARD SUBSYSTEM"));
1207 }
1208
1209 void KEYBOARD::release(void)
1210 {
1211 #if defined(_FM77AV_VARIANTS)
1212         cmd_fifo->release();
1213         data_fifo->release();
1214         delete cmd_fifo;
1215         delete data_fifo;
1216 #endif   
1217         key_fifo->release();
1218         delete key_fifo;
1219 }
1220
1221
1222
1223 KEYBOARD::~KEYBOARD()
1224 {
1225 }
1226
1227 #define STATE_VERSION 8
1228 //#if defined(Q_OS_WIN)
1229 //DLL_PREFIX_I struct cur_time_s cur_time;
1230 //#endif
1231
1232 #include "../../statesub.h"
1233
1234 void KEYBOARD::decl_state()
1235 {
1236 #if defined(_FM77AV_VARIANTS)
1237         enter_decl_state(STATE_VERSION, _T("KEYBOARD_AND_RTC"));
1238 #else
1239         enter_decl_state(STATE_VERSION, _T("KEYBOARD"));
1240 #endif
1241         
1242         DECL_STATE_ENTRY_UINT32(keycode_7);
1243         DECL_STATE_ENTRY_INT32(keymode);
1244            
1245         DECL_STATE_ENTRY_BOOL(ctrl_pressed);
1246         DECL_STATE_ENTRY_BOOL(lshift_pressed);
1247         DECL_STATE_ENTRY_BOOL(rshift_pressed);
1248         DECL_STATE_ENTRY_BOOL(shift_pressed);
1249         DECL_STATE_ENTRY_BOOL(graph_pressed);
1250         DECL_STATE_ENTRY_BOOL(caps_pressed);
1251         DECL_STATE_ENTRY_BOOL(kana_pressed);
1252         DECL_STATE_ENTRY_BOOL(break_pressed);
1253
1254         DECL_STATE_ENTRY_INT32(event_keyrepeat);
1255            
1256         DECL_STATE_ENTRY_UINT8(scancode); // After V.4, uint8_t
1257         DECL_STATE_ENTRY_UINT8(datareg);
1258         DECL_STATE_ENTRY_UINT32(older_vk);
1259            
1260         DECL_STATE_ENTRY_BOOL(repeat_mode);
1261         DECL_STATE_ENTRY_INT32(repeat_time_short);
1262         DECL_STATE_ENTRY_INT32(repeat_time_long);
1263         DECL_STATE_ENTRY_UINT8(repeat_keycode);
1264            
1265 #if defined(_FM77AV_VARIANTS)
1266         DECL_STATE_ENTRY_INT32(event_key_rtc);
1267   
1268         DECL_STATE_ENTRY_UINT8(rtc_yy);
1269         DECL_STATE_ENTRY_UINT8(rtc_mm);
1270         DECL_STATE_ENTRY_UINT8(rtc_dd);
1271         DECL_STATE_ENTRY_UINT8(rtc_dayofweek);
1272         DECL_STATE_ENTRY_UINT8(rtc_hour);
1273         DECL_STATE_ENTRY_UINT8(rtc_minute);
1274         DECL_STATE_ENTRY_UINT8(rtc_sec);
1275
1276         DECL_STATE_ENTRY_BOOL(rtc_count24h);
1277         DECL_STATE_ENTRY_BOOL(rtc_ispm);
1278
1279         DECL_STATE_ENTRY_BOOL(rtc_set);
1280         DECL_STATE_ENTRY_BOOL(rtc_set_flag);
1281         DECL_STATE_ENTRY_BOOL(rxrdy_status);
1282         DECL_STATE_ENTRY_BOOL(key_ack_status);
1283                 
1284         DECL_STATE_ENTRY_BOOL(did_hidden_message_av_1);         
1285         DECL_STATE_ENTRY_INT32(event_hidden1_av);
1286
1287         DECL_STATE_ENTRY_INT32(cmd_phase);
1288         DECL_STATE_ENTRY_UINT16(hidden1_ptr);
1289         DECL_STATE_ENTRY_INT32(beep_phase);
1290         //cmd_fifo->save_state((void *)state_fio);
1291         //data_fifo->save_state((void *)state_fio);
1292         //cur_time.save_state((void *)state_fio);
1293 #endif
1294 #if defined(_FM77AV_VARIANTS)
1295         DECL_STATE_ENTRY_FIFO(cmd_fifo);
1296         DECL_STATE_ENTRY_FIFO(data_fifo);
1297         DECL_STATE_ENTRY_CUR_TIME_T(cur_time);
1298 #endif
1299         DECL_STATE_ENTRY_FIFO(key_fifo);
1300         DECL_STATE_ENTRY_INT32(event_int);
1301         //key_fifo->save_state((void *)state_fio);
1302         DECL_STATE_ENTRY_UINT8(autokey_backup);
1303         // Version 5
1304         DECL_STATE_ENTRY_BOOL(ins_led_status);
1305         DECL_STATE_ENTRY_BOOL(kana_led_status);
1306         DECL_STATE_ENTRY_BOOL(caps_led_status);
1307         // Version 6
1308         DECL_STATE_ENTRY_BOOL(override_break_key);
1309
1310         leave_decl_state();
1311 }
1312
1313 void KEYBOARD::save_state(FILEIO *state_fio)
1314 {
1315         if(state_entry != NULL) {
1316                 state_entry->save_state(state_fio);
1317         }
1318         //state_fio->FputUint32_BE(STATE_VERSION);
1319         //state_fio->FputInt32_BE(this_device_id);
1320         this->out_debug_log(_T("Save State: KEYBOARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
1321 }
1322
1323 bool KEYBOARD::load_state(FILEIO *state_fio)
1324 {
1325         uint32_t version;
1326         
1327         //version = state_fio->FgetUint32_BE();
1328         //if(this_device_id != state_fio->FgetInt32_BE()) return false;
1329         //this->out_debug_log(_T("Load State: KEYBOARD: id=%d ver=%d\n"), this_device_id, version);
1330         bool mb = false;
1331         if(state_entry != NULL) {
1332                 mb = state_entry->load_state(state_fio);
1333         }
1334         if(!mb) return false;
1335         return true;
1336 }
1337
1338