OSDN Git Service

[VM] TRY:Use namespace {VMNAME} to separate around VMs. This feature still apply...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / keyboard.cpp
index 8d55cd1..f479e55 100644 (file)
@@ -6,15 +6,24 @@
  *  Feb 12, 2015 : Initial 
  */
 
+#include "vm.h"
+#include "emu.h"
 #include "../../fifo.h"
 #include "../device.h"
-#include "fm7_keyboard.h"
 
+#include "fm7_keyboard.h"
 #include "keyboard_tables.h"
+
 #if defined(_FM77AV_VARIANTS)
 #include "../beep.h"
-#include "fm77av_hidden_message_keyboard.h"
+
+namespace FM7 {
+       #include "fm77av_hidden_message_keyboard.h"
+}
 #endif
+
+namespace FM7 {
+
 enum {
        ID_KEYBOARD_RXRDY_OK = 1,
        ID_KEYBOARD_ACK,
@@ -26,6 +35,11 @@ enum {
        ID_KEYBOARD_HIDDENMESSAGE_AV,
        ID_KEYBOARD_HIDDEN_BEEP_ON,
        ID_KEYBOARD_HIDDEN_BEEP_OFF,
+       ID_KEYBOARD_AUTO_8KEY_START,
+       ID_KEYBOARD_AUTO_8KEY_END,
+       ID_KEYBOARD_AUTO_5KEY_START,
+       ID_KEYBOARD_AUTO_5KEY_END,
+       ID_KEYBOARD_BREAK_ONESHOT,
 };
 
 //
@@ -51,13 +65,13 @@ uint8_t KEYBOARD::get_keycode_low(void)
 // 0xd40d : R
 void KEYBOARD::turn_on_ins_led(void)
 {
-       this->write_signals(&ins_led, 0xff);
+       ins_led_status = true;
 }
 
 // 0xd40d : W
 void KEYBOARD::turn_off_ins_led(void)
 {
-       this->write_signals(&ins_led, 0x00);
+       ins_led_status = false;
 }
 
 // UI Handler. 
@@ -73,7 +87,7 @@ uint16_t KEYBOARD::vk2scancode(uint32_t vk)
        return 0x0000;
 }
 
-bool KEYBOARD::isModifier(uint16_t sc)
+bool KEYBOARD::isModifier(uint8_t sc)
 {
        if(((sc >= 0x52) && (sc <= 0x56)) || // CTRL LSHIFT RSHIFT CAPS GRPH
                (sc == 0x5a) || (sc == 0x5c)) { // KANA BREAK
@@ -82,7 +96,7 @@ bool KEYBOARD::isModifier(uint16_t sc)
        return false;
 }
 
-void KEYBOARD::set_modifiers(uint16_t sc, bool flag)
+void KEYBOARD::set_modifiers(uint8_t sc, bool flag)
 {
        if(sc == 0x52) { // CTRL
                ctrl_pressed = flag; 
@@ -104,8 +118,7 @@ void KEYBOARD::set_modifiers(uint16_t sc, bool flag)
                        } else {
                                caps_pressed = true;
                        }
-                       if(keymode == KEYMODE_STANDARD) this->write_signals(&caps_led, caps_pressed ? 0xff : 0x00);
-                       //this->write_signals(&caps_led, caps_pressed ? 0xff : 0x00);
+                       if(keymode == KEYMODE_STANDARD) caps_led_status = caps_pressed;
                }
        } else if(sc == 0x5a) { // KANA
                // Toggle on press.
@@ -115,14 +128,16 @@ void KEYBOARD::set_modifiers(uint16_t sc, bool flag)
                        } else {
                                kana_pressed = true;
                        }
-                       if(keymode == KEYMODE_STANDARD) this->write_signals(&kana_led, kana_pressed ? 0xff : 0x00);
+                       if(keymode == KEYMODE_STANDARD) kana_led_status = kana_pressed;
                }
        } else if(sc == 0x5c) { // Break
-               break_pressed = flag;
+               if(!override_break_key) {
+                       break_pressed = flag;
+               }
        }
 }
 
