OSDN Git Service

[VM] Add vm_template.h . This class, VM_TEMPLATE:: must be mother of VM:: .See fm7...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / fm7_mainio.cpp
index fe50739..63c71fd 100644 (file)
 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
 #include "../and.h"
 #endif
+#include "./fm7_mainmem.h"
+#include "./fm7_display.h"
+#include "./fm7_keyboard.h"
+#include "./kanjirom.h"
+#include "./joystick.h"
+#if defined(CAPABLE_JCOMMCARD)
+#include "./jcommcard.h"
+#endif
+#include "../../statesub.h"
 
-
-FM7_MAINIO::FM7_MAINIO(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
+FM7_MAINIO::FM7_MAINIO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
 {
        int i;
-       p_vm = parent_vm;
-       p_emu = parent_emu;
        for(i = 0; i < 3; i++) {
                opn[i] = NULL;
        }
@@ -121,6 +127,7 @@ FM7_MAINIO::FM7_MAINIO(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, paren
                opn_address[i] = 0x00;
                opn_data[i] = 0x00;
                opn_cmdreg[i] = 0;
+               opn_prescaler_type[i] = 1;
        }
        intstat_whg = false;
        intstat_thg = false;
@@ -182,6 +189,7 @@ FM7_MAINIO::FM7_MAINIO(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, paren
        initialize_output_signals(&irq_bus);
        initialize_output_signals(&firq_bus);
        initialize_output_signals(&nmi_bus);
+       
        set_device_name(_T("MAIN I/O"));
 }
 
@@ -216,11 +224,11 @@ void FM7_MAINIO::initialize()
 #else
        bootmode = config.boot_mode & 3;
 #endif
-#if defined(_FM8) || defined(_FM77_VARIANTS)
+#if defined(HAS_2HD)
        event_2hd_nmi = -1;
        nmi_delay = 300;
 #endif
-       reset_printer();
+       //reset_printer();
 }
 
 void FM7_MAINIO::reset()
@@ -279,7 +287,7 @@ void FM7_MAINIO::reset()
        } else {
                clock_fast = false;
        }
-       this->write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
+       write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
    
        // FD03
        irqmask_syndet = true;
@@ -309,8 +317,8 @@ void FM7_MAINIO::reset()
        midi_uart_irqmask = midi_syndet = midi_rxrdy = midi_txrdy = false;
        // FD00
        if(drec != NULL) {
-               drec->write_signal(SIG_DATAREC_MIC, 0x00, 0x01);
-               drec->write_signal(SIG_DATAREC_REMOTE, 0x00, 0x02);
+               call_write_signal(drec, SIG_DATAREC_MIC, 0x00, 0x01);
+               call_write_signal(drec, SIG_DATAREC_REMOTE, 0x00, 0x02);
        }
        reset_fdc();
        reset_sound();
@@ -336,11 +344,11 @@ void FM7_MAINIO::reset()
        reg_fd12 = 0xbc; // 0b10111100
 #endif
 #if defined(WITH_Z80)
-       if(z80 != NULL) z80->write_signal(SIG_CPU_BUSREQ, 0xffffffff, 0xffffffff);
+       if(z80 != NULL) call_write_signal(z80, SIG_CPU_BUSREQ, 0xffffffff, 0xffffffff);
 #endif
-       maincpu->write_signal(SIG_CPU_BUSREQ, 0, 0xffffffff);
-       maincpu->write_signal(SIG_CPU_HALTREQ, 0, 0xffffffff);
-
+       call_write_signal(maincpu, SIG_CPU_BUSREQ, 0, 0xffffffff);
+       call_write_signal(maincpu, SIG_CPU_HALTREQ, 0, 0xffffffff);
+       do_irq();
 
 //#if !defined(_FM8)
        register_event(this, EVENT_TIMERIRQ_ON, 10000.0 / 4.9152, true, &event_timerirq); // TIMER IRQ
@@ -359,9 +367,9 @@ void FM7_MAINIO::reset_printer()
        lpt_strobe = false;
        // FD01
        lpt_outdata = 0x00;
-       this->write_signals(&printer_strobe_bus, 0);
-       this->write_signals(&printer_select_bus, 0xffffffff);
-       this->write_signals(&printer_reset_bus, 0xffffffff);
+       write_signals(&printer_strobe_bus, 0);
+       write_signals(&printer_select_bus, 0xffffffff);
+       write_signals(&printer_reset_bus, 0xffffffff);
        register_event(this, EVENT_PRINTER_RESET_COMPLETED, 5.0 * 1000.0, false, NULL);
        if(lpt_type == 0) {
                printer->write_signal(SIG_PRINTER_STROBE, 0x00, 0xff);
@@ -382,7 +390,7 @@ void FM7_MAINIO::set_clockmode(uint8_t flags)
                clock_fast = true;
        }
        if(f != clock_fast) {
-               this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
+               write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
        }
 }
 
