OSDN Git Service

[General] Merge Updtream 2020-08-10.
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz2500 / mz2500.cpp
index 66cb066..6f082a4 100644 (file)
@@ -44,7 +44,7 @@
 #include "interrupt.h"
 #include "joystick.h"
 #include "keyboard.h"
-#include "memory.h"
+#include "./memory.h"
 #include "mouse.h"
 #include "mz1e26.h"
 #include "mz1e30.h"
 #include "serial.h"
 #include "timer.h"
 
+using MZ2500::CALENDAR;
+using MZ2500::CMT;
+using MZ2500::CRTC;
+using MZ2500::FLOPPY;
+using MZ2500::INTERRUPT;
+using MZ2500::JOYSTICK;
+using MZ2500::KEYBOARD;
+using MZ2500::MEMORY;
+using MZ2500::MOUSE;
+using MZ2500::MZ1E26;
+using MZ2500::MZ1E30;
+using MZ2500::MZ1R13;
+using MZ2500::MZ1R37;
+using MZ2500::PRINTER;
+using MZ2500::SERIAL;
+using MZ2500::TIMER;
+
 // ----------------------------------------------------------------------------
 // initialize
 // ----------------------------------------------------------------------------
 
-VM::VM(EMU* parent_emu) : emu(parent_emu)
+VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu)
 {
        // create devices
        first_device = last_device = NULL;
@@ -77,10 +94,16 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        fdc->set_context_noise_seek(new NOISE(this, emu));
        fdc->set_context_noise_head_down(new NOISE(this, emu));
        fdc->set_context_noise_head_up(new NOISE(this, emu));
+#ifdef USE_DEBUGGER
+//     fdc->set_context_debugger(new DEBUGGER(this, emu));
+#endif
        pcm = new PCM1BIT(this, emu);
+#ifdef USE_DEBUGGER
+//     pcm->set_context_debugger(new DEBUGGER(this, emu));
+#endif
        rtc = new RP5C01(this, emu);    // RP-5C15
        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 = 32 * 1024; // 32KB/s
@@ -91,6 +114,9 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        sasi_host->set_context_target(sasi_hdd);
        w3100a = new W3100A(this, emu);
        opn = new YM2203(this, emu);
+#ifdef USE_DEBUGGER
+       opn->set_context_debugger(new DEBUGGER(this, emu));
+#endif
        cpu = new Z80(this, emu);
        pio = new Z80PIO(this, emu);
        sio = new Z80SIO(this, emu);
@@ -235,16 +261,24 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        io->set_iowait_range_rw(0xe8, 0xeb, 1);
        
        // 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();
+
+       for(int drv = 0; drv < MAX_DRIVE; drv++) {
+//             if(config.drive_type) {
+//                     fdc->set_drive_type(drv, DRIVE_TYPE_2D);
+//             } else {
+                       fdc->set_drive_type(drv, DRIVE_TYPE_2DD);
+//             }
+       }
        for(int drv = 0; drv < USE_HARD_DISK; drv++) {
-#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
+               if(!(config.last_hard_disk_path[drv][0] != _T('\0') && FILEIO::IsFileExisting(config.last_hard_disk_path[drv]))) {
+                       create_local_path(config.last_hard_disk_path[drv], _MAX_PATH, _T("SASI%d.DAT"), drv);
+               }
        }
        monitor_type = config.monitor_type;
 }
@@ -280,36 +314,18 @@ void VM::reset()
        for(DEVICE* device = first_device; device; device = device->next_device) {
                device->reset();
        }
-       for(int i = 0; i < MAX_DRIVE; i++) {
-               if(config.drive_type) {
-                       fdc->set_drive_type(i, DRIVE_TYPE_2D);
-               } else {
-                       fdc->set_drive_type(i, DRIVE_TYPE_2DD);
-               }
-       }
        
        // set initial port status
        opn->write_signal(SIG_YM2203_PORT_B, (monitor_type & 2) ? 0x77 : 0x37, 0xff);
-       
-#if 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::special_reset()
+void VM::special_reset(int num)
 {
        // reset all devices
 //     for(DEVICE* device = first_device; device; device = device->next_device) {
 //             device->special_reset();
 //     }
-       memory->special_reset();
+       memory->special_reset(num);
        cpu->reset();
 }
 
@@ -441,6 +457,16 @@ void VM::inc_socket_recv_buffer_ptr(int ch, int size)
 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
 {
        fdc->open_disk(drv, file_path, bank);
+       
+       if(fdc->get_media_type(drv) == MEDIA_TYPE_2DD) {
+               if(fdc->get_drive_type(drv) == DRIVE_TYPE_2D) {
+                       fdc->set_drive_type(drv, DRIVE_TYPE_2DD);
+               }
+       } else if(fdc->get_media_type(drv) == MEDIA_TYPE_2D) {
+               if(fdc->get_drive_type(drv) == DRIVE_TYPE_2DD) {
+                       fdc->set_drive_type(drv, DRIVE_TYPE_2D);
+               }
+       }
 }
 
 void VM::close_floppy_disk(int drv)
