OSDN Git Service

[VM][STATE] Apply new framework to some VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc6001 / pc6001.cpp
index 1d3c7f1..54c86df 100644 (file)
 #else
 #include "../upd7752.h"
 #endif
+#include "../noise.h"
 #include "../pc6031.h"
 #include "../pc80s31k.h"
 #include "../prnfile.h"
 #include "../upd765a.h"
+#if defined(_PC6001MK2SR) || defined(_PC6601SR)
 #include "../ym2203.h"
+#else
+#include "../ay_3_891x.h"
+#endif
 #include "../z80.h"
 
 #include "../datarec.h"
@@ -52,7 +57,7 @@
 // initialize
 // ----------------------------------------------------------------------------
 
-VM::VM(EMU* parent_emu) : emu(parent_emu)
+VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
 {
        support_pc80s31k = FILEIO::IsFileExisting(create_local_path(_T("DISK.ROM")));
 #ifdef _PC6601SR
@@ -65,29 +70,20 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        first_device = last_device = NULL;
        dummy = new DEVICE(this, emu);  // must be 1st device
        event = new EVENT(this, emu);   // must be 2nd device
-#if defined(_USE_QT)
-       dummy->set_device_name(_T("1st Dummy"));
-#endif 
-       d_pc80s31k_seek = d_pc6031_seek = d_floppy_seek = NULL; 
+       
        pio_sub = new I8255(this, emu);
        io = new IO(this, emu);
+       noise_seek = new NOISE(this, emu);
+       noise_head_down = new NOISE(this, emu);
+       noise_head_up = new NOISE(this, emu);
+#if defined(_PC6001MK2SR) || defined(_PC6601SR)
        psg = new YM2203(this, emu);
-       cpu = new Z80(this, emu);
-#if defined(_USE_QT)
-#ifdef _PC6001
-       pio_sub->set_device_name(_T("i8255 PIO(PRINTER/SOUND/SUB/VDP)"));
 #else
-       pio_sub->set_device_name(_T("i8255 PIO(PRINTER/SOUND/SUB)"));
+       psg = new AY_3_891X(this, emu);
 #endif
-#if defined(_PC6601SR) || defined(_PC6001MK2SR)
-       psg->set_device_name(_T("YM2203 OPN"));
-#else
-       psg->set_device_name(_T("AY-3-8910 PSG"));
-#endif
-       cpu->set_device_name(_T("CPU(Z80)"));
-#endif 
+       cpu = new Z80(this, emu);
        
-       if(config.printer_device_type == 0) {
+       if(config.printer_type == 0) {
                printer = new PRNFILE(this, emu);
        } else {
                printer = dummy;
@@ -95,22 +91,20 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        
 #if defined(_PC6601) || defined(_PC6601SR)
        floppy = new FLOPPY(this, emu);
-#if defined(_USE_QT)
-       floppy->set_device_name(_T("FLOPPY I/F"));
-#endif
+       floppy->set_context_noise_seek(noise_seek);
+//     floppy->set_context_noise_head_down(noise_head_down);
+//     floppy->set_context_noise_head_up(noise_head_up);
 #endif
        joystick = new JOYSTICK(this, emu);
-       memory = new MEMORY(this, emu);
+       memory = new PC6001_MEMORY(this, emu);
        timer = new TIMER(this, emu);
-#if defined(_USE_QT)
-       joystick->set_device_name(_T("JOYSTICK I/F"));
-       memory->set_device_name(_T("MEMORY"));
-       timer->set_device_name(_T("TIMER"));
-#endif
        
        // set contexts
        event->set_context_cpu(cpu);
        event->set_context_sound(psg);
+       event->set_context_sound(noise_seek);
+       event->set_context_sound(noise_head_down);
+       event->set_context_sound(noise_head_up);
        
        pio_sub->set_context_port_b(printer, SIG_PRINTER_DATA, 0xff, 0);
        pio_sub->set_context_port_c(printer, SIG_PRINTER_STROBE, 0x01, 0);
@@ -125,9 +119,6 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        vdp->load_font_image(create_local_path(_T("CGROM60.60")));
        vdp->set_context_cpu(cpu);
        pio_sub->set_context_port_c(vdp, SIG_MC6847_ENABLE, 0x02, 0);   // CRTKILL
-#if defined(_USE_QT)
-       display->set_device_name(_T("DISPLAY I/F"));
-#endif
 #else
        voice = new UPD7752(this, emu);
        event->set_context_sound(voice);
@@ -142,14 +133,18 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
 #endif
        if(support_sub_cpu) {
                cpu_sub = new MCS48(this, emu);
+               cpu_sub->set_device_name(_T("MCS48 MCU (Sub)"));
                sub = new SUB(this, emu);
                drec = new DATAREC(this, emu);
+               drec->set_device_name(_T("Data Recorder (Sub)"));
+               drec->set_context_noise_play(new NOISE(this, emu));
+               drec->set_context_noise_stop(new NOISE(this, emu));
+               drec->set_context_noise_fast(new NOISE(this, emu));
                event->set_context_cpu(cpu_sub, 8000000);
                event->set_context_sound(drec);
-#if defined(USE_SOUND_FILES)
-               drec->load_sound_data(DATAREC_SNDFILE_RELAY_ON, _T("RELAY_ON.WAV"));
-               drec->load_sound_data(DATAREC_SNDFILE_RELAY_OFF, _T("RELAY_OFF.WAV"));
-#endif         
+               event->set_context_sound(drec->get_context_noise_play());
+               event->set_context_sound(drec->get_context_noise_stop());
+               event->set_context_sound(drec->get_context_noise_fast());
                cpu_sub->set_context_mem(new MCS48MEM(this, emu));
                cpu_sub->set_context_io(sub);
 #ifdef USE_DEBUGGER
@@ -163,9 +158,6 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
                timer->set_context_sub(sub);
        } else {
                psub = new PSUB(this, emu);
-#if defined(_USE_QT)
-               psub->set_device_name(_T("PSEUDO SUB SYSTEM"));
-#endif
                psub->set_context_pio(pio_sub);
                psub->set_context_timer(timer);
                timer->set_context_sub(psub);
@@ -173,23 +165,18 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        }
        if(support_pc80s31k) {
                pio_fdd = new I8255(this, emu);
+               pio_fdd->set_device_name(_T("8255 PIO (FDD I/F)"));
                pio_pc80s31k = new I8255(this, emu);
+               pio_pc80s31k->set_device_name(_T("8255 PIO (320KB FDD)"));
                pc80s31k = new PC80S31K(this, emu);
+               pc80s31k->set_device_name(_T("PC-80S31K (320KB FDD)"));
                fdc_pc80s31k = new UPD765A(this, emu);
+               fdc_pc80s31k->set_device_name(_T("uPD765A FDC (320KB FDD)"));
                cpu_pc80s31k = new Z80(this, emu);
-#if defined(_USE_QT)
-               pio_fdd->set_device_name(_T("i8255 PIO(FDD)"));
-               pio_pc80s31k->set_device_name(_T("i8255 PIO(PC-80S31K)"));
-               pc80s31k->set_device_name(_T("PC-80S31K FDD"));
-               fdc_pc80s31k->set_device_name(_T("uPD765A FDC(PC-80S31K)"));
-               cpu_pc80s31k->set_device_name(_T("Z80 CPU(PC-80S31K)"));
-#endif
-#if defined(USE_SOUND_FILES)
-               if(fdc_pc80s31k->load_sound_data(UPD765A_SND_TYPE_SEEK, _T("FDDSEEK.WAV"))) {
-                       event->set_context_sound(fdc_pc80s31k);
-               }
-#endif         
+               cpu_pc80s31k->set_device_name(_T("Z80 CPU (320KB FDD)"));
+               
                event->set_context_cpu(cpu_pc80s31k, 4000000);
+               
                pc80s31k->set_context_cpu(cpu_pc80s31k);
                pc80s31k->set_context_fdc(fdc_pc80s31k);
                pc80s31k->set_context_pio(pio_pc80s31k);
@@ -204,6 +191,9 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
                pio_pc80s31k->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0xf0, -4);
                pio_pc80s31k->clear_ports_by_cmdreg = true;
                fdc_pc80s31k->set_context_irq(cpu_pc80s31k, SIG_CPU_IRQ, 1);
+               fdc_pc80s31k->set_context_noise_seek(noise_seek);
+               fdc_pc80s31k->set_context_noise_head_down(noise_head_down);
+               fdc_pc80s31k->set_context_noise_head_up(noise_head_up);
                cpu_pc80s31k->set_context_mem(pc80s31k);
                cpu_pc80s31k->set_context_io(pc80s31k);
                cpu_pc80s31k->set_context_intr(pc80s31k);
@@ -215,17 +205,12 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
 #endif
        } else {
                pc6031 = new PC6031(this, emu);
+               pc6031->set_context_noise_seek(noise_seek);
+//             pc6031->set_context_noise_head_down(noise_head_down);
+//             pc6031->set_context_noise_head_up(noise_head_up);
 #if defined(_PC6601) || defined(_PC6601SR)
                floppy->set_context_ext(pc6031);
 #endif
-#if defined(USE_SOUND_FILES)
-               if(pc6031->load_sound_data(PC6031_SND_TYPE_SEEK, _T("FDDSEEK.WAV"))) {
-                       event->set_context_sound(pc6031);
-               }
-               if(floppy->load_sound_data(FLOPPY_SND_TYPE_SEEK, _T("FDDSEEK.WAV"))) {
-                       event->set_context_sound(floppy);
-               }
-#endif         
                cpu_pc80s31k = NULL;
        }
        
@@ -286,9 +271,13 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        io->set_iomap_range_rw(0xf0, 0xf2, memory);             // MEMORY MAP
        
        // 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();
        }
+
        if(support_sub_cpu) {
                // load rom images after cpustate is allocated
 #ifdef _PC6601SR
@@ -420,17 +409,17 @@ void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
                if(support_sub_cpu) {
                        drec->set_volume(0, decibel_l, decibel_r);
                }
+       } else if(ch-- == 0) {
+               noise_seek->set_volume(0, decibel_l, decibel_r);
+               noise_head_down->set_volume(0, decibel_l, decibel_r);
+               noise_head_up->set_volume(0, decibel_l, decibel_r);
+       } else if(ch-- == 0) {
+               if(support_sub_cpu) {
+                       drec->get_context_noise_play()->set_volume(0, decibel_l, decibel_r);
+                       drec->get_context_noise_stop()->set_volume(0, decibel_l, decibel_r);
+                       drec->get_context_noise_fast()->set_volume(0, decibel_l, decibel_r);
+               }
        }
-#if defined(USE_SOUND_FILES)
-        else if(ch-- == 0) {
-                if(support_pc80s31k) {
-                        if(fdc_pc80s31k != NULL) fdc_pc80s31k->set_volume(0, decibel_l, decibel_r);
-                } else {
-                        if(pc6031 != NULL) pc6031->set_volume(0, decibel_l, decibel_r);
-                        if(floppy != NULL) floppy->set_volume(0, decibel_l, decibel_r);
-                }
-       }
-#endif
 }
 #endif
 