-uint16_t KEYBOARD::scan2fmkeycode(uint16_t sc)
+uint16_t KEYBOARD::scan2fmkeycode(uint8_t sc)
 {
        const struct key_tbl_t *keyptr = NULL;
        bool stdkey = false;
@@ -182,7 +197,7 @@ uint16_t KEYBOARD::scan2fmkeycode(uint16_t sc)
          // F10: TV
        }
        if(keymode == KEYMODE_SCAN) {
-               retval = sc;
+               retval = (uint16_t)sc;
                return retval;
        } else if(keymode == KEYMODE_16BETA) { // Will Implement
                if(ctrl_pressed) {
@@ -217,7 +232,7 @@ uint16_t KEYBOARD::scan2fmkeycode(uint16_t sc)
        retval = 0xffff;
        if (keyptr == NULL) return 0xffff;
        do {
-               if(keyptr[i].phy == sc) {
+               if(keyptr[i].phy == (uint16_t)sc) {
                        retval = keyptr[i].code;
                        break;
                }
@@ -238,9 +253,8 @@ uint16_t KEYBOARD::scan2fmkeycode(uint16_t sc)
        return retval;
 }
 
-void KEYBOARD::key_up(uint32_t vk)
+void KEYBOARD::key_up_main(uint8_t bak_scancode)
 {
-       uint16_t bak_scancode = vk2scancode(vk);
        bool stat_break = break_pressed;
        older_vk = 0;
        if(bak_scancode == 0) return;
@@ -256,22 +270,90 @@ void KEYBOARD::key_up(uint32_t vk)
                                this->write_signals(&break_line, 0x00);
                        }
                }
+               if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
+                       if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
+                               switch(bak_scancode) {
+                                       case 0x42: // 1
+                                       case 0x43: // 2
+                                       case 0x44: // 3
+                                       case 0x3f: // 5
+                                       case 0x46: // 0
+                                               register_event(this,
+                                                                          ID_KEYBOARD_AUTO_8KEY_START,
+                                                                          10.0 * 1000.0, false, NULL);
+                                               break;
+                                       default:
+                                               if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
+                                               break;
+                               }
+                       } else { // Auto 5
+                               switch(bak_scancode) {
+                                       case 0x42: // 1
+                                       case 0x43: // 2
+                                       case 0x44: // 3
+                                       case 0x3e: // 4
+                                       case 0x40: // 6
+                                       case 0x3a: // 7
+                                       case 0x3b: // 8
+                                       case 0x3c: // 9
+                                               register_event(this,
+                                                                          ID_KEYBOARD_AUTO_5KEY_START,
+                                                                          10.0 * 1000.0, false, NULL);
+                                               break;
+                                       default:
+                                               if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
+                                               break;
+                               }
+                       }                               
+               }
        } else {
                //scancode = 0;
-               if((keymode == KEYMODE_SCAN) && (bak_scancode != 0)) { // Notify even key-up, when using SCAN mode.
-                       uint32_t code = (bak_scancode & 0x7f) | 0x80;
-                       key_fifo->write(code);
-                       scancode = bak_scancode;
+               if(bak_scancode != 0) { // Notify even key-up, when using SCAN mode.
+                       uint8_t code = (bak_scancode & 0x7f) | 0x80;
+                       if(this->isModifier(bak_scancode)) {
+                               set_modifiers(bak_scancode, false);
+                       }
+#if defined(_FM77AV_VARIANTS)     
+                       if(bak_scancode != 0x5c) {
+                               if(beep_phase == 1) {
+                                       if(break_pressed) this->write_signals(&break_line, 0x00);
+                                       break_pressed = false;
+                                       beep_phase++;
+                                       bak_scancode = 0x7f;
+                                       code = 0xff;
+                               } else if(beep_phase == 2) {
+                                       beep_phase = 0;
+                                       register_event(this,
+                                                                  ID_KEYBOARD_HIDDEN_BEEP_ON,
+                                                                  100.0, false, NULL); // 100.0 us is dummy.
+                                       bak_scancode = 0x7f;
+                                       code = 0xff;
+                               }
+                       } else { // 0x5c : BREAK is up.
+                               beep_phase = 0;
+                               if(stat_break) this->write_signals(&break_line, 0x00);
+                       }
+#endif            
+                       if(code != 0x80) {
+                               key_fifo->write(code);
+                               scancode = bak_scancode;
+                       }
                }
        }
 }
 