@@ -404,13 +412,13 @@ uint8_t FM7_MAINIO::get_port_fd00(void)
 void FM7_MAINIO::set_port_fd00(uint8_t data)
 {
        if(drec != NULL) {
-               drec->write_signal(SIG_DATAREC_MIC, data, 0x01);
-               drec->write_signal(SIG_DATAREC_REMOTE, data, 0x02);
+               call_write_signal(drec, SIG_DATAREC_MIC, data, 0x01);
+               call_write_signal(drec, SIG_DATAREC_REMOTE, data, 0x02);
        }       
        lpt_slctin = ((data & 0x80) == 0);
        lpt_strobe = ((data & 0x40) != 0);
-       this->write_signals(&printer_strobe_bus, lpt_strobe ? 0xffffffff : 0);
-       this->write_signals(&printer_select_bus, lpt_slctin ? 0xffffffff : 0);
+       write_signals(&printer_strobe_bus, lpt_strobe ? 0xffffffff : 0);
+       write_signals(&printer_select_bus, lpt_slctin ? 0xffffffff : 0);
        if((lpt_type == 0) && (lpt_slctin)) {
                printer->write_signal(SIG_PRINTER_STROBE, lpt_strobe ? 0xff : 0x00, 0xff);
        }
@@ -517,7 +525,7 @@ void FM7_MAINIO::set_port_fd02(uint8_t val)
                irqmask_keyboard = true;
        }
        if(keyirq_bak != irqmask_keyboard) {
-               display->write_signal(SIG_FM7_SUB_KEY_MASK, irqmask_keyboard ? 1 : 0, 1); 
+               call_write_signal(display, SIG_FM7_SUB_KEY_MASK, irqmask_keyboard ? 1 : 0, 1); 
                set_irq_keyboard(irqreq_keyboard);
        }
 //#endif       
@@ -645,8 +653,7 @@ void FM7_MAINIO::do_firq(void)
        firq_stat = firq_break_key | firq_sub_attention;
 #if defined(HAS_2HD)
        if(intmode_fdc) {
-               //if((connect_fdc_2HD) && (fdc_2HD != NULL) && ((irqreg_fdc_2HD & 0x40) != 0)) {
-               firq_stat |= drqstat_fdc_2hd;
+               firq_stat = drqstat_fdc_2hd;  // 20180226 BREAK KEY AND ATTENTION MUST BE MASK IF FIRQ USING FOR FDC's DRQ.Thanks to Haserin.
                        //}
        }
 #endif
@@ -729,10 +736,10 @@ void FM7_MAINIO::set_fd04(uint8_t val)
 {
        // NOOP?
 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
-       display->write_signal(SIG_DISPLAY_EXTRA_MODE, val, 0xff);
+       call_write_signal(display, SIG_DISPLAY_EXTRA_MODE, val, 0xff);
        stat_kanjirom = ((val & 0x20) != 0);
 #elif defined(_FM77_VARIANTS)
-       display->write_signal(SIG_DISPLAY_EXTRA_MODE, val, 0xff);
+       call_write_signal(display, SIG_DISPLAY_EXTRA_MODE, val, 0xff);
        stat_kanjirom    = ((val & 0x20) != 0);
 #endif
 #if defined(HAS_2HD)
@@ -759,21 +766,21 @@ void FM7_MAINIO::set_fd05(uint8_t val)
        sub_cancel = ((val & 0x40) != 0) ? true : false;
        sub_halt   = ((val & 0x80) != 0) ? true : false;
        //if(sub_halt != sub_halt_bak) {
-       display->write_signal(SIG_DISPLAY_HALT,  (sub_halt) ? 0xff : 0x00, 0xff);
+       call_write_signal(display, SIG_DISPLAY_HALT,  (sub_halt) ? 0xff : 0x00, 0xff);
        //}
        sub_halt_bak = sub_halt;
 
        //if(sub_cancel != sub_cancel_bak) {
-       display->write_signal(SIG_FM7_SUB_CANCEL, (sub_cancel) ? 0xff : 0x00, 0xff); // HACK
+       call_write_signal(display, SIG_FM7_SUB_CANCEL, (sub_cancel) ? 0xff : 0x00, 0xff); // HACK
        //}
        sub_cancel_bak = sub_cancel;
 #ifdef WITH_Z80
        if((val & 0x01) != 0) {
-               maincpu->write_signal(SIG_CPU_HALTREQ, 1, 1);
+               call_write_signal(maincpu, SIG_CPU_HALTREQ, 1, 1);
                req_z80run = true;
        } else {
                req_z80run = false;
-               if(z80 != NULL) z80->write_signal(SIG_CPU_BUSREQ, 1, 1);
+               if(z80 != NULL) call_write_signal(z80, SIG_CPU_BUSREQ, 1, 1);
        }
 #endif
 }
@@ -785,12 +792,12 @@ void FM7_MAINIO::set_extdet(bool flag)
 
 void FM7_MAINIO::write_fd0f(void)
 {
-       mainmem->write_signal(FM7_MAINIO_PUSH_FD0F, 0, 0xffffffff);
+       call_write_signal(mainmem, FM7_MAINIO_PUSH_FD0F, 0, 0xffffffff);
 }
 
 uint8_t FM7_MAINIO::read_fd0f(void)
 {
-       mainmem->write_signal(FM7_MAINIO_PUSH_FD0F, 0xffffffff, 0xffffffff);
+       call_write_signal(mainmem, FM7_MAINIO_PUSH_FD0F, 0xffffffff, 0xffffffff);
        return 0xff;
 }
 
@@ -956,7 +963,7 @@ void FM7_MAINIO::write_signal(int id, uint32_t data, uint32_t mask)
                } else {
                        clock_fast = false;
                }
-               this->write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
+               write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
                break;
        case FM7_MAINIO_CMT_RECV: // FD02
                cmt_indat = val_b ^ cmt_invert;
@@ -1019,7 +1026,7 @@ void FM7_MAINIO::write_signal(int id, uint32_t data, uint32_t mask)
 #if defined(WITH_Z80)
        case FM7_MAINIO_RUN_Z80:
                if((req_z80run)/*  && (val_b) */) {
-                       if(z80 != NULL) z80->write_signal(SIG_CPU_BUSREQ, 0, 1);
+                       if(z80 != NULL) call_write_signal(z80, SIG_CPU_BUSREQ, 0, 1);
                        z80_run = true;
                        //z80->reset(); // OK?
                }