@@ -481,20 +470,6 @@ bool VM::is_cart_inserted(int drv)
        }
 }
 
-uint32_t VM::get_access_lamp_status()
-{
-       uint32_t status = 0; /// fdc->read_signal(0);
-#if defined(_PC6601) || defined(_PC6601SR)
-       status = floppy->read_signal(0);
-#endif
-       if(support_pc80s31k) {
-               status |= fdc_pc80s31k->read_signal(0);
-       } else {
-               status |= pc6031->read_signal(0);
-       }
-       return status;
-}
-
 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
 {
 #if defined(_PC6601) || defined(_PC6601SR)
@@ -578,43 +553,63 @@ bool VM::is_floppy_disk_protected(int drv)
        }
 }
 
-void VM::play_tape(const _TCHAR* file_path)
+uint32_t VM::is_floppy_disk_accessed()
+{
+       uint32_t status = 0; /// fdc->read_signal(0);
+       if(support_pc80s31k) {
+               status |= fdc_pc80s31k->read_signal(0);
+       } else {
+               status |= pc6031->read_signal(0);
+       }
+#if defined(_PC6601) || defined(_PC6601SR)
+       status <<= 2;
+       status |= floppy->read_signal(0);
+#endif
+       return status;
+}
+
+void VM::play_tape(int drv, const _TCHAR* file_path)
 {
        if(support_sub_cpu) {
                // support both p6/p6t and wav
                drec->play_tape(file_path);
+//             drec->set_remote(true);
        } else {
                // support only p6/p6t
                psub->play_tape(file_path);
        }
 }
 