+void KEYBOARD::key_up(uint32_t vk)
+{
+       uint8_t bak_scancode = (uint8_t)(vk2scancode(vk) & 0x00ff);
+       key_up_main(bak_scancode);
+}
+
 void KEYBOARD::key_down(uint32_t vk)
 {
        if(older_vk == vk) return;
        older_vk = vk;
        
-       scancode = vk2scancode(vk);
+       scancode = (uint8_t)vk2scancode(vk);
 #if defined(_FM77AV_VARIANTS)
        // Below are FM-77AV's hidden message , see :
        // https://twitter.com/maruan/status/499558392092831745
@@ -290,16 +372,40 @@ void KEYBOARD::key_down(uint32_t vk)
                }
        }
 #endif 
-       key_down_main();
+       key_down_main(true);
 }
 
-void KEYBOARD::key_down_main(void)
+void KEYBOARD::key_down_main(bool repeat_auto_key)
 {
        bool stat_break = break_pressed;
        uint32_t code;
        if(scancode == 0) return;
        if(keymode == KEYMODE_SCAN) {
                code = scancode & 0x7f;
+               if(this->isModifier(scancode)) {  // modifiers
+                       set_modifiers(scancode, true);
+               }
+#if defined(_FM77AV_VARIANTS)
+               if(break_pressed) {
+                       if(!stat_break) {
+                               beep_phase = 1;
+                               // It's dirty hack for AMNORK ; Set dead zone for FIRQ to 0.25sec.
+                               // I wish to replace this solution to more simple. 
+                               register_event(this,
+                                                          ID_KEYBOARD_BREAK_ONESHOT,
+                                                          250.0 * 1000.0, false, NULL);
+                       } else if(beep_phase == 1) {
+                               if(code != 0x5c) {
+                                       if(break_pressed) this->write_signals(&break_line, 0x00);
+                                       break_pressed = false;
+                                       beep_phase++;
+                                       code = 0x7f; // Special
+                                       scancode = 0x7f;        
+                               }
+                       }
+               }
+#endif
+
                if(code != 0) {
                        key_fifo->write(code);
                        // NOTE: With scan key code mode, auto repeat seems to be not effectable.
@@ -316,16 +422,46 @@ void KEYBOARD::key_down_main(void)
                }
                code = scan2fmkeycode(scancode);
                if((code > 0x3ff) || (code == 0)) return;
+               if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
+                       if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
+                               switch(scancode) {
+                                       case 0x42: // 1
+                                       case 0x43: // 2
+                                       case 0x44: // 3
+                                       case 0x3f: // 5
+                                       case 0x46: // 0
+                                               autokey_backup = scancode;
+                                               break;
+                               }
+                       } else { // Auto 5
+                               switch(scancode) {
+                                       case 0x42: // 1
+                                       case 0x43: // 2
+                                       case 0x44: // 3
+                                       case 0x3e: // 4
+                                       case 0x40: // 6
+                                       case 0x3a: // 7
+                                       case 0x3b: // 8
+                                       case 0x3c: // 9
+                                               autokey_backup = scancode;
+                                               break;
+                               }
+                       }                               
+               } else {
+                       autokey_backup = 0x00;
+               }
                if(code != 0) {
                        key_fifo->write(code);
-                       if(scancode < 0x5c) {
+                       if((scancode < 0x5c) && repeat_auto_key) {
                                double usec = (double)repeat_time_long * 1000.0;
-                               if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
-                               event_keyrepeat = -1;
-                               repeat_keycode = (uint8_t)scancode;
-                               if(repeat_mode) register_event(this,
-                                                                                          ID_KEYBOARD_AUTOREPEAT_FIRST,
-                                                                                          usec, false, &event_keyrepeat);
+                               if((repeat_keycode == 0) && repeat_mode) {
+                                       if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
+                                       event_keyrepeat = -1;
+                                       register_event(this,
+                                                                  ID_KEYBOARD_AUTOREPEAT_FIRST,
+                                                                  usec, false, &event_keyrepeat);
+                               }
+                               repeat_keycode = scancode;
                        }
                }
        }
