OSDN Git Service

[General] Completely merge upstream 2019-01-11.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc9801 / pc9801.cpp
index 9f2b0ad..a35b5a4 100644 (file)
@@ -78,6 +78,7 @@
 #include "mouse.h"
 #if defined(SUPPORT_SASI_IF)
 #include "sasi.h"
+#include "sasi_bios.h"
 #endif
 #if defined(SUPPORT_SCSI_IF)
 #include "scsi.h"
 #include "ide.h"
 #endif
 
+#if defined(SUPPORT_CMT_IF)
+using PC9801::CMT;
+#endif
+#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
+using PC9801::CPUREG;
+#endif
+using PC9801::DISPLAY;
+using PC9801::DMAREG;
+using PC9801::FLOPPY;
+using PC9801::FMSOUND;
+using PC9801::JOYSTICK;
+using PC9801::KEYBOARD;
+using PC9801::MEMBUS;
+using PC9801::MOUSE;
+#if defined(SUPPORT_SASI_IF)
+using PC9801::SASI;
+using PC9801::BIOS;
+#endif
+#if defined(SUPPORT_SCSI_IF)
+using PC9801::SCSI;
+#endif
+#if defined(SUPPORT_IDE_IF)
+using PC9801::IDE;
+#endif
+
 #if defined(SUPPORT_320KB_FDD_IF)
 #include "../pc80s31k.h"
 #include "../z80.h"
 #include "../pc8801/pc88.h"
 #endif
 
+#if defined(_PC98DO) || defined(_PC98DOPLUS)
+using PC88DEV::PC88;
+#endif
 // ----------------------------------------------------------------------------
 // initialize
 // ----------------------------------------------------------------------------
 