@@ -1028,7 +1035,7 @@ void FM7_MAINIO::write_signal(int id, uint32_t data, uint32_t mask)
                if(!(req_z80run) /* && (val_b) */ && (z80_run)) {
                        z80_run = false;
                        // Wait dead cycle?
-                       maincpu->write_signal(SIG_CPU_HALTREQ, 0, 1);
+                       call_write_signal(maincpu, SIG_CPU_HALTREQ, 0, 1);
                }
                break;
 #endif
@@ -1617,16 +1624,16 @@ void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
 #if defined(_FM77AV_VARIANTS)
                case 0x10:
                        flag = ((data & 0x02) == 0) ? true : false;
-                       mainmem->write_signal(FM7_MAINIO_INITROM_ENABLED, (flag) ? 0xffffffff : 0 , 0xffffffff);
+                       call_write_signal(mainmem, FM7_MAINIO_INITROM_ENABLED, (flag) ? 0xffffffff : 0 , 0xffffffff);
                        break;
                case 0x12:
-                       display->write_signal(SIG_DISPLAY_MODE320, data,  0x40);
+                       call_write_signal(display, SIG_DISPLAY_MODE320, data,  0x40);
                        reg_fd12 &= ~0x40;
                        reg_fd12 |= (data & 0x40);
                        break;
                case 0x13:
                        sub_monitor_type = data & 0x07;
-                       display->write_signal(SIG_FM7_SUB_BANK, sub_monitor_type, 0x07);
+                       call_write_signal(display, SIG_FM7_SUB_BANK, sub_monitor_type, 0x07);
                        break;
 #endif
                case 0x15: // OPN CMD
@@ -1762,7 +1769,7 @@ void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
                        break;
 #if defined(CAPABLE_DICTROM)
                case 0x2e: // 
-                       mainmem->write_signal(FM7_MAINIO_EXTBANK, data, 0xff);
+                       call_write_signal(mainmem, FM7_MAINIO_EXTBANK, data, 0xff);
                        break;
 #endif                 
 #if defined(_FM77AV_VARIANTS)
@@ -1784,7 +1791,7 @@ void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
 #endif
 //#if !defined(_FM8)                   
                case 0x37: // Multi page
-                       display->write_signal(SIG_DISPLAY_MULTIPAGE, data, 0x00ff);
+                       call_write_signal(display, SIG_DISPLAY_MULTIPAGE, data, 0x00ff);
                        break;
                case 0x40: // MODEM
                case 0x41:
@@ -1830,26 +1837,26 @@ void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
                        mainmem->write_data8(FM7_MAINIO_WINDOW_OFFSET, (uint32_t)(data & 0x00ff));
                        break;
                case 0x93:
-                       mainmem->write_signal(FM7_MAINIO_BOOTRAM_RW, data, 0x01);
-                       mainmem->write_signal(FM7_MAINIO_WINDOW_ENABLED, data , 0x40);
+                       call_write_signal(mainmem, FM7_MAINIO_BOOTRAM_RW, data, 0x01);
+                       call_write_signal(mainmem, FM7_MAINIO_WINDOW_ENABLED, data , 0x40);
                        //this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
                        //mainmem->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
-                       mainmem->write_signal(FM7_MAINIO_MMR_ENABLED, data, 0x80);
+                       call_write_signal(mainmem, FM7_MAINIO_MMR_ENABLED, data, 0x80);
                        //}
                        break;
 #endif
 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
     defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
                case 0x94:
-                       mainmem->write_signal(FM7_MAINIO_MMR_EXTENDED, data, 0x80);
-                       mainmem->write_signal(FM7_MAINIO_MEM_REFRESH_FAST, data, 0x04);
-                       mainmem->write_signal(FM7_MAINIO_WINDOW_FAST , data, 0x01);
+                       call_write_signal(mainmem, FM7_MAINIO_MMR_EXTENDED, data, 0x80);
+                       call_write_signal(mainmem, FM7_MAINIO_MEM_REFRESH_FAST, data, 0x04);
+                       call_write_signal(mainmem, FM7_MAINIO_WINDOW_FAST , data, 0x01);
 
                        break;
 # if defined(_FM77AV40SX) || defined(_FM77AV40EX)
                case 0x95:
-                       mainmem->write_signal(FM7_MAINIO_FASTMMR_ENABLED, data, 0x08);
-                       mainmem->write_signal(FM7_MAINIO_EXTROM, data , 0x80);
+                       call_write_signal(mainmem, FM7_MAINIO_FASTMMR_ENABLED, data, 0x08);
+                       call_write_signal(mainmem, FM7_MAINIO_EXTROM, data , 0x80);
                        break;
 # endif
 #endif                 
@@ -1897,7 +1904,7 @@ void FM7_MAINIO::event_callback(int event_id, int err)
                event_beep_cycle();
                break;
        case EVENT_UP_BREAK:
-               keyboard->write_signal(SIG_FM7KEY_OVERRIDE_PRESS_BREAK, 0, 0xffffffff);
+               call_write_signal(keyboard, SIG_FM7KEY_OVERRIDE_PRESS_BREAK, 0, 0xffffffff);
                set_break_key(false);
                break;
 //#if !defined(_FM8)
@@ -1929,7 +1936,7 @@ void FM7_MAINIO::event_callback(int event_id, int err)
                break;
 #endif
        case EVENT_PRINTER_RESET_COMPLETED:                     
