2 NEC PC-9801 Emulator 'ePC-9801'
3 NEC PC-9801E/F/M Emulator 'ePC-9801E'
4 NEC PC-98DO Emulator 'ePC-98DO'
6 Author : Takeda.Toshiya
13 #include "../../emu.h"
14 #include "../device.h"
17 #if defined(SUPPORT_OLD_BUZZER)
26 #if defined(HAS_I86) || defined(HAS_V30)
33 #include "../memory.h"
36 #if !defined(SUPPORT_OLD_BUZZER)
37 #include "../pcm1bit.h"
39 //#include "../pcpr201.h"
40 #include "../prnfile.h"
41 #include "../tms3631.h"
42 #include "../upd1990a.h"
43 #include "../upd7220.h"
44 #include "../upd765a.h"
45 #include "../ym2203.h"
48 #include "../debugger.h"
58 #if defined(SUPPORT_320KB_FDD_IF)
59 #include "../pc80s31k.h"
62 #if defined(SUPPORT_CMT_IF)
66 #if defined(_PC98DO) || defined(_PC98DOPLUS)
67 #include "../pc80s31k.h"
69 #include "../pc8801/pc88.h"
72 // ----------------------------------------------------------------------------
74 // ----------------------------------------------------------------------------
76 VM::VM(EMU* parent_emu) : emu(parent_emu)
79 #if defined(_PC98DO) || defined(_PC98DOPLUS)
80 boot_mode = config.boot_mode;
82 int cpu_clocks = CPU_CLOCKS;
83 #if defined(PIT_CLOCK_8MHZ)
84 pit_clock_8mhz = true;
86 pit_clock_8mhz = false;
89 if(config.cpu_type != 0) {
92 pit_clock_8mhz = false;
94 #elif defined(_PC9801VM) || defined(_PC98DO)
95 if(config.cpu_type != 0) {
98 pit_clock_8mhz = true;
101 int pit_clocks = pit_clock_8mhz ? 1996812 : 2457600;
103 sound_type = config.sound_type;
106 first_device = last_device = NULL;
107 dummy = new DEVICE(this, emu); // must be 1st device
108 event = new EVENT(this, emu); // must be 2nd device
110 #if defined(SUPPORT_OLD_BUZZER)
111 beep = new BEEP(this, emu);
113 beep = new PCM1BIT(this, emu);
115 dma = new I8237(this, emu);
116 #if defined(SUPPORT_CMT_IF)
117 sio_cmt = new I8251(this, emu); // for cmt
118 sio_cmt->set_device_name(_T("8251 SIO (CMT)"));
120 sio_rs = new I8251(this, emu); // for rs232c
121 sio_rs->set_device_name(_T("8251 SIO (RS-232C)"));
122 sio_kbd = new I8251(this, emu); // for keyboard
123 sio_kbd->set_device_name(_T("8251 SIO (Keyboard)"));
124 pit = new I8253(this, emu);
125 #if defined(SUPPORT_320KB_FDD_IF)
126 pio_fdd = new I8255(this, emu); // for 320kb fdd i/f
127 pio_fdd->set_device_name(_T("8255 PIO (320KB I/F)"));
129 pio_mouse = new I8255(this, emu); // for mouse
130 pio_mouse->set_device_name(_T("8255 PIO (Mouse)"));
131 pio_sys = new I8255(this, emu); // for system port
132 pio_sys->set_device_name(_T("8255 PIO (System)"));
133 pio_prn = new I8255(this, emu); // for printer
134 pio_prn->set_device_name(_T("8255 PIO (Printer)"));
135 pic = new I8259(this, emu);
136 #if defined(HAS_I86) || defined(HAS_V30)
137 cpu = new I286(this, emu);
139 cpu = new I286(this, emu);
142 cpu->set_device_name(_T("CPU(i8086)"));
143 #elif defined(HAS_I386)
144 cpu->set_device_name(_T("CPU(i386)"));
145 #elif defined(HAS_I486)
146 cpu->set_device_name(_T("CPU(i486)"));
147 #elif defined(HAS_PENTIUM)
148 cpu->set_device_name(_T("CPU(Pentium)"));
149 #elif defined(HAS_V33A)
150 cpu->set_device_name(_T("CPU(V33A)"));
151 #elif defined(HAS_V30)
152 cpu->set_device_name(_T("CPU(V30)"));
154 cpu->set_device_name(_T("CPU(i286)"));
156 io = new IO(this, emu);
157 dmareg1 = new LS244(this, emu);
158 dmareg1->set_device_name(_T("74LS244 (DMA #1)"));
159 dmareg2 = new LS244(this, emu);
160 dmareg2->set_device_name(_T("74LS244 (DMA #2)"));
161 dmareg3 = new LS244(this, emu);
162 dmareg3->set_device_name(_T("74LS244 (DMA #3)"));
163 dmareg0 = new LS244(this, emu);
164 dmareg0->set_device_name(_T("74LS244 (DMA #0)"));
165 rtcreg = new LS244(this, emu);
166 rtcreg->set_device_name(_T("74LS244 (RTC)"));
167 memory = new MEMORY(this, emu);
168 not_busy = new NOT(this, emu);
169 not_busy->set_device_name(_T("NOT Gate (Printer Busy)"));
170 #if defined(HAS_I86) || defined(HAS_V30)
171 not_prn = new NOT(this, emu);
172 not_prn->set_device_name(_T("NOT Gate (Printer IRQ)"));
174 rtc = new UPD1990A(this, emu);
175 #if defined(SUPPORT_2HD_FDD_IF)
176 fdc_2hd = new UPD765A(this, emu);
177 fdc_2hd->set_device_name(_T("uPD765A FDC (2HD I/F)"));
179 #if defined(SUPPORT_2DD_FDD_IF)
180 fdc_2dd = new UPD765A(this, emu);
181 fdc_2dd->set_device_name(_T("uPD765A FDC (2DD I/F)"));
183 #if defined(SUPPORT_2HD_2DD_FDD_IF)
184 fdc = new UPD765A(this, emu);
185 fdc->set_device_name(_T("uPD765A FDC (2HD/2DD I/F)"));
187 noise_seek = new NOISE(this, emu);
188 noise_head_down = new NOISE(this, emu);
189 noise_head_up = new NOISE(this, emu);
190 gdc_chr = new UPD7220(this, emu);
191 gdc_chr->set_device_name(_T("uPD7220 GDC (Character)"));
192 gdc_gfx = new UPD7220(this, emu);
193 gdc_gfx->set_device_name(_T("uPD7220 GDC (Graphics)"));
195 if(sound_type == 0 || sound_type == 1) {
196 opn = new YM2203(this, emu);
197 #ifdef SUPPORT_PC98_OPNA
198 opn->is_ym2608 = true;
200 fmsound = new FMSOUND(this, emu);
201 joystick = new JOYSTICK(this, emu);
202 } else if(sound_type == 2 || sound_type == 3) {
203 tms3631 = new TMS3631(this, emu);
204 tms3631->set_device_name(_T("TMS3631 SSG (PC-9801-14)"));
205 pit_14 = new I8253(this, emu);
206 pit_14->set_device_name(_T("8253 PIT (PC-9801-14)"));
207 pio_14 = new I8255(this, emu);
208 pio_14->set_device_name(_T("8255 PIO (PC-9801-14)"));
209 maskreg_14 = new LS244(this, emu);
210 maskreg_14->set_device_name(_T("74LS244 (PC-9801-14)"));
212 if(config.printer_type == 0) {
213 printer = new PRNFILE(this, emu);
214 // } else if(config.printer_type == 1) {
215 // printer = new PCPR201(this, emu);
220 #if defined(SUPPORT_CMT_IF)
221 cmt = new CMT(this, emu);
223 display = new DISPLAY(this, emu);
224 floppy = new FLOPPY(this, emu);
225 keyboard = new KEYBOARD(this, emu);
226 mouse = new MOUSE(this, emu);
228 #if defined(SUPPORT_320KB_FDD_IF)
230 pio_sub = new I8255(this, emu);
231 pio_sub->set_device_name(_T("8255 PIO (320KB FDD)"));
232 pc80s31k = new PC80S31K(this, emu);
233 pc80s31k->set_device_name(_T("PC-80S31K (320KB FDD)"));
234 fdc_sub = new UPD765A(this, emu);
235 fdc_sub->set_device_name(_T("uPD765A FDC (320KB FDD)"));
236 cpu_sub = new Z80(this, emu);
237 cpu_sub->set_device_name(_T("Z80 CPU (320KB FDD)"));
250 10 (INT41) FDC (640KB I/F)
251 11 (INT42) FDC (1MB I/F)
252 12 (INT5) PC-9801-26(K) or PC-9801-14
259 event->set_context_cpu(cpu, cpu_clocks);
260 #if defined(SUPPORT_320KB_FDD_IF)
261 event->set_context_cpu(cpu_sub, 4000000);
263 event->set_context_sound(beep);
264 if(sound_type == 0 || sound_type == 1) {
265 event->set_context_sound(opn);
266 } else if(sound_type == 2 || sound_type == 3) {
267 event->set_context_sound(tms3631);
269 event->set_context_sound(noise_seek);
270 event->set_context_sound(noise_head_down);
271 event->set_context_sound(noise_head_up);
273 dma->set_context_memory(memory);
275 // dma ch.1: memory refresh
276 #if defined(SUPPORT_2HD_FDD_IF)
277 dma->set_context_ch2(fdc_2hd);
279 #if defined(SUPPORT_2DD_FDD_IF)
280 dma->set_context_ch3(fdc_2dd);
282 #if defined(SUPPORT_2HD_2DD_FDD_IF)
283 dma->set_context_ch2(fdc);
284 dma->set_context_ch3(fdc);
286 // sio_rs->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR4, 1);
287 sio_kbd->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR1, 1);
288 pit->set_context_ch0(pic, SIG_I8259_CHIP0 | SIG_I8259_IR0, 1);
289 #if defined(SUPPORT_OLD_BUZZER)
290 // pit ch.1: memory refresh
293 pit->set_context_ch1(beep, SIG_PCM1BIT_SIGNAL, 1);
296 pit->set_constant_clock(0, pit_clocks);
297 pit->set_constant_clock(1, pit_clocks);
298 pit->set_constant_clock(2, pit_clocks);
299 pio_mouse->set_context_port_c(mouse, SIG_MOUSE_PORT_C, 0xf0, 0);
300 // sysport port.c bit6: printer strobe
301 #if defined(SUPPORT_OLD_BUZZER)
302 pio_sys->set_context_port_c(beep, SIG_BEEP_MUTE, 8, 0);
304 pio_sys->set_context_port_c(beep, SIG_PCM1BIT_MUTE, 8, 0);
306 // sysport port.c bit2: enable txrdy interrupt
307 // sysport port.c bit1: enable txempty interrupt
308 // sysport port.c bit0: enable rxrdy interrupt
309 pio_prn->set_context_port_a(printer, SIG_PRINTER_DATA, 0xff, 0);
310 pio_prn->set_context_port_c(printer, SIG_PRINTER_STROBE, 0x80, 0);
311 if(config.printer_type == 0) {
312 PRNFILE *prnfile = (PRNFILE *)printer;
313 prnfile->set_context_busy(not_busy, SIG_NOT_INPUT, 1);
314 // } else if(config.printer_type == 1) {
315 // PRNFILE *pcpr201 = (PCPR201 *)printer;
316 // pcpr201->set_context_busy(not_busy, SIG_NOT_INPUT, 1);
318 not_busy->set_context_out(pio_prn, SIG_I8255_PORT_B, 4);
319 #if defined(HAS_I86) || defined(HAS_V30)
320 pio_prn->set_context_port_c(not_prn, SIG_NOT_INPUT, 8, 0);
321 not_prn->set_context_out(pic, SIG_I8259_CHIP1 | SIG_I8259_IR0, 1);
323 dmareg1->set_context_output(dma, SIG_I8237_BANK1, 0x0f, 0);
324 dmareg2->set_context_output(dma, SIG_I8237_BANK2, 0x0f, 0);
325 dmareg3->set_context_output(dma, SIG_I8237_BANK3, 0x0f, 0);
326 dmareg0->set_context_output(dma, SIG_I8237_BANK0, 0x0f, 0);
327 rtcreg->set_context_output(rtc, SIG_UPD1990A_CMD, 0x07, 0);
328 rtcreg->set_context_output(rtc, SIG_UPD1990A_DIN, 0x20, 0);
329 rtcreg->set_context_output(rtc, SIG_UPD1990A_STB, 0x08, 0);
330 rtcreg->set_context_output(rtc, SIG_UPD1990A_CLK, 0x10, 0);
331 pic->set_context_cpu(cpu);
332 rtc->set_context_dout(pio_sys, SIG_I8255_PORT_B, 1);
334 if(sound_type == 0 || sound_type == 1) {
335 opn->set_context_irq(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1);
336 opn->set_context_port_b(joystick, SIG_JOYSTICK_SELECT, 0xc0, 0);
337 fmsound->set_context_opn(opn);
338 joystick->set_context_opn(opn);
339 } else if(sound_type == 2 || sound_type == 3) {
340 pio_14->set_context_port_a(tms3631, SIG_TMS3631_ENVELOP1, 0xff, 0);
341 pio_14->set_context_port_b(tms3631, SIG_TMS3631_ENVELOP2, 0xff, 0);
342 pio_14->set_context_port_c(tms3631, SIG_TMS3631_DATAREG, 0xff, 0);
343 maskreg_14->set_context_output(tms3631, SIG_TMS3631_MASKREG, 0xff, 0);
344 pit_14->set_constant_clock(2, 1996800 / 8);
345 pit_14->set_context_ch2(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1);
348 display->set_context_pic(pic);
349 display->set_context_gdc_chr(gdc_chr, gdc_chr->get_ra());
350 display->set_context_gdc_gfx(gdc_gfx, gdc_gfx->get_ra(), gdc_gfx->get_cs());
351 keyboard->set_context_sio(sio_kbd);
352 mouse->set_context_pic(pic);
353 mouse->set_context_pio(pio_mouse);
355 #if defined(SUPPORT_2HD_FDD_IF)
356 fdc_2hd->set_context_irq(floppy, SIG_FLOPPY_2HD_IRQ, 1);
357 fdc_2hd->set_context_drq(floppy, SIG_FLOPPY_2HD_DRQ, 1);
358 fdc_2hd->set_context_noise_seek(noise_seek);
359 fdc_2hd->set_context_noise_head_down(noise_head_down);
360 fdc_2hd->set_context_noise_head_up(noise_head_up);
361 fdc_2hd->raise_irq_when_media_changed = true;
362 floppy->set_context_fdc_2hd(fdc_2hd);
364 #if defined(SUPPORT_2DD_FDD_IF)
365 fdc_2dd->set_context_irq(floppy, SIG_FLOPPY_2DD_IRQ, 1);
366 fdc_2dd->set_context_drq(floppy, SIG_FLOPPY_2DD_DRQ, 1);
367 fdc_2dd->set_context_noise_seek(noise_seek);
368 fdc_2dd->set_context_noise_head_down(noise_head_down);
369 fdc_2dd->set_context_noise_head_up(noise_head_up);
370 fdc_2dd->raise_irq_when_media_changed = true;
371 floppy->set_context_fdc_2dd(fdc_2dd);
373 #if defined(SUPPORT_2HD_2DD_FDD_IF)
374 fdc->set_context_irq(floppy, SIG_FLOPPY_IRQ, 1);
375 fdc->set_context_drq(floppy, SIG_FLOPPY_DRQ, 1);
376 fdc->set_context_noise_seek(noise_seek);
377 fdc->set_context_noise_head_down(noise_head_down);
378 fdc->set_context_noise_head_up(noise_head_up);
379 fdc->raise_irq_when_media_changed = true;
380 floppy->set_context_fdc(fdc);
382 floppy->set_context_dma(dma);
383 floppy->set_context_pic(pic);
385 #if defined(SUPPORT_CMT_IF)
386 sio_cmt->set_context_out(cmt, SIG_CMT_OUT);
387 // sio_cmt->set_context_txrdy(cmt, SIG_CMT_TXRDY, 1);
388 // sio_cmt->set_context_rxrdy(cmt, SIG_CMT_RXRDY, 1);
389 // sio_cmt->set_context_txe(cmt, SIG_CMT_TXEMP, 1);
390 cmt->set_context_sio(sio_cmt);
394 cpu->set_context_mem(memory);
395 cpu->set_context_io(io);
396 cpu->set_context_intr(pic);
397 #ifdef SINGLE_MODE_DMA
398 cpu->set_context_dma(dma);
401 cpu->set_context_debugger(new DEBUGGER(this, emu));
404 #if defined(SUPPORT_320KB_FDD_IF)
406 pc80s31k->set_context_cpu(cpu_sub);
407 pc80s31k->set_context_fdc(fdc_sub);
408 pc80s31k->set_context_pio(pio_sub);
409 pio_fdd->set_context_port_a(pio_sub, SIG_I8255_PORT_A, 0xff, 0);
410 pio_fdd->set_context_port_b(pio_sub, SIG_I8255_PORT_A, 0xff, 0);
411 pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0x0f, 4);
412 pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0xf0, -4);
413 pio_fdd->clear_ports_by_cmdreg = true;
414 pio_sub->set_context_port_a(pio_fdd, SIG_I8255_PORT_B, 0xff, 0);
415 pio_sub->set_context_port_b(pio_fdd, SIG_I8255_PORT_A, 0xff, 0);
416 pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0x0f, 4);
417 pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0xf0, -4);
418 pio_sub->clear_ports_by_cmdreg = true;
419 fdc_sub->set_context_irq(cpu_sub, SIG_CPU_IRQ, 1);
420 fdc_sub->set_context_noise_seek(noise_seek);
421 fdc_sub->set_context_noise_head_down(noise_head_down);
422 fdc_sub->set_context_noise_head_up(noise_head_up);
423 cpu_sub->set_context_mem(pc80s31k);
424 cpu_sub->set_context_io(pc80s31k);
425 cpu_sub->set_context_intr(pc80s31k);
427 cpu_sub->set_context_debugger(new DEBUGGER(this, emu));
432 memset(ram, 0, sizeof(ram));
433 memset(ipl, 0xff, sizeof(ipl));
434 memset(sound_bios, 0xff, sizeof(sound_bios));
435 #if defined(_PC9801) || defined(_PC9801E)
436 memset(fd_bios_2hd, 0xff, sizeof(fd_bios_2hd));
437 memset(fd_bios_2dd, 0xff, sizeof(fd_bios_2dd));
440 memory->read_bios(_T("IPL.ROM"), ipl, sizeof(ipl));
441 if(sound_type == 0) {
442 display->sound_bios_ok = (memory->read_bios(_T("SOUND.ROM"), sound_bios, sizeof(sound_bios)) != 0);
443 } else if(sound_type == 2) {
444 display->sound_bios_ok = (memory->read_bios(_T("MUSIC.ROM"), sound_bios, sizeof(sound_bios)) != 0);
446 display->sound_bios_ok = false;
448 #if defined(_PC9801) || defined(_PC9801E)
449 memory->read_bios(_T("2HDIF.ROM"), fd_bios_2hd, sizeof(fd_bios_2hd));
450 memory->read_bios(_T("2DDIF.ROM"), fd_bios_2dd, sizeof(fd_bios_2dd));
453 memory->set_memory_rw(0x00000, 0x9ffff, ram);
454 // A0000h - A1FFFh: TEXT VRAM
455 // A2000h - A3FFFh: ATTRIBUTE
456 memory->set_memory_mapped_io_rw(0xa0000, 0xa3fff, display);
457 // A8000h - BFFFFh: VRAM
458 memory->set_memory_mapped_io_rw(0xa8000, 0xbffff, display);
459 if(sound_type == 0 || sound_type == 2) {
460 memory->set_memory_r(0xcc000, 0xcffff, sound_bios);
462 #if defined(_PC9801) || defined(_PC9801E)
463 memory->set_memory_r(0xd6000, 0xd6fff, fd_bios_2dd);
464 memory->set_memory_r(0xd7000, 0xd7fff, fd_bios_2hd);
466 #if defined(SUPPORT_16_COLORS)
467 // E0000h - E7FFFh: VRAM
468 memory->set_memory_mapped_io_rw(0xe0000, 0xe7fff, display);
470 memory->set_memory_r(0xe8000, 0xfffff, ipl);
473 io->set_iomap_alias_rw(0x00, pic, 0);
474 io->set_iomap_alias_rw(0x02, pic, 1);
475 io->set_iomap_alias_rw(0x08, pic, 2);
476 io->set_iomap_alias_rw(0x0a, pic, 3);
478 io->set_iomap_alias_rw(0x01, dma, 0x00);
479 io->set_iomap_alias_rw(0x03, dma, 0x01);
480 io->set_iomap_alias_rw(0x05, dma, 0x02);
481 io->set_iomap_alias_rw(0x07, dma, 0x03);
482 io->set_iomap_alias_rw(0x09, dma, 0x04);
483 io->set_iomap_alias_rw(0x0b, dma, 0x05);
484 io->set_iomap_alias_rw(0x0d, dma, 0x06);
485 io->set_iomap_alias_rw(0x0f, dma, 0x07);
486 io->set_iomap_alias_rw(0x11, dma, 0x08);
487 io->set_iomap_alias_w(0x13, dma, 0x09);
488 io->set_iomap_alias_w(0x15, dma, 0x0a);
489 io->set_iomap_alias_w(0x17, dma, 0x0b);
490 io->set_iomap_alias_w(0x19, dma, 0x0c);
491 io->set_iomap_alias_rw(0x1b, dma, 0x0d);
492 io->set_iomap_alias_w(0x1d, dma, 0x0e);
493 io->set_iomap_alias_w(0x1f, dma, 0x0f);
494 io->set_iomap_single_w(0x21, dmareg1);
495 io->set_iomap_single_w(0x23, dmareg2);
496 io->set_iomap_single_w(0x25, dmareg3);
497 io->set_iomap_single_w(0x27, dmareg0);
499 io->set_iomap_single_w(0x20, rtcreg);
501 io->set_iomap_alias_rw(0x30, sio_rs, 0);
502 io->set_iomap_alias_rw(0x32, sio_rs, 1);
504 io->set_iomap_alias_rw(0x31, pio_sys, 0);
505 io->set_iomap_alias_rw(0x33, pio_sys, 1);
506 io->set_iomap_alias_rw(0x35, pio_sys, 2);
507 io->set_iomap_alias_w(0x37, pio_sys, 3);
509 io->set_iomap_alias_rw(0x40, pio_prn, 0);
510 io->set_iomap_alias_rw(0x42, pio_prn, 1);
511 io->set_iomap_alias_rw(0x44, pio_prn, 2);
512 io->set_iomap_alias_w(0x46, pio_prn, 3);
514 io->set_iomap_alias_rw(0x41, sio_kbd, 0);
515 io->set_iomap_alias_rw(0x43, sio_kbd, 1);
517 // 50h, 52h: NMI Flip Flop
519 #if defined(SUPPORT_320KB_FDD_IF)
520 io->set_iomap_alias_rw(0x51, pio_fdd, 0);
521 io->set_iomap_alias_rw(0x53, pio_fdd, 1);
522 io->set_iomap_alias_rw(0x55, pio_fdd, 2);
523 io->set_iomap_alias_w(0x57, pio_fdd, 3);
526 io->set_iomap_alias_rw(0x60, gdc_chr, 0);
527 io->set_iomap_alias_rw(0x62, gdc_chr, 1);
529 io->set_iomap_single_w(0x64, display);
530 io->set_iomap_single_w(0x68, display);
531 #if defined(SUPPORT_16_COLORS)
532 io->set_iomap_single_w(0x6a, display);
534 io->set_iomap_single_w(0x6c, display);
535 io->set_iomap_single_w(0x6e, display);
537 io->set_iomap_single_w(0x70, display);
538 io->set_iomap_single_w(0x72, display);
539 io->set_iomap_single_w(0x74, display);
540 io->set_iomap_single_w(0x76, display);
541 io->set_iomap_single_w(0x78, display);
542 io->set_iomap_single_w(0x7a, display);
543 #if defined(SUPPORT_16_COLORS)
544 io->set_iomap_single_w(0x7c, display);
545 io->set_iomap_single_w(0x7e, display);
548 io->set_iomap_alias_rw(0x71, pit, 0);
549 io->set_iomap_alias_rw(0x73, pit, 1);
550 io->set_iomap_alias_rw(0x75, pit, 2);
551 io->set_iomap_alias_w(0x77, pit, 3);
555 io->set_iomap_single_rw(0x90, floppy);
556 io->set_iomap_single_rw(0x92, floppy);
557 io->set_iomap_single_rw(0x94, floppy);
559 #if defined(SUPPORT_CMT_IF)
560 io->set_iomap_alias_rw(0x91, sio_cmt, 0);
561 io->set_iomap_alias_rw(0x93, sio_cmt, 1);
562 io->set_iomap_single_w(0x95, cmt);
563 io->set_iomap_single_w(0x97, cmt);
566 io->set_iomap_alias_rw(0xa0, gdc_gfx, 0);
567 io->set_iomap_alias_rw(0xa2, gdc_gfx, 1);
569 #if defined(SUPPORT_2ND_VRAM)
570 io->set_iomap_single_w(0xa4, display);
571 io->set_iomap_single_w(0xa6, display);
573 io->set_iomap_single_rw(0xa8, display);
574 io->set_iomap_single_rw(0xaa, display);
575 io->set_iomap_single_rw(0xac, display);
576 io->set_iomap_single_rw(0xae, display);
578 io->set_iomap_single_w(0xa1, display);
579 io->set_iomap_single_w(0xa3, display);
580 io->set_iomap_single_w(0xa5, display);
581 io->set_iomap_single_rw(0xa9, display);
583 #if defined(SUPPORT_2HD_2DD_FDD_IF)
584 io->set_iomap_single_rw(0xbe, floppy);
586 io->set_iomap_single_rw(0xc8, floppy);
587 io->set_iomap_single_rw(0xca, floppy);
588 io->set_iomap_single_rw(0xcc, floppy);
590 if(sound_type == 0 || sound_type == 1) {
591 io->set_iomap_single_rw(0x188, fmsound);
592 io->set_iomap_single_rw(0x18a, fmsound);
593 #ifdef SUPPORT_PC98_OPNA
594 io->set_iomap_single_rw(0x18c, fmsound);
595 io->set_iomap_single_rw(0x18e, fmsound);
596 io->set_iomap_single_rw(0xa460, fmsound);
598 } else if(sound_type == 2 || sound_type == 3) {
599 io->set_iomap_alias_rw(0x88, pio_14, 0);
600 io->set_iomap_alias_rw(0x8a, pio_14, 1);
601 io->set_iomap_alias_rw(0x8c, pio_14, 2);
602 io->set_iomap_alias_w(0x8e, pio_14, 3);
603 io->set_iovalue_single_r(0x8e, 0x08);
604 io->set_iomap_single_w(0x188, maskreg_14);
605 io->set_iomap_single_w(0x18a, maskreg_14);
606 io->set_iomap_alias_rw(0x18c, pit_14, 2);
607 io->set_iomap_alias_w(0x18e, pit_14, 3);
608 // io->set_iovalue_single_r(0x18e, 0x00); // INT0
609 // io->set_iovalue_single_r(0x18e, 0x40); // INT41
610 io->set_iovalue_single_r(0x18e, 0x80); // INT5
611 // io->set_iovalue_single_r(0x18e, 0xc0); // INT6
614 #if !defined(SUPPORT_OLD_BUZZER)
615 io->set_iomap_alias_rw(0x3fd9, pit, 0);
616 io->set_iomap_alias_rw(0x3fdb, pit, 1);
617 io->set_iomap_alias_rw(0x3fdd, pit, 2);
618 io->set_iomap_alias_w(0x3fdf, pit, 3);
621 io->set_iomap_alias_rw(0x7fd9, pio_mouse, 0);
622 io->set_iomap_alias_rw(0x7fdb, pio_mouse, 1);
623 io->set_iomap_alias_rw(0x7fdd, pio_mouse, 2);
624 io->set_iomap_alias_w(0x7fdf, pio_mouse, 3);
625 #if !(defined(_PC9801) || defined(_PC9801E))
626 io->set_iomap_single_w(0xbfdb, mouse);
629 #if defined(_PC98DO) || defined(_PC98DOPLUS)
630 pc88event = new EVENT(this, emu);
631 pc88event->set_device_name(_T("Event Manager (PC-8801)"));
632 pc88event->set_frames_per_sec(60);
633 pc88event->set_lines_per_frame(260);
635 pc88 = new PC88(this, emu);
636 pc88->set_context_event_manager(pc88event);
637 pc88sio = new I8251(this, emu);
638 pc88sio->set_device_name(_T("8251 SIO (PC-8801)"));
639 pc88sio->set_context_event_manager(pc88event);
640 pc88pio = new I8255(this, emu);
641 pc88pio->set_device_name(_T("8255 PIO (PC-8801)"));
642 pc88pio->set_context_event_manager(pc88event);
643 pc88pcm = new PCM1BIT(this, emu);
644 pc88pcm->set_device_name(_T("1-Bit PCM Sound (PC-8801)"));
645 pc88pcm->set_context_event_manager(pc88event);
646 pc88rtc = new UPD1990A(this, emu);
647 pc88rtc->set_device_name(_T("uPD1990A RTC (PC-8801)"));
648 pc88rtc->set_context_event_manager(pc88event);
649 pc88opn = new YM2203(this, emu);
650 #ifdef SUPPORT_PC88_OPNA
651 pc88opn->set_device_name(_T("YM2608 OPNA (PC-8801)"));
652 pc88opn->is_ym2608 = true;
654 pc88opn->set_device_name(_T("YM2203 OPN (PC-8801)"));
656 pc88opn->set_context_event_manager(pc88event);
657 pc88cpu = new Z80(this, emu);
658 pc88cpu->set_device_name(_T("Z80 CPU (PC-8801)"));
659 pc88cpu->set_context_event_manager(pc88event);
661 if(config.printer_type == 0) {
662 pc88prn = new PRNFILE(this, emu);
663 pc88prn->set_context_event_manager(pc88event);
664 // } else if(config.printer_type == 1) {
665 // pc88prn = new PCPR201(this, emu);
666 // pc88prn->set_context_event_manager(pc88event);
671 pc88sub = new PC80S31K(this, emu);
672 pc88sub->set_device_name(_T("PC-80S31K (PC-8801 Sub)"));
673 pc88sub->set_context_event_manager(pc88event);
674 pc88pio_sub = new I8255(this, emu);
675 pc88pio_sub->set_device_name(_T("8255 PIO (PC-8801 Sub)"));
676 pc88pio_sub->set_context_event_manager(pc88event);
677 pc88fdc_sub = new UPD765A(this, emu);
678 pc88fdc_sub->set_device_name(_T("uPD765A FDC (PC-8801 Sub)"));
679 pc88fdc_sub->set_context_event_manager(pc88event);
680 pc88noise_seek = new NOISE(this, emu);
681 pc88noise_seek->set_context_event_manager(pc88event);
682 pc88noise_head_down = new NOISE(this, emu);
683 pc88noise_head_down->set_context_event_manager(pc88event);
684 pc88noise_head_up = new NOISE(this, emu);
685 pc88noise_head_up->set_context_event_manager(pc88event);
686 pc88cpu_sub = new Z80(this, emu);
687 pc88cpu_sub->set_device_name(_T("Z80 CPU (PC-8801 Sub)"));
688 pc88cpu_sub->set_context_event_manager(pc88event);
690 pc88event->set_context_cpu(pc88cpu, (config.cpu_type != 0) ? 3993624 : 7987248);
691 pc88event->set_context_cpu(pc88cpu_sub, 3993624);
692 pc88event->set_context_sound(pc88opn);
693 pc88event->set_context_sound(pc88pcm);
694 pc88event->set_context_sound(pc88noise_seek);
695 pc88event->set_context_sound(pc88noise_head_down);
696 pc88event->set_context_sound(pc88noise_head_up);
698 pc88->set_context_cpu(pc88cpu);
699 pc88->set_context_opn(pc88opn);
700 pc88->set_context_pcm(pc88pcm);
701 pc88->set_context_pio(pc88pio);
702 pc88->set_context_prn(pc88prn);
703 pc88->set_context_rtc(pc88rtc);
704 pc88->set_context_sio(pc88sio);
705 pc88cpu->set_context_mem(pc88);
706 pc88cpu->set_context_io(pc88);
707 pc88cpu->set_context_intr(pc88);
709 pc88cpu->set_context_debugger(new DEBUGGER(this, emu));
711 pc88opn->set_context_irq(pc88, SIG_PC88_SOUND_IRQ, 1);
712 pc88sio->set_context_rxrdy(pc88, SIG_PC88_USART_IRQ, 1);
713 pc88sio->set_context_out(pc88, SIG_PC88_USART_OUT);
715 pc88sub->set_context_cpu(pc88cpu_sub);
716 pc88sub->set_context_fdc(pc88fdc_sub);
717 pc88sub->set_context_pio(pc88pio_sub);
718 pc88pio->set_context_port_a(pc88pio_sub, SIG_I8255_PORT_B, 0xff, 0);
719 pc88pio->set_context_port_b(pc88pio_sub, SIG_I8255_PORT_A, 0xff, 0);
720 pc88pio->set_context_port_c(pc88pio_sub, SIG_I8255_PORT_C, 0x0f, 4);
721 pc88pio->set_context_port_c(pc88pio_sub, SIG_I8255_PORT_C, 0xf0, -4);
722 pc88pio->clear_ports_by_cmdreg = true;
723 pc88pio_sub->set_context_port_a(pc88pio, SIG_I8255_PORT_B, 0xff, 0);
724 pc88pio_sub->set_context_port_b(pc88pio, SIG_I8255_PORT_A, 0xff, 0);
725 pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0x0f, 4);
726 pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0xf0, -4);
727 pc88pio_sub->clear_ports_by_cmdreg = true;
728 pc88fdc_sub->set_context_irq(pc88cpu_sub, SIG_CPU_IRQ, 1);
729 pc88fdc_sub->set_context_noise_seek(pc88noise_seek);
730 pc88fdc_sub->set_context_noise_head_down(pc88noise_head_down);
731 pc88fdc_sub->set_context_noise_head_up(pc88noise_head_up);
732 pc88cpu_sub->set_context_mem(pc88sub);
733 pc88cpu_sub->set_context_io(pc88sub);
734 pc88cpu_sub->set_context_intr(pc88sub);
736 pc88cpu_sub->set_context_debugger(new DEBUGGER(this, emu));
740 // initialize all devices
741 for(DEVICE* device = first_device; device; device = device->next_device) {
742 device->initialize();
744 #if defined(_PC9801) || defined(_PC9801E)
745 fdc_2hd->get_disk_handler(0)->drive_num = 0;
746 fdc_2hd->get_disk_handler(1)->drive_num = 1;
747 fdc_2dd->get_disk_handler(0)->drive_num = 2;
748 fdc_2dd->get_disk_handler(1)->drive_num = 3;
749 fdc_sub->get_disk_handler(0)->drive_num = 4;
750 fdc_sub->get_disk_handler(1)->drive_num = 5;
751 #elif defined(_PC9801VF) || defined(_PC9801U)
752 fdc_2dd->get_disk_handler(0)->drive_num = 0;
753 fdc_2dd->get_disk_handler(1)->drive_num = 1;
754 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
755 fdc->get_disk_handler(0)->drive_num = 0;
756 fdc->get_disk_handler(1)->drive_num = 1;
757 pc88fdc_sub->get_disk_handler(0)->drive_num = 2;
758 pc88fdc_sub->get_disk_handler(1)->drive_num = 3;
760 fdc->get_disk_handler(0)->drive_num = 0;
761 fdc->get_disk_handler(1)->drive_num = 1;
767 // delete all devices
768 for(DEVICE* device = first_device; device;) {
769 DEVICE *next_device = device->next_device;
772 device = next_device;
776 DEVICE* VM::get_device(int id)
778 for(DEVICE* device = first_device; device; device = device->next_device) {
779 if(device->this_device_id == id) {
786 // ----------------------------------------------------------------------------
787 // drive virtual machine
788 // ----------------------------------------------------------------------------
793 for(DEVICE* device = first_device; device; device = device->next_device) {
796 #if defined(_PC98DO) || defined(_PC98DOPLUS)
797 for(DEVICE* device = first_device; device; device = device->next_device) {
802 // initial device settings
803 pio_mouse->write_signal(SIG_I8255_PORT_A, 0xf0, 0xff); // clear mouse status
804 pio_mouse->write_signal(SIG_I8255_PORT_B, 0x40, 0xff); // cpu high & sw3-6
805 uint8_t port_c = 0x08; // normal mode & sw1-5 & sw1-6
806 #if defined(HAS_V30) || defined(HAS_V33)
807 port_c |= 0x04; // V30
809 pio_mouse->write_signal(SIG_I8255_PORT_C, 0x40, 0xff);
811 pio_sys->write_signal(SIG_I8255_PORT_A, 0xe3, 0xff);
812 pio_sys->write_signal(SIG_I8255_PORT_B, 0xf8, 0xff);//0xe8??
815 uint8_t prn_b = 0x00; // system type = first PC-9801
816 #elif defined(_PC9801U)
817 uint8_t prn_b = 0xc0; // system type = PC-9801U,PC-98LT,PC-98HA
819 uint8_t prn_b = 0x80; // system type = others
822 prn_b |= 0x20; // system clock is 8MHz
824 prn_b |= 0x10; // don't use LCD display
825 #if !defined(SUPPORT_16_COLORS)
826 prn_b |= 0x08; // standard graphics
828 prn_b |= 0x04; // printer is not busy
829 #if defined(HAS_V30) || defined(HAS_V33)
832 #if defined(_PC9801VF) || defined(_PC9801U)
833 prn_b |= 0x01; // PC-9801VF or PC-9801U
835 pio_prn->write_signal(SIG_I8255_PORT_B, prn_b, 0xff);
837 #if defined(SUPPORT_320KB_FDD_IF)
838 pio_fdd->write_signal(SIG_I8255_PORT_A, 0xff, 0xff);
839 pio_fdd->write_signal(SIG_I8255_PORT_B, 0xff, 0xff);
840 pio_fdd->write_signal(SIG_I8255_PORT_C, 0xff, 0xff);
842 #if defined(SUPPORT_2DD_FDD_IF)
843 fdc_2dd->write_signal(SIG_UPD765A_FREADY, 1, 1); // 2DD FDC RDY is pulluped
846 if(sound_type == 0 || sound_type == 1) {
847 // opn->write_signal(SIG_YM2203_PORT_A, 0x3f, 0xff); // PC-9801-26(K) INT0
848 // opn->write_signal(SIG_YM2203_PORT_A, 0xbf, 0xff); // PC-9801-26(K) INT41
849 opn->write_signal(SIG_YM2203_PORT_A, 0xff, 0xff); // PC-9801-26(K) INT5
850 // opn->write_signal(SIG_YM2203_PORT_A, 0x7f, 0xff); // PC-9801-26(K) INT6
853 #if defined(SUPPORT_OLD_BUZZER)
854 beep->write_signal(SIG_BEEP_ON, 1, 1);
855 beep->write_signal(SIG_BEEP_MUTE, 1, 1);
857 beep->write_signal(SIG_PCM1BIT_ON, 1, 1);
858 beep->write_signal(SIG_PCM1BIT_MUTE, 1, 1);
861 #if defined(_PC98DO) || defined(_PC98DOPLUS)
862 pc88opn->set_reg(0x29, 3); // for Misty Blue
863 pc88pio->write_signal(SIG_I8255_PORT_C, 0, 0xff);
864 pc88pio_sub->write_signal(SIG_I8255_PORT_C, 0, 0xff);
870 #if defined(_PC98DO) || defined(_PC98DOPLUS)
878 double VM::get_frame_rate()
880 #if defined(_PC98DO) || defined(_PC98DOPLUS)
881 if(config.boot_mode != 0) {
882 return pc88event->get_frame_rate();
885 return event->get_frame_rate();
888 // ----------------------------------------------------------------------------
890 // ----------------------------------------------------------------------------
893 DEVICE *VM::get_cpu(int index)
895 #if defined(_PC98DO) || defined(_PC98DOPLUS)
896 if(index == 0 && boot_mode == 0) {
898 } else if(index == 1 && boot_mode != 0) {
900 } else if(index == 2 && boot_mode != 0) {
906 #if defined(SUPPORT_320KB_FDD_IF)
907 } else if(index == 1) {
916 // ----------------------------------------------------------------------------
918 // ----------------------------------------------------------------------------
920 void VM::draw_screen()
922 #if defined(_PC98DO) || defined(_PC98DOPLUS)
927 display->draw_screen();
930 // ----------------------------------------------------------------------------
932 // ----------------------------------------------------------------------------
934 void VM::initialize_sound(int rate, int samples)
936 // init sound manager
937 event->initialize_sound(rate, samples);
940 #if defined(SUPPORT_OLD_BUZZER)
941 beep->initialize_sound(rate, 2400, 8000);
943 beep->initialize_sound(rate, 8000);
945 if(sound_type == 0 || sound_type == 1) {
947 opn->initialize_sound(rate, 7987248, samples, 0, 0);
949 opn->initialize_sound(rate, 3993624, samples, 0, 0);
951 } else if(sound_type == 2 || sound_type == 3) {
952 tms3631->initialize_sound(rate, 8000);
955 #if defined(_PC98DO) || defined(_PC98DOPLUS)
956 // init sound manager
957 pc88event->initialize_sound(rate, samples);
961 pc88opn->initialize_sound(rate, 7987248, samples, 0, 0);
963 pc88opn->initialize_sound(rate, 3993624, samples, 0, 0);
965 pc88pcm->initialize_sound(rate, 8000);
969 uint16_t* VM::create_sound(int* extra_frames)
971 #if defined(_PC98DO) || defined(_PC98DOPLUS)
973 return pc88event->create_sound(extra_frames);
976 return event->create_sound(extra_frames);
979 int VM::get_sound_buffer_ptr()
981 #if defined(_PC98DO) || defined(_PC98DOPLUS)
983 return pc88event->get_sound_buffer_ptr();
986 return event->get_sound_buffer_ptr();
989 #ifdef USE_SOUND_VOLUME
990 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
993 if(sound_type == 0 || sound_type == 1) {
994 opn->set_volume(0, decibel_l, decibel_r);
996 } else if(ch-- == 0) {
997 if(sound_type == 0 || sound_type == 1) {
998 opn->set_volume(1, decibel_l, decibel_r);
1000 #if defined(SUPPORT_PC98_OPNA)
1001 } else if(ch-- == 0) {
1002 if(sound_type == 0 || sound_type == 1) {
1003 opn->set_volume(2, decibel_l, decibel_r);
1005 } else if(ch-- == 0) {
1006 if(sound_type == 0 || sound_type == 1) {
1007 opn->set_volume(3, decibel_l, decibel_r);
1010 } else if(ch-- == 0) {
1011 if(sound_type == 2 || sound_type == 3) {
1012 tms3631->set_volume(0, decibel_l, decibel_r);
1014 } else if(ch-- == 0) {
1015 beep->set_volume(0, decibel_l, decibel_r);
1016 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1017 } else if(ch-- == 0) {
1018 pc88opn->set_volume(0, decibel_l, decibel_r);
1019 } else if(ch-- == 0) {
1020 pc88opn->set_volume(1, decibel_l, decibel_r);
1021 #if defined(SUPPORT_PC88_OPNA)
1022 } else if(ch-- == 0) {
1023 pc88opn->set_volume(2, decibel_l, decibel_r);
1024 } else if(ch-- == 0) {
1025 pc88opn->set_volume(3, decibel_l, decibel_r);
1027 } else if(ch-- == 0) {
1028 pc88pcm->set_volume(0, decibel_l, decibel_r);
1030 } else if(ch-- == 0) {
1031 noise_seek->set_volume(0, decibel_l, decibel_r);
1032 noise_head_down->set_volume(0, decibel_l, decibel_r);
1033 noise_head_up->set_volume(0, decibel_l, decibel_r);
1034 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1035 pc88noise_seek->set_volume(0, decibel_l, decibel_r);
1036 pc88noise_head_down->set_volume(0, decibel_l, decibel_r);
1037 pc88noise_head_up->set_volume(0, decibel_l, decibel_r);
1043 // ----------------------------------------------------------------------------
1045 // ----------------------------------------------------------------------------
1047 void VM::key_down(int code, bool repeat)
1049 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1050 if(boot_mode != 0) {
1051 pc88->key_down(code, repeat);
1054 keyboard->key_down(code, repeat);
1057 void VM::key_up(int code)
1059 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1060 if(boot_mode != 0) {
1061 // pc88->key_up(code);
1064 keyboard->key_up(code);
1067 // ----------------------------------------------------------------------------
1069 // ----------------------------------------------------------------------------
1071 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
1073 #if defined(_PC9801) || defined(_PC9801E)
1074 if(drv == 0 || drv == 1) {
1075 fdc_2hd->open_disk(drv, file_path, bank);
1076 } else if(drv == 2 || drv == 3) {
1077 fdc_2dd->open_disk(drv - 2, file_path, bank);
1078 } else if(drv == 4 || drv == 5) {
1079 fdc_sub->open_disk(drv - 4, file_path, bank);
1081 #elif defined(_PC9801VF) || defined(_PC9801U)
1082 if(drv == 0 || drv == 1) {
1083 fdc_2dd->open_disk(drv, file_path, bank);
1085 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1086 if(drv == 0 || drv == 1) {
1087 fdc->open_disk(drv, file_path, bank);
1088 } else if(drv == 2 || drv == 3) {
1089 pc88fdc_sub->open_disk(drv - 2, file_path, bank);
1092 if(drv == 0 || drv == 1) {
1093 fdc->open_disk(drv, file_path, bank);
1098 void VM::close_floppy_disk(int drv)
1100 #if defined(_PC9801) || defined(_PC9801E)
1101 if(drv == 0 || drv == 1) {
1102 fdc_2hd->close_disk(drv);
1103 } else if(drv == 2 || drv == 3) {
1104 fdc_2dd->close_disk(drv - 2);
1105 } else if(drv == 4 || drv == 5) {
1106 fdc_sub->close_disk(drv - 4);
1108 #elif defined(_PC9801VF) || defined(_PC9801U)
1109 if(drv == 0 || drv == 1) {
1110 fdc_2dd->close_disk(drv);
1112 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1113 if(drv == 0 || drv == 1) {
1114 fdc->close_disk(drv);
1115 } else if(drv == 2 || drv == 3) {
1116 pc88fdc_sub->close_disk(drv - 2);
1119 if(drv == 0 || drv == 1) {
1120 fdc->close_disk(drv);
1125 bool VM::is_floppy_disk_inserted(int drv)
1127 #if defined(_PC9801) || defined(_PC9801E)
1128 if(drv == 0 || drv == 1) {
1129 return fdc_2hd->is_disk_inserted(drv);
1130 } else if(drv == 2 || drv == 3) {
1131 return fdc_2dd->is_disk_inserted(drv - 2);
1132 } else if(drv == 4 || drv == 5) {
1133 return fdc_sub->is_disk_inserted(drv - 4);
1135 #elif defined(_PC9801VF) || defined(_PC9801U)
1136 if(drv == 0 || drv == 1) {
1137 return fdc_2dd->is_disk_inserted(drv);
1139 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1140 if(drv == 0 || drv == 1) {
1141 return fdc->is_disk_inserted(drv);
1142 } else if(drv == 2 || drv == 3) {
1143 return pc88fdc_sub->is_disk_inserted(drv - 2);
1146 if(drv == 0 || drv == 1) {
1147 return fdc->is_disk_inserted(drv);
1153 void VM::is_floppy_disk_protected(int drv, bool value)
1155 #if defined(_PC9801) || defined(_PC9801E)
1156 if(drv == 0 || drv == 1) {
1157 fdc_2hd->is_disk_protected(drv, value);
1158 } else if(drv == 2 || drv == 3) {
1159 fdc_2dd->is_disk_protected(drv - 2, value);
1160 } else if(drv == 4 || drv == 5) {
1161 fdc_sub->is_disk_protected(drv - 4, value);
1163 #elif defined(_PC9801VF) || defined(_PC9801U)
1164 if(drv == 0 || drv == 1) {
1165 fdc_2dd->is_disk_protected(drv, value);
1167 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1168 if(drv == 0 || drv == 1) {
1169 fdc->is_disk_protected(drv, value);
1170 } else if(drv == 2 || drv == 3) {
1171 pc88fdc_sub->is_disk_protected(drv - 2, value);
1174 if(drv == 0 || drv == 1) {
1175 fdc->is_disk_protected(drv, value);
1180 bool VM::is_floppy_disk_protected(int drv)
1182 #if defined(_PC9801) || defined(_PC9801E)
1183 if(drv == 0 || drv == 1) {
1184 return fdc_2hd->is_disk_protected(drv);
1185 } else if(drv == 2 || drv == 3) {
1186 return fdc_2dd->is_disk_protected(drv - 2);
1187 } else if(drv == 4 || drv == 5) {
1188 return fdc_sub->is_disk_protected(drv - 4);
1190 #elif defined(_PC9801VF) || defined(_PC9801U)
1191 if(drv == 0 || drv == 1) {
1192 return fdc_2dd->is_disk_protected(drv);
1194 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1195 if(drv == 0 || drv == 1) {
1196 return fdc->is_disk_protected(drv);
1197 } else if(drv == 2 || drv == 3) {
1198 return pc88fdc_sub->is_disk_protected(drv - 2);
1201 if(drv == 0 || drv == 1) {
1202 return fdc->is_disk_protected(drv);
1208 uint32_t VM::is_floppy_disk_accessed()
1210 #if defined(_PC9801) || defined(_PC9801E)
1211 return (fdc_2hd->read_signal(0) & 3) | ((fdc_2dd->read_signal(0) & 3) << 2) | ((fdc_sub->read_signal(0) & 3) << 4);
1212 #elif defined(_PC9801VF) || defined(_PC9801U)
1213 return fdc_2dd->read_signal(0);
1214 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1215 if(boot_mode != 0) {
1216 return pc88fdc_sub->read_signal(0);
1218 return fdc->read_signal(0);
1221 return fdc->read_signal(0);
1225 #if defined(SUPPORT_CMT_IF) || defined(_PC98DO) || defined(_PC98DOPLUS)
1226 void VM::play_tape(int drv, const _TCHAR* file_path)
1228 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1229 pc88->play_tape(file_path);
1231 cmt->play_tape(file_path);
1235 void VM::rec_tape(int drv, const _TCHAR* file_path)
1237 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1238 pc88->rec_tape(file_path);
1240 cmt->rec_tape(file_path);
1244 void VM::close_tape(int drv)
1246 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1253 bool VM::is_tape_inserted(int drv)
1255 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1256 return pc88->is_tape_inserted();
1258 return cmt->is_tape_inserted();
1263 bool VM::is_frame_skippable()
1265 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1266 if(boot_mode != 0) {
1267 // return pc88event->is_frame_skippable();
1268 return pc88->is_frame_skippable();
1271 return event->is_frame_skippable();
1274 void VM::update_config()
1276 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1277 if(boot_mode != config.boot_mode) {
1278 // boot mode is changed !!!
1279 boot_mode = config.boot_mode;
1283 for(DEVICE* device = first_device; device; device = device->next_device) {
1284 device->update_config();
1288 #define STATE_VERSION 8
1290 void VM::save_state(FILEIO* state_fio)
1292 state_fio->FputUint32(STATE_VERSION);
1294 for(DEVICE* device = first_device; device; device = device->next_device) {
1295 device->save_state(state_fio);
1297 state_fio->Fwrite(ram, sizeof(ram), 1);
1298 state_fio->FputBool(pit_clock_8mhz);
1299 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1300 state_fio->FputInt32(boot_mode);
1302 state_fio->FputInt32(sound_type);
1305 bool VM::load_state(FILEIO* state_fio)
1307 if(state_fio->FgetUint32() != STATE_VERSION) {
1310 for(DEVICE* device = first_device; device; device = device->next_device) {
1311 if(!device->load_state(state_fio)) {
1315 state_fio->Fread(ram, sizeof(ram), 1);
1316 pit_clock_8mhz = state_fio->FgetBool();
1317 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1318 boot_mode = state_fio->FgetInt32();
1320 sound_type = state_fio->FgetInt32();