OSDN Git Service

[UI][Qt][VM][PC8801] Update to Upstream.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 20 Feb 2019 13:03:58 +0000 (22:03 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 20 Feb 2019 13:03:58 +0000 (22:03 +0900)
source/src/qt/machines/pc8801/MainWindow.cpp
source/src/qt/machines/pc8801/menuclasses.h
source/src/vm/pc8801/pc88.cpp
source/src/vm/pc8801/pc88.h
source/src/vm/pc8801/pc8801.cpp
source/src/vm/pc8801/pc8801.h

index db1bd63..b38ef3b 100644 (file)
@@ -37,6 +37,20 @@ void Object_Menu_Control_88::do_set_memory_wait(bool flag)
        emit sig_set_dipsw(0, flag);
 }
 
+void Object_Menu_Control_88::do_set_hmb20(bool flag)
+{
+       emit sig_set_dipsw(1, flag);
+}
+
+void Object_Menu_Control_88::do_set_gsx8800(bool flag)
+{
+       emit sig_set_dipsw(2, flag);
+}
+
+void Object_Menu_Control_88::do_set_pcg8100(bool flag)
+{
+       emit sig_set_dipsw(3, flag);
+}
 
 Action_Control_88::Action_Control_88(QObject *parent, USING_FLAGS *p) : Action_Control(parent, p)
 {
@@ -230,8 +244,25 @@ void META_MainWindow::retranslateUi(void)
        actionPrintDevice[1]->setEnabled(false);
 #endif
        
+#if defined(USE_DIPSWITCH)
        actionMemoryWait->setText(QApplication::translate("MenuPC88", "Wait Memory", 0));
        actionMemoryWait->setToolTip(QApplication::translate("MenuPC88", "Simulate waiting memory.", 0));
+
+       #if defined(SUPPORT_PC88_HMB20)
+       actionHMB20->setText(QApplication::translate("MenuPC88", "Use HMB20(Need RESTART)", 0));
+       actionHMB20->setToolTip(QApplication::translate("MenuPC88", "Using HMB20 OPM sound board.\nRe-start emulator when changed.", 0));
+       #endif
+       #if defined(SUPPORT_PC88_GSX8800)
+       actionGSX8800->setText(QApplication::translate("MenuPC88", "Use GSX8800(Need RESTART)", 0));
+       actionGSX8800->setToolTip(QApplication::translate("MenuPC88", "Using GSX8800 PSGs sound board.\nRe-start emulator when changed.", 0));
+       #endif
+       #if defined(SUPPORT_PC88_PCG8100)
+       actionPCG8100->setText(QApplication::translate("MenuPC88", "Use PCG8100(Need RESTART)", 0));
+       actionPCG8100->setToolTip(QApplication::translate("MenuPC88", "Using PCG8100 programmable character generator board.\nRe-start emulator when changed.", 0));
+       #endif
+       
+
+#endif
 #if defined(USE_MONITOR_TYPE)
        actionMonitorType[0]->setText(QApplication::translate("MenuPC88", "High Resolution", 0));
        actionMonitorType[1]->setText(QApplication::translate("MenuPC88", "Standard", 0));
@@ -253,6 +284,7 @@ void META_MainWindow::setupUI_Emu(void)
 #else
        ConfigCPUBootMode(4);
 #endif
+#if defined(USE_DIPSWITCH)
        actionMemoryWait = new Action_Control_88(this, using_flags);
        actionMemoryWait->setCheckable(true);
        actionMemoryWait->setVisible(true);
@@ -265,6 +297,46 @@ void META_MainWindow::setupUI_Emu(void)
        connect(actionMemoryWait->pc88_binds, SIGNAL(sig_set_dipsw(int, bool)),
                        this, SLOT(set_dipsw(int, bool)));
 
+       #ifdef SUPPORT_PC88_HMB20
+       actionHMB20 = new Action_Control_88(this, using_flags);
+       actionHMB20->setCheckable(true);
+       actionHMB20->setVisible(true);
+       actionHMB20->setChecked(false);
+
+       menuMachine->addAction(actionHMB20);
+       if((config.dipswitch & DIPSWITCH_HMB20) != 0) actionHMB20->setChecked(true);
+       connect(actionHMB20, SIGNAL(toggled(bool)),
+                       actionHMB20->pc88_binds, SLOT(do_set_hmb20(bool)));
+       connect(actionHMB20->pc88_binds, SIGNAL(sig_set_dipsw(int, bool)),
+                       this, SLOT(set_dipsw(int, bool)));
+       #endif  
+       #ifdef SUPPORT_PC88_GSX8800
+       actionGSX8800 = new Action_Control_88(this, using_flags);
+       actionGSX8800->setCheckable(true);
+       actionGSX8800->setVisible(true);
+       actionGSX8800->setChecked(false);
+
+       menuMachine->addAction(actionGSX8800);
+       if((config.dipswitch & DIPSWITCH_GSX8800) != 0) actionGSX8800->setChecked(true);
+       connect(actionGSX8800, SIGNAL(toggled(bool)),
+                       actionGSX8800->pc88_binds, SLOT(do_set_gsx8800(bool)));
+       connect(actionGSX8800->pc88_binds, SIGNAL(sig_set_dipsw(int, bool)),
+                       this, SLOT(set_dipsw(int, bool)));
+       #endif
+       #ifdef SUPPORT_PC88_PCG8100
+       actionPCG8100 = new Action_Control_88(this, using_flags);
+       actionPCG8100->setCheckable(true);
+       actionPCG8100->setVisible(true);
+       actionPCG8100->setChecked(false);
+
+       menuMachine->addAction(actionPCG8100);
+       if((config.dipswitch & DIPSWITCH_PCG8100) != 0) actionPCG8100->setChecked(true);
+       connect(actionPCG8100, SIGNAL(toggled(bool)),
+                       actionPCG8100->pc88_binds, SLOT(do_set_pcg8100(bool)));
+       connect(actionPCG8100->pc88_binds, SIGNAL(sig_set_dipsw(int, bool)),
+                       this, SLOT(set_dipsw(int, bool)));
+       #endif
+#endif
 }
 
 
index 5795ca1..a39caad 100644 (file)
@@ -18,6 +18,9 @@ class Object_Menu_Control_88: public Object_Menu_Control
 signals:
 public slots:
        void do_set_memory_wait(bool);
+       void do_set_hmb20(bool);
+       void do_set_gsx8800(bool);
+       void do_set_pcg8100(bool);
 };
 
 class Action_Control_88 : public Action_Control
@@ -39,6 +42,9 @@ class META_MainWindow : public Ui_MainWindow {
 protected:
        int config_sound_device_type;
        class Action_Control_88 *actionMemoryWait; //
+       class Action_Control_88 *actionHMB20; //
+       class Action_Control_88 *actionGSX8800; //
+       class Action_Control_88 *actionPCG8100; //
        void setupUI_Emu(void);
        void retranslateUi(void);
 public:
index 9dae1d8..8eed6e2 100644 (file)
@@ -45,6 +45,7 @@
 #define IRQ_USART      0
 #define IRQ_VRTC       1
 #define IRQ_TIMER      2
+#define IRQ_INT3       3
 #define IRQ_SOUND      4
 
 namespace PC88DEV 
@@ -156,9 +157,7 @@ namespace PC88DEV
 #define PortE2_RDEN    (port[0xe2] & 0x01)
 #define PortE2_WREN    (port[0xe2] & 0x10)
 
-#ifdef PC88_IODATA_EXRAM
-#define PortE3_ERAMSL  port[0xe3]
-#else
+#if !defined(PC8001_VARIANT)
 #define PortE3_ERAMSL  (port[0xe3] & 0x0f)
 #endif
 #endif
@@ -262,8 +261,12 @@ void PC88::initialize()
 #ifdef PC88_EXRAM_BANKS
        memset(exram, 0, sizeof(exram));
 #endif
+#if defined(SUPPORT_PC88_GVRAM)
        memset(gvram, 0, sizeof(gvram));
        memset(gvram_null, 0, sizeof(gvram_null));
+#else
+       memset(graph, 0, sizeof(graph));
+#endif
 #if defined(PC8801SR_VARIANT)
        memset(tvram, 0, sizeof(tvram));
 #endif
@@ -365,13 +368,11 @@ void PC88::initialize()
        }
 #endif
 #ifdef SUPPORT_PC88_CDROM
-//     if(config.boot_mode == MODE_PC88_V2) {
-               if(fio->Fopen(create_local_path(_T("CDBIOS.ROM")), FILEIO_READ_BINARY)) {
-                       fio->Fread(cdbios, 0x10000, 1);
-                       fio->Fclose();
-                       cdbios_loaded = true;
-               }
-//     }
+       if(fio->Fopen(create_local_path(_T("CDBIOS.ROM")), FILEIO_READ_BINARY)) {
+               fio->Fread(cdbios, 0x10000, 1);
+               fio->Fclose();
+               cdbios_loaded = true;
+       }
 #endif
        delete fio;
        