-               this->write_signals(&printer_reset_bus, 0x00);
+               write_signals(&printer_reset_bus, 0x00);
                break;
        default:
                break;
@@ -1947,348 +1954,193 @@ void FM7_MAINIO::update_config()
                clock_fast = false;
                break;
        }
-       this->write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
+       write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
 }
 
 void FM7_MAINIO::event_vline(int v, int clock)
 {
 }
 
-#define STATE_VERSION 13
-void FM7_MAINIO::save_state_main(FILEIO *state_fio)
+
+#define STATE_VERSION 16
+#include "../../statesub.h"
+
+void FM7_MAINIO::decl_state(void)
 {
-       uint32_t addr;
-       // Version 1
-       {
-               for(addr = 0; addr < 0x100; addr++) state_fio->FputUint8(io_w_latch[addr]);
-               // FD00
-               state_fio->FputBool(clock_fast);
-               state_fio->FputBool(lpt_strobe);
-               state_fio->FputBool(lpt_slctin);
-               state_fio->FputBool(beep_flag);
-               state_fio->FputBool(beep_snd);
+       enter_decl_state(STATE_VERSION);
+
+       DECL_STATE_ENTRY_MULTI(void, io_w_latch, sizeof(io_w_latch));
+       
+       DECL_STATE_ENTRY_BOOL(clock_fast);
+       DECL_STATE_ENTRY_BOOL(lpt_strobe);
+       DECL_STATE_ENTRY_BOOL(lpt_slctin);
+       DECL_STATE_ENTRY_BOOL(beep_flag);
+       DECL_STATE_ENTRY_BOOL(beep_snd);
        
                // FD01
-               state_fio->FputUint8(lpt_outdata);
-               // FD02
-               state_fio->FputBool(cmt_indat);
-               state_fio->FputBool(cmt_invert);
-               state_fio->FputBool(lpt_det2);
-               state_fio->FputBool(lpt_det1);
-               state_fio->FputBool(lpt_pe);
-               state_fio->FputBool(lpt_ackng_inv);
-               state_fio->FputBool(lpt_error_inv);
-               state_fio->FputUint8(irqmask_reg0);
-               
-               state_fio->FputBool(irqmask_syndet);
-               state_fio->FputBool(irqmask_rxrdy);
-               state_fio->FputBool(irqmask_txrdy);
-               state_fio->FputBool(irqmask_mfd);
-               state_fio->FputBool(irqmask_timer);
-               state_fio->FputBool(irqmask_printer);
-               state_fio->FputBool(irqmask_keyboard);
-
-               state_fio->FputBool(irqreq_syndet);
-               state_fio->FputBool(irqreq_rxrdy);
-               state_fio->FputBool(irqreq_txrdy);
-               state_fio->FputBool(irqreq_printer);
-               state_fio->FputBool(irqreq_keyboard);
-               // FD03
-               state_fio->FputUint8(irqstat_reg0);
+       DECL_STATE_ENTRY_UINT8(lpt_outdata);
+       // FD02
+       DECL_STATE_ENTRY_BOOL(cmt_indat);
+       DECL_STATE_ENTRY_BOOL(cmt_invert);
+       DECL_STATE_ENTRY_BOOL(lpt_det2);
+       DECL_STATE_ENTRY_BOOL(lpt_det1);
+       DECL_STATE_ENTRY_BOOL(lpt_pe);
+       DECL_STATE_ENTRY_BOOL(lpt_ackng_inv);
+       DECL_STATE_ENTRY_BOOL(lpt_error_inv);
+       DECL_STATE_ENTRY_UINT8(irqmask_reg0);
+       
+       DECL_STATE_ENTRY_BOOL(irqmask_syndet);
+       DECL_STATE_ENTRY_BOOL(irqmask_rxrdy);
+       DECL_STATE_ENTRY_BOOL(irqmask_txrdy);
+       DECL_STATE_ENTRY_BOOL(irqmask_mfd);
+       DECL_STATE_ENTRY_BOOL(irqmask_timer);
+       DECL_STATE_ENTRY_BOOL(irqmask_printer);
+       DECL_STATE_ENTRY_BOOL(irqmask_keyboard);
+
+       DECL_STATE_ENTRY_BOOL(irqreq_syndet);
+       DECL_STATE_ENTRY_BOOL(irqreq_rxrdy);
+       DECL_STATE_ENTRY_BOOL(irqreq_txrdy);
+       DECL_STATE_ENTRY_BOOL(irqreq_printer);
+       DECL_STATE_ENTRY_BOOL(irqreq_keyboard);
+       DECL_STATE_ENTRY_UINT8(irqstat_reg0);
                
-               state_fio->FputBool(irqstat_timer);
-               state_fio->FputBool(irqstat_printer);
-               state_fio->FputBool(irqstat_keyboard);
+       DECL_STATE_ENTRY_BOOL(irqstat_timer);
+       DECL_STATE_ENTRY_BOOL(irqstat_printer);
+       DECL_STATE_ENTRY_BOOL(irqstat_keyboard);
                
                // FD04
 #if defined(_FM77_VARIANTS)
-               state_fio->FputBool(stat_fdmode_2hd);
-               state_fio->FputBool(stat_kanjirom);
+       DECL_STATE_ENTRY_BOOL(stat_fdmode_2hd);
+       DECL_STATE_ENTRY_BOOL(stat_kanjirom);
 #elif defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
        defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
-               state_fio->FputBool(stat_kanjirom);
+       DECL_STATE_ENTRY_BOOL(stat_kanjirom);
 #endif
-               state_fio->FputBool(firq_break_key);
-               state_fio->FputBool(firq_sub_attention);
-               
-               state_fio->FputBool(intmode_fdc);
-               // FD05
-               state_fio->FputBool(extdet_neg);
-               state_fio->FputBool(sub_halt);
-               state_fio->FputBool(sub_cancel);
-               // FD06, 07
-               state_fio->FputBool(intstat_syndet);
-               state_fio->FputBool(intstat_rxrdy);
-               state_fio->FputBool(intstat_txrdy);
-
-
-               state_fio->FputBool(intstat_opn);
-               state_fio->FputBool(intstat_mouse);
-               state_fio->FputBool(mouse_enable);
+       DECL_STATE_ENTRY_BOOL(firq_break_key);
+       DECL_STATE_ENTRY_BOOL(firq_sub_attention);
+       
+       DECL_STATE_ENTRY_BOOL(intmode_fdc);
+       // FD05
+       DECL_STATE_ENTRY_BOOL(extdet_neg);
+       DECL_STATE_ENTRY_BOOL(sub_halt);
+       DECL_STATE_ENTRY_BOOL(sub_cancel);
+       // FD06, 07
+       DECL_STATE_ENTRY_BOOL(intstat_syndet);
+       DECL_STATE_ENTRY_BOOL(intstat_rxrdy);
+       DECL_STATE_ENTRY_BOOL(intstat_txrdy);
+       
        
-               state_fio->FputBool(intstat_whg);
-               state_fio->FputBool(intstat_thg);
-
-               // FDC
-               state_fio->FputBool(connect_fdc);
-               state_fio->FputUint8(fdc_statreg);
-               state_fio->FputUint8(fdc_cmdreg);
-               state_fio->FputUint8(fdc_trackreg);
-               state_fio->FputUint8(fdc_sectreg);
-               state_fio->FputUint8(fdc_datareg);
-               state_fio->FputUint8(fdc_headreg);
-               state_fio->FputUint8(fdc_drvsel);
-               state_fio->FputUint8(irqreg_fdc);
-               state_fio->FputBool(fdc_motor);
-               state_fio->FputBool(irqstat_fdc);
-               // KANJI ROM
-               state_fio->FputBool(connect_kanjiroml1);
+       DECL_STATE_ENTRY_BOOL(intstat_opn);
+       DECL_STATE_ENTRY_BOOL(intstat_mouse);
+       DECL_STATE_ENTRY_BOOL(mouse_enable);
+       
+       DECL_STATE_ENTRY_BOOL(intstat_whg);
+       DECL_STATE_ENTRY_BOOL(intstat_thg);
+       
+       // FDC
+       DECL_STATE_ENTRY_BOOL(connect_fdc);
+       DECL_STATE_ENTRY_UINT8(fdc_statreg);
+       DECL_STATE_ENTRY_UINT8(fdc_cmdreg);
+       DECL_STATE_ENTRY_UINT8(fdc_trackreg);
+       DECL_STATE_ENTRY_UINT8(fdc_sectreg);
+       DECL_STATE_ENTRY_UINT8(fdc_datareg);
+       DECL_STATE_ENTRY_UINT8(fdc_headreg);
+       DECL_STATE_ENTRY_UINT8(fdc_drvsel);
+       DECL_STATE_ENTRY_UINT8(irqreg_fdc);
+       DECL_STATE_ENTRY_BOOL(fdc_motor);
+       DECL_STATE_ENTRY_BOOL(irqstat_fdc);
+       // KANJI ROM
+       DECL_STATE_ENTRY_BOOL(connect_kanjiroml1);
 #if defined(_FM77AV_VARIANTS)
-               state_fio->FputBool(connect_kanjiroml2);
+       DECL_STATE_ENTRY_BOOL(connect_kanjiroml2);
        
-               state_fio->FputBool(boot_ram);
-               state_fio->FputBool(hotreset);
+       DECL_STATE_ENTRY_BOOL(boot_ram);
+       DECL_STATE_ENTRY_BOOL(hotreset);
                // FD13
-               state_fio->FputUint8(sub_monitor_type);
+       DECL_STATE_ENTRY_UINT8(sub_monitor_type);
 #endif 
                // MMR
-       }
        //V2
        {
-               state_fio->FputInt32_BE(event_beep);
-               state_fio->FputInt32_BE(event_beep_oneshot);
-               state_fio->FputInt32_BE(event_timerirq);
+               DECL_STATE_ENTRY_INT(event_beep);
+               DECL_STATE_ENTRY_INT(event_beep_oneshot);
+               DECL_STATE_ENTRY_INT(event_timerirq);
        }               
        { // V3
-               state_fio->FputInt32_BE(event_fdc_motor);
+               DECL_STATE_ENTRY_INT(event_fdc_motor);
 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)|| \
     defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
-               for(int ch = 0; ch < 4; ch++) state_fio->FputUint8(fdc_drive_table[ch]);
-               state_fio->FputUint8(fdc_reg_fd1e);
+               DECL_STATE_ENTRY_UINT8_ARRAY(fdc_drive_table, 4);
+               DECL_STATE_ENTRY_UINT8(fdc_reg_fd1e);
 #endif 
 #if defined(HAS_DMA)
-               state_fio->FputBool(intstat_dma);
-               state_fio->FputUint8(dma_addr & 0x1f);
+               DECL_STATE_ENTRY_BOOL(intstat_dma);
+               DECL_STATE_ENTRY_UINT8(dma_addr);
 #endif                 
 #if defined(_FM77AV_VARIANTS)
-               state_fio->FputUint8(reg_fd12);
+               DECL_STATE_ENTRY_UINT8(reg_fd12);
 #endif         
        }
