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-98DO Emulator 'ePC-98DO'
10 Author : Takeda.Toshiya
17 #include "../../emu.h"
18 #include "../device.h"
21 #if defined(SUPPORT_OLD_BUZZER)
30 #if defined(HAS_I386) || defined(HAS_I486)
32 #elif defined(HAS_I86) || defined(HAS_V30)
39 #include "../memory.h"
42 #if !defined(SUPPORT_OLD_BUZZER)
43 #include "../pcm1bit.h"
45 //#include "../pcpr201.h"
46 #include "../prnfile.h"
47 #include "../tms3631.h"
48 #include "../upd1990a.h"
49 #include "../upd7220.h"
50 #include "../upd765a.h"
51 #include "../ym2203.h"
54 #include "../debugger.h"
57 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
69 #if defined(SUPPORT_320KB_FDD_IF)
70 #include "../pc80s31k.h"
73 #if defined(SUPPORT_CMT_IF)
77 #if defined(_PC98DO) || defined(_PC98DOPLUS)
78 #include "../pc80s31k.h"
80 #include "../pc8801/pc88.h"
83 // ----------------------------------------------------------------------------
85 // ----------------------------------------------------------------------------
87 VM::VM(EMU* parent_emu) : emu(parent_emu)
90 #if defined(_PC98DO) || defined(_PC98DOPLUS)
91 boot_mode = config.boot_mode;
93 int cpu_clocks = CPU_CLOCKS;
94 #if defined(PIT_CLOCK_8MHZ)
95 pit_clock_8mhz = true;
97 pit_clock_8mhz = false;
100 if(config.cpu_type != 0) {
102 cpu_clocks = 4992030;
103 pit_clock_8mhz = false;
105 #elif defined(_PC9801VM) || defined(_PC98DO) || defined(_PC98DOPLUS) || defined(_PC9801VX) || defined(_PC98XL)
106 if(config.cpu_type != 0) {
107 // 10MHz/16MHz -> 8MHz
108 cpu_clocks = 7987248;
109 pit_clock_8mhz = true;
111 #elif defined(_PC9801RA) || defined(_PC98RL)
112 if(config.cpu_type != 0) {
114 cpu_clocks = 15974496;
115 pit_clock_8mhz = true;
118 int pit_clocks = pit_clock_8mhz ? 1996812 : 2457600;
120 sound_type = config.sound_type;
123 first_device = last_device = NULL;
124 dummy = new DEVICE(this, emu); // must be 1st device
125 event = new EVENT(this, emu); // must be 2nd device
127 #if defined(SUPPORT_OLD_BUZZER)
128 beep = new BEEP(this, emu);
130 beep = new PCM1BIT(this, emu);
132 dma = new I8237(this, emu);
133 #if defined(SUPPORT_CMT_IF)
134 sio_cmt = new I8251(this, emu); // for cmt
135 sio_cmt->set_device_name(_T("8251 SIO (CMT)"));
137 sio_rs = new I8251(this, emu); // for rs232c
138 sio_rs->set_device_name(_T("8251 SIO (RS-232C)"));
139 sio_kbd = new I8251(this, emu); // for keyboard
140 sio_kbd->set_device_name(_T("8251 SIO (Keyboard)"));
141 pit = new I8253(this, emu);
142 #if defined(SUPPORT_320KB_FDD_IF)
143 pio_fdd = new I8255(this, emu); // for 320kb fdd i/f
144 pio_fdd->set_device_name(_T("8255 PIO (320KB I/F)"));
146 pio_mouse = new I8255(this, emu); // for mouse
147 pio_mouse->set_device_name(_T("8255 PIO (Mouse)"));
148 pio_sys = new I8255(this, emu); // for system port
149 pio_sys->set_device_name(_T("8255 PIO (System)"));
150 pio_prn = new I8255(this, emu); // for printer
151 pio_prn->set_device_name(_T("8255 PIO (Printer)"));
152 pic = new I8259(this, emu);
153 #if defined(HAS_I386) || defined(HAS_I486)
154 cpu = new I386(this, emu); // 80386, 80486
155 #elif defined(HAS_I86) || defined(HAS_V30)
156 cpu = new I286(this, emu);// 8086, V30, 80286
158 cpu = new I286(this, emu);
161 cpu->set_device_name(_T("CPU(i8086)"));
162 #elif defined(HAS_I386)
163 cpu->set_device_name(_T("CPU(i386)"));
164 #elif defined(HAS_I486)
165 cpu->set_device_name(_T("CPU(i486)"));
166 #elif defined(HAS_PENTIUM)
167 cpu->set_device_name(_T("CPU(Pentium)"));
168 #elif defined(HAS_V33A)
169 cpu->set_device_name(_T("CPU(V33A)"));
170 #elif defined(HAS_V30)
171 cpu->set_device_name(_T("CPU(V30)"));
173 cpu->set_device_name(_T("CPU(i286)"));
175 io = new IO(this, emu);
176 rtcreg = new LS244(this, emu);
177 rtcreg->set_device_name(_T("74LS244 (RTC)"));
178 //memory = new MEMORY(this, emu);
179 memory = new MEMBUS(this, emu);
180 not_busy = new NOT(this, emu);
181 not_busy->set_device_name(_T("NOT Gate (Printer Busy)"));
182 #if defined(HAS_I86) || defined(HAS_V30)
183 not_prn = new NOT(this, emu);
184 not_prn->set_device_name(_T("NOT Gate (Printer IRQ)"));
186 rtc = new UPD1990A(this, emu);
187 #if defined(SUPPORT_2HD_FDD_IF)
188 fdc_2hd = new UPD765A(this, emu);
189 fdc_2hd->set_device_name(_T("uPD765A FDC (2HD I/F)"));
191 #if defined(SUPPORT_2DD_FDD_IF)
192 fdc_2dd = new UPD765A(this, emu);
193 fdc_2dd->set_device_name(_T("uPD765A FDC (2DD I/F)"));
195 #if defined(SUPPORT_2HD_2DD_FDD_IF)
196 fdc = new UPD765A(this, emu);
197 fdc->set_device_name(_T("uPD765A FDC (2HD/2DD I/F)"));
199 noise_seek = new NOISE(this, emu);
200 noise_head_down = new NOISE(this, emu);
201 noise_head_up = new NOISE(this, emu);
202 gdc_chr = new UPD7220(this, emu);
203 gdc_chr->set_device_name(_T("uPD7220 GDC (Character)"));
204 gdc_gfx = new UPD7220(this, emu);
205 gdc_gfx->set_device_name(_T("uPD7220 GDC (Graphics)"));
207 if(sound_type == 0 || sound_type == 1) {
208 opn = new YM2203(this, emu);
209 #ifdef SUPPORT_PC98_OPNA
210 opn->is_ym2608 = true;
212 fmsound = new FMSOUND(this, emu);
213 joystick = new JOYSTICK(this, emu);
214 } else if(sound_type == 2 || sound_type == 3) {
215 tms3631 = new TMS3631(this, emu);
216 tms3631->set_device_name(_T("TMS3631 SSG (PC-9801-14)"));
217 pit_14 = new I8253(this, emu);
218 pit_14->set_device_name(_T("8253 PIT (PC-9801-14)"));
219 pio_14 = new I8255(this, emu);
220 pio_14->set_device_name(_T("8255 PIO (PC-9801-14)"));
221 maskreg_14 = new LS244(this, emu);
222 maskreg_14->set_device_name(_T("74LS244 (PC-9801-14)"));
224 if(config.printer_type == 0) {
225 printer = new PRNFILE(this, emu);
226 // } else if(config.printer_type == 1) {
227 // printer = new PCPR201(this, emu);
232 #if defined(SUPPORT_CMT_IF)
233 cmt = new CMT(this, emu);
235 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
236 cpureg = new CPUREG(this, emu);
238 display = new DISPLAY(this, emu);
239 dmareg = new DMAREG(this, emu);
240 floppy = new FLOPPY(this, emu);
241 keyboard = new KEYBOARD(this, emu);
242 mouse = new MOUSE(this, emu);
244 #if defined(SUPPORT_320KB_FDD_IF)
246 pio_sub = new I8255(this, emu);
247 pio_sub->set_device_name(_T("8255 PIO (320KB FDD)"));
248 pc80s31k = new PC80S31K(this, emu);
249 pc80s31k->set_device_name(_T("PC-80S31K (320KB FDD)"));
250 fdc_sub = new UPD765A(this, emu);
251 fdc_sub->set_device_name(_T("uPD765A FDC (320KB FDD)"));
252 cpu_sub = new Z80(this, emu);
253 cpu_sub->set_device_name(_T("Z80 CPU (320KB FDD)"));
266 10 (INT41) FDC (640KB I/F)
267 11 (INT42) FDC (1MB I/F)
268 12 (INT5) PC-9801-26(K) or PC-9801-14
275 event->set_context_cpu(cpu, cpu_clocks);
276 #if defined(SUPPORT_320KB_FDD_IF)
277 event->set_context_cpu(cpu_sub, 4000000);
279 event->set_context_sound(beep);
280 if(sound_type == 0 || sound_type == 1) {
281 event->set_context_sound(opn);
282 } else if(sound_type == 2 || sound_type == 3) {
283 event->set_context_sound(tms3631);
285 event->set_context_sound(noise_seek);
286 event->set_context_sound(noise_head_down);
287 event->set_context_sound(noise_head_up);
289 dma->set_context_memory(memory);
291 // dma ch.1: memory refresh
292 #if defined(SUPPORT_2HD_FDD_IF)
293 dma->set_context_ch2(fdc_2hd);
295 #if defined(SUPPORT_2DD_FDD_IF)
296 dma->set_context_ch3(fdc_2dd);
298 #if defined(SUPPORT_2HD_2DD_FDD_IF)
299 #if !defined(SUPPORT_HIRESO)
300 dma->set_context_ch2(fdc);
301 dma->set_context_ch3(fdc);
303 dma->set_context_ch1(fdc);
306 // sio_rs->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR4, 1);
307 sio_kbd->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR1, 1);
308 pit->set_context_ch0(pic, SIG_I8259_CHIP0 | SIG_I8259_IR0, 1);
309 #if defined(SUPPORT_OLD_BUZZER)
310 // pit ch.1: memory refresh
313 pit->set_context_ch1(beep, SIG_PCM1BIT_SIGNAL, 1);
316 pit->set_constant_clock(0, pit_clocks);
317 pit->set_constant_clock(1, pit_clocks);
318 pit->set_constant_clock(2, pit_clocks);
319 pio_mouse->set_context_port_c(mouse, SIG_MOUSE_PORT_C, 0xf0, 0);
320 #if defined(SUPPORT_HIRESO)
321 // sysport port.c bit7,5: sysport port.b bit4,3
322 pio_sys->set_context_port_c(pio_sys, SIG_I8255_PORT_B, 0x80, -3); // SHUT0
323 pio_sys->set_context_port_c(pio_sys, SIG_I8255_PORT_B, 0x20, -2); // SHUT1
325 // sysport port.c bit6: printer strobe
326 #if defined(SUPPORT_OLD_BUZZER)
327 pio_sys->set_context_port_c(beep, SIG_BEEP_MUTE, 0x08, 0);
329 pio_sys->set_context_port_c(beep, SIG_PCM1BIT_MUTE, 0x08, 0);
331 // sysport port.c bit2: enable txrdy interrupt
332 // sysport port.c bit1: enable txempty interrupt
333 // sysport port.c bit0: enable rxrdy interrupt
334 pio_prn->set_context_port_a(printer, SIG_PRINTER_DATA, 0xff, 0);
335 pio_prn->set_context_port_c(printer, SIG_PRINTER_STROBE, 0x80, 0);
336 if(config.printer_type == 0) {
337 PRNFILE *prnfile = (PRNFILE *)printer;
338 prnfile->set_context_busy(not_busy, SIG_NOT_INPUT, 1);
339 // } else if(config.printer_type == 1) {
340 // PRNFILE *pcpr201 = (PCPR201 *)printer;
341 // pcpr201->set_context_busy(not_busy, SIG_NOT_INPUT, 1);
343 not_busy->set_context_out(pio_prn, SIG_I8255_PORT_B, 4);
344 #if defined(HAS_I86) || defined(HAS_V30)
345 pio_prn->set_context_port_c(not_prn, SIG_NOT_INPUT, 8, 0);
346 not_prn->set_context_out(pic, SIG_I8259_CHIP1 | SIG_I8259_IR0, 1);
348 rtcreg->set_context_output(rtc, SIG_UPD1990A_CMD, 0x07, 0);
349 rtcreg->set_context_output(rtc, SIG_UPD1990A_DIN, 0x20, 0);
350 rtcreg->set_context_output(rtc, SIG_UPD1990A_STB, 0x08, 0);
351 rtcreg->set_context_output(rtc, SIG_UPD1990A_CLK, 0x10, 0);
352 pic->set_context_cpu(cpu);
353 rtc->set_context_dout(pio_sys, SIG_I8255_PORT_B, 1);
355 if(sound_type == 0 || sound_type == 1) {
356 opn->set_context_irq(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1);
357 opn->set_context_port_b(joystick, SIG_JOYSTICK_SELECT, 0xc0, 0);
358 fmsound->set_context_opn(opn);
359 joystick->set_context_opn(opn);
360 } else if(sound_type == 2 || sound_type == 3) {
361 pio_14->set_context_port_a(tms3631, SIG_TMS3631_ENVELOP1, 0xff, 0);
362 pio_14->set_context_port_b(tms3631, SIG_TMS3631_ENVELOP2, 0xff, 0);
363 pio_14->set_context_port_c(tms3631, SIG_TMS3631_DATAREG, 0xff, 0);
364 maskreg_14->set_context_output(tms3631, SIG_TMS3631_MASKREG, 0xff, 0);
365 pit_14->set_constant_clock(2, 1996800 / 8);
366 pit_14->set_context_ch2(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1);
369 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
370 cpureg->set_context_cpu(cpu);
372 display->set_context_pic(pic);
373 display->set_context_gdc_chr(gdc_chr, gdc_chr->get_ra());
374 display->set_context_gdc_gfx(gdc_gfx, gdc_gfx->get_ra(), gdc_gfx->get_cs());
375 dmareg->set_context_dma(dma);
376 keyboard->set_context_sio(sio_kbd);
377 mouse->set_context_pic(pic);
378 mouse->set_context_pio(pio_mouse);
380 #if defined(SUPPORT_2HD_FDD_IF)
381 fdc_2hd->set_context_irq(floppy, SIG_FLOPPY_2HD_IRQ, 1);
382 fdc_2hd->set_context_drq(floppy, SIG_FLOPPY_2HD_DRQ, 1);
383 fdc_2hd->set_context_noise_seek(noise_seek);
384 fdc_2hd->set_context_noise_head_down(noise_head_down);
385 fdc_2hd->set_context_noise_head_up(noise_head_up);
386 fdc_2hd->raise_irq_when_media_changed = true;
387 floppy->set_context_fdc_2hd(fdc_2hd);
389 #if defined(SUPPORT_2DD_FDD_IF)
390 fdc_2dd->set_context_irq(floppy, SIG_FLOPPY_2DD_IRQ, 1);
391 fdc_2dd->set_context_drq(floppy, SIG_FLOPPY_2DD_DRQ, 1);
392 fdc_2dd->set_context_noise_seek(noise_seek);
393 fdc_2dd->set_context_noise_head_down(noise_head_down);
394 fdc_2dd->set_context_noise_head_up(noise_head_up);
395 fdc_2dd->raise_irq_when_media_changed = true;
396 floppy->set_context_fdc_2dd(fdc_2dd);
398 #if defined(SUPPORT_2HD_2DD_FDD_IF)
399 fdc->set_context_irq(floppy, SIG_FLOPPY_IRQ, 1);
400 fdc->set_context_drq(floppy, SIG_FLOPPY_DRQ, 1);
401 fdc->set_context_noise_seek(noise_seek);
402 fdc->set_context_noise_head_down(noise_head_down);
403 fdc->set_context_noise_head_up(noise_head_up);
404 fdc->raise_irq_when_media_changed = true;
405 floppy->set_context_fdc(fdc);
407 floppy->set_context_dma(dma);
408 floppy->set_context_pic(pic);
410 #if defined(SUPPORT_CMT_IF)
411 sio_cmt->set_context_out(cmt, SIG_CMT_OUT);
412 // sio_cmt->set_context_txrdy(cmt, SIG_CMT_TXRDY, 1);
413 // sio_cmt->set_context_rxrdy(cmt, SIG_CMT_RXRDY, 1);
414 // sio_cmt->set_context_txe(cmt, SIG_CMT_TXEMP, 1);
415 cmt->set_context_sio(sio_cmt);
419 cpu->set_context_mem(memory);
420 cpu->set_context_io(io);
421 cpu->set_context_intr(pic);
422 #ifdef SINGLE_MODE_DMA
423 cpu->set_context_dma(dma);
426 cpu->set_context_debugger(new DEBUGGER(this, emu));
429 #if defined(SUPPORT_320KB_FDD_IF)
431 pc80s31k->set_context_cpu(cpu_sub);
432 pc80s31k->set_context_fdc(fdc_sub);
433 pc80s31k->set_context_pio(pio_sub);
434 pio_fdd->set_context_port_a(pio_sub, SIG_I8255_PORT_A, 0xff, 0);
435 pio_fdd->set_context_port_b(pio_sub, SIG_I8255_PORT_A, 0xff, 0);
436 pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0x0f, 4);
437 pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0xf0, -4);
438 pio_fdd->clear_ports_by_cmdreg = true;
439 pio_sub->set_context_port_a(pio_fdd, SIG_I8255_PORT_B, 0xff, 0);
440 pio_sub->set_context_port_b(pio_fdd, SIG_I8255_PORT_A, 0xff, 0);
441 pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0x0f, 4);
442 pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0xf0, -4);
443 pio_sub->clear_ports_by_cmdreg = true;
444 fdc_sub->set_context_irq(cpu_sub, SIG_CPU_IRQ, 1);
445 fdc_sub->set_context_noise_seek(noise_seek);
446 fdc_sub->set_context_noise_head_down(noise_head_down);
447 fdc_sub->set_context_noise_head_up(noise_head_up);
448 cpu_sub->set_context_mem(pc80s31k);
449 cpu_sub->set_context_io(pc80s31k);
450 cpu_sub->set_context_intr(pc80s31k);
452 cpu_sub->set_context_debugger(new DEBUGGER(this, emu));
460 A0000h - A1FFFh: TEXT VRAM
461 A2000h - A3FFFh: ATTRIBUTE
462 A4000h - A4FFFh: CG WINDOW
463 A8000h - BFFFFh: VRAM (BRG)
464 E0000h - E7FFFh: VRAM (I)
467 HIRESO PC-98XA/XL/XL^2/RL
469 80000h - BFFFFh: MEMORY WINDOW
470 C0000h - DFFFFh: VRAM
471 E0000h - E1FFFh: TEXT VRAM
472 E2000h - E3FFFh: ATTRIBUTE
473 E4000h - E4FFFh: CG WINDOW
477 memset(ram, 0, sizeof(ram));
478 // set_memory_r(0x100000 - sizeof(ipl), 0x0fffff, ipl);
479 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
480 memory->set_memory_rw(0x100000, sizeof(ram) - 1, ram + 0x100000);
483 #if !defined(SUPPORT_HIRESO)
484 memory->set_memory_rw(0x000000, 0x09ffff, ram);
485 memory->set_memory_mapped_io_rw(0xa0000, 0xa4fff, display);
486 memory->set_memory_mapped_io_rw(0xa8000, 0xbffff, display);
487 #if defined(SUPPORT_16_COLORS)
488 memory->set_memory_mapped_io_rw(0xe0000, 0xe7fff, display);
491 memory->set_memory_rw(0x00000, 0xbffff, ram);
492 memory->set_memory_mapped_io_rw(0xc0000, 0xe4fff, display);
495 #if defined(_PC9801) || defined(_PC9801E)
496 memset(fd_bios_2hd, 0xff, sizeof(fd_bios_2hd));
497 memory->read_bios(_T("2HDIF.ROM"), fd_bios_2hd, sizeof(fd_bios_2hd));
498 memory->set_memory_r(0xd6000, 0xd6fff, fd_bios_2dd);
500 memset(fd_bios_2dd, 0xff, sizeof(fd_bios_2dd));
501 memory->read_bios(_T("2DDIF.ROM"), fd_bios_2dd, sizeof(fd_bios_2dd));
502 memory->set_memory_r(0xd7000, 0xd7fff, fd_bios_2hd);
504 #if !defined(SUPPORT_HIRESO)
505 memset(sound_bios, 0xff, sizeof(sound_bios));
506 if(sound_type == 0) {
507 display->sound_bios_ok = (memory->read_bios(_T("SOUND.ROM"), sound_bios, sizeof(sound_bios)) != 0);
508 memory->set_memory_r(0xcc000, 0xcffff, sound_bios);
509 } else if(sound_type == 2) {
510 display->sound_bios_ok = (memory->read_bios(_T("MUSIC.ROM"), sound_bios, sizeof(sound_bios)) != 0);
511 memory->set_memory_r(0xcc000, 0xcffff, sound_bios);
514 display->sound_bios_ok = false;
515 // memory->set_memory_r(0x100000 - sizeof(ipl), 0xfffff, ipl);
518 io->set_iomap_alias_rw(0x0000, pic, 0);
519 io->set_iomap_alias_rw(0x0002, pic, 1);
520 io->set_iomap_alias_rw(0x0008, pic, 2);
521 io->set_iomap_alias_rw(0x000a, pic, 3);
523 io->set_iomap_alias_rw(0x0001, dma, 0x00);
524 io->set_iomap_alias_rw(0x0003, dma, 0x01);
525 io->set_iomap_alias_rw(0x0005, dma, 0x02);
526 io->set_iomap_alias_rw(0x0007, dma, 0x03);
527 io->set_iomap_alias_rw(0x0009, dma, 0x04);
528 io->set_iomap_alias_rw(0x000b, dma, 0x05);
529 io->set_iomap_alias_rw(0x000d, dma, 0x06);
530 io->set_iomap_alias_rw(0x000f, dma, 0x07);
531 io->set_iomap_alias_rw(0x0011, dma, 0x08);
532 io->set_iomap_alias_w (0x0013, dma, 0x09);
533 io->set_iomap_alias_w (0x0015, dma, 0x0a);
534 io->set_iomap_alias_w (0x0017, dma, 0x0b);
535 io->set_iomap_alias_w (0x0019, dma, 0x0c);
536 io->set_iomap_alias_rw(0x001b, dma, 0x0d);
537 io->set_iomap_alias_w (0x001d, dma, 0x0e);
538 io->set_iomap_alias_w (0x001f, dma, 0x0f);
539 io->set_iomap_single_w(0x0021, dmareg);
540 io->set_iomap_single_w(0x0023, dmareg);
541 io->set_iomap_single_w(0x0025, dmareg);
542 io->set_iomap_single_w(0x0027, dmareg);
543 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
544 io->set_iomap_single_w(0x0029, dmareg);
546 #if defined(SUPPORT_32BIT_ADDRESS)
547 io->set_iomap_single_w(0x0e05, dmareg);
548 io->set_iomap_single_w(0x0e07, dmareg);
549 io->set_iomap_single_w(0x0e09, dmareg);
550 io->set_iomap_single_w(0x0e0b, dmareg);
553 io->set_iomap_single_w(0x0020, rtcreg);
555 io->set_iomap_alias_rw(0x0030, sio_rs, 0);
556 io->set_iomap_alias_rw(0x0032, sio_rs, 1);
558 io->set_iomap_alias_rw(0x0031, pio_sys, 0);
559 io->set_iomap_alias_rw(0x0033, pio_sys, 1);
560 io->set_iomap_alias_rw(0x0035, pio_sys, 2);
561 io->set_iomap_alias_w (0x0037, pio_sys, 3);
563 io->set_iomap_alias_rw(0x0040, pio_prn, 0);
564 io->set_iomap_alias_rw(0x0042, pio_prn, 1);
565 io->set_iomap_alias_rw(0x0044, pio_prn, 2);
566 io->set_iomap_alias_w (0x0046, pio_prn, 3);
568 io->set_iomap_alias_rw(0x0041, sio_kbd, 0);
569 io->set_iomap_alias_rw(0x0043, sio_kbd, 1);
571 #if !defined(_PC9801U)
572 io->set_iomap_single_w(0x0050, dummy); // NMI disabled
573 io->set_iomap_single_w(0x0052, dummy); // NMI enabled
576 #if defined(SUPPORT_320KB_FDD_IF)
577 io->set_iomap_alias_rw(0x0051, pio_fdd, 0);
578 io->set_iomap_alias_rw(0x0053, pio_fdd, 1);
579 io->set_iomap_alias_rw(0x0055, pio_fdd, 2);
580 io->set_iomap_alias_w (0x0057, pio_fdd, 3);
583 io->set_iomap_alias_rw(0x0060, gdc_chr, 0);
584 io->set_iomap_alias_rw(0x0062, gdc_chr, 1);
586 io->set_iomap_single_w(0x64, display);
587 io->set_iomap_single_w(0x68, display);
588 #if defined(SUPPORT_16_COLORS)
589 io->set_iomap_single_w(0x6a, display);
591 io->set_iomap_single_w(0x6c, display);
592 io->set_iomap_single_w(0x6e, display);
594 io->set_iomap_single_w(0x70, display);
595 io->set_iomap_single_w(0x72, display);
596 io->set_iomap_single_w(0x74, display);
597 io->set_iomap_single_w(0x76, display);
598 io->set_iomap_single_w(0x78, display);
599 io->set_iomap_single_w(0x7a, display);
600 #if defined(SUPPORT_GRCG)
601 #if !defined(SUPPORT_HIRESO)
602 io->set_iomap_single_w(0x007c, display);
603 io->set_iomap_single_w(0x007e, display);
605 io->set_iomap_single_w(0x00a4, display);
606 io->set_iomap_single_w(0x00a6, display);
610 io->set_iomap_alias_rw(0x00a0, gdc_gfx, 0);
611 io->set_iomap_alias_rw(0x00a2, gdc_gfx, 1);
613 #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
614 io->set_iomap_single_rw(0x00a4, display);
615 io->set_iomap_single_rw(0x00a6, display);
617 io->set_iomap_single_rw(0xa8, display);
618 io->set_iomap_single_rw(0xaa, display);
619 io->set_iomap_single_rw(0xac, display);
620 io->set_iomap_single_rw(0xae, display);
622 // io->set_iomap_single_w(0xa1, display);
623 // io->set_iomap_single_w(0xa3, display);
624 // io->set_iomap_single_w(0xa5, display);
625 io->set_iomap_single_rw(0xa1, display);
626 io->set_iomap_single_rw(0xa3, display);
627 io->set_iomap_single_rw(0xa5, display);
628 io->set_iomap_single_rw(0xa9, display);
629 #if defined(SUPPORT_EGC) && !defined(SUPPORT_HIRESO)
630 io->set_iomap_range_rw(0x04a0, 0x04af, display);
633 io->set_iomap_alias_rw(0x0071, pit, 0);
634 io->set_iomap_alias_rw(0x0073, pit, 1);
635 io->set_iomap_alias_rw(0x0075, pit, 2);
636 io->set_iomap_alias_w (0x0077, pit, 3);
640 io->set_iomap_single_rw(0x0090, floppy);
641 io->set_iomap_single_rw(0x0092, floppy);
642 io->set_iomap_single_rw(0x0094, floppy);
643 #if defined(SUPPORT_2HD_2DD_FDD_IF)
644 #if !defined(SUPPORT_HIRESO)
645 io->set_iomap_single_rw(0x00be, floppy);
647 io->set_iomap_single_w (0x00be, floppy);
650 #if !defined(SUPPORT_HIRESO)
651 io->set_iomap_single_rw(0x00c8, floppy);
652 io->set_iomap_single_rw(0x00ca, floppy);
653 io->set_iomap_single_rw(0x00cc, floppy);
656 #if defined(SUPPORT_CMT_IF)
657 io->set_iomap_alias_rw(0x0091, sio_cmt, 0);
658 io->set_iomap_alias_rw(0x0093, sio_cmt, 1);
659 io->set_iomap_single_w(0x0095, cmt);
660 io->set_iomap_single_w(0x0097, cmt);
663 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
664 io->set_iomap_single_rw(0x00f0, cpureg);
665 io->set_iomap_single_rw(0x00f2, cpureg);
667 #if defined(SUPPORT_32BIT_ADDRESS)
668 io->set_iomap_single_rw(0x00f6, cpureg);
671 if(sound_type == 0 || sound_type == 1) {
672 io->set_iomap_single_rw(0x0188, fmsound);
673 io->set_iomap_single_rw(0x018a, fmsound);
674 #ifdef SUPPORT_PC98_OPNA
675 io->set_iomap_single_rw(0x018c, fmsound);
676 io->set_iomap_single_rw(0x018e, fmsound);
677 io->set_iomap_single_rw(0xa460, fmsound);
679 } else if(sound_type == 2 || sound_type == 3) {
680 io->set_iomap_alias_rw(0x0088, pio_14, 0);
681 io->set_iomap_alias_rw(0x008a, pio_14, 1);
682 io->set_iomap_alias_rw(0x008c, pio_14, 2);
683 io->set_iomap_alias_w(0x008e, pio_14, 3);
684 io->set_iovalue_single_r(0x008e, 0x08);
685 io->set_iomap_single_w(0x0188, maskreg_14);
686 io->set_iomap_single_w(0x018a, maskreg_14);
687 io->set_iomap_alias_rw(0x018c, pit_14, 2);
688 io->set_iomap_alias_w(0x018e, pit_14, 3);
689 // io->set_iovalue_single_r(0x018e, 0x00); // INT0
690 // io->set_iovalue_single_r(0x018e, 0x40); // INT41
691 io->set_iovalue_single_r(0x018e, 0x80); // INT5
692 // io->set_iovalue_single_r(0x018e, 0xc0); // INT6
695 #if defined(SUPPORT_ITF_ROM)
696 io->set_iomap_single_w(0x043d, memory);
698 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
699 io->set_iomap_single_rw(0x0439, memory);
700 #if !defined(SUPPORT_HIRESO)
701 io->set_iomap_single_rw(0x0461, memory);
702 io->set_iomap_single_rw(0x0463, memory);
704 io->set_iomap_single_rw(0x0091, memory);
705 io->set_iomap_single_rw(0x0093, memory);
709 #if !(defined(_PC9801) || defined(_PC9801E) || defined(SUPPORT_HIRESO))
710 io->set_iomap_alias_rw(0x3fd9, pit, 0);
711 io->set_iomap_alias_rw(0x3fdb, pit, 1);
712 io->set_iomap_alias_rw(0x3fdd, pit, 2);
713 io->set_iomap_alias_w (0x3fdf, pit, 3);
716 #if !defined(SUPPORT_HIRESO)
717 io->set_iomap_alias_rw(0x7fd9, pio_mouse, 0);
718 io->set_iomap_alias_rw(0x7fdb, pio_mouse, 1);
719 io->set_iomap_alias_rw(0x7fdd, pio_mouse, 2);
720 io->set_iomap_alias_w (0x7fdf, pio_mouse, 3);
722 io->set_iomap_alias_rw(0x0061, pio_mouse, 0);
723 io->set_iomap_alias_rw(0x0063, pio_mouse, 1);
724 io->set_iomap_alias_rw(0x0065, pio_mouse, 2);
725 io->set_iomap_alias_rw(0x0067, pio_mouse, 3);
727 #if !(defined(_PC9801) || defined(_PC9801E) || defined(SUPPORT_HIRESO))
728 io->set_iomap_single_rw(0xbfdb, mouse);
731 #if defined(_PC98DO) || defined(_PC98DOPLUS)
732 pc88event = new EVENT(this, emu);
733 pc88event->set_device_name(_T("Event Manager (PC-8801)"));
734 pc88event->set_frames_per_sec(60);
735 pc88event->set_lines_per_frame(260);
737 pc88 = new PC88(this, emu);
738 pc88->set_context_event_manager(pc88event);
739 pc88sio = new I8251(this, emu);
740 pc88sio->set_device_name(_T("8251 SIO (PC-8801)"));
741 pc88sio->set_context_event_manager(pc88event);
742 pc88pio = new I8255(this, emu);
743 pc88pio->set_device_name(_T("8255 PIO (PC-8801)"));
744 pc88pio->set_context_event_manager(pc88event);
745 pc88pcm = new PCM1BIT(this, emu);
746 pc88pcm->set_device_name(_T("1-Bit PCM Sound (PC-8801)"));
747 pc88pcm->set_context_event_manager(pc88event);
748 pc88rtc = new UPD1990A(this, emu);
749 pc88rtc->set_device_name(_T("uPD1990A RTC (PC-8801)"));
750 pc88rtc->set_context_event_manager(pc88event);
751 pc88opn = new YM2203(this, emu);
752 #ifdef SUPPORT_PC88_OPNA
753 pc88opn->set_device_name(_T("YM2608 OPNA (PC-8801)"));
754 pc88opn->is_ym2608 = true;
756 pc88opn->set_device_name(_T("YM2203 OPN (PC-8801)"));
758 pc88opn->set_context_event_manager(pc88event);
759 pc88cpu = new Z80(this, emu);
760 pc88cpu->set_device_name(_T("Z80 CPU (PC-8801)"));
761 pc88cpu->set_context_event_manager(pc88event);
763 if(config.printer_type == 0) {
764 pc88prn = new PRNFILE(this, emu);
765 pc88prn->set_context_event_manager(pc88event);
766 // } else if(config.printer_type == 1) {
767 // pc88prn = new PCPR201(this, emu);
768 // pc88prn->set_context_event_manager(pc88event);
773 pc88sub = new PC80S31K(this, emu);
774 pc88sub->set_device_name(_T("PC-80S31K (PC-8801 Sub)"));
775 pc88sub->set_context_event_manager(pc88event);
776 pc88pio_sub = new I8255(this, emu);
777 pc88pio_sub->set_device_name(_T("8255 PIO (PC-8801 Sub)"));
778 pc88pio_sub->set_context_event_manager(pc88event);
779 pc88fdc_sub = new UPD765A(this, emu);
780 pc88fdc_sub->set_device_name(_T("uPD765A FDC (PC-8801 Sub)"));
781 pc88fdc_sub->set_context_event_manager(pc88event);
782 pc88noise_seek = new NOISE(this, emu);
783 pc88noise_seek->set_context_event_manager(pc88event);
784 pc88noise_head_down = new NOISE(this, emu);
785 pc88noise_head_down->set_context_event_manager(pc88event);
786 pc88noise_head_up = new NOISE(this, emu);
787 pc88noise_head_up->set_context_event_manager(pc88event);
788 pc88cpu_sub = new Z80(this, emu);
789 pc88cpu_sub->set_device_name(_T("Z80 CPU (PC-8801 Sub)"));
790 pc88cpu_sub->set_context_event_manager(pc88event);
792 pc88event->set_context_cpu(pc88cpu, (config.cpu_type == 1) ? 3993624 : 7987248);
793 pc88event->set_context_cpu(pc88cpu_sub, 3993624);
794 pc88event->set_context_sound(pc88opn);
795 pc88event->set_context_sound(pc88pcm);
796 pc88event->set_context_sound(pc88noise_seek);
797 pc88event->set_context_sound(pc88noise_head_down);
798 pc88event->set_context_sound(pc88noise_head_up);
800 pc88->set_context_cpu(pc88cpu);
801 pc88->set_context_opn(pc88opn);
802 pc88->set_context_pcm(pc88pcm);
803 pc88->set_context_pio(pc88pio);
804 pc88->set_context_prn(pc88prn);
805 pc88->set_context_rtc(pc88rtc);
806 pc88->set_context_sio(pc88sio);
807 pc88cpu->set_context_mem(pc88);
808 pc88cpu->set_context_io(pc88);
809 pc88cpu->set_context_intr(pc88);
811 pc88cpu->set_context_debugger(new DEBUGGER(this, emu));
813 pc88opn->set_context_irq(pc88, SIG_PC88_SOUND_IRQ, 1);
814 pc88sio->set_context_rxrdy(pc88, SIG_PC88_USART_IRQ, 1);
815 pc88sio->set_context_out(pc88, SIG_PC88_USART_OUT);
817 pc88sub->set_context_cpu(pc88cpu_sub);
818 pc88sub->set_context_fdc(pc88fdc_sub);
819 pc88sub->set_context_pio(pc88pio_sub);
820 pc88pio->set_context_port_a(pc88pio_sub, SIG_I8255_PORT_B, 0xff, 0);
821 pc88pio->set_context_port_b(pc88pio_sub, SIG_I8255_PORT_A, 0xff, 0);
822 pc88pio->set_context_port_c(pc88pio_sub, SIG_I8255_PORT_C, 0x0f, 4);
823 pc88pio->set_context_port_c(pc88pio_sub, SIG_I8255_PORT_C, 0xf0, -4);
824 pc88pio->clear_ports_by_cmdreg = true;
825 pc88pio_sub->set_context_port_a(pc88pio, SIG_I8255_PORT_B, 0xff, 0);
826 pc88pio_sub->set_context_port_b(pc88pio, SIG_I8255_PORT_A, 0xff, 0);
827 pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0x0f, 4);
828 pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0xf0, -4);
829 pc88pio_sub->clear_ports_by_cmdreg = true;
830 pc88fdc_sub->set_context_irq(pc88cpu_sub, SIG_CPU_IRQ, 1);
831 pc88fdc_sub->set_context_noise_seek(pc88noise_seek);
832 pc88fdc_sub->set_context_noise_head_down(pc88noise_head_down);
833 pc88fdc_sub->set_context_noise_head_up(pc88noise_head_up);
834 pc88cpu_sub->set_context_mem(pc88sub);
835 pc88cpu_sub->set_context_io(pc88sub);
836 pc88cpu_sub->set_context_intr(pc88sub);
838 pc88cpu_sub->set_context_debugger(new DEBUGGER(this, emu));
842 // initialize all devices
843 for(DEVICE* device = first_device; device; device = device->next_device) {
844 device->initialize();
846 #if defined(_PC9801) || defined(_PC9801E)
847 fdc_2hd->get_disk_handler(0)->drive_num = 0;
848 fdc_2hd->get_disk_handler(1)->drive_num = 1;
849 fdc_2dd->get_disk_handler(0)->drive_num = 2;
850 fdc_2dd->get_disk_handler(1)->drive_num = 3;
851 fdc_sub->get_disk_handler(0)->drive_num = 4;
852 fdc_sub->get_disk_handler(1)->drive_num = 5;
853 #elif defined(_PC9801VF) || defined(_PC9801U)
854 fdc_2dd->get_disk_handler(0)->drive_num = 0;
855 fdc_2dd->get_disk_handler(1)->drive_num = 1;
856 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
857 fdc->get_disk_handler(0)->drive_num = 0;
858 fdc->get_disk_handler(1)->drive_num = 1;
859 pc88fdc_sub->get_disk_handler(0)->drive_num = 2;
860 pc88fdc_sub->get_disk_handler(1)->drive_num = 3;
862 fdc->get_disk_handler(0)->drive_num = 0;
863 fdc->get_disk_handler(1)->drive_num = 1;
869 // delete all devices
870 for(DEVICE* device = first_device; device;) {
871 DEVICE *next_device = device->next_device;
874 device = next_device;
878 DEVICE* VM::get_device(int id)
880 for(DEVICE* device = first_device; device; device = device->next_device) {
881 if(device->this_device_id == id) {
888 // ----------------------------------------------------------------------------
889 // drive virtual machine
890 // ----------------------------------------------------------------------------
895 for(DEVICE* device = first_device; device; device = device->next_device) {
898 #if defined(_PC98DO) || defined(_PC98DOPLUS)
899 for(DEVICE* device = first_device; device; device = device->next_device) {
904 // initial device settings
905 pio_mouse->write_signal(SIG_I8255_PORT_A, 0xf0, 0xff); // clear mouse status
906 pio_mouse->write_signal(SIG_I8255_PORT_B, 0x40, 0xff); // cpu high & sw3-6
907 uint8_t port_c = 0x08; // normal mode & sw1-5 & sw1-6
908 #if defined(HAS_V30) || defined(HAS_V33)
909 port_c |= 0x04; // V30
911 pio_mouse->write_signal(SIG_I8255_PORT_C, 0x40, 0xff);
913 pio_sys->write_signal(SIG_I8255_PORT_A, 0xe3, 0xff);
914 pio_sys->write_signal(SIG_I8255_PORT_B, 0xf8, 0xff);//0xe8??
915 pio_sys->write_signal(SIG_I8255_PORT_C, 0xff, 0xff);
918 uint8_t prn_b = 0x00; // system type = first PC-9801
919 #elif defined(_PC9801U)
920 uint8_t prn_b = 0xc0; // system type = PC-9801U,PC-98LT,PC-98HA
922 uint8_t prn_b = 0x80; // system type = others
925 prn_b |= 0x20; // system clock is 8MHz
927 prn_b |= 0x10; // don't use LCD display
928 #if !defined(SUPPORT_16_COLORS)
929 prn_b |= 0x08; // standard graphics
931 prn_b |= 0x04; // printer is not busy
932 #if defined(HAS_V30) || defined(HAS_V33)
935 #if defined(_PC9801VF) || defined(_PC9801U)
936 prn_b |= 0x01; // PC-9801VF or PC-9801U
938 pio_prn->write_signal(SIG_I8255_PORT_B, prn_b, 0xff);
940 #if defined(SUPPORT_320KB_FDD_IF)
941 pio_fdd->write_signal(SIG_I8255_PORT_A, 0xff, 0xff);
942 pio_fdd->write_signal(SIG_I8255_PORT_B, 0xff, 0xff);
943 pio_fdd->write_signal(SIG_I8255_PORT_C, 0xff, 0xff);
945 #if defined(SUPPORT_2DD_FDD_IF)
946 fdc_2dd->write_signal(SIG_UPD765A_FREADY, 1, 1); // 2DD FDC RDY is pulluped
949 if(sound_type == 0 || sound_type == 1) {
950 // opn->write_signal(SIG_YM2203_PORT_A, 0x3f, 0xff); // PC-9801-26(K) INT0
951 // opn->write_signal(SIG_YM2203_PORT_A, 0xbf, 0xff); // PC-9801-26(K) INT41
952 opn->write_signal(SIG_YM2203_PORT_A, 0xff, 0xff); // PC-9801-26(K) INT5
953 // opn->write_signal(SIG_YM2203_PORT_A, 0x7f, 0xff); // PC-9801-26(K) INT6
956 #if defined(SUPPORT_OLD_BUZZER)
957 beep->write_signal(SIG_BEEP_ON, 1, 1);
958 beep->write_signal(SIG_BEEP_MUTE, 1, 1);
960 beep->write_signal(SIG_PCM1BIT_ON, 1, 1);
961 beep->write_signal(SIG_PCM1BIT_MUTE, 1, 1);
964 #if defined(_PC98DO) || defined(_PC98DOPLUS)
965 pc88opn->set_reg(0x29, 3); // for Misty Blue
966 pc88pio->write_signal(SIG_I8255_PORT_C, 0, 0xff);
967 pc88pio_sub->write_signal(SIG_I8255_PORT_C, 0, 0xff);
973 #if defined(_PC98DO) || defined(_PC98DOPLUS)
981 double VM::get_frame_rate()
983 #if defined(_PC98DO) || defined(_PC98DOPLUS)
984 if(config.boot_mode != 0) {
985 return pc88event->get_frame_rate();
988 return event->get_frame_rate();
991 // ----------------------------------------------------------------------------
993 // ----------------------------------------------------------------------------
996 DEVICE *VM::get_cpu(int index)
998 #if defined(_PC98DO) || defined(_PC98DOPLUS)
999 if(index == 0 && boot_mode == 0) {
1001 } else if(index == 1 && boot_mode != 0) {
1003 } else if(index == 2 && boot_mode != 0) {
1009 #if defined(SUPPORT_320KB_FDD_IF)
1010 } else if(index == 1) {
1019 // ----------------------------------------------------------------------------
1021 // ----------------------------------------------------------------------------
1023 void VM::draw_screen()
1025 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1026 if(boot_mode != 0) {
1027 pc88->draw_screen();
1030 display->draw_screen();
1033 // ----------------------------------------------------------------------------
1035 // ----------------------------------------------------------------------------
1037 void VM::initialize_sound(int rate, int samples)
1039 // init sound manager
1040 event->initialize_sound(rate, samples);
1043 #if defined(SUPPORT_OLD_BUZZER)
1044 beep->initialize_sound(rate, 2400, 8000);
1046 beep->initialize_sound(rate, 8000);
1048 if(sound_type == 0 || sound_type == 1) {
1050 opn->initialize_sound(rate, 7987248, samples, 0, 0);
1052 opn->initialize_sound(rate, 3993624, samples, 0, 0);
1054 } else if(sound_type == 2 || sound_type == 3) {
1055 tms3631->initialize_sound(rate, 8000);
1058 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1059 // init sound manager
1060 pc88event->initialize_sound(rate, samples);
1064 pc88opn->initialize_sound(rate, 7987248, samples, 0, 0);
1066 pc88opn->initialize_sound(rate, 3993624, samples, 0, 0);
1068 pc88pcm->initialize_sound(rate, 8000);
1072 uint16_t* VM::create_sound(int* extra_frames)
1074 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1075 if(boot_mode != 0) {
1076 return pc88event->create_sound(extra_frames);
1079 return event->create_sound(extra_frames);
1082 int VM::get_sound_buffer_ptr()
1084 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1085 if(boot_mode != 0) {
1086 return pc88event->get_sound_buffer_ptr();
1089 return event->get_sound_buffer_ptr();
1092 #ifdef USE_SOUND_VOLUME
1093 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
1096 if(sound_type == 0 || sound_type == 1) {
1097 opn->set_volume(0, decibel_l, decibel_r);
1099 } else if(ch-- == 0) {
1100 if(sound_type == 0 || sound_type == 1) {
1101 opn->set_volume(1, decibel_l, decibel_r);
1103 #if defined(SUPPORT_PC98_OPNA)
1104 } else if(ch-- == 0) {
1105 if(sound_type == 0 || sound_type == 1) {
1106 opn->set_volume(2, decibel_l, decibel_r);
1108 } else if(ch-- == 0) {
1109 if(sound_type == 0 || sound_type == 1) {
1110 opn->set_volume(3, decibel_l, decibel_r);
1113 } else if(ch-- == 0) {
1114 if(sound_type == 2 || sound_type == 3) {
1115 tms3631->set_volume(0, decibel_l, decibel_r);
1117 } else if(ch-- == 0) {
1118 beep->set_volume(0, decibel_l, decibel_r);
1119 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1120 } else if(ch-- == 0) {
1121 pc88opn->set_volume(0, decibel_l, decibel_r);
1122 } else if(ch-- == 0) {
1123 pc88opn->set_volume(1, decibel_l, decibel_r);
1124 #if defined(SUPPORT_PC88_OPNA)
1125 } else if(ch-- == 0) {
1126 pc88opn->set_volume(2, decibel_l, decibel_r);
1127 } else if(ch-- == 0) {
1128 pc88opn->set_volume(3, decibel_l, decibel_r);
1130 } else if(ch-- == 0) {
1131 pc88pcm->set_volume(0, decibel_l, decibel_r);
1133 } else if(ch-- == 0) {
1134 noise_seek->set_volume(0, decibel_l, decibel_r);
1135 noise_head_down->set_volume(0, decibel_l, decibel_r);
1136 noise_head_up->set_volume(0, decibel_l, decibel_r);
1137 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1138 pc88noise_seek->set_volume(0, decibel_l, decibel_r);
1139 pc88noise_head_down->set_volume(0, decibel_l, decibel_r);
1140 pc88noise_head_up->set_volume(0, decibel_l, decibel_r);
1146 // ----------------------------------------------------------------------------
1148 // ----------------------------------------------------------------------------
1150 void VM::key_down(int code, bool repeat)
1152 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1153 if(boot_mode != 0) {
1154 pc88->key_down(code, repeat);
1157 keyboard->key_down(code, repeat);
1160 void VM::key_up(int code)
1162 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1163 if(boot_mode != 0) {
1164 // pc88->key_up(code);
1167 keyboard->key_up(code);
1170 bool VM::get_caps_locked()
1172 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1173 if(boot_mode != 0) {
1174 return pc88->get_caps_locked();
1177 return keyboard->get_caps_locked();
1180 bool VM::get_kana_locked()
1182 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1183 if(boot_mode != 0) {
1184 return pc88->get_kana_locked();
1187 return keyboard->get_kana_locked();
1190 // ----------------------------------------------------------------------------
1192 // ----------------------------------------------------------------------------
1194 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
1196 #if defined(_PC9801) || defined(_PC9801E)
1197 if(drv == 0 || drv == 1) {
1198 fdc_2hd->open_disk(drv, file_path, bank);
1199 } else if(drv == 2 || drv == 3) {
1200 fdc_2dd->open_disk(drv - 2, file_path, bank);
1201 } else if(drv == 4 || drv == 5) {
1202 fdc_sub->open_disk(drv - 4, file_path, bank);
1204 #elif defined(_PC9801VF) || defined(_PC9801U)
1205 if(drv == 0 || drv == 1) {
1206 fdc_2dd->open_disk(drv, file_path, bank);
1208 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1209 if(drv == 0 || drv == 1) {
1210 fdc->open_disk(drv, file_path, bank);
1211 } else if(drv == 2 || drv == 3) {
1212 pc88fdc_sub->open_disk(drv - 2, file_path, bank);
1215 if(drv == 0 || drv == 1) {
1216 fdc->open_disk(drv, file_path, bank);
1221 void VM::close_floppy_disk(int drv)
1223 #if defined(_PC9801) || defined(_PC9801E)
1224 if(drv == 0 || drv == 1) {
1225 fdc_2hd->close_disk(drv);
1226 } else if(drv == 2 || drv == 3) {
1227 fdc_2dd->close_disk(drv - 2);
1228 } else if(drv == 4 || drv == 5) {
1229 fdc_sub->close_disk(drv - 4);
1231 #elif defined(_PC9801VF) || defined(_PC9801U)
1232 if(drv == 0 || drv == 1) {
1233 fdc_2dd->close_disk(drv);
1235 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1236 if(drv == 0 || drv == 1) {
1237 fdc->close_disk(drv);
1238 } else if(drv == 2 || drv == 3) {
1239 pc88fdc_sub->close_disk(drv - 2);
1242 if(drv == 0 || drv == 1) {
1243 fdc->close_disk(drv);
1248 bool VM::is_floppy_disk_inserted(int drv)
1250 #if defined(_PC9801) || defined(_PC9801E)
1251 if(drv == 0 || drv == 1) {
1252 return fdc_2hd->is_disk_inserted(drv);
1253 } else if(drv == 2 || drv == 3) {
1254 return fdc_2dd->is_disk_inserted(drv - 2);
1255 } else if(drv == 4 || drv == 5) {
1256 return fdc_sub->is_disk_inserted(drv - 4);
1258 #elif defined(_PC9801VF) || defined(_PC9801U)
1259 if(drv == 0 || drv == 1) {
1260 return fdc_2dd->is_disk_inserted(drv);
1262 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1263 if(drv == 0 || drv == 1) {
1264 return fdc->is_disk_inserted(drv);
1265 } else if(drv == 2 || drv == 3) {
1266 return pc88fdc_sub->is_disk_inserted(drv - 2);
1269 if(drv == 0 || drv == 1) {
1270 return fdc->is_disk_inserted(drv);
1276 void VM::is_floppy_disk_protected(int drv, bool value)
1278 #if defined(_PC9801) || defined(_PC9801E)
1279 if(drv == 0 || drv == 1) {
1280 fdc_2hd->is_disk_protected(drv, value);
1281 } else if(drv == 2 || drv == 3) {
1282 fdc_2dd->is_disk_protected(drv - 2, value);
1283 } else if(drv == 4 || drv == 5) {
1284 fdc_sub->is_disk_protected(drv - 4, value);
1286 #elif defined(_PC9801VF) || defined(_PC9801U)
1287 if(drv == 0 || drv == 1) {
1288 fdc_2dd->is_disk_protected(drv, value);
1290 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1291 if(drv == 0 || drv == 1) {
1292 fdc->is_disk_protected(drv, value);
1293 } else if(drv == 2 || drv == 3) {
1294 pc88fdc_sub->is_disk_protected(drv - 2, value);
1297 if(drv == 0 || drv == 1) {
1298 fdc->is_disk_protected(drv, value);
1303 bool VM::is_floppy_disk_protected(int drv)
1305 #if defined(_PC9801) || defined(_PC9801E)
1306 if(drv == 0 || drv == 1) {
1307 return fdc_2hd->is_disk_protected(drv);
1308 } else if(drv == 2 || drv == 3) {
1309 return fdc_2dd->is_disk_protected(drv - 2);
1310 } else if(drv == 4 || drv == 5) {
1311 return fdc_sub->is_disk_protected(drv - 4);
1313 #elif defined(_PC9801VF) || defined(_PC9801U)
1314 if(drv == 0 || drv == 1) {
1315 return fdc_2dd->is_disk_protected(drv);
1317 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1318 if(drv == 0 || drv == 1) {
1319 return fdc->is_disk_protected(drv);
1320 } else if(drv == 2 || drv == 3) {
1321 return pc88fdc_sub->is_disk_protected(drv - 2);
1324 if(drv == 0 || drv == 1) {
1325 return fdc->is_disk_protected(drv);
1331 uint32_t VM::is_floppy_disk_accessed()
1333 #if defined(_PC9801) || defined(_PC9801E)
1334 return (fdc_2hd->read_signal(0) & 3) | ((fdc_2dd->read_signal(0) & 3) << 2) | ((fdc_sub->read_signal(0) & 3) << 4);
1335 #elif defined(_PC9801VF) || defined(_PC9801U)
1336 return fdc_2dd->read_signal(0);
1337 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1338 if(boot_mode != 0) {
1339 return pc88fdc_sub->read_signal(0);
1341 return fdc->read_signal(0);
1344 return fdc->read_signal(0);
1348 #if defined(SUPPORT_CMT_IF) || defined(_PC98DO) || defined(_PC98DOPLUS)
1349 void VM::play_tape(int drv, const _TCHAR* file_path)
1351 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1352 pc88->play_tape(file_path);
1354 cmt->play_tape(file_path);
1358 void VM::rec_tape(int drv, const _TCHAR* file_path)
1360 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1361 pc88->rec_tape(file_path);
1363 cmt->rec_tape(file_path);
1367 void VM::close_tape(int drv)
1369 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1376 bool VM::is_tape_inserted(int drv)
1378 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1379 return pc88->is_tape_inserted();
1381 return cmt->is_tape_inserted();
1386 bool VM::is_frame_skippable()
1388 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1389 if(boot_mode != 0) {
1390 // return pc88event->is_frame_skippable();
1391 return pc88->is_frame_skippable();
1394 return event->is_frame_skippable();
1397 void VM::update_config()
1399 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1400 if(boot_mode != config.boot_mode) {
1401 // boot mode is changed !!!
1402 boot_mode = config.boot_mode;
1406 for(DEVICE* device = first_device; device; device = device->next_device) {
1407 device->update_config();
1411 #define STATE_VERSION 9
1413 void VM::save_state(FILEIO* state_fio)
1415 state_fio->FputUint32(STATE_VERSION);
1417 for(DEVICE* device = first_device; device; device = device->next_device) {
1418 device->save_state(state_fio);
1420 state_fio->Fwrite(ram, sizeof(ram), 1);
1421 state_fio->FputBool(pit_clock_8mhz);
1422 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1423 state_fio->FputInt32(boot_mode);
1425 state_fio->FputInt32(sound_type);
1428 bool VM::load_state(FILEIO* state_fio)
1430 if(state_fio->FgetUint32() != STATE_VERSION) {
1433 for(DEVICE* device = first_device; device; device = device->next_device) {
1434 if(!device->load_state(state_fio)) {
1438 state_fio->Fread(ram, sizeof(ram), 1);
1439 pit_clock_8mhz = state_fio->FgetBool();
1440 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1441 boot_mode = state_fio->FgetInt32();
1443 sound_type = state_fio->FgetInt32();