-void VM::rec_tape(const _TCHAR* file_path)
+void VM::rec_tape(int drv, const _TCHAR* file_path)
 {
        if(support_sub_cpu) {
                // support both p6/p6t and wav
                sub->rec_tape(file_path);       // temporary
 //             drec->rec_tape(file_path);
+//             drec->set_remote(true);
        } else {
                // support both p6/p6t and wav
                psub->rec_tape(file_path);
        }
 }
 
-void VM::close_tape()
+void VM::close_tape(int drv)
 {
        if(support_sub_cpu) {
                if(sub->is_tape_inserted()) {
                        sub->close_tape();      // temporary
                } else {
+                       emu->lock_vm();
                        drec->close_tape();
+                       emu->unlock_vm();
+//                     drec->set_remote(false);
                }
        } else {
                psub->close_tape();
        }
 }
 
-bool VM::is_tape_inserted()
+bool VM::is_tape_inserted(int drv)
 {
        if(support_sub_cpu) {
                return drec->is_tape_inserted() || sub->is_tape_inserted();
@@ -623,7 +618,7 @@ bool VM::is_tape_inserted()
        }
 }
 
-bool VM::is_tape_playing()
+bool VM::is_tape_playing(int drv)
 {
        if(support_sub_cpu) {
                return drec->is_tape_playing();
@@ -632,7 +627,7 @@ bool VM::is_tape_playing()
        }
 }
 
