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 fbcb59e..54c86df 100644 (file)
@@ -16,6 +16,7 @@
 #include "../device.h"
 #include "../event.h"
 
+#include "../disk.h"
 #include "../i8255.h"
 #include "../io.h"
 #ifdef _PC6001
 #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"
 #endif
 #include "joystick.h"
 #include "memory.h"
-#include "printer.h"
 #include "psub.h"
 #include "sub.h"
 #include "timer.h"
 
-#include "../../fileio.h"
-
 // ----------------------------------------------------------------------------
 // initialize
 // ----------------------------------------------------------------------------
 
-VM::VM(EMU* parent_emu) : emu(parent_emu)
+VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
 {
-       support_pc80s31k = FILEIO::IsFileExists(emu->bios_path(_T("DISK.ROM")));
+       support_pc80s31k = FILEIO::IsFileExisting(create_local_path(_T("DISK.ROM")));
 #ifdef _PC6601SR
        support_sub_cpu = false;
 #else
-       support_sub_cpu = FILEIO::IsFileExists(emu->bios_path(_T(SUB_CPU_ROM_FILE_NAME)));
+       support_sub_cpu = FILEIO::IsFileExisting(create_local_path(_T(SUB_CPU_ROM_FILE_NAME)));
 #endif
        
        // create devices
@@ -69,23 +73,41 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        
        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);
+#else
+       psg = new AY_3_891X(this, emu);
+#endif
        cpu = new Z80(this, emu);
        
+       if(config.printer_type == 0) {
+               printer = new PRNFILE(this, emu);
+       } else {
+               printer = dummy;
+       }
+       
 #if defined(_PC6601) || defined(_PC6601SR)
        floppy = new FLOPPY(this, emu);
+       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);
-//     printer = new PRINTER(this, emu);
+       memory = new PC6001_MEMORY(this, emu);
        timer = new TIMER(this, emu);
        
        // 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_OUT, 0xff, 0);
-//     pio_sub->set_context_port_c(printer, SIG_PRINTER_STB, 0x01, 0);
+       pio_sub->set_context_port_b(printer, SIG_PRINTER_DATA, 0xff, 0);
+       pio_sub->set_context_port_c(printer, SIG_PRINTER_STROBE, 0x01, 0);
        pio_sub->set_context_port_c(memory, SIG_MEMORY_PIO_PORT_C, 0x06, 0);    // CRTKILL,CGSWN
        
 #ifdef _PC6001
@@ -94,7 +116,7 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
        display->set_context_vdp(vdp);
        display->set_vram_ptr(memory->get_vram());
        display->set_context_timer(timer);
-       vdp->load_font_image(emu->bios_path(_T("CGROM60.60")));
+       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
 #else
@@ -111,9 +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);
+               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
@@ -123,7 +154,7 @@ VM::VM(EMU* parent_emu) : emu(parent_emu)
                sub->set_context_drec(drec);
                sub->set_context_timer(timer);
                pio_sub->set_context_port_c(cpu_sub, SIG_CPU_IRQ, 0x80, 0);
-               drec->set_context_out(sub, SIG_SUB_DATAREC, 1);
+               drec->set_context_ear(sub, SIG_SUB_DATAREC, 1);
                timer->set_context_sub(sub);
        } else {
                psub = new PSUB(this, emu);
@@ -134,16 +165,22 @@ 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);
+               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);
-               pio_fdd->set_context_port_a(pio_pc80s31k, SIG_I8255_PORT_A, 0xff, 0);
+               pio_fdd->set_context_port_a(pio_pc80s31k, SIG_I8255_PORT_B, 0xff, 0);
                pio_fdd->set_context_port_b(pio_pc80s31k, SIG_I8255_PORT_A, 0xff, 0);
                pio_fdd->set_context_port_c(pio_pc80s31k, SIG_I8255_PORT_C, 0x0f, 4);
                pio_fdd->set_context_port_c(pio_pc80s31k, SIG_I8255_PORT_C, 0xf0, -4);
@@ -154,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);
@@ -165,6 +205,9 @@ 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
@@ -228,15 +271,31 @@ 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
 #else