-VM::VM(EMU* parent_emu) : emu(parent_emu)
+VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
 {
        // check configs
 #if defined(_PC98DO) || defined(_PC98DOPLUS)
@@ -221,7 +250,7 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        noise_head_up = new NOISE(this, emu);
 #if defined(SUPPORT_SASI_IF)
        sasi_host = new SCSI_HOST(this, emu);
-       sasi_hdd = new SCSI_HDD(this, emu);
+       sasi_hdd = new SASI_HDD(this, emu);
        sasi_hdd->set_device_name(_T("SASI Hard Disk Drive"));
        sasi_hdd->scsi_id = 0;
        sasi_hdd->bytes_per_sec = 625 * 1024; // 625KB/s
@@ -250,7 +279,11 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        if(sound_type == 0 || sound_type == 1) {
                opn = new YM2203(this, emu);
 #ifdef SUPPORT_PC98_OPNA
+               opn->set_device_name(_T("YM2608 OPNA (PC-9801-86)"));
                opn->is_ym2608 = true;
+#else
+               opn->set_device_name(_T("YM2203 OPN (PC-9801-26)"));
+               opn->is_ym2608 = false;
 #endif
                fmsound = new FMSOUND(this, emu);
                joystick = new JOYSTICK(this, emu);
@@ -285,6 +318,7 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        mouse = new MOUSE(this, emu);
 #if defined(SUPPORT_SASI_IF)
        sasi = new SASI(this, emu);
+       sasi_bios = new BIOS(this, emu);
 #endif
 #if defined(SUPPORT_SCSI_IF)
        scsi = new SCSI(this, emu);
@@ -482,6 +516,13 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        sasi->set_context_hdd(sasi_hdd);
        sasi->set_context_dma(dma);
        sasi->set_context_pic(pic);
+
+       sasi_bios->set_context_sasi(sasi);
+       sasi_bios->set_context_memory(memory);
+       sasi_bios->set_context_cpu(cpu);
+       sasi_bios->set_context_pic(pic);
+       cpu->set_context_bios(sasi_bios);
+   
 #endif
 #if defined(SUPPORT_SCSI_IF)
        dma->set_context_ch0(scsi);
@@ -810,14 +851,15 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        pc88rtc = new UPD1990A(this, emu);
        pc88rtc->set_device_name(_T("uPD1990A RTC (PC-8801)"));
        pc88rtc->set_context_event_manager(pc88event);
-       pc88opn = new YM2203(this, emu);
+       pc88opn1 = new YM2203(this, emu);
 #ifdef SUPPORT_PC88_OPNA
-       pc88opn->set_device_name(_T("YM2608 OPNA (PC-8801)"));
-       pc88opn->is_ym2608 = true;
+       pc88opn1->set_device_name(_T("YM2608 OPNA (PC-8801)"));
+       pc88opn1->is_ym2608 = true;
 #else
-       pc88opn->set_device_name(_T("YM2203 OPN (PC-8801)"));
+       pc88opn1->set_device_name(_T("YM2203 OPN (PC-8801)"));
+       pc88opn1->is_ym2608 = false;
 #endif
-       pc88opn->set_context_event_manager(pc88event);
+       pc88opn1->set_context_event_manager(pc88event);
        pc88cpu = new Z80(this, emu);
        pc88cpu->set_device_name(_T("Z80 CPU (PC-8801)"));
        pc88cpu->set_context_event_manager(pc88event);
@@ -853,14 +895,14 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        
        pc88event->set_context_cpu(pc88cpu, (config.cpu_type == 1) ? 3993624 : 7987248);
        pc88event->set_context_cpu(pc88cpu_sub, 3993624);
-       pc88event->set_context_sound(pc88opn);
+       pc88event->set_context_sound(pc88opn1);
        pc88event->set_context_sound(pc88pcm);
        pc88event->set_context_sound(pc88noise_seek);
        pc88event->set_context_sound(pc88noise_head_down);
        pc88event->set_context_sound(pc88noise_head_up);
        
        pc88->set_context_cpu(pc88cpu);
-       pc88->set_context_opn(pc88opn);
+       pc88->set_context_opn1(pc88opn1);
        pc88->set_context_pcm(pc88pcm);
        pc88->set_context_pio(pc88pio);
        pc88->set_context_prn(pc88prn);
@@ -872,7 +914,7 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
 #ifdef USE_DEBUGGER
        pc88cpu->set_context_debugger(new DEBUGGER(this, emu));
 #endif
-       pc88opn->set_context_irq(pc88, SIG_PC88_SOUND_IRQ, 1);
+       pc88opn1->set_context_irq(pc88, SIG_PC88_OPN1_IRQ, 1);
        pc88sio->set_context_rxrdy(pc88, SIG_PC88_USART_IRQ, 1);
        pc88sio->set_context_out(pc88, SIG_PC88_USART_OUT);
        
@@ -902,10 +944,12 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
 #endif
 
        // initialize all devices
+#if defined(__GIT_REPO_VERSION)
+       strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1);
+#endif
        for(DEVICE* device = first_device; device; device = device->next_device) {
                device->initialize();
        }
-       decl_state();
        
 #if defined(_PC9801) || defined(_PC9801E)
        fdc_2hd->get_disk_handler(0)->drive_num = 0;
@@ -928,27 +972,17 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
 #endif
 #if defined(USE_HARD_DISK)
        for(int drv = 0; drv < USE_HARD_DISK; drv++) {
+               if(!(config.last_hard_disk_path[drv][0] != _T('\0') && FILEIO::IsFileExisting(config.last_hard_disk_path[drv]))) {
 #if defined(SUPPORT_SASI_IF)
-       #if defined(OPEN_HARD_DISK_IN_RESET)
-               create_local_path(hd_file_path[drv], _MAX_PATH, _T("SASI%d.DAT"), drv);
-       #else
-               open_hard_disk_tmp(drv, create_local_path(_T("SASI%d.DAT"), drv));
-       #endif
+                       create_local_path(config.last_hard_disk_path[drv], _MAX_PATH, _T("SASI%d.DAT"), drv);
 #endif
 #if defined(SUPPORT_SCSI_IF)
-       #if defined(OPEN_HARD_DISK_IN_RESET)
-               create_local_path(hd_file_path[drv], _MAX_PATH, _T("SCSI%d.DAT"), drv);
-       #else
-               open_hard_disk_tmp(drv, create_local_path(_T("SCSI%d.DAT"), drv));
-       #endif
+                       create_local_path(config.last_hard_disk_path[drv], _MAX_PATH, _T("SCSI%d.DAT"), drv);
 #endif
 #if defined(SUPPORT_IDE_IF)
-       #if defined(OPEN_HARD_DISK_IN_RESET)
-               create_local_path(hd_file_path[drv], _MAX_PATH, _T("IDE%d.DAT"),  drv);
-       #else
-               open_hard_disk_tmp(drv, create_local_path(_T("IDE%d.DAT"), drv));
-       #endif
+                       create_local_path(config.last_hard_disk_path[drv], _MAX_PATH, _T("IDE%d.DAT"), drv);
 #endif
+               }
        }
 #endif
 }