-bool VM::is_tape_recording()
+bool VM::is_tape_recording(int drv)
 {
        if(support_sub_cpu) {
                return drec->is_tape_recording();
@@ -641,7 +636,7 @@ bool VM::is_tape_recording()
        }
 }
 
-int VM::get_tape_position()
+int VM::get_tape_position(int drv)
 {
        if(support_sub_cpu) {
                return drec->get_tape_position();
@@ -650,41 +645,92 @@ int VM::get_tape_position()
        }
 }
 
-bool VM::is_frame_skippable()
+const _TCHAR* VM::get_tape_message(int drv)
 {
-       return event->is_frame_skippable();
+       if(support_sub_cpu) {
+               return drec->get_message();
+       } else {
+               return NULL;
+       }
 }
 
-void VM::update_config()
+void VM::push_play(int drv)
 {
-       for(DEVICE* device = first_device; device; device = device->next_device) {
-               device->update_config();
+       if(support_sub_cpu) {
+               drec->set_ff_rew(0);
+               drec->set_remote(true);
        }
 }
 
-#define STATE_VERSION  3
+void VM::push_stop(int drv)
+{
+       if(support_sub_cpu) {
+               drec->set_remote(false);
+       }
+}
 
-void VM::save_state(FILEIO* state_fio)
+void VM::push_fast_forward(int drv)
+{
+       if(support_sub_cpu) {
+               drec->set_ff_rew(1);
+               drec->set_remote(true);
+       }
+}
+
+void VM::push_fast_rewind(int drv)
+{
+       if(support_sub_cpu) {
+               drec->set_ff_rew(-1);
+               drec->set_remote(true);
+       }
+}
+
+bool VM::is_frame_skippable()
+{
+       return event->is_frame_skippable();
+}
+
+void VM::update_config()
 {
-       state_fio->FputUint32(STATE_VERSION);
-       
        for(DEVICE* device = first_device; device; device = device->next_device) {
-               device->save_state(state_fio);
+               device->update_config();
        }
-       state_fio->FputInt32(sr_mode);
 }
 
-bool VM::load_state(FILEIO* state_fio)
+#define STATE_VERSION  6
+
+bool VM::process_state(FILEIO* state_fio, bool loading)
 {
-       if(state_fio->FgetUint32() != STATE_VERSION) {
+       if(!state_fio->StateCheckUint32(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 = 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;
                }
-       }
-       sr_mode = state_fio->FgetInt32();
+               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->StateInt32(sr_mode);
        return true;
 }
-