-       // FD05
-       state_fio->FputBool(req_z80run);
-       state_fio->FputBool(z80_run);
+// FD05
+       DECL_STATE_ENTRY_BOOL(req_z80run);
+       DECL_STATE_ENTRY_BOOL(z80_run);
 
        // UART
-       state_fio->FputBool(rs232c_enabled);
-       state_fio->FputBool(rs232c_dcd);
-       for(int i = 0; i < 3; i++) state_fio->FputBool(uart_enabled[i]);
-       state_fio->FputBool(modem_irqmask_rxrdy);
-       state_fio->FputBool(modem_irqmask_txrdy);
-       state_fio->FputBool(modem_syndet);
-       state_fio->FputBool(modem_rxrdy);
-       state_fio->FputBool(modem_txrdy);
-
-       state_fio->FputBool(midi_uart_irqmask);
-       state_fio->FputBool(midi_syndet);
-       state_fio->FputBool(midi_rxrdy);
-       state_fio->FputBool(midi_txrdy);
+       DECL_STATE_ENTRY_BOOL(rs232c_enabled);
+       DECL_STATE_ENTRY_BOOL(rs232c_dcd);
+       DECL_STATE_ENTRY_BOOL_ARRAY(uart_enabled, 3);
+       
+       DECL_STATE_ENTRY_BOOL(modem_irqmask_rxrdy);
+       DECL_STATE_ENTRY_BOOL(modem_irqmask_txrdy);
+       DECL_STATE_ENTRY_BOOL(modem_syndet);
+       DECL_STATE_ENTRY_BOOL(modem_rxrdy);
+       DECL_STATE_ENTRY_BOOL(modem_txrdy);
+
+       DECL_STATE_ENTRY_BOOL(midi_uart_irqmask);
+       DECL_STATE_ENTRY_BOOL(midi_syndet);
+       DECL_STATE_ENTRY_BOOL(midi_rxrdy);
+       DECL_STATE_ENTRY_BOOL(midi_txrdy);
 #if defined(HAS_2HD)