@@ -403,6 +404,9 @@ void PC88::initialize()
                        ofs += 16;
                }
        }
+#ifdef PC8001_VARIANT
+       ram[0xff33] = 0; // DEMPA Galaxian
+#endif
        
        // create semi graphics pattern
        for(int i = 0; i < 256; i++) {
@@ -487,16 +491,16 @@ void PC88::reset()
 //     port[0x70] = 0x80;      // XM8 version 1.10
        port[0x71] = port[0xf1] = 0xff;
 #if defined(SUPPORT_PC88_CDROM)
-       if(config.boot_mode == MODE_PC88_V2) {
-               if(cdbios_loaded) {
-                       port[0x99]  = 0x10;
-               }
+       if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
+               port[0x99]  = 0x10;
        }
 #endif
 #if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
        memset(alu_reg, 0, sizeof(alu_reg));
 #endif
+#if defined(SUPPORT_PC88_GVRAM)
        gvram_plane = gvram_sel = 0;
+#endif
        
 #if defined(PC8001_VARIANT)
 #if defined(_PC8001SR)
@@ -555,7 +559,7 @@ void PC88::reset()
        memset(&dmac, 0, sizeof(dmac));
        dmac.ch[0].io = dmac.ch[3].io = vm->dummy;
 #ifdef SUPPORT_PC88_CDROM
-       if(cdbios_loaded) {
+       if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
                dmac.ch[1].io = d_scsi_host;
        } else
 #endif
@@ -633,7 +637,7 @@ void PC88::write_data8w(uint32_t addr, uint32_t data, int* wait)
                return;
        }
 #endif
-#if defined(_PC8001MK2) || defined(_PC8001SR) || defined(PC8801_VARIANT)
+#if defined(SUPPORT_PC88_GVRAM)
 #if defined(PC8801_VARIANT)
        if((addr & 0xc000) == 0xc000) {
 #else
@@ -714,7 +718,7 @@ uint32_t PC88::read_data8w(uint32_t addr, int* wait)
                return ram[addr & 0xffff];
        }
 #endif
-#if defined(_PC8001MK2) || defined(_PC8001SR) || defined(PC8801_VARIANT)
+#if defined(SUPPORT_PC88_GVRAM)
 #if defined(PC8801_VARIANT)
        if((addr & 0xc000) == 0xc000) {
 #else
@@ -869,15 +873,23 @@ void PC88::write_io8(uint32_t addr, uint32_t data)
                }
                pcg_addr = (pcg_addr & 0x0ff) | ((data & 3) << 8);
                pcg_ctrl = data;
-               d_pcg_pcm0->write_signal(SIG_PCM1BIT_ON, data, 0x08);
-               d_pcg_pcm1->write_signal(SIG_PCM1BIT_ON, data, 0x40);
-               d_pcg_pcm2->write_signal(SIG_PCM1BIT_ON, data, 0x80);
+               if(d_pcg_pcm1 != NULL) {
+                       d_pcg_pcm1->write_signal(SIG_PCM1BIT_ON, data, 0x08);
+               }
+               if(d_pcg_pcm2 != NULL) {
+                       d_pcg_pcm2->write_signal(SIG_PCM1BIT_ON, data, 0x40);
+               }
+               if(d_pcg_pcm3 != NULL) {
+                       d_pcg_pcm3->write_signal(SIG_PCM1BIT_ON, data, 0x80);
+               }
                break;
        case 0x0c:
        case 0x0d:
        case 0x0e:
        case 0x0f:
-               d_pcg_pit->write_io8(addr & 3, data);
+               if(d_pcg_pit != NULL) {
+                       d_pcg_pit->write_io8(addr & 3, data);
+               }
                break;
 #endif
        case 0x10:
@@ -983,7 +995,7 @@ void PC88::write_io8(uint32_t addr, uint32_t data)
                }
                if(mod & 0x10) {
                        // XM8 version 1.10
-//                     if(config.boot_mode == MODE_PC88_V1H || config.boot_mode == MODE_PC88_V2) {
+//                     if(config.boot_mode == MODE_PC88_V1H || config.boot_mode == MODE_PC88_V2 || config.boot_mode == MODE_PC88_V2CD) {
                                update_tvram_memmap();
                                f000_m1_wait_clocks = get_m1_wait(true);
 //                     }
@@ -1011,9 +1023,11 @@ void PC88::write_io8(uint32_t addr, uint32_t data)
                d_rtc->write_signal(SIG_UPD1990A_STB, ~data, 2);
                d_rtc->write_signal(SIG_UPD1990A_CLK, data, 4);
                // bit3: crtc i/f sync mode
+#if defined(SUPPORT_PC88_GVRAM)
                if(mod & 0x10) {
                        update_gvram_wait();
                }
+#endif
                beep_on = ((data & 0x20) != 0);
 #ifdef SUPPORT_PC88_JOYSTICK
                if(mod & 0x40) {
@@ -1156,13 +1170,15 @@ void PC88::write_io8(uint32_t addr, uint32_t data)
 #ifdef SUPPORT_PC88_HMB20
        case 0x88:
        case 0x89:
-               d_opm->write_io8(addr, data);
+               if(d_opm != NULL) {
+                       d_opm->write_io8(addr, data);
+               }
                break;
 #endif
 #ifdef SUPPORT_PC88_CDROM
        // M88 cdif
        case 0x90:
-               if(cdbios_loaded && (mod & 0x01)) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded && (mod & 0x01)) {
                        if(data & 0x01) {
                                if(port[0x9f] & 0x01) {
                                        d_scsi_host->write_signal(SIG_SCSI_SEL, 0, 1);
@@ -1176,17 +1192,17 @@ void PC88::write_io8(uint32_t addr, uint32_t data)
                }
                break;
        case 0x91:
-               if(cdbios_loaded) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
                        d_scsi_host->write_dma_io8(0, data);
                }
                break;
        case 0x94:
-               if(cdbios_loaded) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
                        d_scsi_host->write_signal(SIG_SCSI_RST, data, 0x80);
                }
                break;
        case 0x98:
-               if(cdbios_loaded) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
                        switch(data & 7) {
                        case 0:
                        case 1:
@@ -1236,12 +1252,46 @@ void PC88::write_io8(uint32_t addr, uint32_t data)
                }
                break;
        case 0x99:
-               if(cdbios_loaded && (mod & 0x10)) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded && (mod & 0x10)) {
                        update_low_read();
                }
                break;
 #endif
 #endif
+#ifdef SUPPORT_PC88_GSX8800
+       case 0xa0:
+       case 0xa1:
+               if(d_gsx_psg1 != NULL) {
+                       d_gsx_psg1->write_io8(addr, data);
+               }
+               break;
+       case 0xa2:
+       case 0xa3:
+               if(d_gsx_psg2 != NULL) {
+                       d_gsx_psg2->write_io8(addr, data);
+               }
+               break;
+       case 0xa4:
+       case 0xa5:
+               if(d_gsx_psg3 != NULL) {
+                       d_gsx_psg3->write_io8(addr, data);
+               }
+               break;
+       case 0xa6:
+       case 0xa7:
+               if(d_gsx_psg4 != NULL) {
+                       d_gsx_psg4->write_io8(addr, data);
+               }
+               break;
+//     case 0xc4:
+//     case 0xc5:
+//     case 0xc6:
+//     case 0xc7:
+//             if(d_gsx_pit != NULL) {
+//                     d_gsx_pit->write_io8(addr & 3, data);
+//             }
+//             break;
+#endif
 #ifdef SUPPORT_PC88_OPN2
        case 0xa8:
        case 0xa9:
@@ -1275,12 +1325,6 @@ void PC88::write_io8(uint32_t addr, uint32_t data)
                        update_n80_write();
                }
                break;
-       case 0xe3:
-               if(mod) {
-                       update_n80_write();
-                       update_n80_read();
-               }
-               break;
 #else
        case 0xe2:
                if(mod & 0x01) {
@@ -1291,11 +1335,7 @@ void PC88::write_io8(uint32_t addr, uint32_t data)
                }
                break;
        case 0xe3:
-#ifdef PC88_IODATA_EXRAM
-               if(mod) {
-#else
                if(mod & 0x0f) {
-#endif
                        if(PortE2_RDEN) {
                                update_low_read();
                        }
@@ -1431,7 +1471,7 @@ uint32_t PC88::read_io8_debug(uint32_t addr)
        case 0x31:
                return (config.boot_mode == MODE_PC80_V2 ? 0 : 0x80) | 0x39;
 #endif
-#if defined(_PC8801SR)
+#if defined(_PC8001SR)
        case 0x32:
                return port[0x32];
        case 0x33:
@@ -1443,8 +1483,8 @@ uint32_t PC88::read_io8_debug(uint32_t addr)
                return (config.boot_mode == MODE_PC88_N ? 0 : 1) | 0xc2; // 80x25
        case 0x31:
                // XM8 version 1.10
-               return (config.boot_mode == MODE_PC88_V2 ? 0 : 0x80) | (config.boot_mode == MODE_PC88_V1S || config.boot_mode == MODE_PC88_N ? 0 : 0x40) | 0x39;
-//             return (config.boot_mode == MODE_PC88_V2 ? 0 : 0x80) | (config.boot_mode == MODE_PC88_V1S || config.boot_mode == MODE_PC88_N ? 0 : 0x40);
+               return (config.boot_mode == MODE_PC88_V2 || config.boot_mode == MODE_PC88_V2CD ? 0 : 0x80) | (config.boot_mode == MODE_PC88_V1S || config.boot_mode == MODE_PC88_N ? 0 : 0x40) | 0x39;
+//             return (config.boot_mode == MODE_PC88_V2 || config.boot_mode == MODE_PC88_V2CD ? 0 : 0x80) | (config.boot_mode == MODE_PC88_V1S || config.boot_mode == MODE_PC88_N ? 0 : 0x40);
        case 0x32:
                return port[0x32];
 #endif
@@ -1550,12 +1590,15 @@ uint32_t PC88::read_io8_debug(uint32_t addr)
 #ifdef SUPPORT_PC88_HMB20
 //     case 0x88:
        case 0x89:
-               return d_opm->read_io8(addr);
+               if(d_opm != NULL) {
+                       return d_opm->read_io8(addr);
+               }
+               break;
 #endif
 #ifdef SUPPORT_PC88_CDROM
        // M88 cdif
        case 0x90:
-               if(cdbios_loaded) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
                        val  = d_scsi_host->read_signal(SIG_SCSI_BSY) ? 0x80 : 0;
                        val |= d_scsi_host->read_signal(SIG_SCSI_REQ) ? 0x40 : 0;
                        val |= d_scsi_host->read_signal(SIG_SCSI_MSG) ? 0x20 : 0;
@@ -1573,36 +1616,58 @@ uint32_t PC88::read_io8_debug(uint32_t addr)
                }
                break;
        case 0x91:
-               if(cdbios_loaded) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
                        return d_scsi_host->read_dma_io8(0);
                }
                break;
        case 0x92:
        case 0x93:
        case 0x96:
-               if(cdbios_loaded) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
                        return 0x00;
                }
                break;
        case 0x99:
-               if(cdbios_loaded) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
 //                     return 0xcd; // PC-8801MC
                        return 0x00;
                }
                break;
        case 0x98:
-               if(cdbios_loaded) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
                        port[0x98] ^= 0x80; // clock ???
                        return port[0x98];
                }
                break;
        case 0x9b:
        case 0x9d:
-               if(cdbios_loaded) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded) {
                        return 60;
                }
                break;
 #endif