@@ -356,7 +492,7 @@ void KEYBOARD::adjust_rtc(void)
 }
 #endif
 
-void KEYBOARD::do_repeatkey(uint16_t sc)
+void KEYBOARD::do_repeatkey(uint8_t sc)
 {
        uint16_t code;
        if((sc == 0) || (sc >= 0x5c)) return; // scancode overrun.
@@ -368,7 +504,7 @@ void KEYBOARD::do_repeatkey(uint16_t sc)
                return;
        }
        if(keymode == KEYMODE_SCAN) {
-               code = sc & 0x7f;
+               code = (uint16_t)(sc & 0x7f);
                key_fifo->write((uint32_t)code); // Make
                //key_fifo->write((uint32_t)(code | 0x80)); // Break
        } else {
@@ -405,31 +541,32 @@ void KEYBOARD::event_callback(int event_id, int err)
                beep->write_signal(SIG_BEEP_ON, 1, 1);
                register_event(this,
                       ID_KEYBOARD_HIDDEN_BEEP_OFF,
-                      20.0 * 1000.0, false, NULL);
+                      25.0 * 1000.0, false, NULL);
        } else  if(event_id == ID_KEYBOARD_HIDDEN_BEEP_ON) {
                beep->write_signal(SIG_BEEP_MUTE, 0, 1);
                beep->write_signal(SIG_BEEP_ON, 1, 1);
                register_event(this,
                       ID_KEYBOARD_HIDDEN_BEEP_OFF,
-                      20.0 * 1000.0, false, NULL);
+                      25.0 * 1000.0, false, NULL);
 
        } else  if(event_id == ID_KEYBOARD_HIDDEN_BEEP_OFF) {
                beep->write_signal(SIG_BEEP_MUTE, 0, 1);
                beep->write_signal(SIG_BEEP_ON, 0, 1);
+       } else if(event_id == ID_KEYBOARD_BREAK_ONESHOT) {
+               if(break_pressed) this->write_signals(&break_line, 0xff);
        } else
 #endif
        if(event_id == ID_KEYBOARD_AUTOREPEAT_FIRST) {
-               uint32_t sc = (uint32_t)repeat_keycode;
                double usec = (double)repeat_time_short * 1000.0;
 
-               do_repeatkey((uint16_t)sc);
+               do_repeatkey(repeat_keycode);
                register_event(this,
                               ID_KEYBOARD_AUTOREPEAT,
                               usec, true, &event_keyrepeat);
                // Key repeat.
        } else if(event_id == ID_KEYBOARD_AUTOREPEAT){
                if(repeat_keycode != 0) {
-                       do_repeatkey((uint16_t)repeat_keycode);
+                       do_repeatkey(repeat_keycode);
                } else {
                        cancel_event(this, event_keyrepeat);
                        event_keyrepeat = -1;
@@ -439,6 +576,28 @@ void KEYBOARD::event_callback(int event_id, int err)
                        keycode_7 = key_fifo->read();
                        this->write_signals(&int_line, 0xffffffff);
                }
+       } else if(event_id == ID_KEYBOARD_AUTO_8KEY_START) {
+               if(keymode != KEYMODE_SCAN) {
+                       scancode = 0x3b; // 8
+                       autokey_backup = 0x00;
+                       key_down_main(false);
+                       register_event(this,
+                                                  ID_KEYBOARD_AUTO_8KEY_END,
+                                                  50.0 * 1000.0, false, NULL);
+               }
+       } else if(event_id == ID_KEYBOARD_AUTO_8KEY_END) {
+               key_up_main(0x3b); // 8
+       } else if(event_id == ID_KEYBOARD_AUTO_5KEY_START) {
+               if(keymode != KEYMODE_SCAN) {
+                       scancode = 0x3f; // 5
+                       autokey_backup = 0x00;
+                       key_down_main(false);
+                       register_event(this,
+                                                  ID_KEYBOARD_AUTO_5KEY_END,
+                                                  50.0 * 1000.0, false, NULL);
+               }
+       } else if(event_id == ID_KEYBOARD_AUTO_5KEY_END) {
+               key_up_main(0x3f); // 5
        }
 }
 