-               cpu_sub->load_rom_image(emu->bios_path(SUB_CPU_ROM_FILE_NAME));
+               cpu_sub->load_rom_image(create_local_path(_T(SUB_CPU_ROM_FILE_NAME)));
+#endif
+       }
+       int drive_num = 0;
+#if defined(_PC6601) || defined(_PC6601SR)
+       floppy->get_disk_handler(0)->drive_num = drive_num++;
+       floppy->get_disk_handler(1)->drive_num = drive_num++;
 #endif
+       if(support_pc80s31k) {
+               fdc_pc80s31k->get_disk_handler(0)->drive_num = drive_num++;
+               fdc_pc80s31k->get_disk_handler(1)->drive_num = drive_num++;
+       } else {
+               pc6031->get_disk_handler(0)->drive_num = drive_num++;
+               pc6031->get_disk_handler(1)->drive_num = drive_num++;
        }
 }
 
@@ -321,24 +380,72 @@ void VM::initialize_sound(int rate, int samples)
        event->initialize_sound(rate, samples);
        
        // init sound gen
-       psg->init(rate, 4000000, samples, 0, 0);
+       psg->initialize_sound(rate, 4000000, samples, 0, 0);
+#ifndef _PC6001
+       voice->initialize_sound(rate);
+#endif
 }
 
-uint16* VM::create_sound(int* extra_frames)
+uint16_t* VM::create_sound(int* extra_frames)
 {
        return event->create_sound(extra_frames);
 }
 
-int VM::sound_buffer_ptr()
+int VM::get_sound_buffer_ptr()
+{
+       return event->get_sound_buffer_ptr();
+}
+
+#ifdef USE_SOUND_VOLUME
+void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
+{
+       if(ch-- == 0) {
+               psg->set_volume(1, decibel_l, decibel_r);
+#if !defined(_PC6001)
+       } else if(ch-- == 0) {
+               voice->set_volume(0, decibel_l, decibel_r);
+#endif
+       } else if(ch-- == 0) {
+               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);
+               }
+       }
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// notify key
+// ----------------------------------------------------------------------------
+
+void VM::key_down(int code, bool repeat)
+{
+       if(!support_sub_cpu) {
+               psub->key_down(code);
+       }
+}
+
+void VM::key_up(int code)
 {
-       return event->sound_buffer_ptr();
+       if(!support_sub_cpu) {
+               psub->key_up(code);
+       }
 }
 
 // ----------------------------------------------------------------------------
 // user interface
 // ----------------------------------------------------------------------------
 
-void VM::open_cart(int drv, _TCHAR* file_path)
+void VM::open_cart(int drv, const _TCHAR* file_path)
 {
        if(drv == 0) {
                memory->open_cart(file_path);
@@ -354,127 +461,233 @@ void VM::close_cart(int drv)
        }
 }
 
-bool VM::cart_inserted(int drv)
+bool VM::is_cart_inserted(int drv)
 {
        if(drv == 0) {
-               return memory->cart_inserted();
+               return memory->is_cart_inserted();
        } else {
                return false;
        }
 }
 
-int VM::access_lamp()
+void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
 {
-       uint32 status = 0; /// fdc->read_signal(0);
 #if defined(_PC6601) || defined(_PC6601SR)
-       status = floppy->read_signal(0);
+       if(drv < 2) {
+               floppy->open_disk(drv, file_path, bank);
+               return;
+       } else {
+               drv -= 2;
+       }
 #endif
        if(support_pc80s31k) {
-               status |= fdc_pc80s31k->read_signal(0);
+               fdc_pc80s31k->open_disk(drv, file_path, bank);
        } else {
-               status |= pc6031->read_signal(0);
+               pc6031->open_disk(drv, file_path, bank);
        }
-       return status;
 }
 