-       state_fio->FputInt32_BE(event_fdc_motor_2HD);
-       state_fio->FputBool(connect_fdc_2HD);
-       state_fio->FputUint8(fdc_2HD_statreg);
-       state_fio->FputUint8(fdc_2HD_cmdreg);
-       state_fio->FputUint8(fdc_2HD_trackreg);
-       state_fio->FputUint8(fdc_2HD_sectreg);
-       state_fio->FputUint8(fdc_2HD_datareg);
-       state_fio->FputUint8(fdc_2HD_headreg);
-       state_fio->FputUint8(fdc_2HD_drvsel);
-       state_fio->FputBool(irqreg_fdc_2HD);
-       state_fio->FputBool(fdc_2HD_motor);
+       DECL_STATE_ENTRY_INT(event_fdc_motor_2HD);
+       DECL_STATE_ENTRY_BOOL(connect_fdc_2HD);
+       DECL_STATE_ENTRY_UINT8(fdc_2HD_statreg);
+       DECL_STATE_ENTRY_UINT8(fdc_2HD_cmdreg);
+       DECL_STATE_ENTRY_UINT8(fdc_2HD_trackreg);
+       DECL_STATE_ENTRY_UINT8(fdc_2HD_sectreg);
+       DECL_STATE_ENTRY_UINT8(fdc_2HD_datareg);
+       DECL_STATE_ENTRY_UINT8(fdc_2HD_headreg);
+       DECL_STATE_ENTRY_UINT8(fdc_2HD_drvsel);
+       DECL_STATE_ENTRY_UINT8(irqreg_fdc_2HD);
+       DECL_STATE_ENTRY_BOOL(fdc_2HD_motor);
        //state_fio->FputBool(irqstat_fdc);
+       DECL_STATE_ENTRY_INT(event_2hd_nmi);
+       DECL_STATE_ENTRY_UINT32(nmi_delay);
+       DECL_STATE_ENTRY_BOOL(irqstat_fdc_2hd);
+       DECL_STATE_ENTRY_BOOL(drqstat_fdc_2hd);
 #endif