@@ -457,10 +616,15 @@ void KEYBOARD::reset_unchange_mode(void)
        graph_pressed = false;
        kana_pressed = false;
        caps_pressed = false;
-       //      ins_pressed = false;
+       ins_led_status = false;
+       kana_led_status = false;
+       caps_led_status = false;
        datareg = 0x00;
        repeat_keycode = 0x00;
+       autokey_backup = 0x00;
 
+       if(override_break_key) write_signals(&break_line, (break_pressed) ? 0xff : 0);
+       key_fifo->clear();
 #if defined(_FM77AV_VARIANTS)
        cmd_fifo->clear();
        data_fifo->clear();
@@ -485,9 +649,6 @@ void KEYBOARD::reset_unchange_mode(void)
        this->write_signals(&rxrdy, 0x00);                
        this->write_signals(&key_ack, 0xff);              
 #endif
-       this->write_signals(&kana_led, 0x00);             
-       this->write_signals(&caps_led, 0x00);             
-       this->write_signals(&ins_led, 0x00);
 }
 
 
@@ -497,20 +658,22 @@ void KEYBOARD::reset(void)
        scancode = 0x00;
 
        keycode_7 = 0xffffffff; 
+       //keycode_7 = 0; 
        reset_unchange_mode();
        this->write_signals(&int_line, 0x00000000);
-       key_fifo->clear();
+
 #if defined(_FM77AV_VARIANTS)  
        adjust_rtc();
        did_hidden_message_av_1 = false;
+       beep_phase = 0;
 #endif
+
+       if(override_break_key) write_signals(&break_line, (break_pressed) ? 0xff : 0);
+
        if(event_int >= 0) cancel_event(this, event_int);
        register_event(this,
-                      ID_KEYBOARD_INT,
-                      20000.0, true, &event_int);
-//     register_event(this,
-//                    ID_KEYBOARD_INT,
-//                    5000.0, true, &event_int);
+                                  ID_KEYBOARD_INT,
+                                  20000.0, true, &event_int);
 }
 
 
@@ -557,7 +720,10 @@ void KEYBOARD::set_mode(void)
                keymode = mode;
                //printf("Keymode : %d\n", keymode);
                //reset_unchange_mode();
-               if(scancode != 0) key_down_main(); 
+               beep_phase = 0;
+               autokey_backup = 0x00;
+               this->write_signals(&break_line, 0x00);
+               if(scancode != 0) key_down_main(true); 
        }
        cmd_fifo->clear();
        data_fifo->clear(); // right?
@@ -590,11 +756,11 @@ void KEYBOARD::set_leds(void)
                if((ledvar & 0x02) != 0) {
                        // Kana
                        kana_pressed = ((ledvar & 0x01) == 0);
-                       write_signals(&kana_led, kana_pressed);
+                       kana_led_status = kana_pressed;
                } else {
                        // Caps
                        caps_pressed = ((ledvar & 0x01) == 0);
-                       write_signals(&caps_led, caps_pressed);
+                       caps_led_status = caps_pressed;
                }
        }
        cmd_fifo->clear();
@@ -807,6 +973,12 @@ uint32_t KEYBOARD::read_signal(int id)
 {
        if(id == SIG_FM7KEY_BREAK_KEY) {
                return break_pressed ? 0xfffffff : 0x00000000;
+       } else if(id == SIG_FM7KEY_LED_STATUS) {
+               uint32_t _l;
+               _l  = (ins_led_status) ? 0x00000001 : 0;
+               _l |= (kana_led_status) ? 0x00000002 : 0;
+               _l |= (caps_led_status) ? 0x00000004 : 0;
+               return _l;
        }
        return 0;
 }