-void VM::open_disk(int drv, _TCHAR* file_path, int offset)
+void VM::close_floppy_disk(int drv)
 {
 #if defined(_PC6601) || defined(_PC6601SR)
        if(drv < 2) {
-               floppy->open_disk(drv, file_path, offset);
+               floppy->close_disk(drv);
                return;
        } else {
                drv -= 2;
        }
 #endif
        if(support_pc80s31k) {
-               fdc_pc80s31k->open_disk(drv, file_path, offset);
+               fdc_pc80s31k->close_disk(drv);
+       } else {
+               pc6031->close_disk(drv);
+       }
+}
+
+bool VM::is_floppy_disk_inserted(int drv)
+{
+#if defined(_PC6601) || defined(_PC6601SR)
+       if(drv < 2) {
+               return floppy->is_disk_inserted(drv);
+       } else {
+               drv -= 2;
+       }
+#endif
+       if(support_pc80s31k) {
+               return fdc_pc80s31k->is_disk_inserted(drv);
        } else {
-               pc6031->open_disk(drv, file_path, offset);
+               return pc6031->is_disk_inserted(drv);
        }
 }
 
-void VM::close_disk(int drv)
+void VM::is_floppy_disk_protected(int drv, bool value)
 {
 #if defined(_PC6601) || defined(_PC6601SR)
        if(drv < 2) {
-               floppy->close_disk(drv);
+               floppy->is_disk_protected(drv, value);
                return;
        } else {
                drv -= 2;
        }
 #endif
        if(support_pc80s31k) {
-               fdc_pc80s31k->close_disk(drv);
+               fdc_pc80s31k->is_disk_protected(drv, value);
        } else {
-               pc6031->close_disk(drv);
+               pc6031->is_disk_protected(drv, value);
        }
 }
 
-bool VM::disk_inserted(int drv)
+bool VM::is_floppy_disk_protected(int drv)
 {
 #if defined(_PC6601) || defined(_PC6601SR)
        if(drv < 2) {
-               return floppy->disk_inserted(drv);
+               return floppy->is_disk_protected(drv);
        } else {
                drv -= 2;
        }
 #endif
        if(support_pc80s31k) {
-               return fdc_pc80s31k->disk_inserted(drv);
+               return fdc_pc80s31k->is_disk_protected(drv);
+       } else {
+               return pc6031->is_disk_protected(drv);
+       }
+}
+
+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 {
-               return pc6031->disk_inserted(drv);
+               status |= pc6031->read_signal(0);
        }
+#if defined(_PC6601) || defined(_PC6601SR)
+       status <<= 2;
+       status |= floppy->read_signal(0);
+#endif
+       return status;
 }
 
-void VM::play_tape(_TCHAR* file_path)
+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(_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->tape_inserted()) {
+               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::tape_inserted()
+bool VM::is_tape_inserted(int drv)
+{
+       if(support_sub_cpu) {
+               return drec->is_tape_inserted() || sub->is_tape_inserted();
+       } else {
+               return psub->is_tape_inserted();
+       }
+}
+
+bool VM::is_tape_playing(int drv)
+{
+       if(support_sub_cpu) {
+               return drec->is_tape_playing();
+       } else {
+               return false;
+       }
+}
+
+bool VM::is_tape_recording(int drv)
+{
+       if(support_sub_cpu) {
+               return drec->is_tape_recording();
+       } else {
+               return false;
+       }
+}
+
+int VM::get_tape_position(int drv)
+{
+       if(support_sub_cpu) {
+               return drec->get_tape_position();
+       } else {
+               return 0;
+       }
+}
+
+const _TCHAR* VM::get_tape_message(int drv)
 {
        if(support_sub_cpu) {
-               return drec->tape_inserted() || sub->tape_inserted();
+               return drec->get_message();
        } else {
-               return psub->tape_inserted();
+               return NULL;
+       }
+}
+
+void VM::push_play(int drv)
+{
+       if(support_sub_cpu) {
+               drec->set_ff_rew(0);
+               drec->set_remote(true);
+       }
+}
+
+void VM::push_stop(int drv)
+{
+       if(support_sub_cpu) {
+               drec->set_remote(false);
+       }
+}
+
+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::now_skip()
+bool VM::is_frame_skippable()
 {
-       return event->now_skip();
+       return event->is_frame_skippable();
 }
 
 void VM::update_config()
@@ -483,3 +696,41 @@ void VM::update_config()
                device->update_config();
        }
 }
+
+#define STATE_VERSION  6
+
+bool VM::process_state(FILEIO* state_fio, bool loading)
+{
+       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;
+               }
+               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;
+}