+#ifdef SUPPORT_PC88_GSX8800
+       case 0xa1:
+               if(d_gsx_psg1 != NULL) {
+                       return d_gsx_psg1->read_io8(addr);
+               }
+               break;
+       case 0xa3:
+               if(d_gsx_psg2 != NULL) {
+                       return d_gsx_psg2->read_io8(addr);
+               }
+               break;
+       case 0xa5:
+               if(d_gsx_psg3 != NULL) {
+                       return d_gsx_psg3->read_io8(addr);
+               }
+               break;
+       case 0xa7:
+               if(d_gsx_psg4 != NULL) {
+                       return d_gsx_psg4->read_io8(addr);
+               }
+               break;
+#endif
 #ifdef SUPPORT_PC88_OPN2
        case 0xa8:
                if(d_opn2 != NULL) {
@@ -1666,10 +1731,8 @@ uint32_t PC88::read_io8_debug(uint32_t addr)
 #if defined(PC88_EXRAM_BANKS)
        case 0xe2:
                return (~port[0xe2]) | 0xee;
+#if !defined(PC8001_VARIANT)
        case 0xe3:
-#ifdef PC88_IODATA_EXRAM
-               return port[0xe3];
-#else
                return port[0xe3] | 0xf0;
 #endif
 #endif
@@ -1697,7 +1760,7 @@ uint32_t PC88::read_dma_data8(uint32_t addr)
 {
        // from ram
 #if defined(PC8801SR_VARIANT)
-       if((addr & 0xf000) == 0xf000 && (config.boot_mode == MODE_PC88_V1H || config.boot_mode == MODE_PC88_V2)) {
+       if((addr & 0xf000) == 0xf000 && (config.boot_mode == MODE_PC88_V1H || config.boot_mode == MODE_PC88_V2 || config.boot_mode == MODE_PC88_V2CD)) {
                return tvram[addr & 0xfff];
        }
 #endif
@@ -1732,11 +1795,13 @@ int PC88::get_m1_wait(bool addr_f000)
        // XM8 version 1.20
        int wait = 0;
        
+#if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
 #if defined(PC8001_VARIANT)
        if(config.boot_mode == MODE_PC80_V1 || config.boot_mode == MODE_PC80_N) {
 #else
        if(config.boot_mode == MODE_PC88_V1S || config.boot_mode == MODE_PC88_N) {
 #endif
+#endif
                // V1S or N
                if(!mem_wait_on) {
                        // memory wait = off
@@ -1745,6 +1810,7 @@ int PC88::get_m1_wait(bool addr_f000)
                                wait += 1;
                        }
                }
+#if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
        } else {
                // V1H or V2
                if(!mem_wait_on) {
@@ -1760,6 +1826,7 @@ int PC88::get_m1_wait(bool addr_f000)
                        }
                }
        }
+#endif
        return wait;
 }
 
@@ -1778,7 +1845,7 @@ int PC88::get_main_wait(bool read)
                }
        } else {
                // 8MHz
-#if defined(PC8801SR_VARIANT)
+#if defined(SUPPORT_PC88_HIGH_CLOCK)
                if(!cpu_clock_high_fe2) {
                        // not 8MHzH
                        wait += 1;
@@ -1819,6 +1886,7 @@ int PC88::get_tvram_wait(bool read)
 }
 #endif
 
+#if defined(SUPPORT_PC88_GVRAM)
 int PC88::get_gvram_wait(bool read)
 {
        // XM8 version 1.20
@@ -1828,12 +1896,14 @@ int PC88::get_gvram_wait(bool read)
                // graphic on
                if(cpu_clock_low) {
                        // 4MHz
+#if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
 #if defined(PC8001_VARIANT)
                        if(config.boot_mode == MODE_PC80_V1 || config.boot_mode == MODE_PC80_N) {
 #else
                        if(config.boot_mode == MODE_PC88_V1S || config.boot_mode == MODE_PC88_N) {
 #endif
-                               // V1S
+#endif
+                               // V1S or N
                                if(!Port40_GHSM && !crtc.vblank) {
                                        // V1S + not GHSM, V-DISP
                                        if(hireso) {
@@ -1848,6 +1918,7 @@ int PC88::get_gvram_wait(bool read)
                                                wait += 2;
                                        }
                                }
+#if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
                        } else {
                                // V1H or V2
                                if(crtc.vblank) {
@@ -1856,14 +1927,17 @@ int PC88::get_gvram_wait(bool read)
                                        wait += 2;
                                }
                        }
+#endif
                } else {
                        // 8MHz
+#if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
 #if defined(PC8001_VARIANT)
                        if(config.boot_mode == MODE_PC80_V1 || config.boot_mode == MODE_PC80_N) {
 #else
                        if(config.boot_mode == MODE_PC88_V1S || config.boot_mode == MODE_PC88_N) {
 #endif
-                               // V1S
+#endif
+                               // V1S or N
                                if(!Port40_GHSM && !crtc.vblank) {
                                        // V1S + not GHSM, V-DISP
                                        if(hireso) {
@@ -1878,6 +1952,7 @@ int PC88::get_gvram_wait(bool read)
                                                wait += 5;
                                        }
                                }
+#if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
                        } else {
                                // V1H or V2
                                if(crtc.vblank) {
@@ -1886,6 +1961,7 @@ int PC88::get_gvram_wait(bool read)
                                        wait += 5;
                                }
                        }
+#endif
                }
        } else {
                // graphic off
@@ -1928,17 +2004,14 @@ void PC88::update_gvram_sel()
        }
        f000_m1_wait_clocks = get_m1_wait(true);
 }
+#endif
 
 #if defined(PC8001_VARIANT)
 void PC88::update_n80_write()
 {
 #if defined(PC88_EXRAM_BANKS)
        if(PortE2_WREN || Port31_MMODE) {
-               if(PortE3_ERAMSL < PC88_EXRAM_BANKS) {
-                       SET_BANK_W(0x0000, 0x7fff, exram + 0x8000 * PortE3_ERAMSL);
-               } else {
-                       SET_BANK_W(0x0000, 0x7fff, exram);
-               }
+               SET_BANK_W(0x0000, 0x7fff, exram);
                return;
        }
 #endif
@@ -1949,11 +2022,7 @@ void PC88::update_n80_read()
 {
 #if defined(PC88_EXRAM_BANKS)
        if(PortE2_RDEN || Port31_MMODE) {
-               if(PortE3_ERAMSL < PC88_EXRAM_BANKS) {
-                       SET_BANK_R(0x0000, 0x7fff, exram + 0x8000 * PortE3_ERAMSL);
-               } else {
-                       SET_BANK_R(0x0000, 0x7fff, exram);
-               }
+               SET_BANK_R(0x0000, 0x7fff, exram);
                return;
        }
 #endif
@@ -1996,7 +2065,7 @@ void PC88::update_low_read()
                return;
        }
 #ifdef SUPPORT_PC88_CDROM
-       if(cdbios_loaded && Port99_CDREN) {
+       if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded && Port99_CDREN) {
                if(Port31_RMODE) {
                        SET_BANK_R(0x0000, 0x7fff, cdbios + 0x8000);
                } else {
@@ -2068,7 +2137,7 @@ void PC88::write_signal(int id, uint32_t data, uint32_t mask)
 #endif
 #ifdef SUPPORT_PC88_CDROM
        } else if(id == SIG_PC88_SCSI_DRQ) {
-               if((data & mask) && cdbios_loaded) {
+               if(config.boot_mode == MODE_PC88_V2CD && cdbios_loaded && (data & mask)) {
                        if(!dmac.ch[1].running) {
                                dmac.start(1);
                        }
@@ -2077,6 +2146,12 @@ void PC88::write_signal(int id, uint32_t data, uint32_t mask)
                        }
                }
 #endif
+#ifdef SUPPORT_PC88_GSX8800
+       } else if(id == SIG_PC88_GSX_IRQ) {
+               if(data & mask) {
+                       request_intr(IRQ_INT3, true);
+               }
+#endif
        } else if(id == SIG_PC88_USART_OUT) {
                // recv from sio
                if(Port30_CMT) {
@@ -2203,19 +2278,25 @@ void PC88::event_vline(int v, int clock)
                crtc.start();
                // for Nobunaga Fuunroku Opening (XM8 version 1.00)
 //             request_intr(IRQ_VRTC, false);
+#if defined(SUPPORT_PC88_GVRAM)
                update_gvram_wait();
+#endif
        }
        if(v < disp_line) {
                if(/*(crtc.status & 0x10) && */dmac.ch[2].running) {
                        // bus request
+#if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
 #if defined(PC8001_VARIANT)
                        if(config.boot_mode == MODE_PC80_V1 || config.boot_mode == MODE_PC80_N) {
 #else
                        if(config.boot_mode == MODE_PC88_V1S || config.boot_mode == MODE_PC88_N) {
 #endif
+#endif
                                d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
                                register_event_by_clock(this, EVENT_BUSREQ, busreq_clocks, false, NULL);
+#if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
                        }
+#endif
                        // run dma transfer to crtc
                        if((v % crtc.char_height) == 0) {
                                dmac.run(2, 80 + crtc.attrib.num * 2);
@@ -2232,7 +2313,9 @@ void PC88::event_vline(int v, int clock)
                
                crtc.finish();
                request_intr(IRQ_VRTC, true);
+#if defined(SUPPORT_PC88_GVRAM)
                update_gvram_wait();
+#endif
        }
        // update palette
 #if defined(PC8801SR_VARIANT)
@@ -2464,13 +2547,11 @@ void PC88::draw_screen()
        // render graph screen
        bool disp_color_graph = true;
        bool draw_scanline_black = config.scan_line;
+#if defined(SUPPORT_PC88_GVRAM)
 #if defined(PC8001_VARIANT)
 #if defined(_PC8001SR)
        if(config.boot_mode != MODE_PC80_V2) {
 #endif
-#if defined(_PC8001)
-               memset(graph, 0, sizeof(graph));
-#else
                if(Port31_V1_320x200) {
                        disp_color_graph = draw_320x200_4color_graph();
                } else if(Port31_V1_MONO) {
@@ -2481,7 +2562,6 @@ void PC88::draw_screen()
                        }
                        draw_640x200_attrib_graph();
                }
-#endif
                emu->set_vm_screen_lines(200);
 #if defined(_PC8001SR)
        } else {
@@ -2510,7 +2590,7 @@ void PC88::draw_screen()
                disp_color_graph = draw_640x200_color_graph();
                emu->set_vm_screen_lines(200);
 #if defined(PC8801SR_VARIANT)
-       } else if (Port31_400LINE) {
+       } else if(Port31_400LINE) {
                if(hireso) {
                        draw_scanline_black = false;
                }
@@ -2527,6 +2607,10 @@ void PC88::draw_screen()
                emu->set_vm_screen_lines(200);
        }
 #endif
+#else
+//     memset(graph, 0, sizeof(graph));
+       emu->set_vm_screen_lines(200);
+#endif
        
        // create palette for each scanline
 #if defined(PC8801SR_VARIANT)
@@ -2709,6 +2793,61 @@ void PC88::draw_screen()
 
 void PC88::draw_text()
 {
+       if(emu->now_waiting_in_debugger) {
+               // dmac.run
+               uint8_t buffer[120 * 200];
+               memset(buffer, 0, sizeof(buffer));
+               
+               for(int i = 0; i < dmac.ch[3].count.sd + 1; i++) {
+                       buffer[i] = this->read_dma_data8(dmac.ch[3].addr.w.l + i);
+               }
+               
+               // crtc.expand_buffer
+               for(int cy = 0, ofs = 0; cy < crtc.height; cy++, ofs += 80 + crtc.attrib.num * 2) {
+                       for(int cx = 0; cx < crtc.width; cx++) {
+                               crtc.text.expand[cy][cx] = buffer[ofs + cx];
+                       }
+               }
+               if(crtc.mode & 4) {
+                       // non transparent
+                       for(int cy = 0, ofs = 0; cy < crtc.height; cy++, ofs += 80 + crtc.attrib.num * 2) {
+                               for(int cx = 0; cx < crtc.width; cx += 2) {
+                                       crtc.set_attrib(buffer[ofs + cx + 1]);
+                                       crtc.attrib.expand[cy][cx] = crtc.attrib.expand[cy][cx + 1] = crtc.attrib.data;
+                               }
+                       }
+               } else {
+                       // transparent
+                       if(crtc.mode & 1) {
+                               memset(crtc.attrib.expand, 0xe0, sizeof(crtc.attrib.expand));
+                       } else {
+                               for(int cy = 0, ofs = 0; cy < crtc.height; cy++, ofs += 80 + crtc.attrib.num * 2) {
+                                       uint8_t flags[128];
+                                       memset(flags, 0, sizeof(flags));
+                                       for(int i = 2 * (crtc.attrib.num - 1); i >= 0; i -= 2) {
+                                               flags[buffer[ofs + i + 80] & 0x7f] = 1;
+                                       }
+                                       crtc.attrib.data &= 0xf3; // for PC-8801mkIIFR \95t\91®\83f\83\82
+                                       
+                                       for(int cx = 0, pos = 0; cx < crtc.width; cx++) {
+                                               if(flags[cx]) {
+                                                       crtc.set_attrib(buffer[ofs + pos + 81]);
+                                                       pos += 2;
+                                               }
+                                               crtc.attrib.expand[cy][cx] = crtc.attrib.data;
+                                       }
+                               }
+                       }
+               }
+               if(crtc.cursor.x < 80 && crtc.cursor.y < 200) {
+                       if((crtc.cursor.type & 1) && crtc.blink.cursor) {
+                               // no cursor
+                       } else {
+                               static const uint8_t ctype[5] = {0, 8, 8, 1, 1};
+                               crtc.attrib.expand[crtc.cursor.y][crtc.cursor.x] ^= ctype[crtc.cursor.type + 1];
+                       }
+               }
+       }
        if(crtc.status & 0x88) {
                // dma underrun
                crtc.status &= ~0x80;
@@ -2736,6 +2875,7 @@ void PC88::draw_text()
        int char_height = crtc.char_height;
        uint8_t color_mask = Port30_COLOR ? 0 : 7;
        uint8_t code_expand, attr_expand;
+       bool attrib_graph = false;
        
        if(!hireso) {
                char_height <<= 1;
@@ -2746,6 +2886,16 @@ void PC88::draw_text()
        if(crtc.skip_line) {
                char_height <<= 1;
        }
+       if(Port31_GRAPH && !Port31_HCOLOR) {
+#if defined(PC8001_VARIANT)
+               if(config.boot_mode != MODE_PC80_V2) {
+                       if(!Port31_V1_320x200 && !Port31_V1_MONO) {
+                               attrib_graph = true;
+                       }
+               } else
+#endif
+               attrib_graph = true;
+       }
 //     for(int cy = 0, ytop = 0; cy < 64 && ytop < 400; cy++, ytop += char_height) {
        for(int cy = 0, ytop = 0; cy < crtc.height && ytop < 400; cy++, ytop += char_height) {
                for(int x = 0, cx = 0; cx < crtc.width; x += 8, cx++) {
@@ -2767,7 +2917,8 @@ void PC88::draw_text()
                        bool reverse_tmp = reverse;
                        
                        // from ePC-8801MA\89ü
-                       if(Port31_GRAPH && !Port31_HCOLOR) {
+//                     if(Port31_GRAPH && !Port31_HCOLOR) {
+                       if(attrib_graph) {
                                if(reverse) {
                                        reverse = false;
                                        color = 8;
@@ -2814,6 +2965,7 @@ void PC88::draw_text()
        }
 }
 
+#if defined(SUPPORT_PC88_GVRAM)
 #if defined(PC8001_VARIANT)
 #if defined(_PC8001SR)
 bool PC88::draw_320x200_color_graph()
@@ -3226,6 +3378,7 @@ void PC88::draw_640x400_attrib_graph()
        }
 }
 #endif
+#endif
 
 void PC88::request_intr(int level, bool status)
 {
@@ -3710,7 +3863,7 @@ void pc88_dmac_t::finish(int c)
        }
 }
 
-#define STATE_VERSION  11
+#define STATE_VERSION  12
 
 bool PC88::process_state(FILEIO* state_fio, bool loading)
 {
@@ -3724,7 +3877,9 @@ bool PC88::process_state(FILEIO* state_fio, bool loading)
 #if defined(PC88_EXRAM_BANKS)
        state_fio->StateArray(exram, sizeof(exram), 1);
 #endif
+#if defined(SUPPORT_PC88_GVRAM)
        state_fio->StateArray(gvram, sizeof(gvram), 1);
+#endif
 #if defined(PC8801SR_VARIANT)
        state_fio->StateArray(tvram, sizeof(tvram), 1);
 #endif
@@ -3769,8 +3924,10 @@ bool PC88::process_state(FILEIO* state_fio, bool loading)
 #if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
        state_fio->StateArray(alu_reg, sizeof(alu_reg), 1);
 #endif
+#if defined(SUPPORT_PC88_GVRAM)
        state_fio->StateValue(gvram_plane);
        state_fio->StateValue(gvram_sel);
+#endif
        state_fio->StateValue(cpu_clock_low);
 #if defined(SUPPORT_PC88_HIGH_CLOCK)
        state_fio->StateValue(cpu_clock_high_fe2);
@@ -3784,8 +3941,10 @@ bool PC88::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(tvram_wait_clocks_r);
        state_fio->StateValue(tvram_wait_clocks_w);
 #endif
+#if defined(SUPPORT_PC88_GVRAM)
        state_fio->StateValue(gvram_wait_clocks_r);
        state_fio->StateValue(gvram_wait_clocks_w);
+#endif
        state_fio->StateValue(busreq_clocks);
        for(int i = 0; i < array_length(palette); i++) {
                state_fio->StateValue(palette[i].r);
index 497b33d..3be4a3f 100644 (file)
 #ifdef SUPPORT_PC88_CDROM
 #define SIG_PC88_SCSI_DRQ      3
 #endif
-#define SIG_PC88_USART_OUT     4
+#ifdef SUPPORT_PC88_GSX8800
+#define SIG_PC88_GSX_IRQ       4
+#endif
+#define SIG_PC88_USART_OUT     5
 
 #define CMT_BUFFER_SIZE                0x40000
 
+#if !defined(_PC8001)
+#define SUPPORT_PC88_GVRAM
+#endif
+
 #if defined(PC8801_VARIANT)
 #define NIPPY_PATCH
 #endif
@@ -128,8 +135,12 @@ private:
 #ifdef SUPPORT_PC88_HMB20
        DEVICE *d_opm;
 #endif
+#ifdef SUPPORT_PC88_GSX8800
+//     DEVICE *d_gsx_pit;
+       DEVICE *d_gsx_psg1, *d_gsx_psg2, *d_gsx_psg3, *d_gsx_psg4;
+#endif
 #ifdef SUPPORT_PC88_PCG8100
-       DEVICE *d_pcg_pit, *d_pcg_pcm0, *d_pcg_pcm1, *d_pcg_pcm2;
+       DEVICE *d_pcg_pit, *d_pcg_pcm1, *d_pcg_pcm2, *d_pcg_pcm3;
 #endif
        
        uint8_t* rbank[16];
@@ -141,8 +152,10 @@ private:
 #if defined(PC88_EXRAM_BANKS)
        uint8_t exram[0x8000 * PC88_EXRAM_BANKS];
 #endif
+#if defined(SUPPORT_PC88_GVRAM)
        uint8_t gvram[0xc000];
        uint8_t gvram_null[0x4000];
+#endif
 #if defined(PC8801SR_VARIANT)
        uint8_t tvram[0x1000];
 #endif
@@ -180,7 +193,9 @@ private:
 #if defined(_PC8001SR) || defined(PC8801SR_VARIANT)
        uint8_t alu_reg[3];
 #endif
+#if defined(SUPPORT_PC88_GVRAM)
        uint8_t gvram_plane, gvram_sel;
+#endif
        
        void update_timing();
        int get_m1_wait(bool addr_f000);
@@ -188,9 +203,11 @@ private:
 #if defined(PC8801SR_VARIANT)
        int get_tvram_wait(bool read);
 #endif
+#if defined(SUPPORT_PC88_GVRAM)
        int get_gvram_wait(bool read);
        void update_gvram_wait();
        void update_gvram_sel();
+#endif
 #if defined(PC8001_VARIANT)
        void update_n80_write();
        void update_n80_read();
@@ -214,7 +231,9 @@ private:
 #if defined(PC8801SR_VARIANT)
        int tvram_wait_clocks_r, tvram_wait_clocks_w;
 #endif
+#if defined(SUPPORT_PC88_GVRAM)
        int gvram_wait_clocks_r, gvram_wait_clocks_w;
+#endif
        int busreq_clocks;
        
        // screen
@@ -241,6 +260,7 @@ private:
 #endif
        
        void draw_text();
+#if defined(SUPPORT_PC88_GVRAM)
 #if defined(PC8001_VARIANT)
 #if defined(_PC8001SR)
        bool draw_320x200_color_graph();
@@ -255,6 +275,7 @@ private:
        void draw_640x400_mono_graph();
        void draw_640x400_attrib_graph();
 #endif
+#endif
        
        // misc
        bool usart_dcd;
@@ -321,6 +342,28 @@ private:
 public:
        PC88(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
        {
+#ifdef SUPPORT_PC88_OPN1
+               d_opn1 = NULL;
+#endif
+#ifdef SUPPORT_PC88_OPN2
+               d_opn2 = NULL;
+#endif
+#ifdef SUPPORT_PC88_HMB20
+               d_opm = NULL;
+#endif
+#ifdef SUPPORT_PC88_GSX8800
+//             d_gsx_pit = NULL;
+               d_gsx_psg1 = NULL;
+               d_gsx_psg2 = NULL;
+               d_gsx_psg3 = NULL;
+               d_gsx_psg4 = NULL;
+#endif
+#ifdef SUPPORT_PC88_PCG8100
+               d_pcg_pit = NULL;
+               d_pcg_pcm1 = NULL;
+               d_pcg_pcm2 = NULL;
+               d_pcg_pcm3 = NULL;
+#endif
 #if defined(PC8001_VARIANT)
                set_device_name(_T("PC-8001 Core"));
 #else
@@ -414,15 +457,33 @@ public:
                d_opm = device;
        }
 #endif
+#ifdef SUPPORT_PC88_GSX8800
+//     void set_context_gsx_pit(DEVICE* device)
+//     {
+//             d_gsx_pit = device;
+//     }
+       void set_context_gsx_psg1(DEVICE* device)
+       {
+               d_gsx_psg1 = device;
+       }
+       void set_context_gsx_psg2(DEVICE* device)
+       {
+               d_gsx_psg2 = device;
+       }
+       void set_context_gsx_psg3(DEVICE* device)
+       {
+               d_gsx_psg3 = device;
+       }
+       void set_context_gsx_psg4(DEVICE* device)
+       {
+               d_gsx_psg4 = device;
+       }
+#endif
 #ifdef SUPPORT_PC88_PCG8100
        void set_context_pcg_pit(DEVICE* device)
        {
                d_pcg_pit = device;
        }
-       void set_context_pcg_pcm0(DEVICE* device)
-       {
-               d_pcg_pcm0 = device;
-       }
        void set_context_pcg_pcm1(DEVICE* device)
        {
                d_pcg_pcm1 = device;
@@ -431,6 +492,10 @@ public:
        {
                d_pcg_pcm2 = device;
        }
+       void set_context_pcg_pcm3(DEVICE* device)
+       {
+               d_pcg_pcm3 = device;
+       }
 #endif
        void key_down(int code, bool repeat);
        bool get_caps_locked()
index 266093f..98cfff3 100644 (file)
 #include "../ym2151.h"
 #endif
 
-#ifdef SUPPORT_PC88_PCG8100
+#ifdef SUPPORT_PC88_GSX8800
+#include "../ay_3_891x.h"
+#endif
+
+#if defined(SUPPORT_PC88_GSX8800) || defined(SUPPORT_PC88_PCG8100)
 #include "../i8253.h"
 #endif
 
@@ -73,7 +77,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
 #endif
 #else
 #if !defined(PC8801SR_VARIANT)
-       if(config.boot_mode == MODE_PC88_V1H || config.boot_mode == MODE_PC88_V2) {
+       if(config.boot_mode == MODE_PC88_V1H || config.boot_mode == MODE_PC88_V2 || config.boot_mode == MODE_PC88_V2CD) {
                config.boot_mode = MODE_PC88_V1S;
        }
 #endif
@@ -137,7 +141,6 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
        // config.sound_type
        //      0: 44h:OPN  A4h:None            PC-8001mkIISR
        //      1: 44h:OPN  A4h:OPN             PC-8001mkIISR + PC-8801-11
-       //      2: 44h:OPN  A4h:OPNA            PC-8001mkIISR + PC-8801-23
        pc88opn1 = new YM2203(this, emu);
 //     pc88opn1->set_context_event_manager(pc88event);
        pc88opn1->is_ym2608 = false;
@@ -147,28 +150,17 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
 //             pc88opn2->set_context_event_manager(pc88event);
                pc88opn2->is_ym2608 = false;
                pc88opn2->set_device_name(_T("YM2203 OPN #2"));
-       } else if(config.sound_type == 2) {
-               pc88opn2 = new YM2203(this, emu);
-//             pc88opn2->set_context_event_manager(pc88event);
-               pc88opn2->is_ym2608 = true;
-               pc88opn2->set_device_name(_T("YM2608 OPNA #2"));
        } else {
                pc88opn2 = NULL;
        }
-#elif defined(_PC8001MK2) || defined(_PC8801MK2)
-       //      0: 44h:None A4h:None            PC-8001/8801mkII
-       //      1: 44h:None A4h:OPN             PC-8001/8801mkII + PC-8801-11
-       //      2: 44h:None A4h:OPNA            PC-8001/8801mkII + PC-8801-23
+#elif defined(_PC8001MK2) || defined(_PC8801) || defined(_PC8801MK2)
+       //      0: 44h:None A4h:None            PC-8001mkII
+       //      1: 44h:None A4h:OPN             PC-8001mkII + PC-8801-11
        if(config.sound_type == 1) {
                pc88opn2 = new YM2203(this, emu);
 //             pc88opn2->set_context_event_manager(pc88event);
                pc88opn2->is_ym2608 = false;
                pc88opn2->set_device_name(_T("YM2203 OPN #2"));
-       } else if(config.sound_type == 2) {
-               pc88opn2 = new YM2203(this, emu);
-//             pc88opn2->set_context_event_manager(pc88event);
-               pc88opn2->is_ym2608 = true;
-               pc88opn2->set_device_name(_T("YM2608 OPNA #2"));
        } else {
                pc88opn2 = NULL;
        }
@@ -196,6 +188,18 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
                #endif
        #endif
 #endif
+#ifdef USE_DEBUGGER
+#ifdef SUPPORT_PC88_OPN1
+       if(pc88opn1 != NULL) {
+               pc88opn1->set_context_debugger(new DEBUGGER(this, emu));
+       }
+#endif
+#ifdef SUPPORT_PC88_OPN2
+       if(pc88opn2 != NULL) {
+               pc88opn2->set_context_debugger(new DEBUGGER(this, emu));
+       }
+#endif
+#endif
        if(config.printer_type == 0) {
                pc88prn = new PRNFILE(this, emu);
 //             pc88prn->set_context_event_manager(pc88event);
@@ -235,24 +239,65 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
 #endif
        
 #ifdef SUPPORT_PC88_HMB20
-       pc88opm = new YM2151(this, emu);
-       pc88opm->set_device_name(_T("YM2151 OPM (HMB20)"));
-//     pc88opm->set_context_event_manager(pc88event);
+       if(config.dipswitch & DIPSWITCH_HMB20) {
+               pc88opm = new YM2151(this, emu);
+#ifdef USE_DEBUGGER
+               pc88opm->set_context_debugger(new DEBUGGER(this, emu));
+#endif
+               pc88opm->set_device_name(_T("YM2151 OPM (HMB-20)"));
+//             pc88opm->set_context_event_manager(pc88event);
+       } else {
+               pc88opm = NULL;
+       }
+#endif
+       
+#ifdef SUPPORT_PC88_GSX8800
+       if(config.dipswitch & DIPSWITCH_GSX8800) {
+//             pc88gsx_pit = new I8253(this, emu);
+//             pc88gsx_pit->set_device_name(_T("8253 PIT (GSX-8800)"));
+//             pc88gsx_pit->set_context_event_manager(pc88event);
+               pc88gsx_psg1 = new AY_3_891X(this, emu);
+               pc88gsx_psg1->set_device_name(_T("AY-3-8910 PSG #1 (GSX-8800)"));
+//             pc88gsx_psg1->set_context_event_manager(pc88event);
+               pc88gsx_psg2 = new AY_3_891X(this, emu);
+               pc88gsx_psg2->set_device_name(_T("AY-3-8910 PSG #2 (GSX-8800)"));
+//             pc88gsx_psg2->set_context_event_manager(pc88event);
+               pc88gsx_psg3 = new AY_3_891X(this, emu);
+               pc88gsx_psg3->set_device_name(_T("AY-3-8910 PSG #3 (GSX-8800)"));
+//             pc88gsx_psg3->set_context_event_manager(pc88event);
+               pc88gsx_psg4 = new AY_3_891X(this, emu);
+               pc88gsx_psg4->set_device_name(_T("AY-3-8910 PSG #4 (GSX-8800)"));
+//             pc88gsx_psg4->set_context_event_manager(pc88event);
+#ifdef USE_DEBUGGER
+               pc88gsx_psg1->set_context_debugger(new DEBUGGER(this, emu));
+               pc88gsx_psg2->set_context_debugger(new DEBUGGER(this, emu));
+               pc88gsx_psg3->set_context_debugger(new DEBUGGER(this, emu));
+               pc88gsx_psg4->set_context_debugger(new DEBUGGER(this, emu));
+#endif
+       } else {
+//             pc88gsx_pit = NULL;
+               pc88gsx_psg1 = pc88gsx_psg2 = pc88gsx_psg3 = pc88gsx_psg4 = NULL;
+       }
 #endif
        
 #ifdef SUPPORT_PC88_PCG8100
-       pc88pit = new I8253(this, emu);
-       pc88pit->set_device_name(_T("8253 PIT (PCG8100)"));
-//     pc88pit->set_context_event_manager(pc88event);
-       pc88pcm0 = new PCM1BIT(this, emu);
-       pc88pcm0->set_device_name(_T("1-Bit PCM Sound (PCG8100 #1)"));
-//     pc88pcm0->set_context_event_manager(pc88event);
-       pc88pcm1 = new PCM1BIT(this, emu);
-       pc88pcm1->set_device_name(_T("1-Bit PCM Sound (PCG8100 #2)"));
-//     pc88pcm1->set_context_event_manager(pc88event);
-       pc88pcm2 = new PCM1BIT(this, emu);
-       pc88pcm2->set_device_name(_T("1-Bit PCM Sound (PCG8100 #3)"));
-//     pc88pcm2->set_context_event_manager(pc88event);
+       if(config.dipswitch & DIPSWITCH_PCG8100) {
+               pc88pcg_pit = new I8253(this, emu);
+               pc88pcg_pit->set_device_name(_T("8253 PIT (PCG-8100)"));
+//             pc88pcg_pit->set_context_event_manager(pc88event);
+               pc88pcg_pcm1 = new PCM1BIT(this, emu);
+               pc88pcg_pcm1->set_device_name(_T("1-Bit PCM Sound (PCG-8100 #1)"));
+//             pc88pcg_pcm1->set_context_event_manager(pc88event);
+               pc88pcg_pcm2 = new PCM1BIT(this, emu);
+               pc88pcg_pcm2->set_device_name(_T("1-Bit PCM Sound (PCG-8100 #2)"));
+//             pc88pcg_pcm2->set_context_event_manager(pc88event);
+               pc88pcg_pcm3 = new PCM1BIT(this, emu);
+               pc88pcg_pcm3->set_device_name(_T("1-Bit PCM Sound (PCG-8100 #3)"));
+//             pc88pcg_pcm3->set_context_event_manager(pc88event);
+       } else {
+               pc88pcg_pit = NULL;
+               pc88pcg_pcm1 = pc88pcg_pcm2 = pc88pcg_pcm3 = NULL;
+       }
 #endif
        
 #ifdef SUPPORT_PC88_HIGH_CLOCK
@@ -276,12 +321,24 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
        pc88event->set_context_sound(pc88scsi_cdrom);
 #endif
 #ifdef SUPPORT_PC88_HMB20
-       pc88event->set_context_sound(pc88opm);
+       if(config.dipswitch & DIPSWITCH_HMB20) {
+               pc88event->set_context_sound(pc88opm);
+       }
+#endif
+#ifdef SUPPORT_PC88_GSX8800
+       if(config.dipswitch & DIPSWITCH_GSX8800) {
+               pc88event->set_context_sound(pc88gsx_psg1);
+               pc88event->set_context_sound(pc88gsx_psg2);
+               pc88event->set_context_sound(pc88gsx_psg3);
+               pc88event->set_context_sound(pc88gsx_psg4);
+       }
 #endif
 #ifdef SUPPORT_PC88_PCG8100
-       pc88event->set_context_sound(pc88pcm0);
-       pc88event->set_context_sound(pc88pcm1);
-       pc88event->set_context_sound(pc88pcm2);
+       if(config.dipswitch & DIPSWITCH_PCG8100) {
+               pc88event->set_context_sound(pc88pcg_pcm1);
+               pc88event->set_context_sound(pc88pcg_pcm2);
+               pc88event->set_context_sound(pc88pcg_pcm3);
+       }
 #endif
        pc88event->set_context_sound(pc88noise_seek);
        pc88event->set_context_sound(pc88noise_head_down);
@@ -308,13 +365,26 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
        pc88->set_context_scsi_cdrom(pc88scsi_cdrom);
 #endif
 #ifdef SUPPORT_PC88_HMB20
-       pc88->set_context_opm(pc88opm);
+       if(config.dipswitch & DIPSWITCH_HMB20) {
+               pc88->set_context_opm(pc88opm);
+       }
+#endif
+#ifdef SUPPORT_PC88_GSX8800
+       if(config.dipswitch & DIPSWITCH_GSX8800) {
+//             pc88->set_context_gsx_pit(pc88gsx_pit);
+               pc88->set_context_gsx_psg1(pc88gsx_psg1);
+               pc88->set_context_gsx_psg2(pc88gsx_psg2);
+               pc88->set_context_gsx_psg3(pc88gsx_psg3);
+               pc88->set_context_gsx_psg4(pc88gsx_psg4);
+       }
 #endif
 #ifdef SUPPORT_PC88_PCG8100
-       pc88->set_context_pcg_pit(pc88pit);
-       pc88->set_context_pcg_pcm0(pc88pcm0);
-       pc88->set_context_pcg_pcm1(pc88pcm1);
-       pc88->set_context_pcg_pcm2(pc88pcm2);
+       if(config.dipswitch & DIPSWITCH_PCG8100) {
+               pc88->set_context_pcg_pit(pc88pcg_pit);
+               pc88->set_context_pcg_pcm1(pc88pcg_pcm1);
+               pc88->set_context_pcg_pcm2(pc88pcg_pcm2);
+               pc88->set_context_pcg_pcm3(pc88pcg_pcm3);
+       }
 #endif
        pc88cpu->set_context_mem(pc88);
        pc88cpu->set_context_io(pc88);
@@ -365,13 +435,23 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
        pc88scsi_host->set_context_target(pc88scsi_cdrom);
        pc88scsi_host->set_context_drq(pc88, SIG_PC88_SCSI_DRQ, 1);
 #endif
+#ifdef SUPPORT_PC88_GSX8800
+//     if(config.dipswitch & DIPSWITCH_GSX8800) {
+//             pc88gsx_pit->set_context_ch0(pc88, SIG_PC88_GSX_IRQ, 1);
+//             pc88gsx_pit->set_context_ch1(pc88gsx_pit, SIG_I8253_CLOCK_2, 1);
+//             pc88gsx_pit->set_constant_clock(0, 1996800);
+//             pc88gsx_pit->set_constant_clock(1, 1996800);
+//     }
+#endif
 #ifdef SUPPORT_PC88_PCG8100
-       pc88pit->set_context_ch0(pc88pcm0, SIG_PCM1BIT_SIGNAL, 1);
-       pc88pit->set_context_ch1(pc88pcm1, SIG_PCM1BIT_SIGNAL, 1);
-       pc88pit->set_context_ch2(pc88pcm2, SIG_PCM1BIT_SIGNAL, 1);
-       pc88pit->set_constant_clock(0, 3993624);
-       pc88pit->set_constant_clock(1, 3993624);
-       pc88pit->set_constant_clock(2, 3993624);
+       if(config.dipswitch & DIPSWITCH_PCG8100) {
+               pc88pcg_pit->set_context_ch0(pc88pcg_pcm1, SIG_PCM1BIT_SIGNAL, 1);
+               pc88pcg_pit->set_context_ch1(pc88pcg_pcm2, SIG_PCM1BIT_SIGNAL, 1);
+               pc88pcg_pit->set_context_ch2(pc88pcg_pcm3, SIG_PCM1BIT_SIGNAL, 1);
+               pc88pcg_pit->set_constant_clock(0, 3993624);
+               pc88pcg_pit->set_constant_clock(1, 3993624);
+               pc88pcg_pit->set_constant_clock(2, 3993624);
+       }
 #endif
        
        // initialize all devices
@@ -490,12 +570,24 @@ void VM::initialize_sound(int rate, int samples)
 #endif
        pc88pcm->initialize_sound(rate, 8000);
 #ifdef SUPPORT_PC88_HMB20
-       pc88opm->initialize_sound(rate, 4000000, samples, 0);
+       if(config.dipswitch & DIPSWITCH_HMB20) {
+               pc88opm->initialize_sound(rate, 4000000, samples, 0);
+       }
+#endif
+#ifdef SUPPORT_PC88_GSX8800
+       if(config.dipswitch & DIPSWITCH_GSX8800) {
+               pc88gsx_psg1->initialize_sound(rate, 3993624, samples, 0, 0);
+               pc88gsx_psg2->initialize_sound(rate, 3993624, samples, 0, 0);
+               pc88gsx_psg3->initialize_sound(rate, 3993624, samples, 0, 0);
+               pc88gsx_psg4->initialize_sound(rate, 3993624, samples, 0, 0);
+       }
 #endif
 #ifdef SUPPORT_PC88_PCG8100
-       pc88pcm0->initialize_sound(rate, 8000);
-       pc88pcm1->initialize_sound(rate, 8000);
-       pc88pcm2->initialize_sound(rate, 8000);
+       if(config.dipswitch & DIPSWITCH_PCG8100) {
+               pc88pcg_pcm1->initialize_sound(rate, 8000);
+               pc88pcg_pcm2->initialize_sound(rate, 8000);
+               pc88pcg_pcm3->initialize_sound(rate, 8000);
+       }
 #endif
 }
 
@@ -576,15 +668,40 @@ void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
 #endif
 #ifdef SUPPORT_PC88_HMB20
        if(ch-- == 0) {
-               pc88opm->set_volume(0, decibel_l, decibel_r);
+               if(pc88opm != NULL) {
+                       pc88opm->set_volume(0, decibel_l, decibel_r);
+               }
+               return;
+       }
+#endif
+#ifdef SUPPORT_PC88_GSX8800
+       if(ch-- == 0) {
+               if(pc88gsx_psg1 != NULL) {
+                       pc88gsx_psg1->set_volume(0, decibel_l, decibel_r);
+               }
+               if(pc88gsx_psg2 != NULL) {
+                       pc88gsx_psg2->set_volume(0, decibel_l, decibel_r);
+               }
+               if(pc88gsx_psg3 != NULL) {
+                       pc88gsx_psg3->set_volume(0, decibel_l, decibel_r);
+               }
+               if(pc88gsx_psg4 != NULL) {
+                       pc88gsx_psg4->set_volume(0, decibel_l, decibel_r);
+               }
                return;
        }
 #endif
 #ifdef SUPPORT_PC88_PCG8100
        if(ch-- == 0) {
-               pc88pcm0->set_volume(0, decibel_l, decibel_r);
-               pc88pcm1->set_volume(0, decibel_l, decibel_r);
-               pc88pcm2->set_volume(0, decibel_l, decibel_r);
+               if(pc88pcg_pcm1 != NULL) {
+                       pc88pcg_pcm1->set_volume(0, decibel_l, decibel_r);
+               }
+               if(pc88pcg_pcm2 != NULL) {
+                       pc88pcg_pcm2->set_volume(0, decibel_l, decibel_r);
+               }
+               if(pc88pcg_pcm3 != NULL) {
+                       pc88pcg_pcm3->set_volume(0, decibel_l, decibel_r);
+               }
                return;
        }
 #endif
@@ -719,7 +836,7 @@ void VM::update_config()
        }
 }
 
-#define STATE_VERSION  10
+#define STATE_VERSION  11
 
 bool VM::process_state(FILEIO* state_fio, bool loading)
 {
index 3b73723..4706dee 100644 (file)
@@ -53,6 +53,7 @@
        #define MODE_PC88_V1H   1
        #define MODE_PC88_V2    2
        #define MODE_PC88_N     3
+       #define MODE_PC88_V2CD  4
 #endif
 
 #if defined(_PC8801MA)
        #define SUPPORT_PC88_KANJI1
 //     #define SUPPORT_PC88_KANJI2
        #define SUPPORT_PC88_OPN2
-       #define SUPPORT_PC88_OPNA
 #elif defined(_PC8801)
        #define SUPPORT_PC88_KANJI1
 //     #define SUPPORT_PC88_KANJI2
-//     #define SUPPORT_PC88_OPN2
-//     #define SUPPORT_PC88_OPNA
+       #define SUPPORT_PC88_OPN2
 #elif defined(_PC8001SR)
        #define SUPPORT_PC88_KANJI1
 //     #define SUPPORT_PC88_KANJI2
        #define SUPPORT_PC88_OPN1
        #define SUPPORT_PC88_OPN2
-       #define SUPPORT_PC88_OPNA
        #define PC88_EXRAM_BANKS        1
 #elif defined(_PC8001MK2)
        #define SUPPORT_PC88_KANJI1
 //     #define SUPPORT_PC88_KANJI2
        #define SUPPORT_PC88_OPN2
-       #define SUPPORT_PC88_OPNA
        #define PC88_EXRAM_BANKS        1
 #elif defined(_PC8001)
 //     #define SUPPORT_PC88_KANJI1
 //     #define SUPPORT_PC88_KANJI2
-//     #define SUPPORT_PC88_OPN2
-//     #define SUPPORT_PC88_OPNA
 #endif
 #define SUPPORT_PC88_PCG8100
 
 #define WINDOW_HEIGHT_ASPECT   480
 #define MAX_DRIVE              2
 #define UPD765A_NO_ST1_EN_OR_FOR_RESULT7
-#if defined(PC8801_VARIANT)
+#if defined(_PC8801MA)
 #define PC80S31K_NO_WAIT
 #endif
 #if defined(SUPPORT_PC88_CDROM)
 #define USE_BOOT_MODE          3
 #define USE_CPU_TYPE           2
 #else
-#define USE_BOOT_MODE          4
+#define USE_BOOT_MODE          5
 #define USE_CPU_TYPE           3
 #endif
 #if defined(_PC8801MA)
 #define CPU_TYPE_DEFAULT       1
 #endif
 #define USE_DIPSWITCH
+#define DIPSWITCH_HMB20                2
+#define DIPSWITCH_GSX8800      4
+#define DIPSWITCH_PCG8100      8
+#define DIPSWITCH_DEFAULT      (DIPSWITCH_HMB20 + DIPSWITCH_GSX8800 + DIPSWITCH_PCG8100)
 #define USE_JOYSTICK_TYPE      2
 #define USE_FLOPPY_DISK                2
 #define USE_TAPE               1
 #if defined(_PC8801MA)
        #define USE_SOUND_TYPE          6       // OPNA,OPN,OPN+OPNA,OPN+OPN,OPNA+OPNA,OPNA+OPN
 #elif defined(_PC8001SR)
-       #define USE_SOUND_TYPE          3       // OPN,OPN+OPN,OPN+OPNA
-#elif defined(_PC8001MK2) || defined(_PC8801MK2)
-       #define USE_SOUND_TYPE          3       // None,OPN,OPNA
+       #define USE_SOUND_TYPE          2       // OPN,OPN+OPN
+#elif defined(_PC8001MK2) || defined(_PC8801) || defined(_PC8801MK2)
+       #define USE_SOUND_TYPE          2       // None,OPN
 #endif
 #if defined(SUPPORT_PC88_OPN1)
        #if defined(SUPPORT_PC88_OPNA)
 #else
        #define SOUND_VOLUME_HMB20      0
 #endif
+#if defined(SUPPORT_PC88_GSX8800)
+       #define SOUND_VOLUME_GSX8800    1
+#else
+       #define SOUND_VOLUME_GSX8800    0
+#endif
 #if defined(SUPPORT_PC88_PCG8100)
        #define SOUND_VOLUME_PCG8100    1
 #else
        #define SOUND_VOLUME_PCG8100    0
 #endif
-#define USE_SOUND_VOLUME       (SOUND_VOLUME_OPN1 + SOUND_VOLUME_OPN2 + SOUND_VOLUME_CDROM + SOUND_VOLUME_HMB20 + SOUND_VOLUME_PCG8100 + 1 + 1)
+#define USE_SOUND_VOLUME       (SOUND_VOLUME_OPN1 + SOUND_VOLUME_OPN2 + SOUND_VOLUME_CDROM + SOUND_VOLUME_HMB20 + SOUND_VOLUME_GSX8800 + SOUND_VOLUME_PCG8100 + 1 + 1)
 
 #define SUPPORT_TV_RENDER
 #define USE_JOYSTICK
 #ifdef USE_SOUND_VOLUME
 static const _TCHAR *sound_device_caption[USE_SOUND_VOLUME] = {
 #ifdef SUPPORT_PC88_OPN1
-       _T("OPN1 (FM)"), _T("OPN1 (PSG)"),
+       #ifdef SUPPORT_PC88_OPN2
+               #define NUM1 " #1 "
+       #else
+               #define NUM1 " "
+       #endif
 #ifdef SUPPORT_PC88_OPNA
-       _T("OPN1 (ADPCM)"), _T("OPN1 (Rhythm)"),
+       _T("OPNA" NUM1 "(FM)"), _T("OPNA" NUM1 "(PSG)"), _T("OPNA" NUM1 "(ADPCM)"), _T("OPNA" NUM1 "(Rhythm)"),
+#else
+       _T("OPN" NUM1 "(FM)"), _T("OPN" NUM1 "(PSG)"),
 #endif
 #endif
 #ifdef SUPPORT_PC88_OPN2
-       _T("OPN2 (FM)"), _T("OPN2 (PSG)"),
+       #ifdef SUPPORT_PC88_OPN1
+               #define NUM2 " #2 "
+       #else
+               #define NUM2 " "
+       #endif
 #ifdef SUPPORT_PC88_OPNA
-       _T("OPN2 (ADPCM)"), _T("OPN2 (Rhythm)"),
+       _T("OPNA" NUM2 "(FM)"), _T("OPNA" NUM2 "(PSG)"), _T("OPNA" NUM2 "(ADPCM)"), _T("OPNA" NUM2 "(Rhythm)"),
+#else
+       _T("OPN" NUM2 "(FM)"), _T("OPN" NUM2 "(PSG)"),
 #endif
 #endif
 #ifdef SUPPORT_PC88_CDROM
@@ -231,6 +247,9 @@ static const _TCHAR *sound_device_caption[USE_SOUND_VOLUME] = {
 #ifdef SUPPORT_PC88_HMB20
        _T("HMB-20"),
 #endif
+#ifdef SUPPORT_PC88_GSX8800
+       _T("GSX-8800"),
+#endif
 #ifdef SUPPORT_PC88_PCG8100
        _T("PCG-8100"),
 #endif
@@ -264,7 +283,11 @@ class SCSI_CDROM;
 class YM2151;
 #endif
 
-#ifdef SUPPORT_PC88_PCG8100
+#ifdef SUPPORT_PC88_GSX8800
+class AY_3_891X;
+#endif
+
+#if defined(SUPPORT_PC88_GSX8800) || defined(SUPPORT_PC88_PCG8100)
 class I8253;
 #endif
 namespace PC88DEV {
@@ -310,11 +333,19 @@ protected:
        YM2151* pc88opm;
 #endif
        
+#ifdef SUPPORT_PC88_GSX8800
+//     I8253* pc88gsx_pit;
+       AY_3_891X* pc88gsx_psg1;
+       AY_3_891X* pc88gsx_psg2;
+       AY_3_891X* pc88gsx_psg3;
+       AY_3_891X* pc88gsx_psg4;
+#endif
+       
 #ifdef SUPPORT_PC88_PCG8100
-       I8253* pc88pit;
-       PCM1BIT* pc88pcm0;
-       PCM1BIT* pc88pcm1;
-       PCM1BIT* pc88pcm2;
+       I8253* pc88pcg_pit;
+       PCM1BIT* pc88pcg_pcm1;
+       PCM1BIT* pc88pcg_pcm2;
+       PCM1BIT* pc88pcg_pcm3;
 #endif
        
        PC88DEV::PC88* pc88;