@@ -815,7 +987,9 @@ uint32_t KEYBOARD::read_signal(int id)
 void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
 {
        if(id == SIG_FM7KEY_SET_INSLED) {
-               write_signals(&ins_led, data & mask);
+               ins_led_status = ((data & mask) != 0);
+       } else if(id == SIG_FM7KEY_OVERRIDE_PRESS_BREAK) {
+               override_break_key = ((data & mask) != 0);
        }
 #if defined(_FM77AV_VARIANTS)  
         else if(id == SIG_FM7KEY_PUSH_TO_ENCODER) {
@@ -845,7 +1019,7 @@ void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
                        case 0: // Set mode
                                if(count >= 2) {
                                        set_mode();
-                                       if(keymode == KEYMODE_SCAN) key_down_main();
+                                       if(keymode == KEYMODE_SCAN) key_down_main(true);
                                        cmd_phase = -1;
                                        cmd_fifo->clear();
                                }
@@ -858,7 +1032,7 @@ void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
                        case 2: // Set LED Phase
                                if(count >= 2) {
                                        set_leds();
-                                       if(keymode == KEYMODE_SCAN) key_down_main();
+                                       if(keymode == KEYMODE_SCAN) key_down_main(true);
                                        cmd_phase = -1;
                                        cmd_fifo->clear();
                                }
@@ -984,11 +1158,8 @@ void KEYBOARD::write_data8(uint32_t addr, uint32_t data)
        }
 }
 
