2 NEC PC-9801 Emulator 'ePC-9801'
3 NEC PC-9801E/F/M Emulator 'ePC-9801E'
4 NEC PC-9801U Emulator 'ePC-9801U'
5 NEC PC-9801VF Emulator 'ePC-9801VF'
6 NEC PC-9801VM Emulator 'ePC-9801VM'
7 NEC PC-9801VX Emulator 'ePC-9801VX'
8 NEC PC-9801RA Emulator 'ePC-9801RA'
9 NEC PC-98XL Emulator 'ePC-98XL'
10 NEC PC-98RL Emulator 'ePC-98RL'
11 NEC PC-98DO Emulator 'ePC-98DO'
13 Author : Takeda.Toshiya
20 #include "../../emu.h"
21 #include "../device.h"
24 #if defined(SUPPORT_OLD_BUZZER)
33 #if defined(HAS_I386) || defined(HAS_I486)
35 #elif defined(HAS_I86) || defined(HAS_V30)
42 #include "../memory.h"
45 #if !defined(SUPPORT_OLD_BUZZER)
46 #include "../pcm1bit.h"
48 //#include "../pcpr201.h"
49 #include "../prnfile.h"
50 #include "../tms3631.h"
51 #include "../upd1990a.h"
52 #include "../upd7220.h"
53 #include "../upd765a.h"
54 #include "../ym2203.h"
57 #include "../debugger.h"
60 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
71 #if defined(SUPPORT_SASI_IF)
74 #if defined(SUPPORT_SCSI_IF)
77 #if defined(SUPPORT_IDE_IF)
81 #if defined(SUPPORT_320KB_FDD_IF)
82 #include "../pc80s31k.h"
85 #if defined(SUPPORT_CMT_IF)
89 #if defined(_PC98DO) || defined(_PC98DOPLUS)
90 #include "../pc80s31k.h"
92 #include "../pc8801/pc88.h"
95 // ----------------------------------------------------------------------------
97 // ----------------------------------------------------------------------------
99 VM::VM(EMU* parent_emu) : emu(parent_emu)
102 #if defined(_PC98DO) || defined(_PC98DOPLUS)
103 boot_mode = config.boot_mode;
105 int cpu_clocks = CPU_CLOCKS;
106 #if defined(PIT_CLOCK_8MHZ)
107 pit_clock_8mhz = true;
109 pit_clock_8mhz = false;
111 #if defined(_PC9801E)
112 if(config.cpu_type != 0) {
114 cpu_clocks = 4992030;
115 pit_clock_8mhz = false;
117 #elif defined(_PC9801VM) || defined(_PC98DO) || defined(_PC98DOPLUS) || defined(_PC9801VX) || defined(_PC98XL)
118 if(config.cpu_type != 0) {
119 // 10MHz/16MHz -> 8MHz
120 cpu_clocks = 7987248;
121 pit_clock_8mhz = true;
123 #elif defined(_PC9801RA) || defined(_PC98RL)
124 if(config.cpu_type != 0) {
126 cpu_clocks = 15974496;
127 pit_clock_8mhz = true;
130 int pit_clocks = pit_clock_8mhz ? 1996812 : 2457600;
132 sound_type = config.sound_type;
135 first_device = last_device = NULL;
136 dummy = new DEVICE(this, emu); // must be 1st device
137 event = new EVENT(this, emu); // must be 2nd device
139 #if defined(SUPPORT_OLD_BUZZER)
140 beep = new BEEP(this, emu);
142 beep = new PCM1BIT(this, emu);
144 dma = new I8237(this, emu);
145 #if defined(SUPPORT_CMT_IF)
146 sio_cmt = new I8251(this, emu); // for cmt
147 sio_cmt->set_device_name(_T("8251 SIO (CMT)"));
149 sio_rs = new I8251(this, emu); // for rs232c
150 sio_rs->set_device_name(_T("8251 SIO (RS-232C)"));
151 sio_kbd = new I8251(this, emu); // for keyboard
152 sio_kbd->set_device_name(_T("8251 SIO (Keyboard)"));
153 pit = new I8253(this, emu);
154 #if defined(SUPPORT_320KB_FDD_IF)
155 pio_fdd = new I8255(this, emu); // for 320kb fdd i/f
156 pio_fdd->set_device_name(_T("8255 PIO (320KB I/F)"));
158 pio_mouse = new I8255(this, emu); // for mouse
159 pio_mouse->set_device_name(_T("8255 PIO (Mouse)"));
160 pio_sys = new I8255(this, emu); // for system port
161 pio_sys->set_device_name(_T("8255 PIO (System)"));
162 pio_prn = new I8255(this, emu); // for printer
163 pio_prn->set_device_name(_T("8255 PIO (Printer)"));
164 pic = new I8259(this, emu);
165 #if defined(HAS_I386) || defined(HAS_I486)
166 cpu = new I386(this, emu); // 80386, 80486
167 #elif defined(HAS_I86) || defined(HAS_V30)
168 cpu = new I286(this, emu);// 8086, V30, 80286
170 cpu = new I286(this, emu);
173 cpu->set_device_name(_T("CPU(i8086)"));
174 #elif defined(HAS_I386)
175 cpu->set_device_name(_T("CPU(i386)"));
176 #elif defined(HAS_I486)
177 cpu->set_device_name(_T("CPU(i486)"));
178 #elif defined(HAS_PENTIUM)
179 cpu->set_device_name(_T("CPU(Pentium)"));
180 #elif defined(HAS_V33A)
181 cpu->set_device_name(_T("CPU(V33A)"));
182 #elif defined(HAS_V30)
183 cpu->set_device_name(_T("CPU(V30)"));
185 cpu->set_device_name(_T("CPU(i286)"));
187 io = new IO(this, emu);
188 rtcreg = new LS244(this, emu);
189 rtcreg->set_device_name(_T("74LS244 (RTC)"));
190 //memory = new MEMORY(this, emu);
191 memory = new MEMBUS(this, emu);
192 not_busy = new NOT(this, emu);
193 not_busy->set_device_name(_T("NOT Gate (Printer Busy)"));
194 #if defined(HAS_I86) || defined(HAS_V30)
195 not_prn = new NOT(this, emu);
196 not_prn->set_device_name(_T("NOT Gate (Printer IRQ)"));
198 rtc = new UPD1990A(this, emu);
199 #if defined(SUPPORT_2HD_FDD_IF)
200 fdc_2hd = new UPD765A(this, emu);
201 fdc_2hd->set_device_name(_T("uPD765A FDC (2HD I/F)"));
203 #if defined(SUPPORT_2DD_FDD_IF)
204 fdc_2dd = new UPD765A(this, emu);
205 fdc_2dd->set_device_name(_T("uPD765A FDC (2DD I/F)"));
207 #if defined(SUPPORT_2HD_2DD_FDD_IF)
208 fdc = new UPD765A(this, emu);
209 fdc->set_device_name(_T("uPD765A FDC (2HD/2DD I/F)"));
211 noise_seek = new NOISE(this, emu);
212 noise_head_down = new NOISE(this, emu);
213 noise_head_up = new NOISE(this, emu);
214 gdc_chr = new UPD7220(this, emu);
215 gdc_chr->set_device_name(_T("uPD7220 GDC (Character)"));
216 gdc_gfx = new UPD7220(this, emu);
217 gdc_gfx->set_device_name(_T("uPD7220 GDC (Graphics)"));
219 if(sound_type == 0 || sound_type == 1) {
220 opn = new YM2203(this, emu);
221 #ifdef SUPPORT_PC98_OPNA
222 opn->is_ym2608 = true;
224 fmsound = new FMSOUND(this, emu);
225 joystick = new JOYSTICK(this, emu);
226 } else if(sound_type == 2 || sound_type == 3) {
227 tms3631 = new TMS3631(this, emu);
228 tms3631->set_device_name(_T("TMS3631 SSG (PC-9801-14)"));
229 pit_14 = new I8253(this, emu);
230 pit_14->set_device_name(_T("8253 PIT (PC-9801-14)"));
231 pio_14 = new I8255(this, emu);
232 pio_14->set_device_name(_T("8255 PIO (PC-9801-14)"));
233 maskreg_14 = new LS244(this, emu);
234 maskreg_14->set_device_name(_T("74LS244 (PC-9801-14)"));
236 if(config.printer_type == 0) {
237 printer = new PRNFILE(this, emu);
238 // } else if(config.printer_type == 1) {
239 // printer = new PCPR201(this, emu);
244 #if defined(SUPPORT_CMT_IF)
245 cmt = new CMT(this, emu);
247 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
248 cpureg = new CPUREG(this, emu);
250 display = new DISPLAY(this, emu);
251 dmareg = new DMAREG(this, emu);
252 floppy = new FLOPPY(this, emu);
253 keyboard = new KEYBOARD(this, emu);
254 mouse = new MOUSE(this, emu);
255 #if defined(SUPPORT_SASI_IF)
256 sasi = new SASI(this, emu);
258 #if defined(SUPPORT_SCSI_IF)
259 scsi = new SCSI(this, emu);
261 #if defined(SUPPORT_IDE_IF)
262 ide = new IDE(this, emu);
265 #if defined(SUPPORT_320KB_FDD_IF)
267 pio_sub = new I8255(this, emu);
268 pio_sub->set_device_name(_T("8255 PIO (320KB FDD)"));
269 pc80s31k = new PC80S31K(this, emu);
270 pc80s31k->set_device_name(_T("PC-80S31K (320KB FDD)"));
271 fdc_sub = new UPD765A(this, emu);
272 fdc_sub->set_device_name(_T("uPD765A FDC (320KB FDD)"));
273 cpu_sub = new Z80(this, emu);
274 cpu_sub->set_device_name(_T("Z80 CPU (320KB FDD)"));
286 9 (INT3) PC-9801-27 (SASI), PC-9801-55 (SCSI), or IDE
287 10 (INT41) FDC (640KB I/F)
288 11 (INT42) FDC (1MB I/F)
289 12 (INT5) PC-9801-26(K) or PC-9801-14
296 event->set_context_cpu(cpu, cpu_clocks);
297 #if defined(SUPPORT_320KB_FDD_IF)
298 event->set_context_cpu(cpu_sub, 4000000);
300 event->set_context_sound(beep);
301 if(sound_type == 0 || sound_type == 1) {
302 event->set_context_sound(opn);
303 } else if(sound_type == 2 || sound_type == 3) {
304 event->set_context_sound(tms3631);
306 event->set_context_sound(noise_seek);
307 event->set_context_sound(noise_head_down);
308 event->set_context_sound(noise_head_up);
310 dma->set_context_memory(memory);
312 // dma ch.1: memory refresh
313 #if defined(SUPPORT_2HD_FDD_IF)
314 dma->set_context_ch2(fdc_2hd);
315 dma->set_context_tc2(fdc_2hd, SIG_UPD765A_TC, 1);
317 #if defined(SUPPORT_2DD_FDD_IF)
318 dma->set_context_ch3(fdc_2dd);
319 dma->set_context_tc3(fdc_2dd, SIG_UPD765A_TC, 1);
321 #if defined(SUPPORT_2HD_2DD_FDD_IF)
322 #if !defined(SUPPORT_HIRESO)
323 dma->set_context_ch2(fdc);
324 dma->set_context_ch3(fdc);
325 dma->set_context_tc2(fdc, SIG_UPD765A_TC, 1);
326 dma->set_context_tc3(fdc, SIG_UPD765A_TC, 1);
328 dma->set_context_ch1(fdc);
329 dma->set_context_tc1(fdc, SIG_UPD765A_TC, 1);
332 // sio_rs->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR4, 1);
333 sio_kbd->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR1, 1);
334 pit->set_context_ch0(pic, SIG_I8259_CHIP0 | SIG_I8259_IR0, 1);
335 #if defined(SUPPORT_OLD_BUZZER)
336 // pit ch.1: memory refresh
339 pit->set_context_ch1(beep, SIG_PCM1BIT_SIGNAL, 1);
342 pit->set_constant_clock(0, pit_clocks);
343 pit->set_constant_clock(1, pit_clocks);
344 pit->set_constant_clock(2, pit_clocks);
345 pio_mouse->set_context_port_c(mouse, SIG_MOUSE_PORT_C, 0xf0, 0);
346 #if defined(SUPPORT_HIRESO)
347 // sysport port.c bit7,5: sysport port.b bit4,3
348 pio_sys->set_context_port_c(pio_sys, SIG_I8255_PORT_B, 0x80, -3); // SHUT0
349 pio_sys->set_context_port_c(pio_sys, SIG_I8255_PORT_B, 0x20, -2); // SHUT1
351 // sysport port.c bit6: printer strobe
352 #if defined(SUPPORT_OLD_BUZZER)
353 pio_sys->set_context_port_c(beep, SIG_BEEP_MUTE, 0x08, 0);
355 pio_sys->set_context_port_c(beep, SIG_PCM1BIT_MUTE, 0x08, 0);
357 // sysport port.c bit2: enable txrdy interrupt
358 // sysport port.c bit1: enable txempty interrupt
359 // sysport port.c bit0: enable rxrdy interrupt
360 pio_prn->set_context_port_a(printer, SIG_PRINTER_DATA, 0xff, 0);
361 pio_prn->set_context_port_c(printer, SIG_PRINTER_STROBE, 0x80, 0);
362 if(config.printer_type == 0) {
363 PRNFILE *prnfile = (PRNFILE *)printer;
364 prnfile->set_context_busy(not_busy, SIG_NOT_INPUT, 1);
365 // } else if(config.printer_type == 1) {
366 // PRNFILE *pcpr201 = (PCPR201 *)printer;
367 // pcpr201->set_context_busy(not_busy, SIG_NOT_INPUT, 1);
369 not_busy->set_context_out(pio_prn, SIG_I8255_PORT_B, 4);
370 #if defined(HAS_I86) || defined(HAS_V30)
371 pio_prn->set_context_port_c(not_prn, SIG_NOT_INPUT, 8, 0);
372 not_prn->set_context_out(pic, SIG_I8259_CHIP1 | SIG_I8259_IR0, 1);
374 rtcreg->set_context_output(rtc, SIG_UPD1990A_CMD, 0x07, 0);
375 rtcreg->set_context_output(rtc, SIG_UPD1990A_DIN, 0x20, 0);
376 rtcreg->set_context_output(rtc, SIG_UPD1990A_STB, 0x08, 0);
377 rtcreg->set_context_output(rtc, SIG_UPD1990A_CLK, 0x10, 0);
378 pic->set_context_cpu(cpu);
379 rtc->set_context_dout(pio_sys, SIG_I8255_PORT_B, 1);
381 if(sound_type == 0 || sound_type == 1) {
382 opn->set_context_irq(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1);
383 opn->set_context_port_b(joystick, SIG_JOYSTICK_SELECT, 0xc0, 0);
384 fmsound->set_context_opn(opn);
385 joystick->set_context_opn(opn);
386 } else if(sound_type == 2 || sound_type == 3) {
387 pio_14->set_context_port_a(tms3631, SIG_TMS3631_ENVELOP1, 0xff, 0);
388 pio_14->set_context_port_b(tms3631, SIG_TMS3631_ENVELOP2, 0xff, 0);
389 pio_14->set_context_port_c(tms3631, SIG_TMS3631_DATAREG, 0xff, 0);
390 maskreg_14->set_context_output(tms3631, SIG_TMS3631_MASKREG, 0xff, 0);
391 pit_14->set_constant_clock(2, 1996800 / 8);
392 pit_14->set_context_ch2(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1);
395 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
396 cpureg->set_context_cpu(cpu);
398 display->set_context_pic(pic);
399 display->set_context_gdc_chr(gdc_chr, gdc_chr->get_ra());
400 display->set_context_gdc_gfx(gdc_gfx, gdc_gfx->get_ra(), gdc_gfx->get_cs());
401 dmareg->set_context_dma(dma);
402 keyboard->set_context_sio(sio_kbd);
403 memory->set_context_display(display);
404 mouse->set_context_pic(pic);
405 mouse->set_context_pio(pio_mouse);
407 #if defined(SUPPORT_2HD_FDD_IF)
408 fdc_2hd->set_context_irq(floppy, SIG_FLOPPY_2HD_IRQ, 1);
409 fdc_2hd->set_context_drq(floppy, SIG_FLOPPY_2HD_DRQ, 1);
410 fdc_2hd->set_context_noise_seek(noise_seek);
411 fdc_2hd->set_context_noise_head_down(noise_head_down);
412 fdc_2hd->set_context_noise_head_up(noise_head_up);
413 fdc_2hd->raise_irq_when_media_changed = true;
414 floppy->set_context_fdc_2hd(fdc_2hd);
416 #if defined(SUPPORT_2DD_FDD_IF)
417 fdc_2dd->set_context_irq(floppy, SIG_FLOPPY_2DD_IRQ, 1);
418 fdc_2dd->set_context_drq(floppy, SIG_FLOPPY_2DD_DRQ, 1);
419 fdc_2dd->set_context_noise_seek(noise_seek);
420 fdc_2dd->set_context_noise_head_down(noise_head_down);
421 fdc_2dd->set_context_noise_head_up(noise_head_up);
422 fdc_2dd->raise_irq_when_media_changed = true;
423 floppy->set_context_fdc_2dd(fdc_2dd);
425 #if defined(SUPPORT_2HD_2DD_FDD_IF)
426 fdc->set_context_irq(floppy, SIG_FLOPPY_IRQ, 1);
427 fdc->set_context_drq(floppy, SIG_FLOPPY_DRQ, 1);
428 fdc->set_context_noise_seek(noise_seek);
429 fdc->set_context_noise_head_down(noise_head_down);
430 fdc->set_context_noise_head_up(noise_head_up);
431 fdc->raise_irq_when_media_changed = true;
432 floppy->set_context_fdc(fdc);
434 floppy->set_context_dma(dma);
435 floppy->set_context_pic(pic);
437 #if defined(SUPPORT_SASI_IF)
438 sasi->set_context_dma(dma);
439 sasi->set_context_pic(pic);
440 dma->set_context_ch0(sasi);
442 #if defined(SUPPORT_SCSI_IF)
443 scsi->set_context_dma(dma);
444 scsi->set_context_pic(pic);
445 dma->set_context_ch0(scsi);
447 #if defined(SUPPORT_IDE_IF)
448 ide->set_context_dma(dma);
449 ide->set_context_pic(pic);
450 dma->set_context_ch0(ide);
453 #if defined(SUPPORT_CMT_IF)
454 sio_cmt->set_context_out(cmt, SIG_CMT_OUT);
455 // sio_cmt->set_context_txrdy(cmt, SIG_CMT_TXRDY, 1);
456 // sio_cmt->set_context_rxrdy(cmt, SIG_CMT_RXRDY, 1);
457 // sio_cmt->set_context_txe(cmt, SIG_CMT_TXEMP, 1);
458 cmt->set_context_sio(sio_cmt);
462 cpu->set_context_mem(memory);
463 cpu->set_context_io(io);
464 cpu->set_context_intr(pic);
465 #ifdef SINGLE_MODE_DMA
466 cpu->set_context_dma(dma);
469 cpu->set_context_debugger(new DEBUGGER(this, emu));
472 #if defined(SUPPORT_320KB_FDD_IF)
474 pc80s31k->set_context_cpu(cpu_sub);
475 pc80s31k->set_context_fdc(fdc_sub);
476 pc80s31k->set_context_pio(pio_sub);
477 pio_fdd->set_context_port_a(pio_sub, SIG_I8255_PORT_A, 0xff, 0);
478 pio_fdd->set_context_port_b(pio_sub, SIG_I8255_PORT_A, 0xff, 0);
479 pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0x0f, 4);
480 pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0xf0, -4);
481 pio_fdd->clear_ports_by_cmdreg = true;
482 pio_sub->set_context_port_a(pio_fdd, SIG_I8255_PORT_B, 0xff, 0);
483 pio_sub->set_context_port_b(pio_fdd, SIG_I8255_PORT_A, 0xff, 0);
484 pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0x0f, 4);
485 pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0xf0, -4);
486 pio_sub->clear_ports_by_cmdreg = true;
487 fdc_sub->set_context_irq(cpu_sub, SIG_CPU_IRQ, 1);
488 fdc_sub->set_context_noise_seek(noise_seek);
489 fdc_sub->set_context_noise_head_down(noise_head_down);
490 fdc_sub->set_context_noise_head_up(noise_head_up);
491 cpu_sub->set_context_mem(pc80s31k);
492 cpu_sub->set_context_io(pc80s31k);
493 cpu_sub->set_context_intr(pc80s31k);
495 cpu_sub->set_context_debugger(new DEBUGGER(this, emu));
500 io->set_iomap_alias_rw(0x0000, pic, 0);
501 io->set_iomap_alias_rw(0x0002, pic, 1);
502 io->set_iomap_alias_rw(0x0008, pic, 2);
503 io->set_iomap_alias_rw(0x000a, pic, 3);
505 io->set_iomap_alias_rw(0x0001, dma, 0x00);
506 io->set_iomap_alias_rw(0x0003, dma, 0x01);
507 io->set_iomap_alias_rw(0x0005, dma, 0x02);
508 io->set_iomap_alias_rw(0x0007, dma, 0x03);
509 io->set_iomap_alias_rw(0x0009, dma, 0x04);
510 io->set_iomap_alias_rw(0x000b, dma, 0x05);
511 io->set_iomap_alias_rw(0x000d, dma, 0x06);
512 io->set_iomap_alias_rw(0x000f, dma, 0x07);
513 io->set_iomap_alias_rw(0x0011, dma, 0x08);
514 io->set_iomap_alias_w (0x0013, dma, 0x09);
515 io->set_iomap_alias_w (0x0015, dma, 0x0a);
516 io->set_iomap_alias_w (0x0017, dma, 0x0b);
517 io->set_iomap_alias_w (0x0019, dma, 0x0c);
518 io->set_iomap_alias_rw(0x001b, dma, 0x0d);
519 io->set_iomap_alias_w (0x001d, dma, 0x0e);
520 io->set_iomap_alias_w (0x001f, dma, 0x0f);
521 io->set_iomap_single_w(0x0021, dmareg);
522 io->set_iomap_single_w(0x0023, dmareg);
523 io->set_iomap_single_w(0x0025, dmareg);
524 io->set_iomap_single_w(0x0027, dmareg);
525 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
526 io->set_iomap_single_w(0x0029, dmareg);
528 #if defined(SUPPORT_32BIT_ADDRESS)
529 io->set_iomap_single_w(0x0e05, dmareg);
530 io->set_iomap_single_w(0x0e07, dmareg);
531 io->set_iomap_single_w(0x0e09, dmareg);
532 io->set_iomap_single_w(0x0e0b, dmareg);
535 io->set_iomap_single_w(0x0020, rtcreg);
537 io->set_iomap_alias_rw(0x0030, sio_rs, 0);
538 io->set_iomap_alias_rw(0x0032, sio_rs, 1);
540 io->set_iomap_alias_rw(0x0031, pio_sys, 0);
541 io->set_iomap_alias_rw(0x0033, pio_sys, 1);
542 io->set_iomap_alias_rw(0x0035, pio_sys, 2);
543 io->set_iomap_alias_w (0x0037, pio_sys, 3);
545 io->set_iomap_alias_rw(0x0040, pio_prn, 0);
546 io->set_iomap_alias_rw(0x0042, pio_prn, 1);
547 io->set_iomap_alias_rw(0x0044, pio_prn, 2);
548 io->set_iomap_alias_w (0x0046, pio_prn, 3);
550 io->set_iomap_alias_rw(0x0041, sio_kbd, 0);
551 io->set_iomap_alias_rw(0x0043, sio_kbd, 1);
553 #if !defined(_PC9801U)
554 io->set_iomap_single_w(0x0050, dummy); // NMI disabled
555 io->set_iomap_single_w(0x0052, dummy); // NMI enabled
558 #if defined(SUPPORT_320KB_FDD_IF)
559 io->set_iomap_alias_rw(0x0051, pio_fdd, 0);
560 io->set_iomap_alias_rw(0x0053, pio_fdd, 1);
561 io->set_iomap_alias_rw(0x0055, pio_fdd, 2);
562 io->set_iomap_alias_w (0x0057, pio_fdd, 3);
565 io->set_iomap_alias_rw(0x0060, gdc_chr, 0);
566 io->set_iomap_alias_rw(0x0062, gdc_chr, 1);
568 io->set_iomap_single_w(0x64, display);
569 io->set_iomap_single_w(0x68, display);
570 #if defined(SUPPORT_16_COLORS)
571 io->set_iomap_single_w(0x6a, display);
573 io->set_iomap_single_w(0x6c, display);
574 io->set_iomap_single_w(0x6e, display);
576 io->set_iomap_single_w(0x70, display);
577 io->set_iomap_single_w(0x72, display);
578 io->set_iomap_single_w(0x74, display);
579 io->set_iomap_single_w(0x76, display);
580 io->set_iomap_single_w(0x78, display);
581 io->set_iomap_single_w(0x7a, display);
582 #if defined(SUPPORT_GRCG)
583 #if !defined(SUPPORT_HIRESO)
584 io->set_iomap_single_w(0x007c, display);
585 io->set_iomap_single_w(0x007e, display);
587 io->set_iomap_single_w(0x00a4, display);
588 io->set_iomap_single_w(0x00a6, display);
592 #if defined(SUPPORT_SASI_IF)
593 io->set_iomap_single_rw(0x0080, sasi);
594 io->set_iomap_single_rw(0x0082, sasi);
596 #if defined(SUPPORT_SCSI_IF)
597 io->set_iomap_single_rw(0x0cc0, scsi);
598 io->set_iomap_single_rw(0x0cc2, scsi);
599 io->set_iomap_single_rw(0x0cc4, scsi);
601 #if defined(SUPPORT_IDE_IF)
602 io->set_iomap_single_rw(0x0640, ide);
603 io->set_iomap_single_rw(0x0642, ide);
604 io->set_iomap_single_rw(0x0644, ide);
605 io->set_iomap_single_rw(0x0646, ide);
606 io->set_iomap_single_rw(0x0648, ide);
607 io->set_iomap_single_rw(0x064a, ide);
608 io->set_iomap_single_rw(0x064c, ide);
609 io->set_iomap_single_rw(0x064e, ide);
610 io->set_iomap_single_rw(0x074c, ide);
611 io->set_iomap_single_rw(0x074e, ide);
614 io->set_iomap_alias_rw(0x00a0, gdc_gfx, 0);
615 io->set_iomap_alias_rw(0x00a2, gdc_gfx, 1);
617 #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
618 io->set_iomap_single_rw(0x00a4, display);
619 io->set_iomap_single_rw(0x00a6, display);
621 io->set_iomap_single_rw(0xa8, display);
622 io->set_iomap_single_rw(0xaa, display);
623 io->set_iomap_single_rw(0xac, display);
624 io->set_iomap_single_rw(0xae, display);
626 // io->set_iomap_single_w(0xa1, display);
627 // io->set_iomap_single_w(0xa3, display);
628 // io->set_iomap_single_w(0xa5, display);
629 io->set_iomap_single_rw(0xa1, display);
630 io->set_iomap_single_rw(0xa3, display);
631 io->set_iomap_single_rw(0xa5, display);
632 io->set_iomap_single_rw(0xa9, display);
633 #if defined(SUPPORT_EGC)
634 io->set_iomap_range_rw(0x04a0, 0x04af, display);
637 io->set_iomap_alias_rw(0x0071, pit, 0);
638 io->set_iomap_alias_rw(0x0073, pit, 1);
639 io->set_iomap_alias_rw(0x0075, pit, 2);
640 io->set_iomap_alias_w (0x0077, pit, 3);
644 io->set_iomap_single_rw(0x0090, floppy);
645 io->set_iomap_single_rw(0x0092, floppy);
646 io->set_iomap_single_rw(0x0094, floppy);
647 #if defined(SUPPORT_2HD_2DD_FDD_IF)
648 #if !defined(SUPPORT_HIRESO)
649 io->set_iomap_single_rw(0x00be, floppy);
651 io->set_iomap_single_w (0x00be, floppy);
654 #if !defined(SUPPORT_HIRESO)
655 io->set_iomap_single_rw(0x00c8, floppy);
656 io->set_iomap_single_rw(0x00ca, floppy);
657 io->set_iomap_single_rw(0x00cc, floppy);
660 #if defined(SUPPORT_CMT_IF)
661 io->set_iomap_alias_rw(0x0091, sio_cmt, 0);
662 io->set_iomap_alias_rw(0x0093, sio_cmt, 1);
663 io->set_iomap_single_w(0x0095, cmt);
664 io->set_iomap_single_w(0x0097, cmt);
667 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
668 io->set_iomap_single_rw(0x00f0, cpureg);
669 io->set_iomap_single_rw(0x00f2, cpureg);
671 #if defined(SUPPORT_32BIT_ADDRESS)
672 io->set_iomap_single_rw(0x00f6, cpureg);
675 if(sound_type == 0 || sound_type == 1) {
676 io->set_iomap_single_rw(0x0188, fmsound);
677 io->set_iomap_single_rw(0x018a, fmsound);
678 #ifdef SUPPORT_PC98_OPNA
679 io->set_iomap_single_rw(0x018c, fmsound);
680 io->set_iomap_single_rw(0x018e, fmsound);
681 io->set_iomap_single_rw(0xa460, fmsound);
683 } else if(sound_type == 2 || sound_type == 3) {
684 io->set_iomap_alias_rw(0x0088, pio_14, 0);
685 io->set_iomap_alias_rw(0x008a, pio_14, 1);
686 io->set_iomap_alias_rw(0x008c, pio_14, 2);
687 io->set_iomap_alias_w(0x008e, pio_14, 3);
688 io->set_iovalue_single_r(0x008e, 0x08);
689 io->set_iomap_single_w(0x0188, maskreg_14);
690 io->set_iomap_single_w(0x018a, maskreg_14);
691 io->set_iomap_alias_rw(0x018c, pit_14, 2);
692 io->set_iomap_alias_w(0x018e, pit_14, 3);
693 // io->set_iovalue_single_r(0x018e, 0x00); // INT0
694 // io->set_iovalue_single_r(0x018e, 0x40); // INT41
695 io->set_iovalue_single_r(0x018e, 0x80); // INT5
696 // io->set_iovalue_single_r(0x018e, 0xc0); // INT6
699 #if defined(SUPPORT_ITF_ROM)
700 io->set_iomap_single_w(0x043d, memory);
702 #if !defined(SUPPORT_HIRESO)
703 io->set_iomap_single_w(0x043f, memory);
705 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
706 io->set_iomap_single_rw(0x0439, memory);
707 #if !defined(SUPPORT_HIRESO)
708 io->set_iomap_single_rw(0x0461, memory);
709 io->set_iomap_single_rw(0x0463, memory);
711 io->set_iomap_single_rw(0x0091, memory);
712 io->set_iomap_single_rw(0x0093, memory);
714 io->set_iomap_single_r(0x0567, memory);
716 #if defined(SUPPORT_32BIT_ADDRESS)
717 io->set_iomap_single_w(0x053d, memory);
720 #if !(defined(_PC9801) || defined(_PC9801E) || defined(SUPPORT_HIRESO))
721 io->set_iomap_alias_rw(0x3fd9, pit, 0);
722 io->set_iomap_alias_rw(0x3fdb, pit, 1);
723 io->set_iomap_alias_rw(0x3fdd, pit, 2);
724 io->set_iomap_alias_w (0x3fdf, pit, 3);
727 #if !defined(SUPPORT_HIRESO)
728 io->set_iomap_alias_rw(0x7fd9, pio_mouse, 0);
729 io->set_iomap_alias_rw(0x7fdb, pio_mouse, 1);
730 io->set_iomap_alias_rw(0x7fdd, pio_mouse, 2);
731 io->set_iomap_alias_w (0x7fdf, pio_mouse, 3);
733 io->set_iomap_alias_rw(0x0061, pio_mouse, 0);
734 io->set_iomap_alias_rw(0x0063, pio_mouse, 1);
735 io->set_iomap_alias_rw(0x0065, pio_mouse, 2);
736 io->set_iomap_alias_rw(0x0067, pio_mouse, 3);
738 #if !(defined(_PC9801) || defined(_PC9801E) || defined(SUPPORT_HIRESO))
739 io->set_iomap_single_rw(0xbfdb, mouse);
742 #if defined(_PC98DO) || defined(_PC98DOPLUS)
743 pc88event = new EVENT(this, emu);
744 pc88event->set_device_name(_T("Event Manager (PC-8801)"));
745 pc88event->set_frames_per_sec(60);
746 pc88event->set_lines_per_frame(260);
748 pc88 = new PC88(this, emu);
749 pc88->set_context_event_manager(pc88event);
750 pc88sio = new I8251(this, emu);
751 pc88sio->set_device_name(_T("8251 SIO (PC-8801)"));
752 pc88sio->set_context_event_manager(pc88event);
753 pc88pio = new I8255(this, emu);
754 pc88pio->set_device_name(_T("8255 PIO (PC-8801)"));
755 pc88pio->set_context_event_manager(pc88event);
756 pc88pcm = new PCM1BIT(this, emu);
757 pc88pcm->set_device_name(_T("1-Bit PCM Sound (PC-8801)"));
758 pc88pcm->set_context_event_manager(pc88event);
759 pc88rtc = new UPD1990A(this, emu);
760 pc88rtc->set_device_name(_T("uPD1990A RTC (PC-8801)"));
761 pc88rtc->set_context_event_manager(pc88event);
762 pc88opn = new YM2203(this, emu);
763 #ifdef SUPPORT_PC88_OPNA
764 pc88opn->set_device_name(_T("YM2608 OPNA (PC-8801)"));
765 pc88opn->is_ym2608 = true;
767 pc88opn->set_device_name(_T("YM2203 OPN (PC-8801)"));
769 pc88opn->set_context_event_manager(pc88event);
770 pc88cpu = new Z80(this, emu);
771 pc88cpu->set_device_name(_T("Z80 CPU (PC-8801)"));
772 pc88cpu->set_context_event_manager(pc88event);
774 if(config.printer_type == 0) {
775 pc88prn = new PRNFILE(this, emu);
776 pc88prn->set_context_event_manager(pc88event);
777 // } else if(config.printer_type == 1) {
778 // pc88prn = new PCPR201(this, emu);
779 // pc88prn->set_context_event_manager(pc88event);
784 pc88sub = new PC80S31K(this, emu);
785 pc88sub->set_device_name(_T("PC-80S31K (PC-8801 Sub)"));
786 pc88sub->set_context_event_manager(pc88event);
787 pc88pio_sub = new I8255(this, emu);
788 pc88pio_sub->set_device_name(_T("8255 PIO (PC-8801 Sub)"));
789 pc88pio_sub->set_context_event_manager(pc88event);
790 pc88fdc_sub = new UPD765A(this, emu);
791 pc88fdc_sub->set_device_name(_T("uPD765A FDC (PC-8801 Sub)"));
792 pc88fdc_sub->set_context_event_manager(pc88event);
793 pc88noise_seek = new NOISE(this, emu);
794 pc88noise_seek->set_context_event_manager(pc88event);
795 pc88noise_head_down = new NOISE(this, emu);
796 pc88noise_head_down->set_context_event_manager(pc88event);
797 pc88noise_head_up = new NOISE(this, emu);
798 pc88noise_head_up->set_context_event_manager(pc88event);
799 pc88cpu_sub = new Z80(this, emu);
800 pc88cpu_sub->set_device_name(_T("Z80 CPU (PC-8801 Sub)"));
801 pc88cpu_sub->set_context_event_manager(pc88event);
803 pc88event->set_context_cpu(pc88cpu, (config.cpu_type == 1) ? 3993624 : 7987248);
804 pc88event->set_context_cpu(pc88cpu_sub, 3993624);
805 pc88event->set_context_sound(pc88opn);
806 pc88event->set_context_sound(pc88pcm);
807 pc88event->set_context_sound(pc88noise_seek);
808 pc88event->set_context_sound(pc88noise_head_down);
809 pc88event->set_context_sound(pc88noise_head_up);
811 pc88->set_context_cpu(pc88cpu);
812 pc88->set_context_opn(pc88opn);
813 pc88->set_context_pcm(pc88pcm);
814 pc88->set_context_pio(pc88pio);
815 pc88->set_context_prn(pc88prn);
816 pc88->set_context_rtc(pc88rtc);
817 pc88->set_context_sio(pc88sio);
818 pc88cpu->set_context_mem(pc88);
819 pc88cpu->set_context_io(pc88);
820 pc88cpu->set_context_intr(pc88);
822 pc88cpu->set_context_debugger(new DEBUGGER(this, emu));
824 pc88opn->set_context_irq(pc88, SIG_PC88_SOUND_IRQ, 1);
825 pc88sio->set_context_rxrdy(pc88, SIG_PC88_USART_IRQ, 1);
826 pc88sio->set_context_out(pc88, SIG_PC88_USART_OUT);
828 pc88sub->set_context_cpu(pc88cpu_sub);
829 pc88sub->set_context_fdc(pc88fdc_sub);
830 pc88sub->set_context_pio(pc88pio_sub);
831 pc88pio->set_context_port_a(pc88pio_sub, SIG_I8255_PORT_B, 0xff, 0);
832 pc88pio->set_context_port_b(pc88pio_sub, SIG_I8255_PORT_A, 0xff, 0);
833 pc88pio->set_context_port_c(pc88pio_sub, SIG_I8255_PORT_C, 0x0f, 4);
834 pc88pio->set_context_port_c(pc88pio_sub, SIG_I8255_PORT_C, 0xf0, -4);
835 pc88pio->clear_ports_by_cmdreg = true;
836 pc88pio_sub->set_context_port_a(pc88pio, SIG_I8255_PORT_B, 0xff, 0);
837 pc88pio_sub->set_context_port_b(pc88pio, SIG_I8255_PORT_A, 0xff, 0);
838 pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0x0f, 4);
839 pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0xf0, -4);
840 pc88pio_sub->clear_ports_by_cmdreg = true;
841 pc88fdc_sub->set_context_irq(pc88cpu_sub, SIG_CPU_IRQ, 1);
842 pc88fdc_sub->set_context_noise_seek(pc88noise_seek);
843 pc88fdc_sub->set_context_noise_head_down(pc88noise_head_down);
844 pc88fdc_sub->set_context_noise_head_up(pc88noise_head_up);
845 pc88cpu_sub->set_context_mem(pc88sub);
846 pc88cpu_sub->set_context_io(pc88sub);
847 pc88cpu_sub->set_context_intr(pc88sub);
849 pc88cpu_sub->set_context_debugger(new DEBUGGER(this, emu));
853 // initialize all devices
854 for(DEVICE* device = first_device; device; device = device->next_device) {
855 device->initialize();
857 #if defined(_PC9801) || defined(_PC9801E)
858 fdc_2hd->get_disk_handler(0)->drive_num = 0;
859 fdc_2hd->get_disk_handler(1)->drive_num = 1;
860 fdc_2dd->get_disk_handler(0)->drive_num = 2;
861 fdc_2dd->get_disk_handler(1)->drive_num = 3;
862 fdc_sub->get_disk_handler(0)->drive_num = 4;
863 fdc_sub->get_disk_handler(1)->drive_num = 5;
864 #elif defined(_PC9801VF) || defined(_PC9801U)
865 fdc_2dd->get_disk_handler(0)->drive_num = 0;
866 fdc_2dd->get_disk_handler(1)->drive_num = 1;
867 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
868 fdc->get_disk_handler(0)->drive_num = 0;
869 fdc->get_disk_handler(1)->drive_num = 1;
870 pc88fdc_sub->get_disk_handler(0)->drive_num = 2;
871 pc88fdc_sub->get_disk_handler(1)->drive_num = 3;
873 fdc->get_disk_handler(0)->drive_num = 0;
874 fdc->get_disk_handler(1)->drive_num = 1;
880 // delete all devices
881 for(DEVICE* device = first_device; device;) {
882 DEVICE *next_device = device->next_device;
885 device = next_device;
889 DEVICE* VM::get_device(int id)
891 for(DEVICE* device = first_device; device; device = device->next_device) {
892 if(device->this_device_id == id) {
899 // ----------------------------------------------------------------------------
900 // drive virtual machine
901 // ----------------------------------------------------------------------------
906 for(DEVICE* device = first_device; device; device = device->next_device) {
909 #if defined(_PC98DO) || defined(_PC98DOPLUS)
910 for(DEVICE* device = first_device; device; device = device->next_device) {
915 // initial device settings
916 pio_mouse->write_signal(SIG_I8255_PORT_A, 0xf0, 0xff); // clear mouse status
917 pio_mouse->write_signal(SIG_I8255_PORT_B, 0x40, 0xff); // cpu high & sw3-6
918 uint8_t port_c = 0x08; // normal mode & sw1-5 & sw1-6
919 #if defined(HAS_V30) || defined(HAS_V33)
920 port_c |= 0x04; // V30
922 pio_mouse->write_signal(SIG_I8255_PORT_C, 0x40, 0xff);
924 pio_sys->write_signal(SIG_I8255_PORT_A, 0xe3, 0xff);
925 pio_sys->write_signal(SIG_I8255_PORT_B, 0xf8, 0xff);//0xe8??
926 pio_sys->write_signal(SIG_I8255_PORT_C, 0xff, 0xff);
929 uint8_t prn_b = 0x00; // system type = first PC-9801
930 #elif defined(_PC9801U)
931 uint8_t prn_b = 0xc0; // system type = PC-9801U,PC-98LT,PC-98HA
933 uint8_t prn_b = 0x80; // system type = others
936 prn_b |= 0x20; // system clock is 8MHz
938 prn_b |= 0x10; // don't use LCD display
939 #if !defined(SUPPORT_16_COLORS)
940 prn_b |= 0x08; // standard graphics
942 prn_b |= 0x04; // printer is not busy
943 #if defined(HAS_V30) || defined(HAS_V33)
946 #if defined(_PC9801VF) || defined(_PC9801U)
947 prn_b |= 0x01; // PC-9801VF or PC-9801U
949 pio_prn->write_signal(SIG_I8255_PORT_B, prn_b, 0xff);
951 #if defined(SUPPORT_320KB_FDD_IF)
952 pio_fdd->write_signal(SIG_I8255_PORT_A, 0xff, 0xff);
953 pio_fdd->write_signal(SIG_I8255_PORT_B, 0xff, 0xff);
954 pio_fdd->write_signal(SIG_I8255_PORT_C, 0xff, 0xff);
956 #if defined(SUPPORT_2DD_FDD_IF)
957 fdc_2dd->write_signal(SIG_UPD765A_FREADY, 1, 1); // 2DD FDC RDY is pulluped
960 if(sound_type == 0 || sound_type == 1) {
961 // opn->write_signal(SIG_YM2203_PORT_A, 0x3f, 0xff); // PC-9801-26(K) INT0
962 // opn->write_signal(SIG_YM2203_PORT_A, 0xbf, 0xff); // PC-9801-26(K) INT41
963 opn->write_signal(SIG_YM2203_PORT_A, 0xff, 0xff); // PC-9801-26(K) INT5
964 // opn->write_signal(SIG_YM2203_PORT_A, 0x7f, 0xff); // PC-9801-26(K) INT6
967 #if defined(SUPPORT_OLD_BUZZER)
968 beep->write_signal(SIG_BEEP_ON, 1, 1);
969 beep->write_signal(SIG_BEEP_MUTE, 1, 1);
971 beep->write_signal(SIG_PCM1BIT_ON, 1, 1);
972 beep->write_signal(SIG_PCM1BIT_MUTE, 1, 1);
975 #if defined(_PC98DO) || defined(_PC98DOPLUS)
976 pc88opn->set_reg(0x29, 3); // for Misty Blue
977 pc88pio->write_signal(SIG_I8255_PORT_C, 0, 0xff);
978 pc88pio_sub->write_signal(SIG_I8255_PORT_C, 0, 0xff);
984 #if defined(_PC98DO) || defined(_PC98DOPLUS)
992 double VM::get_frame_rate()
994 #if defined(_PC98DO) || defined(_PC98DOPLUS)
995 if(config.boot_mode != 0) {
996 return pc88event->get_frame_rate();
999 return event->get_frame_rate();
1002 // ----------------------------------------------------------------------------
1004 // ----------------------------------------------------------------------------
1007 DEVICE *VM::get_cpu(int index)
1009 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1010 if(index == 0 && boot_mode == 0) {
1012 } else if(index == 1 && boot_mode != 0) {
1014 } else if(index == 2 && boot_mode != 0) {
1020 #if defined(SUPPORT_320KB_FDD_IF)
1021 } else if(index == 1) {
1030 // ----------------------------------------------------------------------------
1032 // ----------------------------------------------------------------------------
1034 void VM::draw_screen()
1036 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1037 if(boot_mode != 0) {
1038 pc88->draw_screen();
1041 display->draw_screen();
1044 // ----------------------------------------------------------------------------
1046 // ----------------------------------------------------------------------------
1048 void VM::initialize_sound(int rate, int samples)
1050 // init sound manager
1051 event->initialize_sound(rate, samples);
1054 #if defined(SUPPORT_OLD_BUZZER)
1055 beep->initialize_sound(rate, 2400, 8000);
1057 beep->initialize_sound(rate, 8000);
1059 if(sound_type == 0 || sound_type == 1) {
1061 opn->initialize_sound(rate, 7987248, samples, 0, 0);
1063 opn->initialize_sound(rate, 3993624, samples, 0, 0);
1065 } else if(sound_type == 2 || sound_type == 3) {
1066 tms3631->initialize_sound(rate, 8000);
1069 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1070 // init sound manager
1071 pc88event->initialize_sound(rate, samples);
1075 pc88opn->initialize_sound(rate, 7987248, samples, 0, 0);
1077 pc88opn->initialize_sound(rate, 3993624, samples, 0, 0);
1079 pc88pcm->initialize_sound(rate, 8000);
1083 uint16_t* VM::create_sound(int* extra_frames)
1085 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1086 if(boot_mode != 0) {
1087 return pc88event->create_sound(extra_frames);
1090 return event->create_sound(extra_frames);
1093 int VM::get_sound_buffer_ptr()
1095 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1096 if(boot_mode != 0) {
1097 return pc88event->get_sound_buffer_ptr();
1100 return event->get_sound_buffer_ptr();
1103 #ifdef USE_SOUND_VOLUME
1104 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
1107 if(sound_type == 0 || sound_type == 1) {
1108 opn->set_volume(0, decibel_l, decibel_r);
1110 } else if(ch-- == 0) {
1111 if(sound_type == 0 || sound_type == 1) {
1112 opn->set_volume(1, decibel_l, decibel_r);
1114 #if defined(SUPPORT_PC98_OPNA)
1115 } else if(ch-- == 0) {
1116 if(sound_type == 0 || sound_type == 1) {
1117 opn->set_volume(2, decibel_l, decibel_r);
1119 } else if(ch-- == 0) {
1120 if(sound_type == 0 || sound_type == 1) {
1121 opn->set_volume(3, decibel_l, decibel_r);
1124 } else if(ch-- == 0) {
1125 if(sound_type == 2 || sound_type == 3) {
1126 tms3631->set_volume(0, decibel_l, decibel_r);
1128 } else if(ch-- == 0) {
1129 beep->set_volume(0, decibel_l, decibel_r);
1130 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1131 } else if(ch-- == 0) {
1132 pc88opn->set_volume(0, decibel_l, decibel_r);
1133 } else if(ch-- == 0) {
1134 pc88opn->set_volume(1, decibel_l, decibel_r);
1135 #if defined(SUPPORT_PC88_OPNA)
1136 } else if(ch-- == 0) {
1137 pc88opn->set_volume(2, decibel_l, decibel_r);
1138 } else if(ch-- == 0) {
1139 pc88opn->set_volume(3, decibel_l, decibel_r);
1141 } else if(ch-- == 0) {
1142 pc88pcm->set_volume(0, decibel_l, decibel_r);
1144 } else if(ch-- == 0) {
1145 noise_seek->set_volume(0, decibel_l, decibel_r);
1146 noise_head_down->set_volume(0, decibel_l, decibel_r);
1147 noise_head_up->set_volume(0, decibel_l, decibel_r);
1148 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1149 pc88noise_seek->set_volume(0, decibel_l, decibel_r);
1150 pc88noise_head_down->set_volume(0, decibel_l, decibel_r);
1151 pc88noise_head_up->set_volume(0, decibel_l, decibel_r);
1157 // ----------------------------------------------------------------------------
1159 // ----------------------------------------------------------------------------
1161 void VM::key_down(int code, bool repeat)
1163 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1164 if(boot_mode != 0) {
1165 pc88->key_down(code, repeat);
1168 keyboard->key_down(code, repeat);
1171 void VM::key_up(int code)
1173 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1174 if(boot_mode != 0) {
1175 // pc88->key_up(code);
1178 keyboard->key_up(code);
1181 bool VM::get_caps_locked()
1183 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1184 if(boot_mode != 0) {
1185 return pc88->get_caps_locked();
1188 return keyboard->get_caps_locked();
1191 bool VM::get_kana_locked()
1193 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1194 if(boot_mode != 0) {
1195 return pc88->get_kana_locked();
1198 return keyboard->get_kana_locked();
1201 // ----------------------------------------------------------------------------
1203 // ----------------------------------------------------------------------------
1205 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
1207 #if defined(_PC9801) || defined(_PC9801E)
1208 if(drv == 0 || drv == 1) {
1209 fdc_2hd->open_disk(drv, file_path, bank);
1210 } else if(drv == 2 || drv == 3) {
1211 fdc_2dd->open_disk(drv - 2, file_path, bank);
1212 } else if(drv == 4 || drv == 5) {
1213 fdc_sub->open_disk(drv - 4, file_path, bank);
1215 #elif defined(_PC9801VF) || defined(_PC9801U)
1216 if(drv == 0 || drv == 1) {
1217 fdc_2dd->open_disk(drv, file_path, bank);
1219 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1220 if(drv == 0 || drv == 1) {
1221 fdc->open_disk(drv, file_path, bank);
1222 } else if(drv == 2 || drv == 3) {
1223 pc88fdc_sub->open_disk(drv - 2, file_path, bank);
1226 if(drv == 0 || drv == 1) {
1227 fdc->open_disk(drv, file_path, bank);
1232 void VM::close_floppy_disk(int drv)
1234 #if defined(_PC9801) || defined(_PC9801E)
1235 if(drv == 0 || drv == 1) {
1236 fdc_2hd->close_disk(drv);
1237 } else if(drv == 2 || drv == 3) {
1238 fdc_2dd->close_disk(drv - 2);
1239 } else if(drv == 4 || drv == 5) {
1240 fdc_sub->close_disk(drv - 4);
1242 #elif defined(_PC9801VF) || defined(_PC9801U)
1243 if(drv == 0 || drv == 1) {
1244 fdc_2dd->close_disk(drv);
1246 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1247 if(drv == 0 || drv == 1) {
1248 fdc->close_disk(drv);
1249 } else if(drv == 2 || drv == 3) {
1250 pc88fdc_sub->close_disk(drv - 2);
1253 if(drv == 0 || drv == 1) {
1254 fdc->close_disk(drv);
1259 bool VM::is_floppy_disk_inserted(int drv)
1261 #if defined(_PC9801) || defined(_PC9801E)
1262 if(drv == 0 || drv == 1) {
1263 return fdc_2hd->is_disk_inserted(drv);
1264 } else if(drv == 2 || drv == 3) {
1265 return fdc_2dd->is_disk_inserted(drv - 2);
1266 } else if(drv == 4 || drv == 5) {
1267 return fdc_sub->is_disk_inserted(drv - 4);
1269 #elif defined(_PC9801VF) || defined(_PC9801U)
1270 if(drv == 0 || drv == 1) {
1271 return fdc_2dd->is_disk_inserted(drv);
1273 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1274 if(drv == 0 || drv == 1) {
1275 return fdc->is_disk_inserted(drv);
1276 } else if(drv == 2 || drv == 3) {
1277 return pc88fdc_sub->is_disk_inserted(drv - 2);
1280 if(drv == 0 || drv == 1) {
1281 return fdc->is_disk_inserted(drv);
1287 void VM::is_floppy_disk_protected(int drv, bool value)
1289 #if defined(_PC9801) || defined(_PC9801E)
1290 if(drv == 0 || drv == 1) {
1291 fdc_2hd->is_disk_protected(drv, value);
1292 } else if(drv == 2 || drv == 3) {
1293 fdc_2dd->is_disk_protected(drv - 2, value);
1294 } else if(drv == 4 || drv == 5) {
1295 fdc_sub->is_disk_protected(drv - 4, value);
1297 #elif defined(_PC9801VF) || defined(_PC9801U)
1298 if(drv == 0 || drv == 1) {
1299 fdc_2dd->is_disk_protected(drv, value);
1301 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1302 if(drv == 0 || drv == 1) {
1303 fdc->is_disk_protected(drv, value);
1304 } else if(drv == 2 || drv == 3) {
1305 pc88fdc_sub->is_disk_protected(drv - 2, value);
1308 if(drv == 0 || drv == 1) {
1309 fdc->is_disk_protected(drv, value);
1314 bool VM::is_floppy_disk_protected(int drv)
1316 #if defined(_PC9801) || defined(_PC9801E)
1317 if(drv == 0 || drv == 1) {
1318 return fdc_2hd->is_disk_protected(drv);
1319 } else if(drv == 2 || drv == 3) {
1320 return fdc_2dd->is_disk_protected(drv - 2);
1321 } else if(drv == 4 || drv == 5) {
1322 return fdc_sub->is_disk_protected(drv - 4);
1324 #elif defined(_PC9801VF) || defined(_PC9801U)
1325 if(drv == 0 || drv == 1) {
1326 return fdc_2dd->is_disk_protected(drv);
1328 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1329 if(drv == 0 || drv == 1) {
1330 return fdc->is_disk_protected(drv);
1331 } else if(drv == 2 || drv == 3) {
1332 return pc88fdc_sub->is_disk_protected(drv - 2);
1335 if(drv == 0 || drv == 1) {
1336 return fdc->is_disk_protected(drv);
1342 uint32_t VM::is_floppy_disk_accessed()
1344 #if defined(_PC9801) || defined(_PC9801E)
1345 return (fdc_2hd->read_signal(0) & 3) | ((fdc_2dd->read_signal(0) & 3) << 2) | ((fdc_sub->read_signal(0) & 3) << 4);
1346 #elif defined(_PC9801VF) || defined(_PC9801U)
1347 return fdc_2dd->read_signal(0);
1348 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1349 if(boot_mode != 0) {
1350 return pc88fdc_sub->read_signal(0);
1352 return fdc->read_signal(0);
1355 return fdc->read_signal(0);
1359 #if defined(SUPPORT_CMT_IF) || defined(_PC98DO) || defined(_PC98DOPLUS)
1360 void VM::play_tape(int drv, const _TCHAR* file_path)
1362 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1363 pc88->play_tape(file_path);
1365 cmt->play_tape(file_path);
1369 void VM::rec_tape(int drv, const _TCHAR* file_path)
1371 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1372 pc88->rec_tape(file_path);
1374 cmt->rec_tape(file_path);
1378 void VM::close_tape(int drv)
1380 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1387 bool VM::is_tape_inserted(int drv)
1389 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1390 return pc88->is_tape_inserted();
1392 return cmt->is_tape_inserted();
1397 bool VM::is_frame_skippable()
1399 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1400 if(boot_mode != 0) {
1401 // return pc88event->is_frame_skippable();
1402 return pc88->is_frame_skippable();
1405 return event->is_frame_skippable();
1408 void VM::update_config()
1410 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1411 if(boot_mode != config.boot_mode) {
1412 // boot mode is changed !!!
1413 boot_mode = config.boot_mode;
1417 for(DEVICE* device = first_device; device; device = device->next_device) {
1418 device->update_config();
1422 #define STATE_VERSION 12
1424 void VM::save_state(FILEIO* state_fio)
1426 state_fio->FputUint32(STATE_VERSION);
1428 for(DEVICE* device = first_device; device; device = device->next_device) {
1429 const char *name = typeid(*device).name() + 6; // skip "class "
1431 state_fio->FputInt32(strlen(name));
1432 state_fio->Fwrite(name, strlen(name), 1);
1433 device->save_state(state_fio);
1435 state_fio->FputBool(pit_clock_8mhz);
1436 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1437 state_fio->FputInt32(boot_mode);
1439 state_fio->FputInt32(sound_type);
1442 bool VM::load_state(FILEIO* state_fio)
1444 if(state_fio->FgetUint32() != STATE_VERSION) {
1447 for(DEVICE* device = first_device; device; device = device->next_device) {
1448 const char *name = typeid(*device).name() + 6; // skip "class "
1450 if(!(state_fio->FgetInt32() == strlen(name) && state_fio->Fcompare(name, strlen(name)))) {
1453 if(!device->load_state(state_fio)) {
1457 pit_clock_8mhz = state_fio->FgetBool();
1458 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1459 boot_mode = state_fio->FgetInt32();
1461 sound_type = state_fio->FgetInt32();