@@ -1114,21 +1148,10 @@ void VM::reset()
 #endif
        
 #if defined(_PC98DO) || defined(_PC98DOPLUS)
-       pc88opn->set_reg(0x29, 3); // for Misty Blue
+       pc88opn1->set_reg(0x29, 3); // for Misty Blue
        pc88pio->write_signal(SIG_I8255_PORT_C, 0, 0xff);
        pc88pio_sub->write_signal(SIG_I8255_PORT_C, 0, 0xff);
 #endif
-       
-#if defined(USE_HARD_DISK) && defined(OPEN_HARD_DISK_IN_RESET)
-       // open/close hard disk images
-       for(int drv = 0; drv < USE_HARD_DISK; drv++) {
-               if(hd_file_path[drv][0] != _T('\0')) {
-                       open_hard_disk_tmp(drv, hd_file_path[drv]);
-               } else {
-                       close_hard_disk_tmp(drv);
-               }
-       }
-#endif
 }
 
 void VM::run()
@@ -1209,11 +1232,11 @@ void VM::initialize_sound(int rate, int samples)
        beep->initialize_sound(rate, 8000);
 #endif
        if(sound_type == 0 || sound_type == 1) {
-#ifdef HAS_YM2608
-               opn->initialize_sound(rate, 7987248, samples, 0, 0);
-#else
-               opn->initialize_sound(rate, 3993624, samples, 0, 0);
-#endif
+               if(opn->is_ym2608) {
+                       opn->initialize_sound(rate, 7987248, samples, 0, 0);
+               } else {
+                       opn->initialize_sound(rate, 3993624, samples, 0, 0);
+               }
        } else if(sound_type == 2 || sound_type == 3) {
                tms3631->initialize_sound(rate, 8000);
        }
@@ -1223,11 +1246,11 @@ void VM::initialize_sound(int rate, int samples)
        pc88event->initialize_sound(rate, samples);
        
        // init sound gen
-#ifdef HAS_YM2608
-       pc88opn->initialize_sound(rate, 7987248, samples, 0, 0);
-#else
-       pc88opn->initialize_sound(rate, 3993624, samples, 0, 0);
-#endif
+       if(pc88opn1->is_ym2608) {
+               pc88opn1->initialize_sound(rate, 7987248, samples, 0, 0);
+       } else {
+               pc88opn1->initialize_sound(rate, 3993624, samples, 0, 0);
+       }
        pc88pcm->initialize_sound(rate, 8000);
 #endif
 }