-KEYBOARD::KEYBOARD(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
+KEYBOARD::KEYBOARD(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
 {
-       p_vm = parent_vm;
-       p_emu = parent_emu;
-       
 #if defined(_FM77AV_VARIANTS)
        beep = NULL;
 #endif 
@@ -1003,8 +1174,10 @@ KEYBOARD::KEYBOARD(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_em
        kana_pressed = false;
        break_pressed = false;
        event_keyrepeat = -1;
-   
+       autokey_backup = 0x00;
+
        keymode = KEYMODE_STANDARD;
+       override_break_key = false;
 #if defined(_FM77AV_VARIANTS)
        cmd_fifo = new FIFO(16);
        data_fifo = new FIFO(16);
@@ -1034,9 +1207,10 @@ KEYBOARD::KEYBOARD(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_em
        initialize_output_signals(&break_line);
        initialize_output_signals(&int_line);
        
-       initialize_output_signals(&kana_led);
-       initialize_output_signals(&caps_led);
-       initialize_output_signals(&ins_led);
+       ins_led_status = false;
+       kana_led_status = false;
+       caps_led_status = false;
+       set_device_name(_T("KEYBOARD SUBSYSTEM"));
 }
 
 void KEYBOARD::release(void)
@@ -1057,146 +1231,110 @@ KEYBOARD::~KEYBOARD()
 {
 }
 
-#define STATE_VERSION 2
-void KEYBOARD::save_state(FILEIO *state_fio)
-{
-       state_fio->FputUint32_BE(STATE_VERSION);
-       state_fio->FputInt32_BE(this_device_id);
+#define STATE_VERSION 9
+//#if defined(Q_OS_WIN)
+//DLL_PREFIX_I struct cur_time_s cur_time;
+//#endif
 
-       // Version 1
-       {
-               state_fio->FputUint32_BE(keycode_7);
-               state_fio->FputInt32_BE(keymode);
-          
-               state_fio->FputBool(ctrl_pressed);
-               state_fio->FputBool(lshift_pressed);
-               state_fio->FputBool(rshift_pressed);
-               state_fio->FputBool(shift_pressed);
-               state_fio->FputBool(graph_pressed);
-               state_fio->FputBool(caps_pressed);
-               state_fio->FputBool(kana_pressed);
-               state_fio->FputBool(break_pressed);
-
-               state_fio->FputInt32_BE(event_keyrepeat);
-          
-               state_fio->FputUint32(scancode);
-               state_fio->FputUint8(datareg);
-               state_fio->FputUint32(older_vk);
+bool KEYBOARD::decl_state(FILEIO *state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       
+       state_fio->StateUint32(keycode_7);
+       state_fio->StateInt32(keymode);
+       state_fio->StateBool(ctrl_pressed);
+       state_fio->StateBool(lshift_pressed);
+       state_fio->StateBool(rshift_pressed);
+       state_fio->StateBool(shift_pressed);
+       state_fio->StateBool(graph_pressed);
+       state_fio->StateBool(caps_pressed);
+       state_fio->StateBool(kana_pressed);
+       state_fio->StateBool(break_pressed);
+
+       state_fio->StateInt32(event_keyrepeat);
           
-               state_fio->FputBool(repeat_mode);
-               state_fio->FputInt32_BE(repeat_time_short);
-               state_fio->FputInt32_BE(repeat_time_long);
-               state_fio->FputUint8(repeat_keycode);
+       state_fio->StateUint8(scancode); // After V.4, uint8_t
+       state_fio->StateUint8(datareg);
+       state_fio->StateUint32(older_vk);
           
+       state_fio->StateBool(repeat_mode);
+       state_fio->StateInt32(repeat_time_short);
+       state_fio->StateInt32(repeat_time_long);
+       state_fio->StateUint8(repeat_keycode);
+          
 #if defined(_FM77AV_VARIANTS)
-               state_fio->FputInt32_BE(event_key_rtc);
-  
-               state_fio->FputUint8(rtc_yy);
-               state_fio->FputUint8(rtc_mm);
-               state_fio->FputUint8(rtc_dd);
-               state_fio->FputUint8(rtc_dayofweek);
-               state_fio->FputUint8(rtc_hour);
-               state_fio->FputUint8(rtc_minute);
-               state_fio->FputUint8(rtc_sec);
-
-               state_fio->FputBool(rtc_count24h);
-               state_fio->FputBool(rtc_ispm);
-
-               state_fio->FputBool(rtc_set);
-               state_fio->FputBool(rtc_set_flag);
-               state_fio->FputBool(rxrdy_status);
-               state_fio->FputBool(key_ack_status);
-               state_fio->FputInt32_BE(cmd_phase);
-
-               state_fio->FputInt32_BE(event_hidden1_av);
-               state_fio->FputUint16_BE(hidden1_ptr);
-
-               cmd_fifo->save_state((void *)state_fio);
-               data_fifo->save_state((void *)state_fio);
-               cur_time.save_state((void *)state_fio);
-#endif
-               state_fio->FputInt32_BE(event_int);
-               key_fifo->save_state((void *)state_fio);
+       state_fio->StateInt32(event_key_rtc);
+       state_fio->StateUint8(rtc_yy);
+       state_fio->StateUint8(rtc_mm);
+       state_fio->StateUint8(rtc_dd);
+       state_fio->StateUint8(rtc_dayofweek);
+       state_fio->StateUint8(rtc_hour);
+       state_fio->StateUint8(rtc_minute);
+       state_fio->StateUint8(rtc_sec);
+
+       state_fio->StateBool(rtc_count24h);
+       state_fio->StateBool(rtc_ispm);
+
+       state_fio->StateBool(rtc_set);
+       state_fio->StateBool(rtc_set_flag);
+       state_fio->StateBool(rxrdy_status);
+       state_fio->StateBool(key_ack_status);
+               
+       state_fio->StateBool(did_hidden_message_av_1);
+       state_fio->StateInt32(event_hidden1_av);
+
+       state_fio->StateInt32(cmd_phase);
+       state_fio->StateUint16(hidden1_ptr);
+       state_fio->StateInt32(beep_phase);
+       
+       if(!cmd_fifo->process_state(state_fio, loading)) {
+               return false;
+       }
+       if(!data_fifo->process_state(state_fio, loading)) {
+               return false;
+       }
+       if(!cur_time.process_state(state_fio, loading)) {
+               return false;
        }
-       // Version 2
-       {
-#if defined(_FM77AV_VARIANTS)
-               state_fio->FputBool(did_hidden_message_av_1);
 #endif
+       if(!key_fifo->process_state(state_fio, loading)) {
+               return false;
        }
+       state_fio->StateInt32(event_int);
+       state_fio->StateUint8(autokey_backup);
+       // Version 5
+       state_fio->StateBool(ins_led_status);
+       state_fio->StateBool(kana_led_status);
+       state_fio->StateBool(caps_led_status);
+       // Version 6
+       state_fio->StateBool(override_break_key);
+
+       return true;
 }
 
+void KEYBOARD::save_state(FILEIO *state_fio)
+{
+       decl_state(state_fio, false);
+       //state_fio->FputUint32_BE(STATE_VERSION);
+       //state_fio->FputInt32_BE(this_device_id);
+       this->out_debug_log(_T("Save State: KEYBOARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
+}
 bool KEYBOARD::load_state(FILEIO *state_fio)
 {
-       uint32_t version;
-       
-       version = state_fio->FgetUint32_BE();
-       if(this_device_id != state_fio->FgetInt32_BE()) return false;
-
-       if(version >= 1) {
-               keycode_7 = state_fio->FgetUint32_BE();
-               keymode = state_fio->FgetInt32_BE();
-          
-               ctrl_pressed = state_fio->FgetBool();
-               lshift_pressed = state_fio->FgetBool();
-               rshift_pressed = state_fio->FgetBool();
-               shift_pressed = state_fio->FgetBool();
-               graph_pressed = state_fio->FgetBool();
-               caps_pressed = state_fio->FgetBool();
-               kana_pressed = state_fio->FgetBool();
-               break_pressed = state_fio->FgetBool();
-
-               event_keyrepeat = state_fio->FgetInt32_BE();
-          
-               scancode = state_fio->FgetUint32();
-               datareg = state_fio->FgetUint8();
-               older_vk = state_fio->FgetUint32();
-          
-               repeat_mode = state_fio->FgetBool();
-               repeat_time_short = state_fio->FgetInt32_BE();
-               repeat_time_long = state_fio->FgetInt32_BE();
-               repeat_keycode = state_fio->FgetUint8();
-          
-#if defined(_FM77AV_VARIANTS)
-               event_key_rtc = state_fio->FgetInt32_BE();
-               rtc_yy = state_fio->FgetUint8();
-               rtc_mm = state_fio->FgetUint8();
-               rtc_dd = state_fio->FgetUint8();
-               rtc_dayofweek = state_fio->FgetUint8();
-               rtc_hour = state_fio->FgetUint8();
-               rtc_minute = state_fio->FgetUint8();
-               rtc_sec = state_fio->FgetUint8();
-
-               rtc_count24h = state_fio->FgetBool();
-               rtc_ispm = state_fio->FgetBool();
-
-               rtc_set = state_fio->FgetBool();
-               rtc_set_flag = state_fio->FgetBool();
-               rxrdy_status = state_fio->FgetBool();
-               key_ack_status = state_fio->FgetBool();
-               cmd_phase = state_fio->FgetInt32_BE();
-
-               event_hidden1_av = state_fio->FgetInt32_BE();
-               hidden1_ptr = state_fio->FgetUint16_BE();
-
-               cmd_fifo->load_state((void *)state_fio);
-               data_fifo->load_state((void *)state_fio);
-               cur_time.load_state((void *)state_fio);
-#endif
-               event_int = state_fio->FgetInt32_BE();
-               key_fifo->load_state((void *)state_fio);
-               if(version == 1) return true;
-       }
-       // Version 2
-       {
-#if defined(_FM77AV_VARIANTS)
-               did_hidden_message_av_1 = state_fio->FgetBool();
-#endif
-       }
-       if(version == 2) {
-               return true;
-       }
-       return false;
+       uint32_t version;
+       
+       //version = state_fio->FgetUint32_BE();
+       //if(this_device_id != state_fio->FgetInt32_BE()) return false;
+       //this->out_debug_log(_T("Load State: KEYBOARD: id=%d ver=%d\n"), this_device_id, version);
+       bool mb = decl_state(state_fio, true);
+       if(!mb) return false;
+       return true;
 }
 
-   
+}