X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=source%2Fsrc%2Fvm%2Fpc9801%2Fpc9801.cpp;h=a35b5a4d79db0400079b0e33e7f634d9164f0804;hb=1bd2ef0d39e50c7d1c0b192540e24c5c934abc44;hp=ef60fe461d72b73394bd14281a5d0f59a3d68ce3;hpb=e4757c8ba1ac44a961dd3469e9b34b88e0197ac6;p=csp-qt%2Fcommon_source_project-fm7.git diff --git a/source/src/vm/pc9801/pc9801.cpp b/source/src/vm/pc9801/pc9801.cpp index ef60fe461..a35b5a4d7 100644 --- a/source/src/vm/pc9801/pc9801.cpp +++ b/source/src/vm/pc9801/pc9801.cpp @@ -1,6 +1,14 @@ /* NEC PC-9801 Emulator 'ePC-9801' NEC PC-9801E/F/M Emulator 'ePC-9801E' + NEC PC-9801U Emulator 'ePC-9801U' + NEC PC-9801VF Emulator 'ePC-9801VF' + NEC PC-9801VM Emulator 'ePC-9801VM' + NEC PC-9801VX Emulator 'ePC-9801VX' + NEC PC-9801RA Emulator 'ePC-9801RA' + NEC PC-98XA Emulator 'ePC-98XA' + NEC PC-98XL Emulator 'ePC-98XL' + NEC PC-98RL Emulator 'ePC-98RL' NEC PC-98DO Emulator 'ePC-98DO' Author : Takeda.Toshiya @@ -9,7 +17,7 @@ [ virtual machine ] */ -//#include "pc9801.h" +#include "pc9801.h" #include "../../emu.h" #include "../device.h" #include "../event.h" @@ -18,25 +26,36 @@ #include "../beep.h" #endif #include "../disk.h" +#if defined(USE_HARD_DISK) +#include "../harddisk.h" +#endif #include "../i8237.h" #include "../i8251.h" #include "../i8253.h" #include "../i8255.h" #include "../i8259.h" -#if defined(HAS_V30) -#include "../i86.h" +#if defined(HAS_I386) || defined(HAS_I486) +#include "../i386.h" +#elif defined(HAS_I86) || defined(HAS_V30) +#include "../i286.h" #else #include "../i286.h" #endif #include "../io.h" #include "../ls244.h" #include "../memory.h" -#if defined(HAS_I86) || defined(HAS_V30) +#include "../noise.h" #include "../not.h" -#endif #if !defined(SUPPORT_OLD_BUZZER) #include "../pcm1bit.h" #endif +//#include "../pcpr201.h" +#include "../prnfile.h" +#if defined(SUPPORT_SASI_IF) || defined(SUPPORT_SCSI_IF) +#include "../scsi_hdd.h" +#include "../scsi_host.h" +#endif +#include "../tms3631.h" #include "../upd1990a.h" #include "../upd7220.h" #include "../upd765a.h" @@ -46,13 +65,52 @@ #include "../debugger.h" #endif +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) +#include "cpureg.h" +#endif #include "display.h" +#include "dmareg.h" #include "floppy.h" #include "fmsound.h" #include "joystick.h" #include "keyboard.h" +#include "membus.h" #include "mouse.h" -#include "printer.h" +#if defined(SUPPORT_SASI_IF) +#include "sasi.h" +#include "sasi_bios.h" +#endif +#if defined(SUPPORT_SCSI_IF) +#include "scsi.h" +#endif +#if defined(SUPPORT_IDE_IF) +#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" @@ -62,20 +120,23 @@ #include "cmt.h" #endif -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) #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) +#if defined(_PC98DO) || defined(_PC98DOPLUS) boot_mode = config.boot_mode; #endif int cpu_clocks = CPU_CLOCKS; @@ -85,22 +146,28 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) pit_clock_8mhz = false; #endif #if defined(_PC9801E) - cpu_type = config.cpu_type; if(config.cpu_type != 0) { // 8MHz -> 5MHz cpu_clocks = 4992030; pit_clock_8mhz = false; } -#elif defined(_PC9801VM) || defined(_PC98DO) - cpu_type = config.cpu_type; +#elif defined(_PC9801VM) || defined(_PC98DO) || defined(_PC98DOPLUS) || defined(_PC9801VX) || defined(_PC98XL) if(config.cpu_type != 0) { - // 10MHz -> 8MHz + // 10MHz/16MHz -> 8MHz cpu_clocks = 7987248; pit_clock_8mhz = true; } +#elif defined(_PC9801RA) || defined(_PC98RL) + if(config.cpu_type != 0) { + // 20MHz -> 16MHz + cpu_clocks = 15974496; + pit_clock_8mhz = true; + } #endif int pit_clocks = pit_clock_8mhz ? 1996812 : 2457600; + sound_type = config.sound_type; + // create devices first_device = last_device = NULL; dummy = new DEVICE(this, emu); // must be 1st device @@ -114,79 +181,178 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) dma = new I8237(this, emu); #if defined(SUPPORT_CMT_IF) sio_cmt = new I8251(this, emu); // for cmt + sio_cmt->set_device_name(_T("8251 SIO (CMT)")); #endif sio_rs = new I8251(this, emu); // for rs232c + sio_rs->set_device_name(_T("8251 SIO (RS-232C)")); sio_kbd = new I8251(this, emu); // for keyboard + sio_kbd->set_device_name(_T("8251 SIO (Keyboard)")); pit = new I8253(this, emu); #if defined(SUPPORT_320KB_FDD_IF) pio_fdd = new I8255(this, emu); // for 320kb fdd i/f + pio_fdd->set_device_name(_T("8255 PIO (320KB I/F)")); #endif pio_mouse = new I8255(this, emu); // for mouse + pio_mouse->set_device_name(_T("8255 PIO (Mouse)")); pio_sys = new I8255(this, emu); // for system port + pio_sys->set_device_name(_T("8255 PIO (System)")); pio_prn = new I8255(this, emu); // for printer + pio_prn->set_device_name(_T("8255 PIO (Printer)")); pic = new I8259(this, emu); -#if defined(HAS_V30) - cpu = new I86(this, emu); +#if defined(HAS_I386) || defined(HAS_I486) + cpu = new I386(this, emu); // 80386, 80486 +#elif defined(HAS_I86) || defined(HAS_V30) + cpu = new I286(this, emu);// 8086, V30, 80286 #else cpu = new I286(this, emu); +#endif +#if defined(HAS_I86) + cpu->set_device_name(_T("CPU(i8086)")); +#elif defined(HAS_I386) + cpu->set_device_name(_T("CPU(i386)")); +#elif defined(HAS_I486) + cpu->set_device_name(_T("CPU(i486)")); +#elif defined(HAS_PENTIUM) + cpu->set_device_name(_T("CPU(Pentium)")); +#elif defined(HAS_V33A) + cpu->set_device_name(_T("CPU(V33A)")); +#elif defined(HAS_V30) + cpu->set_device_name(_T("CPU(V30)")); +#else + cpu->set_device_name(_T("CPU(i286)")); #endif io = new IO(this, emu); - dmareg1 = new LS244(this, emu); - dmareg2 = new LS244(this, emu); - dmareg3 = new LS244(this, emu); - dmareg0 = new LS244(this, emu); rtcreg = new LS244(this, emu); - memory = new MEMORY(this, emu); + rtcreg->set_device_name(_T("74LS244 (RTC)")); + //memory = new MEMORY(this, emu); + memory = new MEMBUS(this, emu); + not_busy = new NOT(this, emu); + not_busy->set_device_name(_T("NOT Gate (Printer Busy)")); #if defined(HAS_I86) || defined(HAS_V30) - g_not = new NOT(this, emu); + not_prn = new NOT(this, emu); + not_prn->set_device_name(_T("NOT Gate (Printer IRQ)")); #endif rtc = new UPD1990A(this, emu); #if defined(SUPPORT_2HD_FDD_IF) fdc_2hd = new UPD765A(this, emu); + fdc_2hd->set_device_name(_T("uPD765A FDC (2HD I/F)")); #endif #if defined(SUPPORT_2DD_FDD_IF) fdc_2dd = new UPD765A(this, emu); + fdc_2dd->set_device_name(_T("uPD765A FDC (2DD I/F)")); #endif #if defined(SUPPORT_2HD_2DD_FDD_IF) fdc = new UPD765A(this, emu); + fdc->set_device_name(_T("uPD765A FDC (2HD/2DD I/F)")); +#endif + noise_seek = new NOISE(this, emu); + noise_head_down = new NOISE(this, emu); + noise_head_up = new NOISE(this, emu); +#if defined(SUPPORT_SASI_IF) + sasi_host = new SCSI_HOST(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 + for(int i = 0; i < USE_HARD_DISK; i++) { + sasi_hdd->set_disk_handler(i, new HARDDISK(emu)); + } + sasi_hdd->set_context_interface(sasi_host); + sasi_host->set_context_target(sasi_hdd); +#endif +#if defined(SUPPORT_SCSI_IF) + scsi_host = new SCSI_HOST(this, emu); + for(int i = 0; i < USE_HARD_DISK; i++) { + scsi_hdd[i] = new SCSI_HDD(this, emu); + scsi_hdd[i]->set_device_name(_T("SCSI Hard Disk Drive #%d"), i + 1); + scsi_hdd[i]->scsi_id = i; + scsi_hdd[i]->set_disk_handler(0, new HARDDISK(emu)); + scsi_hdd[i]->set_context_interface(scsi_host); + scsi_host->set_context_target(scsi_hdd[i]); + } #endif gdc_chr = new UPD7220(this, emu); + gdc_chr->set_device_name(_T("uPD7220 GDC (Character)")); gdc_gfx = new UPD7220(this, emu); - opn = new YM2203(this, emu); + gdc_gfx->set_device_name(_T("uPD7220 GDC (Graphics)")); + + 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); + } else if(sound_type == 2 || sound_type == 3) { + tms3631 = new TMS3631(this, emu); + tms3631->set_device_name(_T("TMS3631 SSG (PC-9801-14)")); + pit_14 = new I8253(this, emu); + pit_14->set_device_name(_T("8253 PIT (PC-9801-14)")); + pio_14 = new I8255(this, emu); + pio_14->set_device_name(_T("8255 PIO (PC-9801-14)")); + maskreg_14 = new LS244(this, emu); + maskreg_14->set_device_name(_T("74LS244 (PC-9801-14)")); + } + if(config.printer_type == 0) { + printer = new PRNFILE(this, emu); +// } else if(config.printer_type == 1) { +// printer = new PCPR201(this, emu); + } else { + printer = dummy; + } #if defined(SUPPORT_CMT_IF) cmt = new CMT(this, emu); #endif +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) + cpureg = new CPUREG(this, emu); +#endif display = new DISPLAY(this, emu); + dmareg = new DMAREG(this, emu); floppy = new FLOPPY(this, emu); - fmsound = new FMSOUND(this, emu); - joystick = new JOYSTICK(this, emu); keyboard = new KEYBOARD(this, emu); mouse = new MOUSE(this, emu); - printer = new PRINTER(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); +#endif +#if defined(SUPPORT_IDE_IF) + ide = new IDE(this, emu); +#endif #if defined(SUPPORT_320KB_FDD_IF) // 320kb fdd drives pio_sub = new I8255(this, emu); + pio_sub->set_device_name(_T("8255 PIO (320KB FDD)")); pc80s31k = new PC80S31K(this, emu); + pc80s31k->set_device_name(_T("PC-80S31K (320KB FDD)")); fdc_sub = new UPD765A(this, emu); + fdc_sub->set_device_name(_T("uPD765A FDC (320KB FDD)")); cpu_sub = new Z80(this, emu); + cpu_sub->set_device_name(_T("Z80 CPU (320KB FDD)")); #endif /* IRQ 0 PIT 1 KEYBOARD 2 CRTV - 3 + 3 (INT0) 4 RS-232C - 5 - 6 + 5 (INT1) + 6 (INT2) 7 SLAVE PIC 8 PRINTER - 9 - 10 FDC (640KB I/F) - 11 FDC (1MB I/F) - 12 PC-9801-26(K) - 13 MOUSE + 9 (INT3) PC-9801-27 (SASI), PC-9801-55 (SCSI), or IDE + 10 (INT41) FDC (640KB I/F) + 11 (INT42) FDC (1MB I/F) + 12 (INT5) PC-9801-26(K) or PC-9801-14 + 13 (INT6) MOUSE 14 15 (RESERVED) */ @@ -197,25 +363,36 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) event->set_context_cpu(cpu_sub, 4000000); #endif event->set_context_sound(beep); - event->set_context_sound(opn); -#if defined(SUPPORT_CMT_IF) - event->set_context_sound(cmt); -#endif -#if defined(_PC98DO) - //event->set_context_sound(pc88); -#endif + if(sound_type == 0 || sound_type == 1) { + event->set_context_sound(opn); + } else if(sound_type == 2 || sound_type == 3) { + event->set_context_sound(tms3631); + } + event->set_context_sound(noise_seek); + event->set_context_sound(noise_head_down); + event->set_context_sound(noise_head_up); + dma->set_context_memory(memory); // dma ch.0: sasi // dma ch.1: memory refresh #if defined(SUPPORT_2HD_FDD_IF) dma->set_context_ch2(fdc_2hd); + dma->set_context_tc2(fdc_2hd, SIG_UPD765A_TC, 1); #endif #if defined(SUPPORT_2DD_FDD_IF) dma->set_context_ch3(fdc_2dd); + dma->set_context_tc3(fdc_2dd, SIG_UPD765A_TC, 1); #endif #if defined(SUPPORT_2HD_2DD_FDD_IF) +#if !defined(SUPPORT_HIRESO) dma->set_context_ch2(fdc); dma->set_context_ch3(fdc); + dma->set_context_tc2(fdc, SIG_UPD765A_TC, 1); + dma->set_context_tc3(fdc, SIG_UPD765A_TC, 1); +#else + dma->set_context_ch1(fdc); + dma->set_context_tc1(fdc, SIG_UPD765A_TC, 1); +#endif #endif // sio_rs->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR4, 1); sio_kbd->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR1, 1); @@ -231,64 +408,133 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) pit->set_constant_clock(1, pit_clocks); pit->set_constant_clock(2, pit_clocks); pio_mouse->set_context_port_c(mouse, SIG_MOUSE_PORT_C, 0xf0, 0); +#if defined(SUPPORT_HIRESO) + // sysport port.c bit7,5: sysport port.b bit4,3 + pio_sys->set_context_port_c(pio_sys, SIG_I8255_PORT_B, 0x80, -3); // SHUT0 + pio_sys->set_context_port_c(pio_sys, SIG_I8255_PORT_B, 0x20, -2); // SHUT1 +#endif // sysport port.c bit6: printer strobe #if defined(SUPPORT_OLD_BUZZER) - pio_sys->set_context_port_c(beep, SIG_BEEP_MUTE, 8, 0); + pio_sys->set_context_port_c(beep, SIG_BEEP_MUTE, 0x08, 0); #else - pio_sys->set_context_port_c(beep, SIG_PCM1BIT_MUTE, 8, 0); + pio_sys->set_context_port_c(beep, SIG_PCM1BIT_MUTE, 0x08, 0); #endif // sysport port.c bit2: enable txrdy interrupt // sysport port.c bit1: enable txempty interrupt // sysport port.c bit0: enable rxrdy interrupt - pio_prn->set_context_port_a(printer, SIG_PRINTER_OUT, 0xff, 0); - pio_prn->set_context_port_c(printer, SIG_PRINTER_STB, 0x80, 0); + pio_prn->set_context_port_a(printer, SIG_PRINTER_DATA, 0xff, 0); + pio_prn->set_context_port_c(printer, SIG_PRINTER_STROBE, 0x80, 0); + if(config.printer_type == 0) { + PRNFILE *prnfile = (PRNFILE *)printer; + prnfile->set_context_busy(not_busy, SIG_NOT_INPUT, 1); +// } else if(config.printer_type == 1) { +// PRNFILE *pcpr201 = (PCPR201 *)printer; +// pcpr201->set_context_busy(not_busy, SIG_NOT_INPUT, 1); + } + not_busy->set_context_out(pio_prn, SIG_I8255_PORT_B, 4); #if defined(HAS_I86) || defined(HAS_V30) - pio_prn->set_context_port_c(g_not, SIG_NOT_INPUT, 8, 0); - g_not->set_context_out(pic, SIG_I8259_CHIP1 | SIG_I8259_IR0, 1); + pio_prn->set_context_port_c(not_prn, SIG_NOT_INPUT, 8, 0); + not_prn->set_context_out(pic, SIG_I8259_CHIP1 | SIG_I8259_IR0, 1); #endif - dmareg1->set_context_output(dma, SIG_I8237_BANK1, 0x0f, 0); - dmareg2->set_context_output(dma, SIG_I8237_BANK2, 0x0f, 0); - dmareg3->set_context_output(dma, SIG_I8237_BANK3, 0x0f, 0); - dmareg0->set_context_output(dma, SIG_I8237_BANK0, 0x0f, 0); rtcreg->set_context_output(rtc, SIG_UPD1990A_CMD, 0x07, 0); rtcreg->set_context_output(rtc, SIG_UPD1990A_DIN, 0x20, 0); rtcreg->set_context_output(rtc, SIG_UPD1990A_STB, 0x08, 0); rtcreg->set_context_output(rtc, SIG_UPD1990A_CLK, 0x10, 0); pic->set_context_cpu(cpu); rtc->set_context_dout(pio_sys, SIG_I8255_PORT_B, 1); - opn->set_context_irq(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1); - opn->set_context_port_b(joystick, SIG_JOYSTICK_SELECT, 0xc0, 0); + if(sound_type == 0 || sound_type == 1) { + opn->set_context_irq(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1); + opn->set_context_port_b(joystick, SIG_JOYSTICK_SELECT, 0xc0, 0); + fmsound->set_context_opn(opn); + joystick->set_context_opn(opn); + } else if(sound_type == 2 || sound_type == 3) { + pio_14->set_context_port_a(tms3631, SIG_TMS3631_ENVELOP1, 0xff, 0); + pio_14->set_context_port_b(tms3631, SIG_TMS3631_ENVELOP2, 0xff, 0); + pio_14->set_context_port_c(tms3631, SIG_TMS3631_DATAREG, 0xff, 0); + maskreg_14->set_context_output(tms3631, SIG_TMS3631_MASKREG, 0xff, 0); + pit_14->set_constant_clock(2, 1996800 / 8); + pit_14->set_context_ch2(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1); + } + +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) + cpureg->set_context_cpu(cpu); +#endif display->set_context_pic(pic); display->set_context_gdc_chr(gdc_chr, gdc_chr->get_ra()); display->set_context_gdc_gfx(gdc_gfx, gdc_gfx->get_ra(), gdc_gfx->get_cs()); - fmsound->set_context_opn(opn); - joystick->set_context_opn(opn); + dmareg->set_context_dma(dma); keyboard->set_context_sio(sio_kbd); + memory->set_context_display(display); mouse->set_context_pic(pic); mouse->set_context_pio(pio_mouse); #if defined(SUPPORT_2HD_FDD_IF) fdc_2hd->set_context_irq(floppy, SIG_FLOPPY_2HD_IRQ, 1); fdc_2hd->set_context_drq(floppy, SIG_FLOPPY_2HD_DRQ, 1); + fdc_2hd->set_context_noise_seek(noise_seek); + fdc_2hd->set_context_noise_head_down(noise_head_down); + fdc_2hd->set_context_noise_head_up(noise_head_up); fdc_2hd->raise_irq_when_media_changed = true; floppy->set_context_fdc_2hd(fdc_2hd); #endif #if defined(SUPPORT_2DD_FDD_IF) fdc_2dd->set_context_irq(floppy, SIG_FLOPPY_2DD_IRQ, 1); fdc_2dd->set_context_drq(floppy, SIG_FLOPPY_2DD_DRQ, 1); + fdc_2dd->set_context_noise_seek(noise_seek); + fdc_2dd->set_context_noise_head_down(noise_head_down); + fdc_2dd->set_context_noise_head_up(noise_head_up); fdc_2dd->raise_irq_when_media_changed = true; floppy->set_context_fdc_2dd(fdc_2dd); #endif #if defined(SUPPORT_2HD_2DD_FDD_IF) fdc->set_context_irq(floppy, SIG_FLOPPY_IRQ, 1); fdc->set_context_drq(floppy, SIG_FLOPPY_DRQ, 1); + fdc->set_context_noise_seek(noise_seek); + fdc->set_context_noise_head_down(noise_head_down); + fdc->set_context_noise_head_up(noise_head_up); fdc->raise_irq_when_media_changed = true; floppy->set_context_fdc(fdc); #endif floppy->set_context_dma(dma); floppy->set_context_pic(pic); +#if defined(SUPPORT_SASI_IF) +#if !defined(SUPPORT_HIRESO) + sasi_host->set_context_irq(pio_sys, SIG_I8255_PORT_B, 0x10); +#endif + sasi_host->set_context_irq(sasi, SIG_SASI_IRQ, 1); + sasi_host->set_context_drq(sasi, SIG_SASI_DRQ, 1); +#ifdef _PC98XA + dma->set_context_ch3(sasi_host); + dma->set_context_tc3(sasi, SIG_SASI_TC, 1); +#else + dma->set_context_ch0(sasi_host); + dma->set_context_tc0(sasi, SIG_SASI_TC, 1); +#endif + sasi->set_context_host(sasi_host); + 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); + scsi->set_context_dma(dma); + scsi->set_context_pic(pic); +#endif +#if defined(SUPPORT_IDE_IF) + dma->set_context_ch0(ide); + ide->set_context_dma(dma); + ide->set_context_pic(pic); +#endif + #if defined(SUPPORT_CMT_IF) sio_cmt->set_context_out(cmt, SIG_CMT_OUT); // sio_cmt->set_context_txrdy(cmt, SIG_CMT_TXRDY, 1); @@ -324,6 +570,9 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0xf0, -4); pio_sub->clear_ports_by_cmdreg = true; fdc_sub->set_context_irq(cpu_sub, SIG_CPU_IRQ, 1); + fdc_sub->set_context_noise_seek(noise_seek); + fdc_sub->set_context_noise_head_down(noise_head_down); + fdc_sub->set_context_noise_head_up(noise_head_up); cpu_sub->set_context_mem(pc80s31k); cpu_sub->set_context_io(pc80s31k); cpu_sub->set_context_intr(pc80s31k); @@ -332,97 +581,74 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) #endif #endif - // memory bus - memset(ram, 0, sizeof(ram)); - memset(ipl, 0xff, sizeof(ipl)); - memset(sound_bios, 0xff, sizeof(sound_bios)); -#if defined(_PC9801) || defined(_PC9801E) - memset(fd_bios_2hd, 0xff, sizeof(fd_bios_2hd)); - memset(fd_bios_2dd, 0xff, sizeof(fd_bios_2dd)); -#endif + // i/o bus + io->set_iomap_alias_rw(0x0000, pic, 0); + io->set_iomap_alias_rw(0x0002, pic, 1); + io->set_iomap_alias_rw(0x0008, pic, 2); + io->set_iomap_alias_rw(0x000a, pic, 3); - memory->read_bios(_T("IPL.ROM"), ipl, sizeof(ipl)); - int sound_bios_ok = memory->read_bios(_T("SOUND.ROM"), sound_bios, sizeof(sound_bios)); -#if defined(_PC9801) || defined(_PC9801E) - memory->read_bios(_T("2HDIF.ROM"), fd_bios_2hd, sizeof(fd_bios_2hd)); - memory->read_bios(_T("2DDIF.ROM"), fd_bios_2dd, sizeof(fd_bios_2dd)); + io->set_iomap_alias_rw(0x0001, dma, 0x00); + io->set_iomap_alias_rw(0x0003, dma, 0x01); + io->set_iomap_alias_rw(0x0005, dma, 0x02); + io->set_iomap_alias_rw(0x0007, dma, 0x03); + io->set_iomap_alias_rw(0x0009, dma, 0x04); + io->set_iomap_alias_rw(0x000b, dma, 0x05); + io->set_iomap_alias_rw(0x000d, dma, 0x06); + io->set_iomap_alias_rw(0x000f, dma, 0x07); + io->set_iomap_alias_rw(0x0011, dma, 0x08); + io->set_iomap_alias_w (0x0013, dma, 0x09); + io->set_iomap_alias_w (0x0015, dma, 0x0a); + io->set_iomap_alias_w (0x0017, dma, 0x0b); + io->set_iomap_alias_w (0x0019, dma, 0x0c); + io->set_iomap_alias_rw(0x001b, dma, 0x0d); + io->set_iomap_alias_w (0x001d, dma, 0x0e); + io->set_iomap_alias_w (0x001f, dma, 0x0f); + io->set_iomap_single_w(0x0021, dmareg); + io->set_iomap_single_w(0x0023, dmareg); + io->set_iomap_single_w(0x0025, dmareg); + io->set_iomap_single_w(0x0027, dmareg); +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) + io->set_iomap_single_w(0x0029, dmareg); +#endif +#if defined(SUPPORT_32BIT_ADDRESS) + io->set_iomap_single_w(0x0e05, dmareg); + io->set_iomap_single_w(0x0e07, dmareg); + io->set_iomap_single_w(0x0e09, dmareg); + io->set_iomap_single_w(0x0e0b, dmareg); #endif - memory->set_memory_rw(0x00000, 0x9ffff, ram); - // A0000h - A1FFFh: TEXT VRAM - // A2000h - A3FFFh: ATTRIBUTE - memory->set_memory_mapped_io_rw(0xa0000, 0xa3fff, display); - // A8000h - BFFFFh: VRAM - memory->set_memory_mapped_io_rw(0xa8000, 0xbffff, display); - memory->set_memory_r(0xcc000, 0xcffff, sound_bios); -#if defined(_PC9801) || defined(_PC9801E) - memory->set_memory_r(0xd6000, 0xd6fff, fd_bios_2dd); - memory->set_memory_r(0xd7000, 0xd7fff, fd_bios_2hd); -#endif -#if defined(SUPPORT_16_COLORS) - // E0000h - E7FFFh: VRAM - memory->set_memory_mapped_io_rw(0xe0000, 0xe7fff, display); -#endif - memory->set_memory_r(0xe8000, 0xfffff, ipl); + io->set_iomap_single_w(0x0020, rtcreg); - display->sound_bios_ok = (sound_bios_ok != 0); // memory switch + io->set_iomap_alias_rw(0x0030, sio_rs, 0); + io->set_iomap_alias_rw(0x0032, sio_rs, 1); - // i/o bus - io->set_iomap_alias_rw(0x00, pic, 0); - io->set_iomap_alias_rw(0x02, pic, 1); - io->set_iomap_alias_rw(0x08, pic, 2); - io->set_iomap_alias_rw(0x0a, pic, 3); - - io->set_iomap_alias_rw(0x01, dma, 0x00); - io->set_iomap_alias_rw(0x03, dma, 0x01); - io->set_iomap_alias_rw(0x05, dma, 0x02); - io->set_iomap_alias_rw(0x07, dma, 0x03); - io->set_iomap_alias_rw(0x09, dma, 0x04); - io->set_iomap_alias_rw(0x0b, dma, 0x05); - io->set_iomap_alias_rw(0x0d, dma, 0x06); - io->set_iomap_alias_rw(0x0f, dma, 0x07); - io->set_iomap_alias_rw(0x11, dma, 0x08); - io->set_iomap_alias_w(0x13, dma, 0x09); - io->set_iomap_alias_w(0x15, dma, 0x0a); - io->set_iomap_alias_w(0x17, dma, 0x0b); - io->set_iomap_alias_w(0x19, dma, 0x0c); - io->set_iomap_alias_rw(0x1b, dma, 0x0d); - io->set_iomap_alias_w(0x1d, dma, 0x0e); - io->set_iomap_alias_w(0x1f, dma, 0x0f); - io->set_iomap_single_w(0x21, dmareg1); - io->set_iomap_single_w(0x23, dmareg2); - io->set_iomap_single_w(0x25, dmareg3); - io->set_iomap_single_w(0x27, dmareg0); - - io->set_iomap_single_w(0x20, rtcreg); - - io->set_iomap_alias_rw(0x30, sio_rs, 0); - io->set_iomap_alias_rw(0x32, sio_rs, 1); - - io->set_iomap_alias_rw(0x31, pio_sys, 0); - io->set_iomap_alias_rw(0x33, pio_sys, 1); - io->set_iomap_alias_rw(0x35, pio_sys, 2); - io->set_iomap_alias_w(0x37, pio_sys, 3); - - io->set_iomap_alias_rw(0x40, pio_prn, 0); - io->set_iomap_alias_rw(0x42, pio_prn, 1); - io->set_iomap_alias_rw(0x44, pio_prn, 2); - io->set_iomap_alias_w(0x46, pio_prn, 3); - - io->set_iomap_alias_rw(0x41, sio_kbd, 0); - io->set_iomap_alias_rw(0x43, sio_kbd, 1); - - // 50h, 52h: NMI Flip Flop + io->set_iomap_alias_rw(0x0031, pio_sys, 0); + io->set_iomap_alias_rw(0x0033, pio_sys, 1); + io->set_iomap_alias_rw(0x0035, pio_sys, 2); + io->set_iomap_alias_w (0x0037, pio_sys, 3); + + io->set_iomap_alias_rw(0x0040, pio_prn, 0); + io->set_iomap_alias_rw(0x0042, pio_prn, 1); + io->set_iomap_alias_rw(0x0044, pio_prn, 2); + io->set_iomap_alias_w (0x0046, pio_prn, 3); + + io->set_iomap_alias_rw(0x0041, sio_kbd, 0); + io->set_iomap_alias_rw(0x0043, sio_kbd, 1); + +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) + io->set_iomap_single_w(0x0050, cpureg); + io->set_iomap_single_w(0x0052, cpureg); +#endif #if defined(SUPPORT_320KB_FDD_IF) - io->set_iomap_alias_rw(0x51, pio_fdd, 0); - io->set_iomap_alias_rw(0x53, pio_fdd, 1); - io->set_iomap_alias_rw(0x55, pio_fdd, 2); - io->set_iomap_alias_w(0x57, pio_fdd, 3); + io->set_iomap_alias_rw(0x0051, pio_fdd, 0); + io->set_iomap_alias_rw(0x0053, pio_fdd, 1); + io->set_iomap_alias_rw(0x0055, pio_fdd, 2); + io->set_iomap_alias_w (0x0057, pio_fdd, 3); #endif - io->set_iomap_alias_rw(0x60, gdc_chr, 0); - io->set_iomap_alias_rw(0x62, gdc_chr, 1); + io->set_iomap_alias_rw(0x0060, gdc_chr, 0); + io->set_iomap_alias_rw(0x0062, gdc_chr, 1); io->set_iomap_single_w(0x64, display); io->set_iomap_single_w(0x68, display); @@ -438,114 +664,248 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) io->set_iomap_single_w(0x76, display); io->set_iomap_single_w(0x78, display); io->set_iomap_single_w(0x7a, display); -#if defined(SUPPORT_16_COLORS) - io->set_iomap_single_w(0x7c, display); - io->set_iomap_single_w(0x7e, display); +#if defined(SUPPORT_GRCG) +#if !defined(SUPPORT_HIRESO) + io->set_iomap_single_w(0x007c, display); + io->set_iomap_single_w(0x007e, display); +#else + io->set_iomap_single_w(0x00a4, display); + io->set_iomap_single_w(0x00a6, display); +#endif #endif - io->set_iomap_alias_rw(0x71, pit, 0); - io->set_iomap_alias_rw(0x73, pit, 1); - io->set_iomap_alias_rw(0x75, pit, 2); - io->set_iomap_alias_w(0x77, pit, 3); - - // 80h, 82h: SASI - - io->set_iomap_single_rw(0x90, floppy); - io->set_iomap_single_rw(0x92, floppy); - io->set_iomap_single_rw(0x94, floppy); - -#if defined(SUPPORT_CMT_IF) - io->set_iomap_alias_rw(0x91, sio_cmt, 0); - io->set_iomap_alias_rw(0x93, sio_cmt, 1); - io->set_iomap_single_w(0x95, cmt); - io->set_iomap_single_w(0x97, cmt); +#if defined(SUPPORT_SASI_IF) + io->set_iomap_single_rw(0x0080, sasi); + io->set_iomap_single_rw(0x0082, sasi); +#endif +#if defined(SUPPORT_SCSI_IF) + io->set_iomap_single_rw(0x0cc0, scsi); + io->set_iomap_single_rw(0x0cc2, scsi); + io->set_iomap_single_rw(0x0cc4, scsi); +#endif +#if defined(SUPPORT_IDE_IF) + io->set_iomap_single_rw(0x0640, ide); + io->set_iomap_single_rw(0x0642, ide); + io->set_iomap_single_rw(0x0644, ide); + io->set_iomap_single_rw(0x0646, ide); + io->set_iomap_single_rw(0x0648, ide); + io->set_iomap_single_rw(0x064a, ide); + io->set_iomap_single_rw(0x064c, ide); + io->set_iomap_single_rw(0x064e, ide); + io->set_iomap_single_rw(0x074c, ide); + io->set_iomap_single_rw(0x074e, ide); #endif - io->set_iomap_alias_rw(0xa0, gdc_gfx, 0); - io->set_iomap_alias_rw(0xa2, gdc_gfx, 1); + io->set_iomap_alias_rw(0x00a0, gdc_gfx, 0); + io->set_iomap_alias_rw(0x00a2, gdc_gfx, 1); -#if defined(SUPPORT_2ND_VRAM) - io->set_iomap_single_w(0xa4, display); - io->set_iomap_single_w(0xa6, display); +#if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO) + io->set_iomap_single_rw(0x00a4, display); + io->set_iomap_single_rw(0x00a6, display); #endif io->set_iomap_single_rw(0xa8, display); io->set_iomap_single_rw(0xaa, display); io->set_iomap_single_rw(0xac, display); io->set_iomap_single_rw(0xae, display); - io->set_iomap_single_w(0xa1, display); - io->set_iomap_single_w(0xa3, display); - io->set_iomap_single_w(0xa5, display); +// io->set_iomap_single_w(0xa1, display); +// io->set_iomap_single_w(0xa3, display); +// io->set_iomap_single_w(0xa5, display); + io->set_iomap_single_rw(0xa1, display); + io->set_iomap_single_rw(0xa3, display); + io->set_iomap_single_rw(0xa5, display); io->set_iomap_single_rw(0xa9, display); +#if defined(SUPPORT_EGC) + io->set_iomap_range_rw(0x04a0, 0x04af, display); +#endif + + io->set_iomap_alias_rw(0x0071, pit, 0); + io->set_iomap_alias_rw(0x0073, pit, 1); + io->set_iomap_alias_rw(0x0075, pit, 2); + io->set_iomap_alias_w (0x0077, pit, 3); + io->set_iomap_single_rw(0x0090, floppy); + io->set_iomap_single_rw(0x0092, floppy); + io->set_iomap_single_rw(0x0094, floppy); + io->set_iomap_single_rw(0x0096, floppy); #if defined(SUPPORT_2HD_2DD_FDD_IF) - io->set_iomap_single_rw(0xbe, floppy); +#if !defined(SUPPORT_HIRESO) + io->set_iomap_single_rw(0x00be, floppy); +#else +//#if !defined(_PC98XA) && !defined(_PC98XL) + io->set_iomap_single_w (0x00be, floppy); +//#endif +#endif +#endif +#if !defined(SUPPORT_HIRESO) + io->set_iomap_single_rw(0x00c8, floppy); + io->set_iomap_single_rw(0x00ca, floppy); + io->set_iomap_single_rw(0x00cc, floppy); + io->set_iomap_single_rw(0x00ce, floppy); #endif - io->set_iomap_single_rw(0xc8, floppy); - io->set_iomap_single_rw(0xca, floppy); - io->set_iomap_single_rw(0xcc, floppy); - io->set_iomap_single_rw(0x188, fmsound); - io->set_iomap_single_rw(0x18a, fmsound); -#ifdef HAS_YM2608 - io->set_iomap_single_rw(0x18c, fmsound); - io->set_iomap_single_rw(0x18e, fmsound); - io->set_iomap_single_rw(0xa460, fmsound); +#if defined(SUPPORT_CMT_IF) + io->set_iomap_alias_rw(0x0091, sio_cmt, 0); + io->set_iomap_alias_rw(0x0093, sio_cmt, 1); + io->set_iomap_single_w(0x0095, cmt); + io->set_iomap_single_w(0x0097, cmt); #endif -#if !defined(SUPPORT_OLD_BUZZER) +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) + io->set_iomap_single_rw(0x00f0, cpureg); + io->set_iomap_single_rw(0x00f2, cpureg); +#endif +#if defined(SUPPORT_32BIT_ADDRESS) + io->set_iomap_single_rw(0x00f6, cpureg); +#endif + + if(sound_type == 0 || sound_type == 1) { + io->set_iomap_single_rw(0x0188, fmsound); + io->set_iomap_single_rw(0x018a, fmsound); +#ifdef SUPPORT_PC98_OPNA + io->set_iomap_single_rw(0x018c, fmsound); + io->set_iomap_single_rw(0x018e, fmsound); + io->set_iomap_single_rw(0xa460, fmsound); +#endif + } else if(sound_type == 2 || sound_type == 3) { + io->set_iomap_alias_rw(0x0088, pio_14, 0); + io->set_iomap_alias_rw(0x008a, pio_14, 1); + io->set_iomap_alias_rw(0x008c, pio_14, 2); + io->set_iomap_alias_w(0x008e, pio_14, 3); + io->set_iovalue_single_r(0x008e, 0x08); + io->set_iomap_single_w(0x0188, maskreg_14); + io->set_iomap_single_w(0x018a, maskreg_14); + io->set_iomap_alias_rw(0x018c, pit_14, 2); + io->set_iomap_alias_w(0x018e, pit_14, 3); +// io->set_iovalue_single_r(0x018e, 0x00); // INT0 +// io->set_iovalue_single_r(0x018e, 0x40); // INT41 + io->set_iovalue_single_r(0x018e, 0x80); // INT5 +// io->set_iovalue_single_r(0x018e, 0xc0); // INT6 + } + +//#if !defined(SUPPORT_HIRESO) +// io->set_iovalue_single_r(0x0431, 0x04); // bit2: 1 = Normal mode, 0 = Hireso mode +//#else +// io->set_iovalue_single_r(0x0431, 0x00); +//#endif +#if defined(SUPPORT_ITF_ROM) + io->set_iomap_single_w(0x043d, memory); +#endif +#if !defined(SUPPORT_HIRESO) + io->set_iomap_single_w(0x043f, memory); +#endif +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) +#if !defined(_PC98XA) + io->set_iomap_single_rw(0x0439, memory); +#endif +#if !defined(SUPPORT_HIRESO) + io->set_iomap_single_rw(0x0461, memory); + io->set_iomap_single_rw(0x0463, memory); +#else + io->set_iomap_single_rw(0x0091, memory); + io->set_iomap_single_rw(0x0093, memory); +#endif + io->set_iomap_single_r(0x0567, memory); +#endif +#if defined(SUPPORT_32BIT_ADDRESS) + io->set_iomap_single_w(0x053d, memory); +#endif + +#if !(defined(_PC9801) || defined(_PC9801E) || defined(SUPPORT_HIRESO)) io->set_iomap_alias_rw(0x3fd9, pit, 0); io->set_iomap_alias_rw(0x3fdb, pit, 1); io->set_iomap_alias_rw(0x3fdd, pit, 2); - io->set_iomap_alias_w(0x3fdf, pit, 3); + io->set_iomap_alias_w (0x3fdf, pit, 3); #endif +#if !defined(SUPPORT_HIRESO) io->set_iomap_alias_rw(0x7fd9, pio_mouse, 0); io->set_iomap_alias_rw(0x7fdb, pio_mouse, 1); io->set_iomap_alias_rw(0x7fdd, pio_mouse, 2); - io->set_iomap_alias_w(0x7fdf, pio_mouse, 3); -#if !(defined(_PC9801) || defined(_PC9801E)) - io->set_iomap_single_w(0xbfdb, mouse); + io->set_iomap_alias_w (0x7fdf, pio_mouse, 3); + io->set_iomap_single_rw(0xbfdb, mouse); +#else + io->set_iomap_alias_rw(0x0061, pio_mouse, 0); + io->set_iomap_alias_rw(0x0063, pio_mouse, 1); + io->set_iomap_alias_rw(0x0065, pio_mouse, 2); + io->set_iomap_alias_rw(0x0067, pio_mouse, 3); #endif -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) pc88event = new EVENT(this, emu); + pc88event->set_device_name(_T("Event Manager (PC-8801)")); pc88event->set_frames_per_sec(60); pc88event->set_lines_per_frame(260); pc88 = new PC88(this, emu); pc88->set_context_event_manager(pc88event); pc88sio = new I8251(this, emu); + pc88sio->set_device_name(_T("8251 SIO (PC-8801)")); pc88sio->set_context_event_manager(pc88event); pc88pio = new I8255(this, emu); + pc88pio->set_device_name(_T("8255 PIO (PC-8801)")); pc88pio->set_context_event_manager(pc88event); pc88pcm = new PCM1BIT(this, emu); + pc88pcm->set_device_name(_T("1-Bit PCM Sound (PC-8801)")); pc88pcm->set_context_event_manager(pc88event); 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); - pc88opn->set_context_event_manager(pc88event); + pc88opn1 = new YM2203(this, emu); +#ifdef SUPPORT_PC88_OPNA + pc88opn1->set_device_name(_T("YM2608 OPNA (PC-8801)")); + pc88opn1->is_ym2608 = true; +#else + pc88opn1->set_device_name(_T("YM2203 OPN (PC-8801)")); + pc88opn1->is_ym2608 = false; +#endif + 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); + if(config.printer_type == 0) { + pc88prn = new PRNFILE(this, emu); + pc88prn->set_context_event_manager(pc88event); +// } else if(config.printer_type == 1) { +// pc88prn = new PCPR201(this, emu); +// pc88prn->set_context_event_manager(pc88event); + } else { + pc88prn = dummy; + } + pc88sub = new PC80S31K(this, emu); + pc88sub->set_device_name(_T("PC-80S31K (PC-8801 Sub)")); pc88sub->set_context_event_manager(pc88event); pc88pio_sub = new I8255(this, emu); + pc88pio_sub->set_device_name(_T("8255 PIO (PC-8801 Sub)")); pc88pio_sub->set_context_event_manager(pc88event); pc88fdc_sub = new UPD765A(this, emu); + pc88fdc_sub->set_device_name(_T("uPD765A FDC (PC-8801 Sub)")); pc88fdc_sub->set_context_event_manager(pc88event); + pc88noise_seek = new NOISE(this, emu); + pc88noise_seek->set_context_event_manager(pc88event); + pc88noise_head_down = new NOISE(this, emu); + pc88noise_head_down->set_context_event_manager(pc88event); + pc88noise_head_up = new NOISE(this, emu); + pc88noise_head_up->set_context_event_manager(pc88event); pc88cpu_sub = new Z80(this, emu); + pc88cpu_sub->set_device_name(_T("Z80 CPU (PC-8801 Sub)")); pc88cpu_sub->set_context_event_manager(pc88event); - pc88event->set_context_cpu(pc88cpu, (config.cpu_type != 0) ? 3993624 : 7987248); + 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); pc88->set_context_rtc(pc88rtc); pc88->set_context_sio(pc88sio); pc88cpu->set_context_mem(pc88); @@ -554,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); @@ -572,6 +932,9 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0xf0, -4); pc88pio_sub->clear_ports_by_cmdreg = true; pc88fdc_sub->set_context_irq(pc88cpu_sub, SIG_CPU_IRQ, 1); + pc88fdc_sub->set_context_noise_seek(pc88noise_seek); + pc88fdc_sub->set_context_noise_head_down(pc88noise_head_down); + pc88fdc_sub->set_context_noise_head_up(pc88noise_head_up); pc88cpu_sub->set_context_mem(pc88sub); pc88cpu_sub->set_context_io(pc88sub); pc88cpu_sub->set_context_intr(pc88sub); @@ -579,11 +942,15 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) pc88cpu_sub->set_context_debugger(new DEBUGGER(this, emu)); #endif #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(); } + #if defined(_PC9801) || defined(_PC9801E) fdc_2hd->get_disk_handler(0)->drive_num = 0; fdc_2hd->get_disk_handler(1)->drive_num = 1; @@ -594,7 +961,7 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) #elif defined(_PC9801VF) || defined(_PC9801U) fdc_2dd->get_disk_handler(0)->drive_num = 0; fdc_2dd->get_disk_handler(1)->drive_num = 1; -#elif defined(_PC98DO) +#elif defined(_PC98DO) || defined(_PC98DOPLUS) fdc->get_disk_handler(0)->drive_num = 0; fdc->get_disk_handler(1)->drive_num = 1; pc88fdc_sub->get_disk_handler(0)->drive_num = 2; @@ -603,6 +970,21 @@ VM::VM(EMU* parent_emu) : emu(parent_emu) fdc->get_disk_handler(0)->drive_num = 0; fdc->get_disk_handler(1)->drive_num = 1; #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) + create_local_path(config.last_hard_disk_path[drv], _MAX_PATH, _T("SASI%d.DAT"), drv); +#endif +#if defined(SUPPORT_SCSI_IF) + create_local_path(config.last_hard_disk_path[drv], _MAX_PATH, _T("SCSI%d.DAT"), drv); +#endif +#if defined(SUPPORT_IDE_IF) + create_local_path(config.last_hard_disk_path[drv], _MAX_PATH, _T("IDE%d.DAT"), drv); +#endif + } + } +#endif } VM::~VM() @@ -636,46 +1018,110 @@ void VM::reset() for(DEVICE* device = first_device; device; device = device->next_device) { device->reset(); } -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) for(DEVICE* device = first_device; device; device = device->next_device) { device->reset(); } #endif // initial device settings - pio_mouse->write_signal(SIG_I8255_PORT_A, 0xf0, 0xff); // clear mouse status - pio_mouse->write_signal(SIG_I8255_PORT_B, 0x40, 0xff); // cpu high & sw3-6 - uint8 port_c = 0x08; // normal mode & sw1-5 & sw1-6 + uint8_t port_a, port_b, port_c; + + port_a = 0xf0; // Clear mouse buttons and counters + port_b = 0x00; +#if defined(_PC98XA) + port_b |= (uint8_t)((RAM_SIZE - 0x100000) / 0x40000); +#else +#if defined(SUPPORT_HIRESO) + port_b |= 0x80; // DIP SW 1-4, 1 = External FDD #3/#4, 0 = #1/#2 +#endif + port_b |= 0x40; // DIP SW 3-6, 1 = Enable internal RAM 80000h-9FFFFh +#if defined(_PC98RL) + port_b |= 0x10; // DIP SW 3-3, 1 = DMA ch.0 for SASI-HDD +#endif +#if defined(USE_CPU_TYPE) + if(config.cpu_type != 0) { +#if !defined(SUPPORT_HIRESO) + port_b |= 0x02; // SPDSW, 1 = 10MHz, 0 = 12MHz +#else + port_b |= 0x01; // SPDSW, 1 = 8/16MHz, 0 = 10/20MHz +#endif + } +#endif +#endif + port_c = 0x00; +#if defined(SUPPORT_HIRESO) +// port_c |= 0x08; // MODSW, 1 = Normal Mode, 0 = Hirezo Mode +#endif #if defined(HAS_V30) || defined(HAS_V33) - port_c |= 0x04; // V30 + port_c |= 0x04; // DIP SW 3-8, 1 = V30, 0 = 80x86 #endif - pio_mouse->write_signal(SIG_I8255_PORT_C, 0x40, 0xff); + pio_mouse->write_signal(SIG_I8255_PORT_A, port_a, 0xff); + pio_mouse->write_signal(SIG_I8255_PORT_B, port_b, 0xff); + pio_mouse->write_signal(SIG_I8255_PORT_C, port_c, 0xff); - pio_sys->write_signal(SIG_I8255_PORT_A, 0xe3, 0xff); - pio_sys->write_signal(SIG_I8255_PORT_B, 0xf8, 0xff);//0xe8?? + port_a = 0x00; + port_a |= 0x80; // DIP SW 2-8, 1 = GDC 2.5MHz, 0 = GDC 5MHz + port_a |= 0x40; // DIP SW 2-7, 1 = Do not control FD motor + port_a |= 0x20; // DIP SW 2-6, 1 = Enable internal HD +// port_a |= 0x10; // DIP SW 2-5, 1 = Initialize emory switch +// port_a |= 0x08; // DIP SW 2-4, 1 = 20 lines, 0 = 25 lines +// port_a |= 0x04; // DIP SW 2-3, 1 = 40 columns, 0 = 80 columns + port_a |= 0x02; // DIP SW 2-2, 1 = BASIC mode, 0 = Terminal mode + port_a |= 0x01; // DIP SW 2-1, 1 = Normal mode, 0 = LT mode + port_b = 0x00; + port_b |= 0x80; // RS-232C CI#, 1 = OFF + port_b |= 0x40; // RS-232C CS#, 1 = OFF + port_b |= 0x20; // RS-232C CD#, 1 = OFF +#if !defined(SUPPORT_HIRESO) +// port_b |= 0x10; // INT3, 1 = Active, 0 = Inactive + port_b |= 0x08; // DIP SW 1-1, 1 = Hiresolution CRT, 0 = Standard CRT +#else + port_b |= 0x10; // SHUT0 + port_b |= 0x08; // SHUT1 +#endif +// port_b |= 0x04; // IMCK, 1 = Parity error occurs in internal RAM +// port_b |= 0x02; // EMCK, 1 = Parity error occurs in external RAM +// port_b |= 0x01; // CDAT + port_c = 0x00; + port_c |= 0x80; // SHUT0 + port_c |= 0x40; // PSTBM, 1 = Mask printer's PSTB# + port_c |= 0x20; // SHUT1 + port_c |= 0x10; // MCHKEN, 1 = Enable parity check for RAM + port_c |= 0x08; // BUZ, 1 = Stop buzzer + port_c |= 0x04; // TXRE, 1 = Enable IRQ from RS-232C 8251A TXRDY + port_c |= 0x02; // TXEE, 1 = Enable IRQ from RS-232C 8251A TXEMPTY + port_c |= 0x01; // RXRE, 1 = Enable IRQ from RS-232C 8251A RXRDY + pio_sys->write_signal(SIG_I8255_PORT_A, port_a, 0xff); + pio_sys->write_signal(SIG_I8255_PORT_B, port_b, 0xff); + pio_sys->write_signal(SIG_I8255_PORT_C, port_c, 0xff); + port_b = 0x00; #if defined(_PC9801) - uint8 prn_b = 0x00; // system type = first PC-9801 +// port_b |= 0x80; // TYP1, 0 = PC-9801 (first) +// port_b |= 0x40; // TYP0, 0 #elif defined(_PC9801U) - uint8 prn_b = 0xc0; // system type = PC-9801U,PC-98LT,PC-98HA + port_b |= 0x80; // TYP1, 1 = PC-9801U + port_b |= 0x40; // TYP0, 1 #else - uint8 prn_b = 0x80; // system type = others + port_b |= 0x80; // TYP1, 1 = Other PC-9801 series +// port_b |= 0x40; // TYP0, 0 #endif if(pit_clock_8mhz) { - prn_b |= 0x20; // system clock is 8MHz + port_b |= 0x20; // MOD, 1 = System clock 8MHz, 0 = 5/10MHz } - prn_b |= 0x10; // don't use LCD display + port_b |= 0x10; // DIP SW 1-3, 1 = Don't use LCD #if !defined(SUPPORT_16_COLORS) - prn_b |= 0x08; // standard graphics + port_b |= 0x08; // DIP SW 1-8, 1 = Standard graphic mode, 0 = Enhanced graphic mode #endif - prn_b |= 0x04; // printer is not busy + port_b |= 0x04; // Printer BUSY#, 1 = Inactive, 0 = Active (BUSY) #if defined(HAS_V30) || defined(HAS_V33) - prn_b |= 0x02; + port_b |= 0x02; // CPUT, 1 = V30/V33, 0 = 80x86 #endif #if defined(_PC9801VF) || defined(_PC9801U) - prn_b |= 0x01; // PC-9801VF or PC-9801U + port_b |= 0x01; // VF, 1 = PC-9801VF/U #endif - pio_prn->write_signal(SIG_I8255_PORT_B, prn_b, 0xff); + pio_prn->write_signal(SIG_I8255_PORT_B, port_b, 0xff); #if defined(SUPPORT_320KB_FDD_IF) pio_fdd->write_signal(SIG_I8255_PORT_A, 0xff, 0xff); @@ -686,7 +1132,12 @@ void VM::reset() fdc_2dd->write_signal(SIG_UPD765A_FREADY, 1, 1); // 2DD FDC RDY is pulluped #endif - opn->write_signal(SIG_YM2203_PORT_A, 0xff, 0xff); // PC-9801-26(K) IRQ=12 + if(sound_type == 0 || sound_type == 1) { +// opn->write_signal(SIG_YM2203_PORT_A, 0x3f, 0xff); // PC-9801-26(K) INT0 +// opn->write_signal(SIG_YM2203_PORT_A, 0xbf, 0xff); // PC-9801-26(K) INT41 + opn->write_signal(SIG_YM2203_PORT_A, 0xff, 0xff); // PC-9801-26(K) INT5 +// opn->write_signal(SIG_YM2203_PORT_A, 0x7f, 0xff); // PC-9801-26(K) INT6 + } #if defined(SUPPORT_OLD_BUZZER) beep->write_signal(SIG_BEEP_ON, 1, 1); @@ -696,8 +1147,8 @@ void VM::reset() beep->write_signal(SIG_PCM1BIT_MUTE, 1, 1); #endif -#if defined(_PC98DO) - pc88opn->SetReg(0x29, 3); // for Misty Blue +#if defined(_PC98DO) || defined(_PC98DOPLUS) + 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 @@ -705,7 +1156,7 @@ void VM::reset() void VM::run() { -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) if(boot_mode != 0) { pc88event->drive(); } else @@ -713,14 +1164,14 @@ void VM::run() event->drive(); } -double VM::frame_rate() +double VM::get_frame_rate() { -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) if(config.boot_mode != 0) { - return pc88event->frame_rate(); + return pc88event->get_frame_rate(); } else #endif - return event->frame_rate(); + return event->get_frame_rate(); } // ---------------------------------------------------------------------------- @@ -730,7 +1181,7 @@ double VM::frame_rate() #ifdef USE_DEBUGGER DEVICE *VM::get_cpu(int index) { -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) if(index == 0 && boot_mode == 0) { return cpu; } else if(index == 1 && boot_mode != 0) { @@ -757,7 +1208,7 @@ DEVICE *VM::get_cpu(int index) void VM::draw_screen() { -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) if(boot_mode != 0) { pc88->draw_screen(); } else @@ -765,23 +1216,6 @@ void VM::draw_screen() display->draw_screen(); } -int VM::access_lamp() -{ -#if defined(_PC9801) || defined(_PC9801E) - return (fdc_2hd->read_signal(0) & 3) | (fdc_2dd->read_signal(0) & 3) | (fdc_sub->read_signal(0) & 3); -#elif defined(_PC9801VF) || defined(_PC9801U) - return fdc_2dd->read_signal(0); -#elif defined(_PC98DO) - if(boot_mode != 0) { - return pc88fdc_sub->read_signal(0); - } else { - return fdc->read_signal(0); - } -#else - return fdc->read_signal(0); -#endif -} - // ---------------------------------------------------------------------------- // soud manager // ---------------------------------------------------------------------------- @@ -793,33 +1227,37 @@ void VM::initialize_sound(int rate, int samples) // init sound gen #if defined(SUPPORT_OLD_BUZZER) - beep->init(rate, 2400, 8000); -#else - beep->init(rate, 8000); -#endif -#ifdef HAS_YM2608 - opn->init(rate, 7987248, samples, 0, 0); + beep->initialize_sound(rate, 2400, 8000); #else - opn->init(rate, 3993624, samples, 0, 0); + beep->initialize_sound(rate, 8000); #endif + if(sound_type == 0 || sound_type == 1) { + 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); + } -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) // init sound manager pc88event->initialize_sound(rate, samples); // init sound gen -#ifdef HAS_YM2608 - pc88opn->init(rate, 7987248, samples, 0, 0); -#else - pc88opn->init(rate, 3993624, samples, 0, 0); -#endif - pc88pcm->init(rate, 8000); + 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 } -uint16* VM::create_sound(int* extra_frames) +uint16_t* VM::create_sound(int* extra_frames) { -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) if(boot_mode != 0) { return pc88event->create_sound(extra_frames); } else @@ -827,23 +1265,77 @@ uint16* VM::create_sound(int* extra_frames) return event->create_sound(extra_frames); } -int VM::sound_buffer_ptr() +int VM::get_sound_buffer_ptr() { -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) if(boot_mode != 0) { - return pc88event->sound_buffer_ptr(); + return pc88event->get_sound_buffer_ptr(); } else #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) { + if(sound_type == 0 || sound_type == 1) { + opn->set_volume(0, decibel_l, decibel_r); + } + } else if(ch-- == 0) { + if(sound_type == 0 || sound_type == 1) { + opn->set_volume(1, decibel_l, decibel_r); + } +#if defined(SUPPORT_PC98_OPNA) + } else if(ch-- == 0) { + if(sound_type == 0 || sound_type == 1) { + opn->set_volume(2, decibel_l, decibel_r); + } + } else if(ch-- == 0) { + if(sound_type == 0 || sound_type == 1) { + opn->set_volume(3, decibel_l, decibel_r); + } +#endif + } else if(ch-- == 0) { + if(sound_type == 2 || sound_type == 3) { + tms3631->set_volume(0, decibel_l, decibel_r); + } + } else if(ch-- == 0) { + beep->set_volume(0, decibel_l, decibel_r); +#if defined(_PC98DO) || defined(_PC98DOPLUS) + } else if(ch-- == 0) { + pc88opn1->set_volume(0, decibel_l, decibel_r); + } else if(ch-- == 0) { + pc88opn1->set_volume(1, decibel_l, decibel_r); +#if defined(SUPPORT_PC88_OPNA) + } else if(ch-- == 0) { + pc88opn1->set_volume(2, decibel_l, decibel_r); + } else if(ch-- == 0) { + pc88opn1->set_volume(3, decibel_l, decibel_r); +#endif + } else if(ch-- == 0) { + pc88pcm->set_volume(0, decibel_l, decibel_r); +#endif + } 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); +#if defined(_PC98DO) || defined(_PC98DOPLUS) + pc88noise_seek->set_volume(0, decibel_l, decibel_r); + pc88noise_head_down->set_volume(0, decibel_l, decibel_r); + pc88noise_head_up->set_volume(0, decibel_l, decibel_r); +#endif + } +} +#endif + // ---------------------------------------------------------------------------- // notify key // ---------------------------------------------------------------------------- void VM::key_down(int code, bool repeat) { -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) if(boot_mode != 0) { pc88->key_down(code, repeat); } else @@ -853,7 +1345,7 @@ void VM::key_down(int code, bool repeat) void VM::key_up(int code) { -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) if(boot_mode != 0) { // pc88->key_up(code); } else @@ -861,288 +1353,261 @@ void VM::key_up(int code) keyboard->key_up(code); } +bool VM::get_caps_locked() +{ +#if defined(_PC98DO) || defined(_PC98DOPLUS) + if(boot_mode != 0) { + return pc88->get_caps_locked(); + } else +#endif + return keyboard->get_caps_locked(); +} + +bool VM::get_kana_locked() +{ +#if defined(_PC98DO) || defined(_PC98DOPLUS) + if(boot_mode != 0) { + return pc88->get_kana_locked(); + } else +#endif + return keyboard->get_kana_locked(); +} + // ---------------------------------------------------------------------------- // user interface // ---------------------------------------------------------------------------- -void VM::open_disk(int drv, _TCHAR* file_path, int bank) +void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank) { -#if defined(_PC9801) || defined(_PC9801E) - if(drv == 0 || drv == 1) { - fdc_2hd->open_disk(drv, file_path, bank); - } else if(drv == 2 || drv == 3) { - fdc_2dd->open_disk(drv - 2, file_path, bank); - } else if(drv == 4 || drv == 5) { - fdc_sub->open_disk(drv - 4, file_path, bank); - } -#elif defined(_PC9801VF) || defined(_PC9801U) - if(drv == 0 || drv == 1) { - fdc_2dd->open_disk(drv, file_path, bank); - } -#elif defined(_PC98DO) - if(drv == 0 || drv == 1) { - fdc->open_disk(drv, file_path, bank); - } else if(drv == 2 || drv == 3) { - pc88fdc_sub->open_disk(drv - 2, file_path, bank); - } -#else - if(drv == 0 || drv == 1) { - fdc->open_disk(drv, file_path, bank); + UPD765A *controller = get_floppy_disk_controller(drv); + + if(controller != NULL) { + controller->open_disk(drv & 1, file_path, bank); } -#endif } -void VM::close_disk(int drv) +void VM::close_floppy_disk(int drv) { -#if defined(_PC9801) || defined(_PC9801E) - if(drv == 0 || drv == 1) { - fdc_2hd->close_disk(drv); - } else if(drv == 2 || drv == 3) { - fdc_2dd->close_disk(drv - 2); - } else if(drv == 4 || drv == 5) { - fdc_sub->close_disk(drv - 4); - } -#elif defined(_PC9801VF) || defined(_PC9801U) - if(drv == 0 || drv == 1) { - fdc_2dd->close_disk(drv); - } -#elif defined(_PC98DO) - if(drv == 0 || drv == 1) { - fdc->close_disk(drv); - } else if(drv == 2 || drv == 3) { - pc88fdc_sub->close_disk(drv - 2); + UPD765A *controller = get_floppy_disk_controller(drv); + + if(controller != NULL) { + controller->close_disk(drv & 1); } -#else - if(drv == 0 || drv == 1) { - fdc->close_disk(drv); +} + +bool VM::is_floppy_disk_inserted(int drv) +{ + DISK *handler = get_floppy_disk_handler(drv); + + if(handler != NULL) { + return handler->inserted; } -#endif + return false; } -bool VM::disk_inserted(int drv) +void VM::is_floppy_disk_protected(int drv, bool value) { -#if defined(_PC9801) || defined(_PC9801E) - if(drv == 0 || drv == 1) { - return fdc_2hd->disk_inserted(drv); - } else if(drv == 2 || drv == 3) { - return fdc_2dd->disk_inserted(drv - 2); - } else if(drv == 4 || drv == 5) { - return fdc_sub->disk_inserted(drv - 4); + DISK *handler = get_floppy_disk_handler(drv); + + if(handler != NULL) { + handler->write_protected = value; } -#elif defined(_PC9801VF) || defined(_PC9801U) - if(drv == 0 || drv == 1) { - return fdc_2dd->disk_inserted(drv); +} + +bool VM::is_floppy_disk_protected(int drv) +{ + DISK *handler = get_floppy_disk_handler(drv); + + if(handler != NULL) { + return handler->write_protected; } -#elif defined(_PC98DO) - if(drv == 0 || drv == 1) { - return fdc->disk_inserted(drv); - } else if(drv == 2 || drv == 3) { - return pc88fdc_sub->disk_inserted(drv - 2); + return false; +} + +uint32_t VM::is_floppy_disk_accessed() +{ + uint32_t status = 0; + +#if defined(_PC98DO) || defined(_PC98DOPLUS) + if(boot_mode != 0) { + status = pc88fdc_sub->read_signal(0) & 3; + } else { + status = fdc->read_signal(0) & 3; } #else - if(drv == 0 || drv == 1) { - return fdc->disk_inserted(drv); + for(int drv = 0; drv < USE_FLOPPY_DISK; drv += 2) { + UPD765A *controller = get_floppy_disk_controller(drv); + + if(controller != NULL) { + status |= (controller->read_signal(0) & 3) << drv; + } } #endif - return false; + return status; } - -void VM::set_disk_protected(int drv, bool value) +UPD765A *VM::get_floppy_disk_controller(int drv) { #if defined(_PC9801) || defined(_PC9801E) if(drv == 0 || drv == 1) { - fdc_2hd->set_disk_protected(drv, value); + return fdc_2hd; } else if(drv == 2 || drv == 3) { - fdc_2dd->set_disk_protected(drv - 2, value); + return fdc_2dd; } else if(drv == 4 || drv == 5) { - fdc_sub->set_disk_protected(drv - 4, value); + return fdc_sub; } #elif defined(_PC9801VF) || defined(_PC9801U) if(drv == 0 || drv == 1) { - fdc_2dd->set_disk_protected(drv, value); + return fdc_2dd; } -#elif defined(_PC98DO) +#elif defined(_PC98DO) || defined(_PC98DOPLUS) if(drv == 0 || drv == 1) { - fdc->set_disk_protected(drv, value); + return fdc; } else if(drv == 2 || drv == 3) { - pc88fdc_sub->set_disk_protected(drv - 2, value); + return pc88fdc_sub; } #else if(drv == 0 || drv == 1) { - fdc->set_disk_protected(drv, value); + return fdc; } #endif + return NULL; } -bool VM::get_disk_protected(int drv) +DISK *VM::get_floppy_disk_handler(int drv) { -#if defined(_PC9801) || defined(_PC9801E) - if(drv == 0 || drv == 1) { - return fdc_2hd->get_disk_protected(drv); - } else if(drv == 2 || drv == 3) { - return fdc_2dd->get_disk_protected(drv - 2); - } else if(drv == 4 || drv == 5) { - return fdc_sub->get_disk_protected(drv - 4); - } -#elif defined(_PC9801VF) || defined(_PC9801U) - if(drv == 0 || drv == 1) { - return fdc_2dd->get_disk_protected(drv); + UPD765A *controller = get_floppy_disk_controller(drv); + + if(controller != NULL) { + return controller->get_disk_handler(drv & 1); } -#elif defined(_PC98DO) - if(drv == 0 || drv == 1) { - return fdc->get_disk_protected(drv); - } else if(drv == 2 || drv == 3) { - return pc88fdc_sub->get_disk_protected(drv - 2); + return NULL; +} + +#if defined(USE_HARD_DISK) +void VM::open_hard_disk(int drv, const _TCHAR* file_path) +{ + if(drv < USE_HARD_DISK) { +#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 } -#else - if(drv == 0 || drv == 1) { - return fdc->get_disk_protected(drv); +} + +void VM::close_hard_disk(int drv) +{ + if(drv < USE_HARD_DISK) { +#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 } +} + +bool VM::is_hard_disk_inserted(int drv) +{ + if(drv < USE_HARD_DISK) { +#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; } -#if defined(SUPPORT_CMT_IF) || defined(_PC98DO) -void VM::play_tape(_TCHAR* file_path) +uint32_t VM::is_hard_disk_accessed() { -#if defined(_PC98DO) + uint32_t status = 0; + + for(int drv = 0; drv < USE_HARD_DISK; drv++) { +#if defined(SUPPORT_SASI_IF) + if(sasi_hdd->accessed(drv)) { + status |= 1 << drv; + } +#endif +#if defined(SUPPORT_SCSI_IF) + if(scsi_hdd[drv]->accessed(0)) { + status |= 1 << drv; + } +#endif +#if defined(SUPPORT_IDE_IF) + if(ide_hdd[drv]->accessed(0)) { + status |= 1 << drv; + } +#endif + } + return status; +} +#endif + +#if defined(USE_TAPE) +void VM::play_tape(int drv, const _TCHAR* file_path) +{ +#if defined(_PC98DO) || defined(_PC98DOPLUS) pc88->play_tape(file_path); #else cmt->play_tape(file_path); #endif } -void VM::rec_tape(_TCHAR* file_path) +void VM::rec_tape(int drv, const _TCHAR* file_path) { -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) pc88->rec_tape(file_path); #else cmt->rec_tape(file_path); #endif } -void VM::close_tape() +void VM::close_tape(int drv) { -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) pc88->close_tape(); #else cmt->close_tape(); #endif } -bool VM::tape_inserted() +bool VM::is_tape_inserted(int drv) { -#if defined(_PC98DO) - return pc88->tape_inserted(); +#if defined(_PC98DO) || defined(_PC98DOPLUS) + return pc88->is_tape_inserted(); #else - return cmt->tape_inserted(); -#endif -} - -#if defined(USE_TAPE_PTR) -int VM::get_tape_ptr() -{ -#if defined(_PC98DO) - return pc88->get_tape_ptr(); -#else - return cmt->get_tape_ptr(); + return cmt->is_tape_inserted(); #endif } #endif -#endif - -void VM::set_mix_cmt(bool flag) -{ -#ifdef DATAREC_SOUND -# if defined(_PC98DO) - if(flag) { - pc88->write_signal(SIG_PC88_DATAREC_MIX, 1, 1); - } else { - pc88->write_signal(SIG_PC88_DATAREC_MIX, 0, 1); - } -# else - if(flag) { - cmt->write_signal(SIG_CMT_MIX, 1, 1); - } else { - cmt->write_signal(SIG_CMT_MIX, 0, 1); - } -# endif -#endif -} - -void VM::set_volume_cmt(uint32 volume) +bool VM::is_frame_skippable() { -#ifdef DATAREC_SOUND -# if defined(_PC98DO) - pc88->write_signal(SIG_PC88_DATAREC_VOLUME, volume, 0xffffffff); -# else // _PC98DO - cmt->write_signal(SIG_CMT_VOLUME, volume, 0xffffffff); -# endif // _PC98DO -#endif -} - - - -bool VM::now_skip() -{ -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) if(boot_mode != 0) { -// return pc88event->now_skip(); - return pc88->now_skip(); +// return pc88event->is_frame_skippable(); + return pc88->is_frame_skippable(); } else #endif - return event->now_skip(); + return event->is_frame_skippable(); } void VM::update_config() { -#if defined(_PC9801E) || defined(_PC9801VM) || defined(_PC98DO) - if(cpu_type != config.cpu_type) { - uint32 pit_clocks; - int cpu_clocks = CPU_CLOCKS; -#if defined(_PC9801E) - if(config.cpu_type != 0) { - // 8MHz -> 5MHz - cpu_clocks = 4992030; - pit_clock_8mhz = false; - } else { - // 5MHz -> 8MHz - cpu_clocks = CPU_CLOCKS; - pit_clock_8mhz = true; - } -#elif defined(_PC9801VM) || defined(_PC98DO) - if(config.cpu_type != 0) { - // 10MHz -> 8MHz - cpu_clocks = 7987248; - pit_clock_8mhz = true; - } else { - cpu_clocks = CPU_CLOCKS; - pit_clock_8mhz = false; - } -#endif - uint8 prn_b = pio_prn->read_signal(SIG_I8255_PORT_B); - if(pit_clock_8mhz) { - prn_b |= 0x20; // system clock is 8MHz - pit_clocks = 1996812; - } else { - prn_b &= ~0x20; - pit_clocks = 2457600; - } - pio_prn->write_signal(SIG_I8255_PORT_B, prn_b, 0xff); - pit->set_constant_clock(0, pit_clocks); - pit->set_constant_clock(1, pit_clocks); - pit->set_constant_clock(2, pit_clocks); - event->set_cpu_clock(cpu, cpu_clocks); -#if defined(_PC98DO) - pc88event->set_cpu_clock(pc88cpu, (config.cpu_type != 0) ? 3993624 : 7987248); -#endif - cpu_type = config.cpu_type; - } -#endif - -#if defined(_PC98DO) +#if defined(_PC98DO) || defined(_PC98DOPLUS) if(boot_mode != config.boot_mode) { // boot mode is changed !!! boot_mode = config.boot_mode; @@ -1154,37 +1619,42 @@ void VM::update_config() } } -#define STATE_VERSION 2 +#define STATE_VERSION 14 -void VM::save_state(FILEIO* state_fio) +bool VM::process_state(FILEIO* state_fio, bool loading) { - state_fio->FputUint32(STATE_VERSION); - - for(DEVICE* device = first_device; device; device = device->next_device) { - device->save_state(state_fio); - } - state_fio->Fwrite(ram, sizeof(ram), 1); - state_fio->FputBool(pit_clock_8mhz); -#if defined(_PC98DO) - state_fio->FputInt32(boot_mode); -#endif -} - -bool VM::load_state(FILEIO* state_fio) -{ - if(state_fio->FgetUint32() != STATE_VERSION) { - 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; } - } - state_fio->Fread(ram, sizeof(ram), 1); - pit_clock_8mhz = state_fio->FgetBool(); -#if defined(_PC98DO) - boot_mode = state_fio->FgetInt32(); -#endif - 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; } -