@@ -471,33 +497,21 @@ uint32_t VM::is_floppy_disk_accessed()
 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);
-#endif
+               sasi_hdd->open(drv, file_path, 256);
        }
 }
 
 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);
-#endif
+               sasi_hdd->close(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);
-#endif
+               return sasi_hdd->mounted(drv);
        }
        return false;
 }
@@ -507,48 +521,37 @@ uint32_t VM::is_hard_disk_accessed()
        uint32_t status = 0;
        
        for(int drv = 0; drv < USE_HARD_DISK; drv++) {
-               if(sasi_hdd->get_disk_handler(drv)->accessed()) {
+               if(sasi_hdd->accessed(drv)) {
                        status |= 1 << drv;
                }
        }
        return status;
 }
 
-void VM::open_hard_disk_tmp(int drv, const _TCHAR* file_path)
-{
-       if(drv < USE_HARD_DISK) {
-               sasi_hdd->get_disk_handler(drv)->open(file_path);
-       }
-}
-
-void VM::close_hard_disk_tmp(int drv)
-{
-       if(drv < USE_HARD_DISK) {
-               sasi_hdd->get_disk_handler(drv)->close();
-       }
-}
-
-bool VM::is_hard_disk_inserted_tmp(int drv)
-{
-       if(drv < USE_HARD_DISK) {
-               return sasi_hdd->get_disk_handler(drv)->mounted();
-       }
-       return false;
-}
-
-
 void VM::play_tape(int drv, const _TCHAR* file_path)
 {
-       bool value = drec->play_tape(file_path);
+       bool remote = drec->get_remote();
+       bool opened = drec->play_tape(file_path);
+       
+       if(opened && remote) {
+               // if machine already sets remote on, start playing now
+               push_play(drv);
+       }
        cmt->close_tape();
-       cmt->play_tape(value);
+       cmt->play_tape(opened);
 }
 
 void VM::rec_tape(int drv, const _TCHAR* file_path)
 {
-       bool value = drec->rec_tape(file_path);
+       bool remote = drec->get_remote();
+       bool opened = drec->rec_tape(file_path);
+       
+       if(opened && remote) {
+               // if machine already sets remote on, start recording now
+               push_play(drv);
+       }
        cmt->close_tape();
-       cmt->rec_tape(value);
+       cmt->rec_tape(opened);
 }
 
 void VM::close_tape(int drv)
@@ -556,6 +559,7 @@ void VM::close_tape(int drv)
        emu->lock_vm();
        drec->close_tape();
        emu->unlock_vm();
+       drec->set_remote(false);
        cmt->close_tape();
 }
 
@@ -586,6 +590,7 @@ const _TCHAR* VM::get_tape_message(int drv)
 
 void VM::push_play(int drv)
 {
+       drec->set_remote(false);
        drec->set_ff_rew(0);
        drec->set_remote(true);
 }
@@ -597,12 +602,14 @@ void VM::push_stop(int drv)
 
 void VM::push_fast_forward(int drv)
 {
+       drec->set_remote(false);
        drec->set_ff_rew(1);
        drec->set_remote(true);
 }
 
 void VM::push_fast_rewind(int drv)
 {
+       drec->set_remote(false);
        drec->set_ff_rew(-1);
        drec->set_remote(true);
 }
@@ -619,49 +626,52 @@ void VM::update_config()
        }
 }
 
-#define STATE_VERSION  7
-
-#include "../../statesub.h"
-#include "../../qt/gui/csp_logger.h"
-extern CSP_Logger DLL_PREFIX_I *csp_logger;
-
-void VM::decl_state(void)
+double VM::get_current_usec()
 {
-       state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::MZ700_SERIES_HEAD")), csp_logger);
-       DECL_STATE_ENTRY_BOOL(monitor_type);
-       for(DEVICE* device = first_device; device; device = device->next_device) {
-               device->decl_state();
-       }
+       if(event == NULL) return 0.0;
+       return event->get_current_usec();
 }
 
-void VM::save_state(FILEIO* state_fio)
+uint64_t VM::get_current_clock_uint64()
 {
-       //state_fio->FputUint32(STATE_VERSION);
-       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);
-       }
-       //state_fio->FputInt32(monitor_type);
+               if(event == NULL) return (uint64_t)0;
+               return event->get_current_clock_uint64();
 }
 
-bool VM::load_state(FILEIO* state_fio)
+#define STATE_VERSION  8
+
+bool VM::process_state(FILEIO* state_fio, bool loading)
 {
-       bool mb = false;
-       if(state_entry != NULL) {
-               mb = state_entry->save_state(state_fio);
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
        }
-       if(!mb) return false;
-       //if(state_fio->FgetUint32() != STATE_VERSION) {
-       //      return false;
-       //}
-       for(DEVICE* device = first_device; device; device = device->next_device) {
-               if(!device->load_state(state_fio)) {
+       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 = (int)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;
                }
-       }
-       //monitor_type = state_fio->FgetInt32();
-       //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;
+               }
+       }
+       // Machine specified.
+       state_fio->StateValue(monitor_type);
+       return true;
 }
-