X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=source%2Fsrc%2Fvm%2Fx1%2Fx1.cpp;h=cb5dc7ca4925b8fb52ccaafd913874dcf1f1033d;hb=90a1d498c79c26d69c78435600856b152aa07291;hp=fa123696ad42a8bc940155ca4d353c9667c445ec;hpb=09a5cb5697856ae8a2f78d741b0e42732c077a50;p=csp-qt%2Fcommon_source_project-fm7.git diff --git a/source/src/vm/x1/x1.cpp b/source/src/vm/x1/x1.cpp index fa123696a..cb5dc7ca4 100644 --- a/source/src/vm/x1/x1.cpp +++ b/source/src/vm/x1/x1.cpp @@ -2,6 +2,7 @@ SHARP X1 Emulator 'eX1' SHARP X1twin Emulator 'eX1twin' SHARP X1turbo Emulator 'eX1turbo' + SHARP X1turboZ Emulator 'eX1turboZ' Author : Takeda.Toshiya Date : 2009.03.11- @@ -16,12 +17,20 @@ #include "../datarec.h" #include "../disk.h" +#include "../harddisk.h" #include "../hd46505.h" #include "../i8255.h" #include "../io.h" #include "../mb8877.h" +#include "../mz1p17.h" +#include "../noise.h" +//#include "../pcpr201.h" +#include "../prnfile.h" +#include "../scsi_hdd.h" +#include "../scsi_host.h" #include "../ym2151.h" -#include "../ym2203.h" +//#include "../ym2203.h" +#include "../ay_3_891x.h" #include "../z80.h" #include "../z80ctc.h" #include "../z80sio.h" @@ -40,8 +49,8 @@ #include "joystick.h" #include "memory.h" #include "mouse.h" -#include "printer.h" #include "psub.h" +#include "sasi.h" #include "../mcs48.h" #include "../upd1990a.h" @@ -52,38 +61,74 @@ #include "../huc6280.h" #include "../pcengine/pce.h" #endif +#if defined(Q_OS_WIN) +DLL_PREFIX_I struct cur_time_s cur_time; +#endif // ---------------------------------------------------------------------------- // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : emu(parent_emu) +VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) { - pseudo_sub_cpu = !(FILEIO::IsFileExists(create_local_path(SUB_ROM_FILE_NAME)) && FILEIO::IsFileExists(create_local_path(KBD_ROM_FILE_NAME))); + pseudo_sub_cpu = !(FILEIO::IsFileExisting(create_local_path(SUB_ROM_FILE_NAME)) && FILEIO::IsFileExisting(create_local_path(KBD_ROM_FILE_NAME))); - sound_device_type = config.sound_device_type; + sound_type = config.sound_type; // create devices first_device = last_device = NULL; dummy = new DEVICE(this, emu); // must be 1st device event = new EVENT(this, emu); // must be 2nd device + dummy->set_device_name(_T("1st Dummy")); drec = new DATAREC(this, emu); + 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)); crtc = new HD46505(this, emu); pio = new I8255(this, emu); io = new IO(this, emu); fdc = new MB8877(this, emu); - psg = new YM2203(this, 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)); + sasi_host = new SCSI_HOST(this, emu); + for (int i = 0; i < array_length(sasi_hdd); i++) { + sasi_hdd[i] = new SCSI_HDD(this, emu); + sasi_hdd[i]->set_device_name(_T("SASI Hard Disk Drive #%d"), i + 1); + sasi_hdd[i]->scsi_id = i; + sasi_hdd[i]->bytes_per_sec = 32 * 1024; // 32KB/s + sasi_hdd[i]->set_context_interface(sasi_host); + sasi_host->set_context_target(sasi_hdd[i]); + } + for(int drv = 0; drv < USE_HARD_DISK; drv++) { + sasi_hdd[drv >> 1]->set_disk_handler(drv & 1, new HARDDISK(emu)); + } +// psg = new YM2203(this, emu); + psg = new AY_3_891X(this, emu); cpu = new Z80(this, emu); ctc = new Z80CTC(this, emu); sio = new Z80SIO(this, emu); - if(sound_device_type >= 1) { + if(sound_type >= 1) { opm1 = new YM2151(this, emu); + opm1->set_device_name(_T("YM2151 OPM (CZ-8BS1 #1)")); ctc1 = new Z80CTC(this, emu); + ctc1->set_device_name(_T("Z80 CTC (CZ-8BS1 #1)")); } - if(sound_device_type == 2) { + if(sound_type == 2) { opm2 = new YM2151(this, emu); + opm2->set_device_name(_T("YM2151 OPM (CZ-8BS1 #2)")); ctc2 = new Z80CTC(this, emu); + ctc2->set_device_name(_T("Z80 CTC (CZ-8BS1 #2)")); + } + if(config.printer_type == 0) { + printer = new PRNFILE(this, emu); + } else if(config.printer_type == 1) { + printer = new MZ1P17(this, emu); +// } else if(config.printer_type == 2) { +// printer = new PCPR201(this, emu); + } else { + printer = dummy; } #ifdef _X1TURBO_FEATURE dma = new Z80DMA(this, emu); @@ -96,7 +141,7 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) joy = new JOYSTICK(this, emu); memory = new MEMORY(this, emu); mouse = new MOUSE(this, emu); - printer = new PRINTER(this, emu); + sasi = new SASI(this, emu); if(pseudo_sub_cpu) { psub = new PSUB(this, emu); @@ -105,12 +150,16 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) } else { // sub cpu cpu_sub = new MCS48(this, emu); + cpu_sub->set_device_name(_T("MCS48 MCU (Sub)")); pio_sub = new I8255(this, emu); + pio_sub->set_device_name(_T("i8255 PIO (Sub)")); rtc_sub = new UPD1990A(this, emu); + rtc_sub->set_device_name(_T("uPD1990A RTC (Sub)")); sub = new SUB(this, emu); - + // keyboard cpu_kbd = new MCS48(this, emu); + cpu_kbd->set_device_name(_T("MCS48 MCU (Keyboard)")); kbd = new KEYBOARD(this, emu); } @@ -120,27 +169,36 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) event->set_context_cpu(cpu_sub, 6000000); event->set_context_cpu(cpu_kbd, 6000000); } - if(sound_device_type >= 1) { + if(sound_type >= 1) { event->set_context_sound(opm1); } - if(sound_device_type == 2) { + if(sound_type == 2) { event->set_context_sound(opm2); } event->set_context_sound(psg); event->set_context_sound(drec); + event->set_context_sound(fdc->get_context_noise_seek()); + event->set_context_sound(fdc->get_context_noise_head_down()); + event->set_context_sound(fdc->get_context_noise_head_up()); + 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()); drec->set_context_ear(pio, SIG_I8255_PORT_B, 0x02); crtc->set_context_vblank(display, SIG_DISPLAY_VBLANK, 1); + crtc->set_context_disp(display, SIG_DISPLAY_DISP, 1); crtc->set_context_vblank(pio, SIG_I8255_PORT_B, 0x80); crtc->set_context_vsync(pio, SIG_I8255_PORT_B, 0x04); - pio->set_context_port_a(printer, SIG_PRINTER_OUT, 0xff, 0); + pio->set_context_port_a(printer, SIG_PRINTER_DATA, 0xff, 0); pio->set_context_port_c(drec, SIG_DATAREC_MIC, 0x01, 0); pio->set_context_port_c(display, SIG_DISPLAY_COLUMN40, 0x40, 0); pio->set_context_port_c(iobus, SIG_IOBUS_MODE, 0x60, 0); - pio->set_context_port_c(printer, SIG_PRINTER_STB, 0x80, 0); + pio->set_context_port_c(printer, SIG_PRINTER_STROBE, 0x80, 0); #ifdef _X1TURBO_FEATURE fdc->set_context_drq(dma, SIG_Z80DMA_READY, 1); #endif + sasi_host->set_context_irq(sasi, SIG_SASI_IRQ, 1); + sasi_host->set_context_drq(sasi, SIG_SASI_DRQ, 1); ctc->set_context_zc0(ctc, SIG_Z80CTC_TRIG_3, 1); ctc->set_context_zc1(sio, SIG_Z80SIO_TX_CLK_CH0, 1); ctc->set_context_zc1(sio, SIG_Z80SIO_RX_CLK_CH0, 1); @@ -154,16 +212,27 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) // sio->set_tx_clock(1, 4800 * 16); // 4800 baud for mouse // sio->set_rx_clock(1, 4800 * 16); // clock is from Z-80CTC ch2 (2MHz/26) - if(sound_device_type >= 1) { + if(sound_type >= 1) { ctc1->set_context_zc0(ctc1, SIG_Z80CTC_TRIG_3, 1); // ctc1->set_constant_clock(1, CPU_CLOCKS >> 1); // ctc1->set_constant_clock(2, CPU_CLOCKS >> 1); } - if(sound_device_type == 2) { + if(sound_type == 2) { ctc2->set_context_zc0(ctc2, SIG_Z80CTC_TRIG_3, 1); // ctc2->set_constant_clock(1, CPU_CLOCKS >> 1); // ctc2->set_constant_clock(2, CPU_CLOCKS >> 1); } + if(config.printer_type == 0) { + PRNFILE *prnfile = (PRNFILE *)printer; + prnfile->set_context_busy(pio, SIG_I8255_PORT_B, 0x08); + } else if(config.printer_type == 1) { + MZ1P17 *mz1p17 = (MZ1P17 *)printer; + mz1p17->mode = MZ1P17_MODE_X1; + mz1p17->set_context_busy(pio, SIG_I8255_PORT_B, 0x08); +// } else if(config.printer_type == 2) { +// PCPR201 *pcpr201 = (PCPR201 *)printer; +// pcpr201->set_context_busy(pio, SIG_I8255_PORT_B, 0x08); + } #ifdef _X1TURBO_FEATURE dma->set_context_memory(memory); dma->set_context_io(iobus); @@ -171,8 +240,8 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) #ifdef _X1TURBO_FEATURE display->set_context_cpu(cpu); - display->set_context_crtc(crtc); #endif + display->set_context_crtc(crtc); display->set_vram_ptr(iobus->get_vram()); display->set_regs_ptr(crtc->get_regs()); floppy->set_context_fdc(fdc); @@ -184,6 +253,10 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) memory->set_context_pio(pio); #endif mouse->set_context_sio(sio); + sasi->set_context_host(sasi_host); +#ifdef _X1TURBO_FEATURE + sasi->set_context_dma(dma); +#endif if(pseudo_sub_cpu) { drec->set_context_remote(psub, SIG_PSUB_TAPE_REMOTE, 1); @@ -249,10 +322,10 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) Z80_DAISY_CHAIN(sio); // CZ-8BM2 Z80_DAISY_CHAIN(ctc); #endif - if(sound_device_type >= 1) { + if(sound_type >= 1) { Z80_DAISY_CHAIN(ctc1); } - if(sound_device_type == 2) { + if(sound_type == 2) { Z80_DAISY_CHAIN(ctc2); } #ifdef _X1TURBO_FEATURE @@ -267,7 +340,7 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) } // i/o bus - if(sound_device_type >= 1) { + if(sound_type >= 1) { io->set_iomap_single_w(0x700, opm1); io->set_iovalue_single_r(0x700, 0x00); io->set_iomap_single_rw(0x701, opm1); @@ -277,7 +350,7 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) io->set_iomap_range_rw(0x704, 0x707, ctc1); #endif } - if(sound_device_type == 2) { + if(sound_type == 2) { io->set_iomap_single_w(0x708, opm2); io->set_iovalue_single_r(0x708, 0x00); io->set_iomap_single_rw(0x709, opm2); @@ -289,6 +362,7 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) io->set_iomap_range_rw(0xd00, 0xd03, emm); io->set_iomap_range_r(0xe80, 0xe81, display); io->set_iomap_range_w(0xe80, 0xe82, display); + io->set_iomap_range_rw(0xfd0, 0xfd3, sasi); io->set_iomap_range_rw(0xff8, 0xffb, fdc); io->set_iomap_single_w(0xffc, floppy); #ifdef _X1TURBO_FEATURE @@ -312,15 +386,15 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) for(int i = 0x1c00; i <= 0x1cff; i++) { io->set_iomap_alias_w(i, psg, 0); } + io->set_iomap_range_r(0x1e00, 0x1eff, memory); io->set_iomap_range_w(0x1d00, 0x1eff, memory); -#ifndef _X1TURBO_FEATURE - io->set_iomap_range_rw(0x1f98, 0x1f9b, sio); // CZ-8BM2 - io->set_iomap_range_rw(0x1fa8, 0x1fab, ctc); -#else +#ifdef _X1TURBO_FEATURE io->set_iomap_range_rw(0x1f80, 0x1f8f, dma); io->set_iomap_range_rw(0x1f90, 0x1f93, sio); io->set_iomap_range_rw(0x1fa0, 0x1fa3, ctc); #ifdef _X1TURBOZ + io->set_iomap_single_rw(0x1fb0, display); + io->set_iomap_range_rw(0x1fb9, 0x1fc5, display); io->set_iomap_single_rw(0x1fd0, display); io->set_iomap_single_rw(0x1fe0, display); #else @@ -328,8 +402,11 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) io->set_iomap_single_w(0x1fe0, display); #endif // 0x1ff0: dipswitch - //io->set_iovalue_single_r(0x1ff0, 0x00); +// io->set_iovalue_single_r(0x1ff0, 0x00); update_dipswitch(); +#else + io->set_iomap_range_rw(0x1f98, 0x1f9b, sio); // CZ-8BM2 + io->set_iomap_range_rw(0x1fa8, 0x1fab, ctc); #endif io->set_iomap_range_rw(0x2000, 0x3fff, display); // tvram @@ -338,12 +415,14 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) pceevent = new EVENT(this, emu); pceevent->set_frames_per_sec(PCE_FRAMES_PER_SEC); pceevent->set_lines_per_frame(PCE_LINES_PER_FRAME); - + pceevent->set_device_name(_T("EVENT (PC-ENGINE)")); pcecpu = new HUC6280(this, emu); + pcecpu->set_device_name(_T("HuC6820 CPU (PC-ENGINE)")); pcecpu->set_context_event_manager(pceevent); pce = new PCE(this, emu); + pce->set_device_name(_T("SUB SYSTEM (PC-ENGINE)")); pce->set_context_event_manager(pceevent); - + pceevent->set_context_cpu(pcecpu, PCE_CPU_CLOCKS); pceevent->set_context_sound(pce); @@ -356,6 +435,9 @@ 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(); } @@ -365,23 +447,32 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) cpu_kbd->load_rom_image(create_local_path(KBD_ROM_FILE_NAME)); // patch to set the current year - uint8 *rom = cpu_sub->get_rom_ptr(); - sub->rom_crc32 = getcrc32(rom, 0x800); // 2KB + uint8_t *rom = cpu_sub->get_rom_ptr(); + sub->rom_crc32 = get_crc32(rom, 0x800); // 2KB if(rom[0x23] == 0xb9 && rom[0x24] == 0x35 && rom[0x25] == 0xb1) { + //dll_cur_time_t cur_time; cur_time_t cur_time; get_host_time(&cur_time); rom[0x26] = TO_BCD(cur_time.year); } } - for(int i = 0; i < MAX_DRIVE; i++) { -#ifdef _X1TURBO_FEATURE - fdc->set_drive_type(i, DRIVE_TYPE_2DD); + for(int drv = 0; drv < MAX_DRIVE; drv++) { +//#ifdef _X1TURBO_FEATURE +// fdc->set_drive_type(drv, DRIVE_TYPE_2DD); +//#else + fdc->set_drive_type(drv, DRIVE_TYPE_2D); +//#endif +// fdc->set_drive_rpm(drv, 300); +// fdc->set_drive_mfm(drv, true); + } + 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 - fdc->set_drive_type(i, DRIVE_TYPE_2D); + open_hard_disk_tmp(drv, create_local_path(_T("SASI%d.DAT"), drv)); #endif -// fdc->set_drive_rpm(i, 300); -// fdc->set_drive_mfm(i, true); } + decl_state(); } VM::~VM() @@ -415,7 +506,19 @@ void VM::reset() for(DEVICE* device = first_device; device; device = device->next_device) { device->reset(); } - psg->SetReg(0x2e, 0); // set prescaler + pio->write_signal(SIG_I8255_PORT_B, 0x00, 0x08); // busy = low + psg->set_reg(0x2e, 0); // set prescaler + +#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() @@ -428,20 +531,20 @@ void VM::run() { event->drive(); #ifdef _X1TWIN - if(pce->cart_inserted()) { + if(pce->is_cart_inserted()) { pceevent->drive(); } #endif } -double VM::frame_rate() +double VM::get_frame_rate() { #ifdef _X1TWIN - if(pce->cart_inserted()) { - return pceevent->frame_rate(); + if(pce->is_cart_inserted()) { + return pceevent->get_frame_rate(); } #endif - return event->frame_rate(); + return event->get_frame_rate(); } // ---------------------------------------------------------------------------- @@ -458,7 +561,7 @@ DEVICE *VM::get_cpu(int index) } else if(index == 2) { return cpu_kbd; #ifdef _X1TWIN - } else if(index == 3 && pce->cart_inserted()) { + } else if(index == 3 && pce->is_cart_inserted()) { return pcecpu; #endif } @@ -474,18 +577,12 @@ void VM::draw_screen() { display->draw_screen(); #ifdef _X1TWIN - if(pce->cart_inserted()) { + if(pce->is_cart_inserted()) { pce->draw_screen(); } #endif } -int VM::access_lamp() -{ - uint32 status = fdc->read_signal(0); - return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0; -} - // ---------------------------------------------------------------------------- // soud manager // ---------------------------------------------------------------------------- @@ -499,23 +596,23 @@ void VM::initialize_sound(int rate, int samples) #endif // init sound gen - if(sound_device_type >= 1) { - opm1->init(rate, 4000000, samples, 0); + if(sound_type >= 1) { + opm1->initialize_sound(rate, 4000000, samples, 0); } - if(sound_device_type == 2) { - opm2->init(rate, 4000000, samples, 0); + if(sound_type == 2) { + opm2->initialize_sound(rate, 4000000, samples, 0); } - psg->init(rate, 2000000, samples, 0, 0); + psg->initialize_sound(rate, 2000000, samples, 0, 0); #ifdef _X1TWIN pce->initialize_sound(rate); #endif } -uint16* VM::create_sound(int* extra_frames) +uint16_t* VM::create_sound(int* extra_frames) { #ifdef _X1TWIN - if(pce->cart_inserted()) { - uint16* buffer = pceevent->create_sound(extra_frames); + if(pce->is_cart_inserted()) { + uint16_t* buffer = pceevent->create_sound(extra_frames); for(int i = 0; i < *extra_frames; i++) { event->drive(); } @@ -525,16 +622,47 @@ uint16* VM::create_sound(int* extra_frames) return event->create_sound(extra_frames); } -int VM::sound_buffer_ptr() +int VM::get_sound_buffer_ptr() { #ifdef _X1TWIN - if(pce->cart_inserted()) { - return pceevent->sound_buffer_ptr(); + if(pce->is_cart_inserted()) { + return pceevent->get_sound_buffer_ptr(); } #endif - return event->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); + } else if(ch == 1) { + if(sound_type >= 1) { + opm1->set_volume(0, decibel_l, decibel_r); + } + } else if(ch == 2) { + if(sound_type >= 2) { + opm2->set_volume(0, decibel_l, decibel_r); + } + } else if(ch == 3) { + drec->set_volume(0, decibel_l, decibel_r); + } else if(ch == 4) { + fdc->get_context_noise_seek()->set_volume(0, decibel_l, decibel_r); + fdc->get_context_noise_head_down()->set_volume(0, decibel_l, decibel_r); + fdc->get_context_noise_head_up()->set_volume(0, decibel_l, decibel_r); + } else if(ch == 5) { + 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(_X1TWIN) + } else if(ch == 6) { + pce->set_volume(0, decibel_l, decibel_r); +#endif + } +} +#endif + // ---------------------------------------------------------------------------- // notify key // ---------------------------------------------------------------------------- @@ -542,7 +670,7 @@ int VM::sound_buffer_ptr() void VM::key_down(int code, bool repeat) { #ifdef _X1TWIN - if(!repeat && !pce->cart_inserted()) { + if(!repeat && !pce->is_cart_inserted()) { #else if(!repeat) { #endif @@ -557,7 +685,7 @@ void VM::key_down(int code, bool repeat) void VM::key_up(int code) { #ifdef _X1TWIN - if(!pce->cart_inserted()) { + if(!pce->is_cart_inserted()) { #endif if(pseudo_sub_cpu) { psub->key_up(code); @@ -569,36 +697,141 @@ void VM::key_up(int code) #endif } +bool VM::get_caps_locked() +{ +#ifdef _X1TWIN + if(!pce->is_cart_inserted()) { +#endif + if(pseudo_sub_cpu) { + return psub->get_caps_locked(); + } else { + return kbd->get_caps_locked(); + } +#ifdef _X1TWIN + } + return false; +#endif +} + +bool VM::get_kana_locked() +{ +#ifdef _X1TWIN + if(!pce->is_cart_inserted()) { +#endif + if(pseudo_sub_cpu) { + return psub->get_kana_locked(); + } else { + return kbd->get_kana_locked(); + } +#ifdef _X1TWIN + } + return false; +#endif +} + // ---------------------------------------------------------------------------- // user interface // ---------------------------------------------------------------------------- -void VM::open_disk(int drv, const _TCHAR* file_path, int bank) +void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank) { fdc->open_disk(drv, file_path, bank); } -void VM::close_disk(int drv) +void VM::close_floppy_disk(int drv) { fdc->close_disk(drv); } -bool VM::disk_inserted(int drv) +bool VM::is_floppy_disk_inserted(int drv) +{ + return fdc->is_disk_inserted(drv); +} + +void VM::is_floppy_disk_protected(int drv, bool value) +{ + fdc->is_disk_protected(drv, value); +} + +bool VM::is_floppy_disk_protected(int drv) +{ + return fdc->is_disk_protected(drv); +} + +uint32_t VM::is_floppy_disk_accessed() +{ + return fdc->read_signal(0); +} + +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 + } +} + +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 + } +} + +bool VM::is_hard_disk_inserted(int drv) { - return fdc->disk_inserted(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 false; } -void VM::set_disk_protected(int drv, bool value) +uint32_t VM::is_hard_disk_accessed() { - fdc->set_disk_protected(drv, value); + uint32_t status = 0; + + for(int drv = 0; drv < USE_HARD_DISK; drv++) { + if(sasi_hdd[drv >> 1]->get_disk_handler(drv & 1)->accessed()) { + status |= 1 << drv; + } + } + return status; } -bool VM::get_disk_protected(int drv) +void VM::open_hard_disk_tmp(int drv, const _TCHAR* file_path) { - return fdc->get_disk_protected(drv); + if(drv < USE_HARD_DISK) { + sasi_hdd[drv >> 1]->get_disk_handler(drv & 1)->open(file_path); + } } - -void VM::play_tape(const _TCHAR* file_path) + +void VM::close_hard_disk_tmp(int drv) +{ + if(drv < USE_HARD_DISK) { + sasi_hdd[drv >> 1]->get_disk_handler(drv & 1)->close(); + } +} + +bool VM::is_hard_disk_inserted_tmp(int drv) +{ + if(drv < USE_HARD_DISK) { + return sasi_hdd[drv >> 1]->get_disk_handler(drv & 1)->mounted(); + } + return false; +} + +void VM::play_tape(int drv, const _TCHAR* file_path) { bool value = drec->play_tape(file_path); if(pseudo_sub_cpu) { @@ -610,7 +843,7 @@ void VM::play_tape(const _TCHAR* file_path) } } -void VM::rec_tape(const _TCHAR* file_path) +void VM::rec_tape(int drv, const _TCHAR* file_path) { bool value = drec->rec_tape(file_path); if(pseudo_sub_cpu) { @@ -622,9 +855,11 @@ void VM::rec_tape(const _TCHAR* file_path) } } -void VM::close_tape() +void VM::close_tape(int drv) { + emu->lock_vm(); drec->close_tape(); + emu->unlock_vm(); if(pseudo_sub_cpu) { psub->close_tape(); } else { @@ -632,67 +867,72 @@ void VM::close_tape() } } -bool VM::tape_inserted() +bool VM::is_tape_inserted(int drv) +{ + return drec->is_tape_inserted(); +} + +bool VM::is_tape_playing(int drv) { - return drec->tape_inserted(); + return drec->is_tape_playing(); } -bool VM::tape_playing() +bool VM::is_tape_recording(int drv) { - return drec->tape_playing(); + return drec->is_tape_recording(); } -bool VM::tape_recording() +int VM::get_tape_position(int drv) { - return drec->tape_recording(); + return drec->get_tape_position(); } -int VM::tape_position() +const _TCHAR* VM::get_tape_message(int drv) { - return drec->tape_position(); + return drec->get_message(); } -void VM::push_play() +void VM::push_play(int drv) { drec->set_ff_rew(0); drec->set_remote(true); } -void VM::push_stop() +void VM::push_stop(int drv) { drec->set_remote(false); } -void VM::push_fast_forward() +void VM::push_fast_forward(int drv) { drec->set_ff_rew(1); drec->set_remote(true); } -void VM::push_fast_rewind() +void VM::push_fast_rewind(int drv) { drec->set_ff_rew(-1); drec->set_remote(true); } -void VM::push_apss_forward() +void VM::push_apss_forward(int drv) { drec->do_apss(1); } -void VM::push_apss_rewind() +void VM::push_apss_rewind(int drv) { drec->do_apss(-1); } -bool VM::now_skip() +bool VM::is_frame_skippable() { #ifdef _X1TWIN - if(pce->cart_inserted()) { - return pceevent->now_skip(); + if(pce->is_cart_inserted()) { + return pceevent->is_frame_skippable(); } #endif - return event->now_skip(); + return event->is_frame_skippable(); } #ifdef _X1TWIN @@ -714,10 +954,10 @@ void VM::close_cart(int drv) } } -bool VM::cart_inserted(int drv) +bool VM::is_cart_inserted(int drv) { if(drv == 0) { - return pce->cart_inserted(); + return pce->is_cart_inserted(); } else { return false; } @@ -738,37 +978,61 @@ void VM::update_config() void VM::update_dipswitch() { // bit0 0=High 1=Standard - // bit2 0=5"2D 1=5"2HD - io->set_iovalue_single_r(0x1ff0, (config.monitor_type & 1) | ((config.drive_type & 1) << 2)); + // bit1-3 000=5"2D 001=5"2DD 010=5"2HD + io->set_iovalue_single_r(0x1ff0, (config.monitor_type & 1) | ((config.drive_type & 7) << 1)); } #endif -#define STATE_VERSION 4 +#define STATE_VERSION 10 +#include "../../statesub.h" +#include "../../qt/gui/csp_logger.h" +extern CSP_Logger DLL_PREFIX_I *csp_logger; +void VM::decl_state(void) +{ +#if defined(_X1) + state_entry = new csp_state_utils(STATE_VERSION, 0, _T("CSP::X1_HEAD"), csp_logger); +#elif defined(_X1TURBO) + state_entry = new csp_state_utils(STATE_VERSION, 0, _T("CSP::X1_TURBO_HEAD"), csp_logger); +#elif defined(_X1TURBOZ) + state_entry = new csp_state_utils(STATE_VERSION, 0, _T("CSP::X1_TURBO_Z_HEAD"), csp_logger); +#elif defined(_X1TWIN) + state_entry = new csp_state_utils(STATE_VERSION, 0, _T("CSP::X1_TWIN_HEAD"), csp_logger); +#else + state_entry = new csp_state_utils(STATE_VERSION, 0, _T("CSP::X1_SERIES_HEAD"), csp_logger); +#endif + + DECL_STATE_ENTRY_BOOL(pseudo_sub_cpu); + DECL_STATE_ENTRY_INT32(sound_type); + for(DEVICE* device = first_device; device; device = device->next_device) { + device->decl_state(); + } +} void VM::save_state(FILEIO* state_fio) { - 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->FputBool(pseudo_sub_cpu); - state_fio->FputInt32(sound_device_type); } bool VM::load_state(FILEIO* state_fio) { - if(state_fio->FgetUint32() != STATE_VERSION) { - return false; + bool mb = false; + if(state_entry != NULL) { + mb = state_entry->load_state(state_fio); } + if(!mb) return false; + + int n = 1; for(DEVICE* device = first_device; device; device = device->next_device) { if(!device->load_state(state_fio)) { + printf("STATE ERROR at device #%d\n", n); return false; } + n++; } - pseudo_sub_cpu = state_fio->FgetBool(); - sound_device_type = state_fio->FgetInt32(); - #ifdef _X1TURBO_FEATURE // post process update_dipswitch();