@@ -1281,14 +1304,14 @@ void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
                beep->set_volume(0, decibel_l, decibel_r);
 #if defined(_PC98DO) || defined(_PC98DOPLUS)
        } else if(ch-- == 0) {
-               pc88opn->set_volume(0, decibel_l, decibel_r);
+               pc88opn1->set_volume(0, decibel_l, decibel_r);
        } else if(ch-- == 0) {
-               pc88opn->set_volume(1, decibel_l, decibel_r);
+               pc88opn1->set_volume(1, decibel_l, decibel_r);
 #if defined(SUPPORT_PC88_OPNA)
        } else if(ch-- == 0) {
-               pc88opn->set_volume(2, decibel_l, decibel_r);
+               pc88opn1->set_volume(2, decibel_l, decibel_r);
        } else if(ch-- == 0) {
-               pc88opn->set_volume(3, decibel_l, decibel_r);
+               pc88opn1->set_volume(3, decibel_l, decibel_r);
 #endif
        } else if(ch-- == 0) {
                pc88pcm->set_volume(0, decibel_l, decibel_r);
@@ -1403,24 +1426,24 @@ bool VM::is_floppy_disk_protected(int drv)
 
 uint32_t VM::is_floppy_disk_accessed()
 {
-       uint32_t value = 0;
+       uint32_t status = 0;
        
 #if defined(_PC98DO) || defined(_PC98DOPLUS)
        if(boot_mode != 0) {
-               value = pc88fdc_sub->read_signal(0) & 3;
+               status = pc88fdc_sub->read_signal(0) & 3;
        } else {
-               value = fdc->read_signal(0) & 3;
+               status = fdc->read_signal(0) & 3;
        }
 #else
        for(int drv = 0; drv < USE_FLOPPY_DISK; drv += 2) {
                UPD765A *controller = get_floppy_disk_controller(drv);
                
                if(controller != NULL) {
-                       value |= (controller->read_signal(0) & 3) << drv;
+                       status |= (controller->read_signal(0) & 3) << drv;
                }
        }
 #endif
-       return value;
+       return status;
 }
 
 UPD765A *VM::get_floppy_disk_controller(int drv)
@@ -1465,10 +1488,14 @@ DISK *VM::get_floppy_disk_handler(int drv)
 void VM::open_hard_disk(int drv, const _TCHAR* file_path)
 {
        if(drv < USE_HARD_DISK) {
-#if defined(OPEN_HARD_DISK_IN_RESET)
-               my_tcscpy_s(hd_file_path[drv], _MAX_PATH, file_path);
-#else
-               open_hard_disk_tmp(drv, file_path);
+#if defined(SUPPORT_SASI_IF)
+               sasi_hdd->open(drv, file_path, 256);
+#endif
+#if defined(SUPPORT_SCSI_IF)
+               scsi_hdd[drv]->open(0, file_path, 512);
+#endif
+#if defined(SUPPORT_IDE_IF)
+               ide_hdd[drv]->open(0, file_path, 512);
 #endif
        }
 }
@@ -1476,10 +1503,14 @@ void VM::open_hard_disk(int drv, const _TCHAR* file_path)
 void VM::close_hard_disk(int drv)
 {
        if(drv < USE_HARD_DISK) {
-#if defined(OPEN_HARD_DISK_IN_RESET)
-               hd_file_path[drv][0] = _T('\0');
-#else
-               close_hard_disk_tmp(drv);
+#if defined(SUPPORT_SASI_IF)
+               sasi_hdd->close(drv);
+#endif
+#if defined(SUPPORT_SCSI_IF)
+               scsi_hdd[drv]->close(0);
+#endif
+#if defined(SUPPORT_IDE_IF)
+               ide_hdd[drv]->close(0);
 #endif
        }
 }
@@ -1487,10 +1518,14 @@ void VM::close_hard_disk(int drv)
 bool VM::is_hard_disk_inserted(int drv)
 {
        if(drv < USE_HARD_DISK) {
-#if defined(OPEN_HARD_DISK_IN_RESET)
-               return (hd_file_path[drv][0] != _T('\0'));
-#else
-               return is_hard_disk_inserted_tmp(drv);
+#if defined(SUPPORT_SASI_IF)
+               return sasi_hdd->mounted(drv);
+#endif
+#if defined(SUPPORT_SCSI_IF)
+               return scsi_hdd[drv]->mounted(0);
+#endif
+#if defined(SUPPORT_IDE_IF)
+               return ide_hdd[drv]->mounted(0);
 #endif
        }
        return false;
@@ -1501,57 +1536,23 @@ uint32_t VM::is_hard_disk_accessed()
        uint32_t status = 0;
        
        for(int drv = 0; drv < USE_HARD_DISK; drv++) {
-               HARDDISK *handler = get_hard_disk_handler(drv);
-               
-               if(handler != NULL && handler->accessed()) {
+#if defined(SUPPORT_SASI_IF)
+               if(sasi_hdd->accessed(drv)) {
                        status |= 1 << drv;
                }
-       }
-       return status;
-}
-
-void VM::open_hard_disk_tmp(int drv, const _TCHAR* file_path)
-{
-       HARDDISK *handler = get_hard_disk_handler(drv);
-       
-       if(handler != NULL) {
-               handler->open(file_path);
-       }
-}
-
-void VM::close_hard_disk_tmp(int drv)
-{
-       HARDDISK *handler = get_hard_disk_handler(drv);
-       
-       if(handler != NULL) {
-               handler->close();
-       }
-}
-
-bool VM::is_hard_disk_inserted_tmp(int drv)
-{
-       HARDDISK *handler = get_hard_disk_handler(drv);
-       
-       if(handler != NULL) {
-               return handler->mounted();
-       }
-       return false;
-}
-
-HARDDISK *VM::get_hard_disk_handler(int drv)
-{
-       if(drv < USE_HARD_DISK) {
-#if defined(SUPPORT_SASI_IF)
-               return sasi_hdd->get_disk_handler(drv);
 #endif
 #if defined(SUPPORT_SCSI_IF)
-               return scsi_hdd[drv]->get_disk_handler(0);
+               if(scsi_hdd[drv]->accessed(0)) {
+                       status |= 1 << drv;
+               }
 #endif
 #if defined(SUPPORT_IDE_IF)
-               return ide_hdd[drv]->get_disk_handler(0);
+               if(ide_hdd[drv]->accessed(0)) {
+                       status |= 1 << drv;
+               }
 #endif
        }
-       return NULL;
+       return status;
 }
 #endif
 
@@ -1618,78 +1619,42 @@ void VM::update_config()
        }
 }
 