-}
-
-void FM7_MAINIO::save_state(FILEIO *state_fio)
-{
-       int ch;
-       int addr;
-       state_fio->FputUint32_BE(STATE_VERSION);
-       state_fio->FputInt32_BE(this_device_id);
-       this->out_debug_log(_T("Save State: MAINIO: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
-
-       save_state_main(state_fio);
-       // FD0B
-       // FD0F
-       state_fio->FputBool(connect_opn);
-       state_fio->FputBool(connect_whg);
-       state_fio->FputBool(connect_thg);
        
-       state_fio->FputBool(opn_psg_77av);
-       for(ch = 0; ch < 4; ch++) {
-               state_fio->FputUint32_BE(opn_address[ch]);
-               state_fio->FputUint32_BE(opn_data[ch]);
-               state_fio->FputUint32_BE(opn_stat[ch]);
-               state_fio->FputUint32_BE(opn_cmdreg[ch]);
-               state_fio->FputUint32_BE(opn_ch3mode[ch]);
-       }
-#if defined(HAS_2HD)
-       state_fio->FputInt32_BE(event_2hd_nmi);
-       state_fio->FputUint32_BE(nmi_delay);
-       state_fio->FputBool(irqstat_fdc_2hd);
-       state_fio->FputBool(drqstat_fdc_2hd);
-#endif
+       decl_state_opn();
+       
+       leave_decl_state();
 }
-
-bool FM7_MAINIO::load_state_main(FILEIO *state_fio, uint32_t version)
+void FM7_MAINIO::save_state(FILEIO *state_fio)
 {
-       int ch;
-       int addr;
-       if(version >= 1) {
-               for(addr = 0; addr < 0x100; addr++) io_w_latch[addr] = state_fio->FgetUint8();
-               // FD00
-               clock_fast = state_fio->FgetBool();
-               lpt_strobe = state_fio->FgetBool();
-               lpt_slctin = state_fio->FgetBool();
-               beep_flag  = state_fio->FgetBool();
-               beep_snd = state_fio->FgetBool();
-       
-               // FD01
-               lpt_outdata = state_fio->FgetUint8();
-               // FD02
-               cmt_indat = state_fio->FgetBool();
-               cmt_invert = state_fio->FgetBool();
-               lpt_det2 = state_fio->FgetBool();
-               lpt_det1 = state_fio->FgetBool();
-               lpt_pe = state_fio->FgetBool();
-               lpt_ackng_inv = state_fio->FgetBool();
-               lpt_error_inv = state_fio->FgetBool();
-               irqmask_reg0 = state_fio->FgetUint8();
-
-               irqmask_syndet = state_fio->FgetBool();
-               irqmask_rxrdy = state_fio->FgetBool();
-               irqmask_txrdy = state_fio->FgetBool();
-               irqmask_mfd = state_fio->FgetBool();
-               irqmask_timer = state_fio->FgetBool();
-               irqmask_printer = state_fio->FgetBool();
-               irqmask_keyboard = state_fio->FgetBool();
-
-               irqreq_syndet = state_fio->FgetBool();
-               irqreq_rxrdy = state_fio->FgetBool();
-               irqreq_txrdy = state_fio->FgetBool();
-               irqreq_printer = state_fio->FgetBool();
-               irqreq_keyboard = state_fio->FgetBool();
-               // FD03
-               irqstat_reg0 = state_fio->FgetUint8();
-
-               irqstat_timer = state_fio->FgetBool();
-               irqstat_printer = state_fio->FgetBool();
-               irqstat_keyboard = state_fio->FgetBool();
-       
-               // FD04
-#if defined(_FM77_VARIANTS)
-               stat_fdmode_2hd = state_fio->FgetBool();
-               stat_kanjirom = state_fio->FgetBool();
-#elif defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
-       defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
-               stat_kanjirom = state_fio->FgetBool();
-#endif
-               firq_break_key = state_fio->FgetBool();
-               firq_sub_attention = state_fio->FgetBool();
-               
-               intmode_fdc = state_fio->FgetBool();
-               // FD05
-               extdet_neg = state_fio->FgetBool();
-               sub_halt = state_fio->FgetBool();
-               sub_cancel = state_fio->FgetBool();
-               // FD06, 07
-               intstat_syndet = state_fio->FgetBool();
-               intstat_rxrdy = state_fio->FgetBool();
-               intstat_txrdy = state_fio->FgetBool();
-
-               intstat_opn = state_fio->FgetBool();
-               intstat_mouse = state_fio->FgetBool();
-               mouse_enable = state_fio->FgetBool();
-       
-               intstat_whg = state_fio->FgetBool();
-               intstat_thg = state_fio->FgetBool();
-
-               // FDC
-               connect_fdc = state_fio->FgetBool();
-               fdc_statreg = state_fio->FgetUint8();
-               fdc_cmdreg = state_fio->FgetUint8();
-               fdc_trackreg = state_fio->FgetUint8();
-               fdc_sectreg = state_fio->FgetUint8();
-               fdc_datareg = state_fio->FgetUint8();
-               fdc_headreg = state_fio->FgetUint8();
-               fdc_drvsel = state_fio->FgetUint8();
-               irqreg_fdc = state_fio->FgetUint8();
-               fdc_motor = state_fio->FgetBool();
-               irqstat_fdc = state_fio->FgetBool();
-
-               // KANJI ROM
-               connect_kanjiroml1 = state_fio->FgetBool();
-#if defined(_FM77AV_VARIANTS)
-               connect_kanjiroml2 = state_fio->FgetBool();
-               boot_ram = state_fio->FgetBool();
-               hotreset = state_fio->FgetBool();
-               // FD13
-               sub_monitor_type = state_fio->FgetUint8();
-#endif 
-       }
-       if(version >= 2) {
-               event_beep = state_fio->FgetInt32_BE();
-               event_beep_oneshot = state_fio->FgetInt32_BE();
-               event_timerirq = state_fio->FgetInt32_BE();
+       if(state_entry != NULL) state_entry->save_state(state_fio);
+#if 0
+       // Debug
+       for(int i = 0; i < 3; i++) {
+               out_debug_log("OPN#%d registers (to Save)", i);
+               out_debug_log("ADDR: +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f");
+               for(int ladr = 0; ladr < 0x100; ladr += 0x10) {
+                       out_debug_log("+%02x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+                                                 ladr,
+                                                 opn_regs[i][ladr + 0],  opn_regs[i][ladr + 1],  opn_regs[i][ladr + 2],  opn_regs[i][ladr + 3],
+                                                 opn_regs[i][ladr + 4],  opn_regs[i][ladr + 5],  opn_regs[i][ladr + 6],  opn_regs[i][ladr + 7],
+                                                 opn_regs[i][ladr + 8],  opn_regs[i][ladr + 9],  opn_regs[i][ladr + 10], opn_regs[i][ladr + 11],
+                                                 opn_regs[i][ladr + 12], opn_regs[i][ladr + 13], opn_regs[i][ladr + 14], opn_regs[i][ladr + 15]);
+               }
        }
-       // V2
-       if(version >= 3) { // V3
-               event_fdc_motor = state_fio->FgetInt32_BE();
-#if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)|| \
-    defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
-               for(ch = 0; ch < 4; ch++) fdc_drive_table[ch] = state_fio->FgetUint8();
-               fdc_reg_fd1e = state_fio->FgetUint8();
 #endif 
-#if defined(HAS_DMA)
-               intstat_dma = state_fio->FgetBool();
-               dma_addr = (uint32_t)(state_fio->FgetUint8() & 0x1f);
-#endif                 
-#if defined(_FM77AV_VARIANTS)
-               reg_fd12 = state_fio->FgetUint8();
-#endif         
-       }
-       // FD05
-       req_z80run = state_fio->FgetBool();
-       z80_run = state_fio->FgetBool();
-       
-       // UART
-       rs232c_enabled = state_fio->FgetBool();
-       rs232c_dcd = state_fio->FgetBool();
-       for(int i = 0; i < 3; i++) uart_enabled[i] = state_fio->FgetBool();
-       modem_irqmask_rxrdy = state_fio->FgetBool();
-       modem_irqmask_txrdy = state_fio->FgetBool();
-       modem_syndet = state_fio->FgetBool();
-       modem_rxrdy = state_fio->FgetBool();
-       modem_txrdy = state_fio->FgetBool();
-
-       midi_uart_irqmask = state_fio->FgetBool();
-       midi_syndet = state_fio->FgetBool();
-       midi_rxrdy = state_fio->FgetBool();
-       midi_txrdy = state_fio->FgetBool();
-#if defined(HAS_2HD)
-       event_fdc_motor_2HD = state_fio->FgetInt32_BE();
-       connect_fdc_2HD = state_fio->FgetBool();
-       fdc_2HD_statreg = state_fio->FgetUint8();
-       fdc_2HD_cmdreg = state_fio->FgetUint8();
-       fdc_2HD_trackreg = state_fio->FgetUint8();
-       fdc_2HD_sectreg = state_fio->FgetUint8();
-       fdc_2HD_datareg =state_fio->FgetUint8();
-       fdc_2HD_headreg = state_fio->FgetUint8();
-       fdc_2HD_drvsel = state_fio->FgetUint8();
-       irqreg_fdc_2HD = state_fio->FgetBool();
-       fdc_2HD_motor = state_fio->FgetBool();
-       //state_fio->FputBool(irqstat_fdc);
-#endif
-       return true;
 }
 
 bool FM7_MAINIO::load_state(FILEIO *state_fio)
@@ -2297,33 +2149,30 @@ bool FM7_MAINIO::load_state(FILEIO *state_fio)
        int addr;
        //bool stat = 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: MAINIO: id=%d ver=%d\n"), this_device_id, version);
-
-       if(!load_state_main(state_fio, version)) return false;
-       // FD0B
-       // FD0F
-       connect_opn = state_fio->FgetBool();
-       connect_whg = state_fio->FgetBool();
-       connect_thg = state_fio->FgetBool();
-
-       opn_psg_77av = state_fio->FgetBool();
-       for(ch = 0; ch < 4; ch++) {
-               opn_address[ch] = state_fio->FgetUint32_BE();
-               opn_data[ch] = state_fio->FgetUint32_BE();
-               opn_stat[ch] = state_fio->FgetUint32_BE();
-               opn_cmdreg[ch] = state_fio->FgetUint32_BE();
-               opn_ch3mode[ch] = state_fio->FgetUint32_BE();
+       bool mb = false;
+       if(state_entry != NULL) {
+               mb = state_entry->load_state(state_fio);
+               if(mb) {
+#if defined(HAS_DMA)
+                       dma_addr = dma_addr & 0x1f;
+#endif
+               }
+       }
+#if 0
+       for(int i = 0; i < 3; i++) {
+               out_debug_log("OPN#%d registers (Loaded)", i);
+               out_debug_log("ADDR: +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f");
+               for(int ladr = 0; ladr < 0x100; ladr += 0x10) {
+                       out_debug_log("+%02x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+                                                 ladr,
+                                                 opn_regs[i][ladr + 0],  opn_regs[i][ladr + 1],  opn_regs[i][ladr + 2],  opn_regs[i][ladr + 3],
+                                                 opn_regs[i][ladr + 4],  opn_regs[i][ladr + 5],  opn_regs[i][ladr + 6],  opn_regs[i][ladr + 7],
+                                                 opn_regs[i][ladr + 8],  opn_regs[i][ladr + 9],  opn_regs[i][ladr + 10], opn_regs[i][ladr + 11],
+                                                 opn_regs[i][ladr + 12], opn_regs[i][ladr + 13], opn_regs[i][ladr + 14], opn_regs[i][ladr + 15]);
+               }
        }
-#if defined(HAS_2HD)
-       event_2hd_nmi = state_fio->FgetInt32_BE();
-       nmi_delay = state_fio->FgetUint32_BE();
-       irqstat_fdc_2hd = state_fio->FgetBool();
-       drqstat_fdc_2hd = state_fio->FgetBool();
 #endif
-       if(version != STATE_VERSION) return false;
-       return true;
+       this->out_debug_log(_T("Load State: MAINIO: id=%d stat=%s\n"), this_device_id, (mb) ? _T("OK") : _T("NG"));
+       return mb;
 }