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-98XA Emulator 'ePC-98XA'
10 NEC PC-98XL Emulator 'ePC-98XL'
11 NEC PC-98RL Emulator 'ePC-98RL'
12 NEC PC-98DO Emulator 'ePC-98DO'
14 Author : Takeda.Toshiya
21 #include "../../emu.h"
22 #include "../device.h"
25 #if defined(SUPPORT_OLD_BUZZER)
29 #if defined(USE_HARD_DISK)
30 #include "../harddisk.h"
37 #if defined(HAS_I386) || defined(HAS_I486)
39 #elif defined(HAS_I86) || defined(HAS_V30)
46 #include "../memory.h"
49 #if !defined(SUPPORT_OLD_BUZZER)
50 #include "../pcm1bit.h"
52 //#include "../pcpr201.h"
53 #include "../prnfile.h"
54 #if defined(SUPPORT_SASI_IF) || defined(SUPPORT_SCSI_IF)
55 #include "../scsi_hdd.h"
56 #include "../scsi_host.h"
58 #include "../tms3631.h"
59 #include "../upd1990a.h"
60 #include "../upd7220.h"
61 #include "../upd765a.h"
62 #include "../ym2203.h"
65 #include "../debugger.h"
68 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
79 #if defined(SUPPORT_SASI_IF)
82 #if defined(SUPPORT_SCSI_IF)
85 #if defined(SUPPORT_IDE_IF)
89 #if defined(SUPPORT_320KB_FDD_IF)
90 #include "../pc80s31k.h"
93 #if defined(SUPPORT_CMT_IF)
97 #if defined(_PC98DO) || defined(_PC98DOPLUS)
98 #include "../pc80s31k.h"
100 #include "../pc8801/pc88.h"
103 // ----------------------------------------------------------------------------
105 // ----------------------------------------------------------------------------
107 VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
110 #if defined(_PC98DO) || defined(_PC98DOPLUS)
111 boot_mode = config.boot_mode;
113 int cpu_clocks = CPU_CLOCKS;
114 #if defined(PIT_CLOCK_8MHZ)
115 pit_clock_8mhz = true;
117 pit_clock_8mhz = false;
119 #if defined(_PC9801E)
120 if(config.cpu_type != 0) {
122 cpu_clocks = 4992030;
123 pit_clock_8mhz = false;
125 #elif defined(_PC9801VM) || defined(_PC98DO) || defined(_PC98DOPLUS) || defined(_PC9801VX) || defined(_PC98XL)
126 if(config.cpu_type != 0) {
127 // 10MHz/16MHz -> 8MHz
128 cpu_clocks = 7987248;
129 pit_clock_8mhz = true;
131 #elif defined(_PC9801RA) || defined(_PC98RL)
132 if(config.cpu_type != 0) {
134 cpu_clocks = 15974496;
135 pit_clock_8mhz = true;
138 int pit_clocks = pit_clock_8mhz ? 1996812 : 2457600;
140 sound_type = config.sound_type;
143 first_device = last_device = NULL;
144 dummy = new DEVICE(this, emu); // must be 1st device
145 event = new EVENT(this, emu); // must be 2nd device
147 #if defined(SUPPORT_OLD_BUZZER)
148 beep = new BEEP(this, emu);
150 beep = new PCM1BIT(this, emu);
152 dma = new I8237(this, emu);
153 #if defined(SUPPORT_CMT_IF)
154 sio_cmt = new I8251(this, emu); // for cmt
155 sio_cmt->set_device_name(_T("8251 SIO (CMT)"));
157 sio_rs = new I8251(this, emu); // for rs232c
158 sio_rs->set_device_name(_T("8251 SIO (RS-232C)"));
159 sio_kbd = new I8251(this, emu); // for keyboard
160 sio_kbd->set_device_name(_T("8251 SIO (Keyboard)"));
161 pit = new I8253(this, emu);
162 #if defined(SUPPORT_320KB_FDD_IF)
163 pio_fdd = new I8255(this, emu); // for 320kb fdd i/f
164 pio_fdd->set_device_name(_T("8255 PIO (320KB I/F)"));
166 pio_mouse = new I8255(this, emu); // for mouse
167 pio_mouse->set_device_name(_T("8255 PIO (Mouse)"));
168 pio_sys = new I8255(this, emu); // for system port
169 pio_sys->set_device_name(_T("8255 PIO (System)"));
170 pio_prn = new I8255(this, emu); // for printer
171 pio_prn->set_device_name(_T("8255 PIO (Printer)"));
172 pic = new I8259(this, emu);
173 #if defined(HAS_I386) || defined(HAS_I486)
174 cpu = new I386(this, emu); // 80386, 80486
175 #elif defined(HAS_I86) || defined(HAS_V30)
176 cpu = new I286(this, emu);// 8086, V30, 80286
178 cpu = new I286(this, emu);
181 cpu->set_device_name(_T("CPU(i8086)"));
182 #elif defined(HAS_I386)
183 cpu->set_device_name(_T("CPU(i386)"));
184 #elif defined(HAS_I486)
185 cpu->set_device_name(_T("CPU(i486)"));
186 #elif defined(HAS_PENTIUM)
187 cpu->set_device_name(_T("CPU(Pentium)"));
188 #elif defined(HAS_V33A)
189 cpu->set_device_name(_T("CPU(V33A)"));
190 #elif defined(HAS_V30)
191 cpu->set_device_name(_T("CPU(V30)"));
193 cpu->set_device_name(_T("CPU(i286)"));
195 io = new IO(this, emu);
196 rtcreg = new LS244(this, emu);
197 rtcreg->set_device_name(_T("74LS244 (RTC)"));
198 //memory = new MEMORY(this, emu);
199 memory = new MEMBUS(this, emu);
200 not_busy = new NOT(this, emu);
201 not_busy->set_device_name(_T("NOT Gate (Printer Busy)"));
202 #if defined(HAS_I86) || defined(HAS_V30)
203 not_prn = new NOT(this, emu);
204 not_prn->set_device_name(_T("NOT Gate (Printer IRQ)"));
206 rtc = new UPD1990A(this, emu);
207 #if defined(SUPPORT_2HD_FDD_IF)
208 fdc_2hd = new UPD765A(this, emu);
209 fdc_2hd->set_device_name(_T("uPD765A FDC (2HD I/F)"));
211 #if defined(SUPPORT_2DD_FDD_IF)
212 fdc_2dd = new UPD765A(this, emu);
213 fdc_2dd->set_device_name(_T("uPD765A FDC (2DD I/F)"));
215 #if defined(SUPPORT_2HD_2DD_FDD_IF)
216 fdc = new UPD765A(this, emu);
217 fdc->set_device_name(_T("uPD765A FDC (2HD/2DD I/F)"));
219 noise_seek = new NOISE(this, emu);
220 noise_head_down = new NOISE(this, emu);
221 noise_head_up = new NOISE(this, emu);
222 #if defined(SUPPORT_SASI_IF)
223 sasi_host = new SCSI_HOST(this, emu);
224 sasi_hdd = new SCSI_HDD(this, emu);
225 sasi_hdd->set_device_name(_T("SASI Hard Disk Drive"));
226 sasi_hdd->scsi_id = 0;
227 sasi_hdd->bytes_per_sec = 625 * 1024; // 625KB/s
228 for(int i = 0; i < USE_HARD_DISK; i++) {
229 sasi_hdd->set_disk_handler(i, new HARDDISK(emu));
231 sasi_hdd->set_context_interface(sasi_host);
232 sasi_host->set_context_target(sasi_hdd);
234 #if defined(SUPPORT_SCSI_IF)
235 scsi_host = new SCSI_HOST(this, emu);
236 for(int i = 0; i < USE_HARD_DISK; i++) {
237 scsi_hdd[i] = new SCSI_HDD(this, emu);
238 scsi_hdd[i]->set_device_name(_T("SCSI Hard Disk Drive #%d"), i + 1);
239 scsi_hdd[i]->scsi_id = i;
240 scsi_hdd[i]->set_disk_handler(0, new HARDDISK(emu));
241 scsi_hdd[i]->set_context_interface(scsi_host);
242 scsi_host->set_context_target(scsi_hdd[i]);
245 gdc_chr = new UPD7220(this, emu);
246 gdc_chr->set_device_name(_T("uPD7220 GDC (Character)"));
247 gdc_gfx = new UPD7220(this, emu);
248 gdc_gfx->set_device_name(_T("uPD7220 GDC (Graphics)"));
250 if(sound_type == 0 || sound_type == 1) {
251 opn = new YM2203(this, emu);
252 #ifdef SUPPORT_PC98_OPNA
253 opn->is_ym2608 = true;
255 fmsound = new FMSOUND(this, emu);
256 joystick = new JOYSTICK(this, emu);
257 } else if(sound_type == 2 || sound_type == 3) {
258 tms3631 = new TMS3631(this, emu);
259 tms3631->set_device_name(_T("TMS3631 SSG (PC-9801-14)"));
260 pit_14 = new I8253(this, emu);
261 pit_14->set_device_name(_T("8253 PIT (PC-9801-14)"));
262 pio_14 = new I8255(this, emu);
263 pio_14->set_device_name(_T("8255 PIO (PC-9801-14)"));
264 maskreg_14 = new LS244(this, emu);
265 maskreg_14->set_device_name(_T("74LS244 (PC-9801-14)"));
267 if(config.printer_type == 0) {
268 printer = new PRNFILE(this, emu);
269 // } else if(config.printer_type == 1) {
270 // printer = new PCPR201(this, emu);
275 #if defined(SUPPORT_CMT_IF)
276 cmt = new CMT(this, emu);
278 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
279 cpureg = new CPUREG(this, emu);
281 display = new DISPLAY(this, emu);
282 dmareg = new DMAREG(this, emu);
283 floppy = new FLOPPY(this, emu);
284 keyboard = new KEYBOARD(this, emu);
285 mouse = new MOUSE(this, emu);
286 #if defined(SUPPORT_SASI_IF)
287 sasi = new SASI(this, emu);
289 #if defined(SUPPORT_SCSI_IF)
290 scsi = new SCSI(this, emu);
292 #if defined(SUPPORT_IDE_IF)
293 ide = new IDE(this, emu);
296 #if defined(SUPPORT_320KB_FDD_IF)
298 pio_sub = new I8255(this, emu);
299 pio_sub->set_device_name(_T("8255 PIO (320KB FDD)"));
300 pc80s31k = new PC80S31K(this, emu);
301 pc80s31k->set_device_name(_T("PC-80S31K (320KB FDD)"));
302 fdc_sub = new UPD765A(this, emu);
303 fdc_sub->set_device_name(_T("uPD765A FDC (320KB FDD)"));
304 cpu_sub = new Z80(this, emu);
305 cpu_sub->set_device_name(_T("Z80 CPU (320KB FDD)"));
317 9 (INT3) PC-9801-27 (SASI), PC-9801-55 (SCSI), or IDE
318 10 (INT41) FDC (640KB I/F)
319 11 (INT42) FDC (1MB I/F)
320 12 (INT5) PC-9801-26(K) or PC-9801-14
327 event->set_context_cpu(cpu, cpu_clocks);
328 #if defined(SUPPORT_320KB_FDD_IF)
329 event->set_context_cpu(cpu_sub, 4000000);
331 event->set_context_sound(beep);
332 if(sound_type == 0 || sound_type == 1) {
333 event->set_context_sound(opn);
334 } else if(sound_type == 2 || sound_type == 3) {
335 event->set_context_sound(tms3631);
337 event->set_context_sound(noise_seek);
338 event->set_context_sound(noise_head_down);
339 event->set_context_sound(noise_head_up);
341 dma->set_context_memory(memory);
343 // dma ch.1: memory refresh
344 #if defined(SUPPORT_2HD_FDD_IF)
345 dma->set_context_ch2(fdc_2hd);
346 dma->set_context_tc2(fdc_2hd, SIG_UPD765A_TC, 1);
348 #if defined(SUPPORT_2DD_FDD_IF)
349 dma->set_context_ch3(fdc_2dd);
350 dma->set_context_tc3(fdc_2dd, SIG_UPD765A_TC, 1);
352 #if defined(SUPPORT_2HD_2DD_FDD_IF)
353 #if !defined(SUPPORT_HIRESO)
354 dma->set_context_ch2(fdc);
355 dma->set_context_ch3(fdc);
356 dma->set_context_tc2(fdc, SIG_UPD765A_TC, 1);
357 dma->set_context_tc3(fdc, SIG_UPD765A_TC, 1);
359 dma->set_context_ch1(fdc);
360 dma->set_context_tc1(fdc, SIG_UPD765A_TC, 1);
363 // sio_rs->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR4, 1);
364 sio_kbd->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR1, 1);
365 pit->set_context_ch0(pic, SIG_I8259_CHIP0 | SIG_I8259_IR0, 1);
366 #if defined(SUPPORT_OLD_BUZZER)
367 // pit ch.1: memory refresh
370 pit->set_context_ch1(beep, SIG_PCM1BIT_SIGNAL, 1);
373 pit->set_constant_clock(0, pit_clocks);
374 pit->set_constant_clock(1, pit_clocks);
375 pit->set_constant_clock(2, pit_clocks);
376 pio_mouse->set_context_port_c(mouse, SIG_MOUSE_PORT_C, 0xf0, 0);
377 #if defined(SUPPORT_HIRESO)
378 // sysport port.c bit7,5: sysport port.b bit4,3
379 pio_sys->set_context_port_c(pio_sys, SIG_I8255_PORT_B, 0x80, -3); // SHUT0
380 pio_sys->set_context_port_c(pio_sys, SIG_I8255_PORT_B, 0x20, -2); // SHUT1
382 // sysport port.c bit6: printer strobe
383 #if defined(SUPPORT_OLD_BUZZER)
384 pio_sys->set_context_port_c(beep, SIG_BEEP_MUTE, 0x08, 0);
386 pio_sys->set_context_port_c(beep, SIG_PCM1BIT_MUTE, 0x08, 0);
388 // sysport port.c bit2: enable txrdy interrupt
389 // sysport port.c bit1: enable txempty interrupt
390 // sysport port.c bit0: enable rxrdy interrupt
391 pio_prn->set_context_port_a(printer, SIG_PRINTER_DATA, 0xff, 0);
392 pio_prn->set_context_port_c(printer, SIG_PRINTER_STROBE, 0x80, 0);
393 if(config.printer_type == 0) {
394 PRNFILE *prnfile = (PRNFILE *)printer;
395 prnfile->set_context_busy(not_busy, SIG_NOT_INPUT, 1);
396 // } else if(config.printer_type == 1) {
397 // PRNFILE *pcpr201 = (PCPR201 *)printer;
398 // pcpr201->set_context_busy(not_busy, SIG_NOT_INPUT, 1);
400 not_busy->set_context_out(pio_prn, SIG_I8255_PORT_B, 4);
401 #if defined(HAS_I86) || defined(HAS_V30)
402 pio_prn->set_context_port_c(not_prn, SIG_NOT_INPUT, 8, 0);
403 not_prn->set_context_out(pic, SIG_I8259_CHIP1 | SIG_I8259_IR0, 1);
405 rtcreg->set_context_output(rtc, SIG_UPD1990A_CMD, 0x07, 0);
406 rtcreg->set_context_output(rtc, SIG_UPD1990A_DIN, 0x20, 0);
407 rtcreg->set_context_output(rtc, SIG_UPD1990A_STB, 0x08, 0);
408 rtcreg->set_context_output(rtc, SIG_UPD1990A_CLK, 0x10, 0);
409 pic->set_context_cpu(cpu);
410 rtc->set_context_dout(pio_sys, SIG_I8255_PORT_B, 1);
412 if(sound_type == 0 || sound_type == 1) {
413 opn->set_context_irq(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1);
414 opn->set_context_port_b(joystick, SIG_JOYSTICK_SELECT, 0xc0, 0);
415 fmsound->set_context_opn(opn);
416 joystick->set_context_opn(opn);
417 } else if(sound_type == 2 || sound_type == 3) {
418 pio_14->set_context_port_a(tms3631, SIG_TMS3631_ENVELOP1, 0xff, 0);
419 pio_14->set_context_port_b(tms3631, SIG_TMS3631_ENVELOP2, 0xff, 0);
420 pio_14->set_context_port_c(tms3631, SIG_TMS3631_DATAREG, 0xff, 0);
421 maskreg_14->set_context_output(tms3631, SIG_TMS3631_MASKREG, 0xff, 0);
422 pit_14->set_constant_clock(2, 1996800 / 8);
423 pit_14->set_context_ch2(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1);
426 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
427 cpureg->set_context_cpu(cpu);
429 display->set_context_pic(pic);
430 display->set_context_gdc_chr(gdc_chr, gdc_chr->get_ra());
431 display->set_context_gdc_gfx(gdc_gfx, gdc_gfx->get_ra(), gdc_gfx->get_cs());
432 dmareg->set_context_dma(dma);
433 keyboard->set_context_sio(sio_kbd);
434 memory->set_context_display(display);
435 mouse->set_context_pic(pic);
436 mouse->set_context_pio(pio_mouse);
438 #if defined(SUPPORT_2HD_FDD_IF)
439 fdc_2hd->set_context_irq(floppy, SIG_FLOPPY_2HD_IRQ, 1);
440 fdc_2hd->set_context_drq(floppy, SIG_FLOPPY_2HD_DRQ, 1);
441 fdc_2hd->set_context_noise_seek(noise_seek);
442 fdc_2hd->set_context_noise_head_down(noise_head_down);
443 fdc_2hd->set_context_noise_head_up(noise_head_up);
444 fdc_2hd->raise_irq_when_media_changed = true;
445 floppy->set_context_fdc_2hd(fdc_2hd);
447 #if defined(SUPPORT_2DD_FDD_IF)
448 fdc_2dd->set_context_irq(floppy, SIG_FLOPPY_2DD_IRQ, 1);
449 fdc_2dd->set_context_drq(floppy, SIG_FLOPPY_2DD_DRQ, 1);
450 fdc_2dd->set_context_noise_seek(noise_seek);
451 fdc_2dd->set_context_noise_head_down(noise_head_down);
452 fdc_2dd->set_context_noise_head_up(noise_head_up);
453 fdc_2dd->raise_irq_when_media_changed = true;
454 floppy->set_context_fdc_2dd(fdc_2dd);
456 #if defined(SUPPORT_2HD_2DD_FDD_IF)
457 fdc->set_context_irq(floppy, SIG_FLOPPY_IRQ, 1);
458 fdc->set_context_drq(floppy, SIG_FLOPPY_DRQ, 1);
459 fdc->set_context_noise_seek(noise_seek);
460 fdc->set_context_noise_head_down(noise_head_down);
461 fdc->set_context_noise_head_up(noise_head_up);
462 fdc->raise_irq_when_media_changed = true;
463 floppy->set_context_fdc(fdc);
465 floppy->set_context_dma(dma);
466 floppy->set_context_pic(pic);
468 #if defined(SUPPORT_SASI_IF)
469 #if !defined(SUPPORT_HIRESO)
470 sasi_host->set_context_irq(pio_sys, SIG_I8255_PORT_B, 0x10);
472 sasi_host->set_context_irq(sasi, SIG_SASI_IRQ, 1);
473 sasi_host->set_context_drq(sasi, SIG_SASI_DRQ, 1);
475 dma->set_context_ch3(sasi_host);
476 dma->set_context_tc3(sasi, SIG_SASI_TC, 1);
478 dma->set_context_ch0(sasi_host);
479 dma->set_context_tc0(sasi, SIG_SASI_TC, 1);
481 sasi->set_context_host(sasi_host);
482 sasi->set_context_hdd(sasi_hdd);
483 sasi->set_context_dma(dma);
484 sasi->set_context_pic(pic);
486 #if defined(SUPPORT_SCSI_IF)
487 dma->set_context_ch0(scsi);
488 scsi->set_context_dma(dma);
489 scsi->set_context_pic(pic);
491 #if defined(SUPPORT_IDE_IF)
492 dma->set_context_ch0(ide);
493 ide->set_context_dma(dma);
494 ide->set_context_pic(pic);
497 #if defined(SUPPORT_CMT_IF)
498 sio_cmt->set_context_out(cmt, SIG_CMT_OUT);
499 // sio_cmt->set_context_txrdy(cmt, SIG_CMT_TXRDY, 1);
500 // sio_cmt->set_context_rxrdy(cmt, SIG_CMT_RXRDY, 1);
501 // sio_cmt->set_context_txe(cmt, SIG_CMT_TXEMP, 1);
502 cmt->set_context_sio(sio_cmt);
506 cpu->set_context_mem(memory);
507 cpu->set_context_io(io);
508 cpu->set_context_intr(pic);
509 #ifdef SINGLE_MODE_DMA
510 cpu->set_context_dma(dma);
513 cpu->set_context_debugger(new DEBUGGER(this, emu));
516 #if defined(SUPPORT_320KB_FDD_IF)
518 pc80s31k->set_context_cpu(cpu_sub);
519 pc80s31k->set_context_fdc(fdc_sub);
520 pc80s31k->set_context_pio(pio_sub);
521 pio_fdd->set_context_port_a(pio_sub, SIG_I8255_PORT_A, 0xff, 0);
522 pio_fdd->set_context_port_b(pio_sub, SIG_I8255_PORT_A, 0xff, 0);
523 pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0x0f, 4);
524 pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0xf0, -4);
525 pio_fdd->clear_ports_by_cmdreg = true;
526 pio_sub->set_context_port_a(pio_fdd, SIG_I8255_PORT_B, 0xff, 0);
527 pio_sub->set_context_port_b(pio_fdd, SIG_I8255_PORT_A, 0xff, 0);
528 pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0x0f, 4);
529 pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0xf0, -4);
530 pio_sub->clear_ports_by_cmdreg = true;
531 fdc_sub->set_context_irq(cpu_sub, SIG_CPU_IRQ, 1);
532 fdc_sub->set_context_noise_seek(noise_seek);
533 fdc_sub->set_context_noise_head_down(noise_head_down);
534 fdc_sub->set_context_noise_head_up(noise_head_up);
535 cpu_sub->set_context_mem(pc80s31k);
536 cpu_sub->set_context_io(pc80s31k);
537 cpu_sub->set_context_intr(pc80s31k);
539 cpu_sub->set_context_debugger(new DEBUGGER(this, emu));
544 io->set_iomap_alias_rw(0x0000, pic, 0);
545 io->set_iomap_alias_rw(0x0002, pic, 1);
546 io->set_iomap_alias_rw(0x0008, pic, 2);
547 io->set_iomap_alias_rw(0x000a, pic, 3);
549 io->set_iomap_alias_rw(0x0001, dma, 0x00);
550 io->set_iomap_alias_rw(0x0003, dma, 0x01);
551 io->set_iomap_alias_rw(0x0005, dma, 0x02);
552 io->set_iomap_alias_rw(0x0007, dma, 0x03);
553 io->set_iomap_alias_rw(0x0009, dma, 0x04);
554 io->set_iomap_alias_rw(0x000b, dma, 0x05);
555 io->set_iomap_alias_rw(0x000d, dma, 0x06);
556 io->set_iomap_alias_rw(0x000f, dma, 0x07);
557 io->set_iomap_alias_rw(0x0011, dma, 0x08);
558 io->set_iomap_alias_w (0x0013, dma, 0x09);
559 io->set_iomap_alias_w (0x0015, dma, 0x0a);
560 io->set_iomap_alias_w (0x0017, dma, 0x0b);
561 io->set_iomap_alias_w (0x0019, dma, 0x0c);
562 io->set_iomap_alias_rw(0x001b, dma, 0x0d);
563 io->set_iomap_alias_w (0x001d, dma, 0x0e);
564 io->set_iomap_alias_w (0x001f, dma, 0x0f);
565 io->set_iomap_single_w(0x0021, dmareg);
566 io->set_iomap_single_w(0x0023, dmareg);
567 io->set_iomap_single_w(0x0025, dmareg);
568 io->set_iomap_single_w(0x0027, dmareg);
569 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
570 io->set_iomap_single_w(0x0029, dmareg);
572 #if defined(SUPPORT_32BIT_ADDRESS)
573 io->set_iomap_single_w(0x0e05, dmareg);
574 io->set_iomap_single_w(0x0e07, dmareg);
575 io->set_iomap_single_w(0x0e09, dmareg);
576 io->set_iomap_single_w(0x0e0b, dmareg);
579 io->set_iomap_single_w(0x0020, rtcreg);
581 io->set_iomap_alias_rw(0x0030, sio_rs, 0);
582 io->set_iomap_alias_rw(0x0032, sio_rs, 1);
584 io->set_iomap_alias_rw(0x0031, pio_sys, 0);
585 io->set_iomap_alias_rw(0x0033, pio_sys, 1);
586 io->set_iomap_alias_rw(0x0035, pio_sys, 2);
587 io->set_iomap_alias_w (0x0037, pio_sys, 3);
589 io->set_iomap_alias_rw(0x0040, pio_prn, 0);
590 io->set_iomap_alias_rw(0x0042, pio_prn, 1);
591 io->set_iomap_alias_rw(0x0044, pio_prn, 2);
592 io->set_iomap_alias_w (0x0046, pio_prn, 3);
594 io->set_iomap_alias_rw(0x0041, sio_kbd, 0);
595 io->set_iomap_alias_rw(0x0043, sio_kbd, 1);
597 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
598 io->set_iomap_single_w(0x0050, cpureg);
599 io->set_iomap_single_w(0x0052, cpureg);
602 #if defined(SUPPORT_320KB_FDD_IF)
603 io->set_iomap_alias_rw(0x0051, pio_fdd, 0);
604 io->set_iomap_alias_rw(0x0053, pio_fdd, 1);
605 io->set_iomap_alias_rw(0x0055, pio_fdd, 2);
606 io->set_iomap_alias_w (0x0057, pio_fdd, 3);
609 io->set_iomap_alias_rw(0x0060, gdc_chr, 0);
610 io->set_iomap_alias_rw(0x0062, gdc_chr, 1);
612 io->set_iomap_single_w(0x64, display);
613 io->set_iomap_single_w(0x68, display);
614 #if defined(SUPPORT_16_COLORS)
615 io->set_iomap_single_w(0x6a, display);
617 io->set_iomap_single_w(0x6c, display);
618 io->set_iomap_single_w(0x6e, display);
620 io->set_iomap_single_w(0x70, display);
621 io->set_iomap_single_w(0x72, display);
622 io->set_iomap_single_w(0x74, display);
623 io->set_iomap_single_w(0x76, display);
624 io->set_iomap_single_w(0x78, display);
625 io->set_iomap_single_w(0x7a, display);
626 #if defined(SUPPORT_GRCG)
627 #if !defined(SUPPORT_HIRESO)
628 io->set_iomap_single_w(0x007c, display);
629 io->set_iomap_single_w(0x007e, display);
631 io->set_iomap_single_w(0x00a4, display);
632 io->set_iomap_single_w(0x00a6, display);
636 #if defined(SUPPORT_SASI_IF)
637 io->set_iomap_single_rw(0x0080, sasi);
638 io->set_iomap_single_rw(0x0082, sasi);
640 #if defined(SUPPORT_SCSI_IF)
641 io->set_iomap_single_rw(0x0cc0, scsi);
642 io->set_iomap_single_rw(0x0cc2, scsi);
643 io->set_iomap_single_rw(0x0cc4, scsi);
645 #if defined(SUPPORT_IDE_IF)
646 io->set_iomap_single_rw(0x0640, ide);
647 io->set_iomap_single_rw(0x0642, ide);
648 io->set_iomap_single_rw(0x0644, ide);
649 io->set_iomap_single_rw(0x0646, ide);
650 io->set_iomap_single_rw(0x0648, ide);
651 io->set_iomap_single_rw(0x064a, ide);
652 io->set_iomap_single_rw(0x064c, ide);
653 io->set_iomap_single_rw(0x064e, ide);
654 io->set_iomap_single_rw(0x074c, ide);
655 io->set_iomap_single_rw(0x074e, ide);
658 io->set_iomap_alias_rw(0x00a0, gdc_gfx, 0);
659 io->set_iomap_alias_rw(0x00a2, gdc_gfx, 1);
661 #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO)
662 io->set_iomap_single_rw(0x00a4, display);
663 io->set_iomap_single_rw(0x00a6, display);
665 io->set_iomap_single_rw(0xa8, display);
666 io->set_iomap_single_rw(0xaa, display);
667 io->set_iomap_single_rw(0xac, display);
668 io->set_iomap_single_rw(0xae, display);
670 // io->set_iomap_single_w(0xa1, display);
671 // io->set_iomap_single_w(0xa3, display);
672 // io->set_iomap_single_w(0xa5, display);
673 io->set_iomap_single_rw(0xa1, display);
674 io->set_iomap_single_rw(0xa3, display);
675 io->set_iomap_single_rw(0xa5, display);
676 io->set_iomap_single_rw(0xa9, display);
677 #if defined(SUPPORT_EGC)
678 io->set_iomap_range_rw(0x04a0, 0x04af, display);
681 io->set_iomap_alias_rw(0x0071, pit, 0);
682 io->set_iomap_alias_rw(0x0073, pit, 1);
683 io->set_iomap_alias_rw(0x0075, pit, 2);
684 io->set_iomap_alias_w (0x0077, pit, 3);
686 io->set_iomap_single_rw(0x0090, floppy);
687 io->set_iomap_single_rw(0x0092, floppy);
688 io->set_iomap_single_rw(0x0094, floppy);
689 io->set_iomap_single_rw(0x0096, floppy);
690 #if defined(SUPPORT_2HD_2DD_FDD_IF)
691 #if !defined(SUPPORT_HIRESO)
692 io->set_iomap_single_rw(0x00be, floppy);
694 //#if !defined(_PC98XA) && !defined(_PC98XL)
695 io->set_iomap_single_w (0x00be, floppy);
699 #if !defined(SUPPORT_HIRESO)
700 io->set_iomap_single_rw(0x00c8, floppy);
701 io->set_iomap_single_rw(0x00ca, floppy);
702 io->set_iomap_single_rw(0x00cc, floppy);
703 io->set_iomap_single_rw(0x00ce, floppy);
706 #if defined(SUPPORT_CMT_IF)
707 io->set_iomap_alias_rw(0x0091, sio_cmt, 0);
708 io->set_iomap_alias_rw(0x0093, sio_cmt, 1);
709 io->set_iomap_single_w(0x0095, cmt);
710 io->set_iomap_single_w(0x0097, cmt);
713 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
714 io->set_iomap_single_rw(0x00f0, cpureg);
715 io->set_iomap_single_rw(0x00f2, cpureg);
717 #if defined(SUPPORT_32BIT_ADDRESS)
718 io->set_iomap_single_rw(0x00f6, cpureg);
721 if(sound_type == 0 || sound_type == 1) {
722 io->set_iomap_single_rw(0x0188, fmsound);
723 io->set_iomap_single_rw(0x018a, fmsound);
724 #ifdef SUPPORT_PC98_OPNA
725 io->set_iomap_single_rw(0x018c, fmsound);
726 io->set_iomap_single_rw(0x018e, fmsound);
727 io->set_iomap_single_rw(0xa460, fmsound);
729 } else if(sound_type == 2 || sound_type == 3) {
730 io->set_iomap_alias_rw(0x0088, pio_14, 0);
731 io->set_iomap_alias_rw(0x008a, pio_14, 1);
732 io->set_iomap_alias_rw(0x008c, pio_14, 2);
733 io->set_iomap_alias_w(0x008e, pio_14, 3);
734 io->set_iovalue_single_r(0x008e, 0x08);
735 io->set_iomap_single_w(0x0188, maskreg_14);
736 io->set_iomap_single_w(0x018a, maskreg_14);
737 io->set_iomap_alias_rw(0x018c, pit_14, 2);
738 io->set_iomap_alias_w(0x018e, pit_14, 3);
739 // io->set_iovalue_single_r(0x018e, 0x00); // INT0
740 // io->set_iovalue_single_r(0x018e, 0x40); // INT41
741 io->set_iovalue_single_r(0x018e, 0x80); // INT5
742 // io->set_iovalue_single_r(0x018e, 0xc0); // INT6
745 //#if !defined(SUPPORT_HIRESO)
746 // io->set_iovalue_single_r(0x0431, 0x04); // bit2: 1 = Normal mode, 0 = Hireso mode
748 // io->set_iovalue_single_r(0x0431, 0x00);
750 #if defined(SUPPORT_ITF_ROM)
751 io->set_iomap_single_w(0x043d, memory);
753 #if !defined(SUPPORT_HIRESO)
754 io->set_iomap_single_w(0x043f, memory);
756 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
757 #if !defined(_PC98XA)
758 io->set_iomap_single_rw(0x0439, memory);
760 #if !defined(SUPPORT_HIRESO)
761 io->set_iomap_single_rw(0x0461, memory);
762 io->set_iomap_single_rw(0x0463, memory);
764 io->set_iomap_single_rw(0x0091, memory);
765 io->set_iomap_single_rw(0x0093, memory);
767 io->set_iomap_single_r(0x0567, memory);
769 #if defined(SUPPORT_32BIT_ADDRESS)
770 io->set_iomap_single_w(0x053d, memory);
773 #if !(defined(_PC9801) || defined(_PC9801E) || defined(SUPPORT_HIRESO))
774 io->set_iomap_alias_rw(0x3fd9, pit, 0);
775 io->set_iomap_alias_rw(0x3fdb, pit, 1);
776 io->set_iomap_alias_rw(0x3fdd, pit, 2);
777 io->set_iomap_alias_w (0x3fdf, pit, 3);
780 #if !defined(SUPPORT_HIRESO)
781 io->set_iomap_alias_rw(0x7fd9, pio_mouse, 0);
782 io->set_iomap_alias_rw(0x7fdb, pio_mouse, 1);
783 io->set_iomap_alias_rw(0x7fdd, pio_mouse, 2);
784 io->set_iomap_alias_w (0x7fdf, pio_mouse, 3);
785 io->set_iomap_single_rw(0xbfdb, mouse);
787 io->set_iomap_alias_rw(0x0061, pio_mouse, 0);
788 io->set_iomap_alias_rw(0x0063, pio_mouse, 1);
789 io->set_iomap_alias_rw(0x0065, pio_mouse, 2);
790 io->set_iomap_alias_rw(0x0067, pio_mouse, 3);
793 #if defined(_PC98DO) || defined(_PC98DOPLUS)
794 pc88event = new EVENT(this, emu);
795 pc88event->set_device_name(_T("Event Manager (PC-8801)"));
796 pc88event->set_frames_per_sec(60);
797 pc88event->set_lines_per_frame(260);
799 pc88 = new PC88(this, emu);
800 pc88->set_context_event_manager(pc88event);
801 pc88sio = new I8251(this, emu);
802 pc88sio->set_device_name(_T("8251 SIO (PC-8801)"));
803 pc88sio->set_context_event_manager(pc88event);
804 pc88pio = new I8255(this, emu);
805 pc88pio->set_device_name(_T("8255 PIO (PC-8801)"));
806 pc88pio->set_context_event_manager(pc88event);
807 pc88pcm = new PCM1BIT(this, emu);
808 pc88pcm->set_device_name(_T("1-Bit PCM Sound (PC-8801)"));
809 pc88pcm->set_context_event_manager(pc88event);
810 pc88rtc = new UPD1990A(this, emu);
811 pc88rtc->set_device_name(_T("uPD1990A RTC (PC-8801)"));
812 pc88rtc->set_context_event_manager(pc88event);
813 pc88opn = new YM2203(this, emu);
814 #ifdef SUPPORT_PC88_OPNA
815 pc88opn->set_device_name(_T("YM2608 OPNA (PC-8801)"));
816 pc88opn->is_ym2608 = true;
818 pc88opn->set_device_name(_T("YM2203 OPN (PC-8801)"));
820 pc88opn->set_context_event_manager(pc88event);
821 pc88cpu = new Z80(this, emu);
822 pc88cpu->set_device_name(_T("Z80 CPU (PC-8801)"));
823 pc88cpu->set_context_event_manager(pc88event);
825 if(config.printer_type == 0) {
826 pc88prn = new PRNFILE(this, emu);
827 pc88prn->set_context_event_manager(pc88event);
828 // } else if(config.printer_type == 1) {
829 // pc88prn = new PCPR201(this, emu);
830 // pc88prn->set_context_event_manager(pc88event);
835 pc88sub = new PC80S31K(this, emu);
836 pc88sub->set_device_name(_T("PC-80S31K (PC-8801 Sub)"));
837 pc88sub->set_context_event_manager(pc88event);
838 pc88pio_sub = new I8255(this, emu);
839 pc88pio_sub->set_device_name(_T("8255 PIO (PC-8801 Sub)"));
840 pc88pio_sub->set_context_event_manager(pc88event);
841 pc88fdc_sub = new UPD765A(this, emu);
842 pc88fdc_sub->set_device_name(_T("uPD765A FDC (PC-8801 Sub)"));
843 pc88fdc_sub->set_context_event_manager(pc88event);
844 pc88noise_seek = new NOISE(this, emu);
845 pc88noise_seek->set_context_event_manager(pc88event);
846 pc88noise_head_down = new NOISE(this, emu);
847 pc88noise_head_down->set_context_event_manager(pc88event);
848 pc88noise_head_up = new NOISE(this, emu);
849 pc88noise_head_up->set_context_event_manager(pc88event);
850 pc88cpu_sub = new Z80(this, emu);
851 pc88cpu_sub->set_device_name(_T("Z80 CPU (PC-8801 Sub)"));
852 pc88cpu_sub->set_context_event_manager(pc88event);
854 pc88event->set_context_cpu(pc88cpu, (config.cpu_type == 1) ? 3993624 : 7987248);
855 pc88event->set_context_cpu(pc88cpu_sub, 3993624);
856 pc88event->set_context_sound(pc88opn);
857 pc88event->set_context_sound(pc88pcm);
858 pc88event->set_context_sound(pc88noise_seek);
859 pc88event->set_context_sound(pc88noise_head_down);
860 pc88event->set_context_sound(pc88noise_head_up);
862 pc88->set_context_cpu(pc88cpu);
863 pc88->set_context_opn(pc88opn);
864 pc88->set_context_pcm(pc88pcm);
865 pc88->set_context_pio(pc88pio);
866 pc88->set_context_prn(pc88prn);
867 pc88->set_context_rtc(pc88rtc);
868 pc88->set_context_sio(pc88sio);
869 pc88cpu->set_context_mem(pc88);
870 pc88cpu->set_context_io(pc88);
871 pc88cpu->set_context_intr(pc88);
873 pc88cpu->set_context_debugger(new DEBUGGER(this, emu));
875 pc88opn->set_context_irq(pc88, SIG_PC88_SOUND_IRQ, 1);
876 pc88sio->set_context_rxrdy(pc88, SIG_PC88_USART_IRQ, 1);
877 pc88sio->set_context_out(pc88, SIG_PC88_USART_OUT);
879 pc88sub->set_context_cpu(pc88cpu_sub);
880 pc88sub->set_context_fdc(pc88fdc_sub);
881 pc88sub->set_context_pio(pc88pio_sub);
882 pc88pio->set_context_port_a(pc88pio_sub, SIG_I8255_PORT_B, 0xff, 0);
883 pc88pio->set_context_port_b(pc88pio_sub, SIG_I8255_PORT_A, 0xff, 0);
884 pc88pio->set_context_port_c(pc88pio_sub, SIG_I8255_PORT_C, 0x0f, 4);
885 pc88pio->set_context_port_c(pc88pio_sub, SIG_I8255_PORT_C, 0xf0, -4);
886 pc88pio->clear_ports_by_cmdreg = true;
887 pc88pio_sub->set_context_port_a(pc88pio, SIG_I8255_PORT_B, 0xff, 0);
888 pc88pio_sub->set_context_port_b(pc88pio, SIG_I8255_PORT_A, 0xff, 0);
889 pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0x0f, 4);
890 pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0xf0, -4);
891 pc88pio_sub->clear_ports_by_cmdreg = true;
892 pc88fdc_sub->set_context_irq(pc88cpu_sub, SIG_CPU_IRQ, 1);
893 pc88fdc_sub->set_context_noise_seek(pc88noise_seek);
894 pc88fdc_sub->set_context_noise_head_down(pc88noise_head_down);
895 pc88fdc_sub->set_context_noise_head_up(pc88noise_head_up);
896 pc88cpu_sub->set_context_mem(pc88sub);
897 pc88cpu_sub->set_context_io(pc88sub);
898 pc88cpu_sub->set_context_intr(pc88sub);
900 pc88cpu_sub->set_context_debugger(new DEBUGGER(this, emu));
904 // initialize all devices
905 #if defined(__GIT_REPO_VERSION)
906 strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1);
908 for(DEVICE* device = first_device; device; device = device->next_device) {
909 device->initialize();
913 #if defined(_PC9801) || defined(_PC9801E)
914 fdc_2hd->get_disk_handler(0)->drive_num = 0;
915 fdc_2hd->get_disk_handler(1)->drive_num = 1;
916 fdc_2dd->get_disk_handler(0)->drive_num = 2;
917 fdc_2dd->get_disk_handler(1)->drive_num = 3;
918 fdc_sub->get_disk_handler(0)->drive_num = 4;
919 fdc_sub->get_disk_handler(1)->drive_num = 5;
920 #elif defined(_PC9801VF) || defined(_PC9801U)
921 fdc_2dd->get_disk_handler(0)->drive_num = 0;
922 fdc_2dd->get_disk_handler(1)->drive_num = 1;
923 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
924 fdc->get_disk_handler(0)->drive_num = 0;
925 fdc->get_disk_handler(1)->drive_num = 1;
926 pc88fdc_sub->get_disk_handler(0)->drive_num = 2;
927 pc88fdc_sub->get_disk_handler(1)->drive_num = 3;
929 fdc->get_disk_handler(0)->drive_num = 0;
930 fdc->get_disk_handler(1)->drive_num = 1;
932 #if defined(USE_HARD_DISK)
933 for(int drv = 0; drv < USE_HARD_DISK; drv++) {
934 #if defined(SUPPORT_SASI_IF)
935 #if defined(OPEN_HARD_DISK_IN_RESET)
936 create_local_path(hd_file_path[drv], _MAX_PATH, _T("SASI%d.DAT"), drv);
938 open_hard_disk_tmp(drv, create_local_path(_T("SASI%d.DAT"), drv));
941 #if defined(SUPPORT_SCSI_IF)
942 #if defined(OPEN_HARD_DISK_IN_RESET)
943 create_local_path(hd_file_path[drv], _MAX_PATH, _T("SCSI%d.DAT"), drv);
945 open_hard_disk_tmp(drv, create_local_path(_T("SCSI%d.DAT"), drv));
948 #if defined(SUPPORT_IDE_IF)
949 #if defined(OPEN_HARD_DISK_IN_RESET)
950 create_local_path(hd_file_path[drv], _MAX_PATH, _T("IDE%d.DAT"), drv);
952 open_hard_disk_tmp(drv, create_local_path(_T("IDE%d.DAT"), drv));
961 // delete all devices
962 for(DEVICE* device = first_device; device;) {
963 DEVICE *next_device = device->next_device;
966 device = next_device;
970 DEVICE* VM::get_device(int id)
972 for(DEVICE* device = first_device; device; device = device->next_device) {
973 if(device->this_device_id == id) {
980 // ----------------------------------------------------------------------------
981 // drive virtual machine
982 // ----------------------------------------------------------------------------
987 for(DEVICE* device = first_device; device; device = device->next_device) {
990 #if defined(_PC98DO) || defined(_PC98DOPLUS)
991 for(DEVICE* device = first_device; device; device = device->next_device) {
996 // initial device settings
997 uint8_t port_a, port_b, port_c;
999 port_a = 0xf0; // Clear mouse buttons and counters
1001 #if defined(_PC98XA)
1002 port_b |= (uint8_t)((RAM_SIZE - 0x100000) / 0x40000);
1004 #if defined(SUPPORT_HIRESO)
1005 port_b |= 0x80; // DIP SW 1-4, 1 = External FDD #3/#4, 0 = #1/#2
1007 port_b |= 0x40; // DIP SW 3-6, 1 = Enable internal RAM 80000h-9FFFFh
1008 #if defined(_PC98RL)
1009 port_b |= 0x10; // DIP SW 3-3, 1 = DMA ch.0 for SASI-HDD
1011 #if defined(USE_CPU_TYPE)
1012 if(config.cpu_type != 0) {
1013 #if !defined(SUPPORT_HIRESO)
1014 port_b |= 0x02; // SPDSW, 1 = 10MHz, 0 = 12MHz
1016 port_b |= 0x01; // SPDSW, 1 = 8/16MHz, 0 = 10/20MHz
1022 #if defined(SUPPORT_HIRESO)
1023 // port_c |= 0x08; // MODSW, 1 = Normal Mode, 0 = Hirezo Mode
1025 #if defined(HAS_V30) || defined(HAS_V33)
1026 port_c |= 0x04; // DIP SW 3-8, 1 = V30, 0 = 80x86
1028 pio_mouse->write_signal(SIG_I8255_PORT_A, port_a, 0xff);
1029 pio_mouse->write_signal(SIG_I8255_PORT_B, port_b, 0xff);
1030 pio_mouse->write_signal(SIG_I8255_PORT_C, port_c, 0xff);
1033 port_a |= 0x80; // DIP SW 2-8, 1 = GDC 2.5MHz, 0 = GDC 5MHz
1034 port_a |= 0x40; // DIP SW 2-7, 1 = Do not control FD motor
1035 port_a |= 0x20; // DIP SW 2-6, 1 = Enable internal HD
1036 // port_a |= 0x10; // DIP SW 2-5, 1 = Initialize emory switch
1037 // port_a |= 0x08; // DIP SW 2-4, 1 = 20 lines, 0 = 25 lines
1038 // port_a |= 0x04; // DIP SW 2-3, 1 = 40 columns, 0 = 80 columns
1039 port_a |= 0x02; // DIP SW 2-2, 1 = BASIC mode, 0 = Terminal mode
1040 port_a |= 0x01; // DIP SW 2-1, 1 = Normal mode, 0 = LT mode
1042 port_b |= 0x80; // RS-232C CI#, 1 = OFF
1043 port_b |= 0x40; // RS-232C CS#, 1 = OFF
1044 port_b |= 0x20; // RS-232C CD#, 1 = OFF
1045 #if !defined(SUPPORT_HIRESO)
1046 // port_b |= 0x10; // INT3, 1 = Active, 0 = Inactive
1047 port_b |= 0x08; // DIP SW 1-1, 1 = Hiresolution CRT, 0 = Standard CRT
1049 port_b |= 0x10; // SHUT0
1050 port_b |= 0x08; // SHUT1
1052 // port_b |= 0x04; // IMCK, 1 = Parity error occurs in internal RAM
1053 // port_b |= 0x02; // EMCK, 1 = Parity error occurs in external RAM
1054 // port_b |= 0x01; // CDAT
1056 port_c |= 0x80; // SHUT0
1057 port_c |= 0x40; // PSTBM, 1 = Mask printer's PSTB#
1058 port_c |= 0x20; // SHUT1
1059 port_c |= 0x10; // MCHKEN, 1 = Enable parity check for RAM
1060 port_c |= 0x08; // BUZ, 1 = Stop buzzer
1061 port_c |= 0x04; // TXRE, 1 = Enable IRQ from RS-232C 8251A TXRDY
1062 port_c |= 0x02; // TXEE, 1 = Enable IRQ from RS-232C 8251A TXEMPTY
1063 port_c |= 0x01; // RXRE, 1 = Enable IRQ from RS-232C 8251A RXRDY
1064 pio_sys->write_signal(SIG_I8255_PORT_A, port_a, 0xff);
1065 pio_sys->write_signal(SIG_I8255_PORT_B, port_b, 0xff);
1066 pio_sys->write_signal(SIG_I8255_PORT_C, port_c, 0xff);
1069 #if defined(_PC9801)
1070 // port_b |= 0x80; // TYP1, 0 = PC-9801 (first)
1071 // port_b |= 0x40; // TYP0, 0
1072 #elif defined(_PC9801U)
1073 port_b |= 0x80; // TYP1, 1 = PC-9801U
1074 port_b |= 0x40; // TYP0, 1
1076 port_b |= 0x80; // TYP1, 1 = Other PC-9801 series
1077 // port_b |= 0x40; // TYP0, 0
1079 if(pit_clock_8mhz) {
1080 port_b |= 0x20; // MOD, 1 = System clock 8MHz, 0 = 5/10MHz
1082 port_b |= 0x10; // DIP SW 1-3, 1 = Don't use LCD
1083 #if !defined(SUPPORT_16_COLORS)
1084 port_b |= 0x08; // DIP SW 1-8, 1 = Standard graphic mode, 0 = Enhanced graphic mode
1086 port_b |= 0x04; // Printer BUSY#, 1 = Inactive, 0 = Active (BUSY)
1087 #if defined(HAS_V30) || defined(HAS_V33)
1088 port_b |= 0x02; // CPUT, 1 = V30/V33, 0 = 80x86
1090 #if defined(_PC9801VF) || defined(_PC9801U)
1091 port_b |= 0x01; // VF, 1 = PC-9801VF/U
1093 pio_prn->write_signal(SIG_I8255_PORT_B, port_b, 0xff);
1095 #if defined(SUPPORT_320KB_FDD_IF)
1096 pio_fdd->write_signal(SIG_I8255_PORT_A, 0xff, 0xff);
1097 pio_fdd->write_signal(SIG_I8255_PORT_B, 0xff, 0xff);
1098 pio_fdd->write_signal(SIG_I8255_PORT_C, 0xff, 0xff);
1100 #if defined(SUPPORT_2DD_FDD_IF)
1101 fdc_2dd->write_signal(SIG_UPD765A_FREADY, 1, 1); // 2DD FDC RDY is pulluped
1104 if(sound_type == 0 || sound_type == 1) {
1105 // opn->write_signal(SIG_YM2203_PORT_A, 0x3f, 0xff); // PC-9801-26(K) INT0
1106 // opn->write_signal(SIG_YM2203_PORT_A, 0xbf, 0xff); // PC-9801-26(K) INT41
1107 opn->write_signal(SIG_YM2203_PORT_A, 0xff, 0xff); // PC-9801-26(K) INT5
1108 // opn->write_signal(SIG_YM2203_PORT_A, 0x7f, 0xff); // PC-9801-26(K) INT6
1111 #if defined(SUPPORT_OLD_BUZZER)
1112 beep->write_signal(SIG_BEEP_ON, 1, 1);
1113 beep->write_signal(SIG_BEEP_MUTE, 1, 1);
1115 beep->write_signal(SIG_PCM1BIT_ON, 1, 1);
1116 beep->write_signal(SIG_PCM1BIT_MUTE, 1, 1);
1119 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1120 pc88opn->set_reg(0x29, 3); // for Misty Blue
1121 pc88pio->write_signal(SIG_I8255_PORT_C, 0, 0xff);
1122 pc88pio_sub->write_signal(SIG_I8255_PORT_C, 0, 0xff);
1125 #if defined(USE_HARD_DISK) && defined(OPEN_HARD_DISK_IN_RESET)
1126 // open/close hard disk images
1127 for(int drv = 0; drv < USE_HARD_DISK; drv++) {
1128 if(hd_file_path[drv][0] != _T('\0')) {
1129 open_hard_disk_tmp(drv, hd_file_path[drv]);
1131 close_hard_disk_tmp(drv);
1139 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1140 if(boot_mode != 0) {
1147 double VM::get_frame_rate()
1149 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1150 if(config.boot_mode != 0) {
1151 return pc88event->get_frame_rate();
1154 return event->get_frame_rate();
1157 // ----------------------------------------------------------------------------
1159 // ----------------------------------------------------------------------------
1162 DEVICE *VM::get_cpu(int index)
1164 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1165 if(index == 0 && boot_mode == 0) {
1167 } else if(index == 1 && boot_mode != 0) {
1169 } else if(index == 2 && boot_mode != 0) {
1175 #if defined(SUPPORT_320KB_FDD_IF)
1176 } else if(index == 1) {
1185 // ----------------------------------------------------------------------------
1187 // ----------------------------------------------------------------------------
1189 void VM::draw_screen()
1191 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1192 if(boot_mode != 0) {
1193 pc88->draw_screen();
1196 display->draw_screen();
1199 // ----------------------------------------------------------------------------
1201 // ----------------------------------------------------------------------------
1203 void VM::initialize_sound(int rate, int samples)
1205 // init sound manager
1206 event->initialize_sound(rate, samples);
1209 #if defined(SUPPORT_OLD_BUZZER)
1210 beep->initialize_sound(rate, 2400, 8000);
1212 beep->initialize_sound(rate, 8000);
1214 if(sound_type == 0 || sound_type == 1) {
1216 opn->initialize_sound(rate, 7987248, samples, 0, 0);
1218 opn->initialize_sound(rate, 3993624, samples, 0, 0);
1220 } else if(sound_type == 2 || sound_type == 3) {
1221 tms3631->initialize_sound(rate, 8000);
1224 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1225 // init sound manager
1226 pc88event->initialize_sound(rate, samples);
1230 pc88opn->initialize_sound(rate, 7987248, samples, 0, 0);
1232 pc88opn->initialize_sound(rate, 3993624, samples, 0, 0);
1234 pc88pcm->initialize_sound(rate, 8000);
1238 uint16_t* VM::create_sound(int* extra_frames)
1240 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1241 if(boot_mode != 0) {
1242 return pc88event->create_sound(extra_frames);
1245 return event->create_sound(extra_frames);
1248 int VM::get_sound_buffer_ptr()
1250 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1251 if(boot_mode != 0) {
1252 return pc88event->get_sound_buffer_ptr();
1255 return event->get_sound_buffer_ptr();
1258 #ifdef USE_SOUND_VOLUME
1259 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
1262 if(sound_type == 0 || sound_type == 1) {
1263 opn->set_volume(0, decibel_l, decibel_r);
1265 } else if(ch-- == 0) {
1266 if(sound_type == 0 || sound_type == 1) {
1267 opn->set_volume(1, decibel_l, decibel_r);
1269 #if defined(SUPPORT_PC98_OPNA)
1270 } else if(ch-- == 0) {
1271 if(sound_type == 0 || sound_type == 1) {
1272 opn->set_volume(2, decibel_l, decibel_r);
1274 } else if(ch-- == 0) {
1275 if(sound_type == 0 || sound_type == 1) {
1276 opn->set_volume(3, decibel_l, decibel_r);
1279 } else if(ch-- == 0) {
1280 if(sound_type == 2 || sound_type == 3) {
1281 tms3631->set_volume(0, decibel_l, decibel_r);
1283 } else if(ch-- == 0) {
1284 beep->set_volume(0, decibel_l, decibel_r);
1285 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1286 } else if(ch-- == 0) {
1287 pc88opn->set_volume(0, decibel_l, decibel_r);
1288 } else if(ch-- == 0) {
1289 pc88opn->set_volume(1, decibel_l, decibel_r);
1290 #if defined(SUPPORT_PC88_OPNA)
1291 } else if(ch-- == 0) {
1292 pc88opn->set_volume(2, decibel_l, decibel_r);
1293 } else if(ch-- == 0) {
1294 pc88opn->set_volume(3, decibel_l, decibel_r);
1296 } else if(ch-- == 0) {
1297 pc88pcm->set_volume(0, decibel_l, decibel_r);
1299 } else if(ch-- == 0) {
1300 noise_seek->set_volume(0, decibel_l, decibel_r);
1301 noise_head_down->set_volume(0, decibel_l, decibel_r);
1302 noise_head_up->set_volume(0, decibel_l, decibel_r);
1303 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1304 pc88noise_seek->set_volume(0, decibel_l, decibel_r);
1305 pc88noise_head_down->set_volume(0, decibel_l, decibel_r);
1306 pc88noise_head_up->set_volume(0, decibel_l, decibel_r);
1312 // ----------------------------------------------------------------------------
1314 // ----------------------------------------------------------------------------
1316 void VM::key_down(int code, bool repeat)
1318 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1319 if(boot_mode != 0) {
1320 pc88->key_down(code, repeat);
1323 keyboard->key_down(code, repeat);
1326 void VM::key_up(int code)
1328 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1329 if(boot_mode != 0) {
1330 // pc88->key_up(code);
1333 keyboard->key_up(code);
1336 bool VM::get_caps_locked()
1338 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1339 if(boot_mode != 0) {
1340 return pc88->get_caps_locked();
1343 return keyboard->get_caps_locked();
1346 bool VM::get_kana_locked()
1348 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1349 if(boot_mode != 0) {
1350 return pc88->get_kana_locked();
1353 return keyboard->get_kana_locked();
1356 // ----------------------------------------------------------------------------
1358 // ----------------------------------------------------------------------------
1360 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
1362 UPD765A *controller = get_floppy_disk_controller(drv);
1364 if(controller != NULL) {
1365 controller->open_disk(drv & 1, file_path, bank);
1369 void VM::close_floppy_disk(int drv)
1371 UPD765A *controller = get_floppy_disk_controller(drv);
1373 if(controller != NULL) {
1374 controller->close_disk(drv & 1);
1378 bool VM::is_floppy_disk_inserted(int drv)
1380 DISK *handler = get_floppy_disk_handler(drv);
1382 if(handler != NULL) {
1383 return handler->inserted;
1388 void VM::is_floppy_disk_protected(int drv, bool value)
1390 DISK *handler = get_floppy_disk_handler(drv);
1392 if(handler != NULL) {
1393 handler->write_protected = value;
1397 bool VM::is_floppy_disk_protected(int drv)
1399 DISK *handler = get_floppy_disk_handler(drv);
1401 if(handler != NULL) {
1402 return handler->write_protected;
1407 uint32_t VM::is_floppy_disk_accessed()
1411 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1412 if(boot_mode != 0) {
1413 value = pc88fdc_sub->read_signal(0) & 3;
1415 value = fdc->read_signal(0) & 3;
1418 for(int drv = 0; drv < USE_FLOPPY_DISK; drv += 2) {
1419 UPD765A *controller = get_floppy_disk_controller(drv);
1421 if(controller != NULL) {
1422 value |= (controller->read_signal(0) & 3) << drv;
1429 UPD765A *VM::get_floppy_disk_controller(int drv)
1431 #if defined(_PC9801) || defined(_PC9801E)
1432 if(drv == 0 || drv == 1) {
1434 } else if(drv == 2 || drv == 3) {
1436 } else if(drv == 4 || drv == 5) {
1439 #elif defined(_PC9801VF) || defined(_PC9801U)
1440 if(drv == 0 || drv == 1) {
1443 #elif defined(_PC98DO) || defined(_PC98DOPLUS)
1444 if(drv == 0 || drv == 1) {
1446 } else if(drv == 2 || drv == 3) {
1450 if(drv == 0 || drv == 1) {
1457 DISK *VM::get_floppy_disk_handler(int drv)
1459 UPD765A *controller = get_floppy_disk_controller(drv);
1461 if(controller != NULL) {
1462 return controller->get_disk_handler(drv & 1);
1467 #if defined(USE_HARD_DISK)
1468 void VM::open_hard_disk(int drv, const _TCHAR* file_path)
1470 if(drv < USE_HARD_DISK) {
1471 #if defined(OPEN_HARD_DISK_IN_RESET)
1472 my_tcscpy_s(hd_file_path[drv], _MAX_PATH, file_path);
1474 open_hard_disk_tmp(drv, file_path);
1479 void VM::close_hard_disk(int drv)
1481 if(drv < USE_HARD_DISK) {
1482 #if defined(OPEN_HARD_DISK_IN_RESET)
1483 hd_file_path[drv][0] = _T('\0');
1485 close_hard_disk_tmp(drv);
1490 bool VM::is_hard_disk_inserted(int drv)
1492 if(drv < USE_HARD_DISK) {
1493 #if defined(OPEN_HARD_DISK_IN_RESET)
1494 return (hd_file_path[drv][0] != _T('\0'));
1496 return is_hard_disk_inserted_tmp(drv);
1502 uint32_t VM::is_hard_disk_accessed()
1504 uint32_t status = 0;
1506 for(int drv = 0; drv < USE_HARD_DISK; drv++) {
1507 HARDDISK *handler = get_hard_disk_handler(drv);
1509 if(handler != NULL && handler->accessed()) {
1516 void VM::open_hard_disk_tmp(int drv, const _TCHAR* file_path)
1518 HARDDISK *handler = get_hard_disk_handler(drv);
1520 if(handler != NULL) {
1521 handler->open(file_path);
1525 void VM::close_hard_disk_tmp(int drv)
1527 HARDDISK *handler = get_hard_disk_handler(drv);
1529 if(handler != NULL) {
1534 bool VM::is_hard_disk_inserted_tmp(int drv)
1536 HARDDISK *handler = get_hard_disk_handler(drv);
1538 if(handler != NULL) {
1539 return handler->mounted();
1544 HARDDISK *VM::get_hard_disk_handler(int drv)
1546 if(drv < USE_HARD_DISK) {
1547 #if defined(SUPPORT_SASI_IF)
1548 return sasi_hdd->get_disk_handler(drv);
1550 #if defined(SUPPORT_SCSI_IF)
1551 return scsi_hdd[drv]->get_disk_handler(0);
1553 #if defined(SUPPORT_IDE_IF)
1554 return ide_hdd[drv]->get_disk_handler(0);
1561 #if defined(USE_TAPE)
1562 void VM::play_tape(int drv, const _TCHAR* file_path)
1564 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1565 pc88->play_tape(file_path);
1567 cmt->play_tape(file_path);
1571 void VM::rec_tape(int drv, const _TCHAR* file_path)
1573 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1574 pc88->rec_tape(file_path);
1576 cmt->rec_tape(file_path);
1580 void VM::close_tape(int drv)
1582 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1589 bool VM::is_tape_inserted(int drv)
1591 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1592 return pc88->is_tape_inserted();
1594 return cmt->is_tape_inserted();
1599 bool VM::is_frame_skippable()
1601 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1602 if(boot_mode != 0) {
1603 // return pc88event->is_frame_skippable();
1604 return pc88->is_frame_skippable();
1607 return event->is_frame_skippable();
1610 void VM::update_config()
1612 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1613 if(boot_mode != config.boot_mode) {
1614 // boot mode is changed !!!
1615 boot_mode = config.boot_mode;
1619 for(DEVICE* device = first_device; device; device = device->next_device) {
1620 device->update_config();
1624 #define STATE_VERSION 13
1626 #include "../../statesub.h"
1627 #include "../../qt/gui/csp_logger.h"
1628 extern CSP_Logger DLL_PREFIX_I *csp_logger;
1630 void VM::decl_state(void)
1632 #if defined(_PC9801)
1633 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801_HEAD")), csp_logger);
1634 #elif defined(_PC9801E)
1635 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801E_HEAD")), csp_logger);
1636 #elif defined(_PC9801U)
1637 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801U_HEAD")), csp_logger);
1638 #elif defined(_PC9801VF)
1639 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801VF_HEAD")), csp_logger);
1640 #elif defined(_PC9801VM)
1641 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801VF_HEAD")), csp_logger);
1642 #elif defined(_PC98DO)
1643 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98DO_HEAD")), csp_logger);
1644 #elif defined(_PC9801DOPLUS)
1645 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98DO_PLUS_HEAD")), csp_logger);
1646 #elif defined(_PC9801VX)
1647 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801VX_HEAD")), csp_logger);
1648 #elif defined(_PC98XL)
1649 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98XL_HEAD")), csp_logger);
1650 #elif defined(_PC98XA)
1651 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98XA_HEAD")), csp_logger);
1652 #elif defined(_PC9801RA)
1653 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801RA_HEAD")), csp_logger);
1654 #elif defined(_PC98RL)
1655 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC98RL_HEAD")), csp_logger);
1657 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::PC9801_SERIES_HEAD")), csp_logger);
1660 DECL_STATE_ENTRY_BOOL(pit_clock_8mhz);
1661 #if defined(_PC98DO) || defined(_PC98DOPLUS)
1662 DECL_STATE_ENTRY_INT32(boot_mode);
1664 DECL_STATE_ENTRY_INT32(sound_type);
1665 #if defined(USE_HARD_DISK) && defined(OPEN_HARD_DISK_IN_RESET)
1666 DECL_STATE_ENTRY_MULTI(void, hd_file_path, sizeof(hd_file_path));
1668 for(DEVICE* device = first_device; device; device = device->next_device) {
1669 device->decl_state();
1673 void VM::save_state(FILEIO* state_fio)
1675 if(state_entry != NULL) {
1676 state_entry->save_state(state_fio);
1678 for(DEVICE* device = first_device; device; device = device->next_device) {
1679 device->save_state(state_fio);
1683 bool VM::load_state(FILEIO* state_fio)
1686 if(state_entry != NULL) {
1687 mb = state_entry->load_state(state_fio);
1690 emu->out_debug_log("INFO: HEADER DATA ERROR");
1693 for(DEVICE* device = first_device; device; device = device->next_device) {
1694 if(!device->load_state(state_fio)) {