-#define STATE_VERSION  13
+#define STATE_VERSION  14
 
-#include "../../statesub.h"
-
-void VM::decl_state(void)
-{
-#if defined(_PC9801)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801_HEAD")));
-#elif defined(_PC9801E)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801E_HEAD")));
-#elif defined(_PC9801U)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801U_HEAD")));
-#elif defined(_PC9801VF)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801VF_HEAD")));
-#elif defined(_PC9801VM)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801VF_HEAD")));
-#elif defined(_PC98DO)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98DO_HEAD")));
-#elif defined(_PC9801DOPLUS)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98DO_PLUS_HEAD")));
-#elif defined(_PC9801VX)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801VX_HEAD")));
-#elif defined(_PC98XL)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98XL_HEAD")));
-#elif defined(_PC98XA)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98XA_HEAD")));
-#elif defined(_PC9801RA)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801RA_HEAD")));
-#elif defined(_PC98RL)
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98RL_HEAD")));
-#else
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801_SERIES_HEAD")));
-#endif
-       
-       DECL_STATE_ENTRY_BOOL(pit_clock_8mhz);
-#if defined(_PC98DO) || defined(_PC98DOPLUS)
-       DECL_STATE_ENTRY_INT32(boot_mode);
-#endif
-       DECL_STATE_ENTRY_INT32(sound_type);
-#if defined(USE_HARD_DISK) && defined(OPEN_HARD_DISK_IN_RESET)
-       DECL_STATE_ENTRY_MULTI(void, hd_file_path, sizeof(hd_file_path));
-#endif
-       for(DEVICE* device = first_device; device; device = device->next_device) {
-               device->decl_state();
-       }
-}
-
-void VM::save_state(FILEIO* state_fio)
+bool VM::process_state(FILEIO* state_fio, bool loading)
 {
-       if(state_entry != NULL) {
-               state_entry->save_state(state_fio);
-       }
-       for(DEVICE* device = first_device; device; device = device->next_device) {
-               device->save_state(state_fio);
-       }
-}
-
-bool VM::load_state(FILEIO* state_fio)
-{
-       bool mb = false;
-       if(state_entry != NULL) {
-               mb = state_entry->load_state(state_fio);
-       }
-       if(!mb) {
-               emu->out_debug_log("INFO: HEADER DATA ERROR");
-               return false;
-       }
-       for(DEVICE* device = first_device; device; device = device->next_device) {
-               if(!device->load_state(state_fio)) {
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       for(DEVICE* device = first_device; device; device = device->next_device) {
+               // Note: typeid(foo).name is fixed by recent ABI.Not dec 6.
+               // const char *name = typeid(*device).name();
+               //       But, using get_device_name() instead of typeid(foo).name() 20181008 K.O
+               const char *name = device->get_device_name();
+               int len = strlen(name);
+               if(!state_fio->StateCheckInt32(len)) {
+                       if(loading) {
+                               printf("Class name len Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name);
+                       }
                        return false;
                }
-       }
-       return true;
+               if(!state_fio->StateCheckBuffer(name, len, 1)) {
+                       if(loading) {
+                               printf("Class name Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name);
+                       }
+                       return false;
+               }
+               if(!device->process_state(state_fio, loading)) {
+                       if(loading) {
+                               printf("Data loading Error: DEVID=%d\n", device->this_device_id);
+                       }
+                       return false;
+               }
+       }
+       state_fio->StateValue(pit_clock_8mhz);
+#if defined(_PC98DO) || defined(_PC98DOPLUS)
+       state_fio->StateValue(boot_mode);
+#endif
+       state_fio->StateValue(sound_type);
+       return true;
 }
-