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
23 #if defined(_PC9801RA) || defined(_PC9801RA2) || defined(_PC9801RA21) //defined(UPPER_I386) && defined(SUPPORT_BIOS_RAM)
24 #define SUPPORT_SHADOW_RAM
28 // Microsoft Visual C++
29 #pragma warning( disable : 4065 )
35 A0000h - A1FFFh: TEXT VRAM
36 A2000h - A3FFFh: ATTRIBUTE
37 A4000h - A4FFFh: CG WINDOW
38 A8000h - BFFFFh: VRAM (BRG)
39 C0000h - DFFFFh: EXT BIOS
40 CC000h - CFFFFh: SOUND BIOS
41 D6000h - D6FFFh: 2DD FDD BIOS
42 D7000h - D7FFFh: 2HD FDD BIOS
43 D7000h - D7FFFh: SASI BIOS
44 D8000h - DBFFFh: IDE BIOS
45 DC000h - DCFFFh: SCSI BIOS
46 E0000h - E7FFFh: VRAM (I)
49 HIRESO PC-98XA/XL/XL^2/RL
51 80000h - BFFFFh: MEMORY WINDOW
53 E0000h - E1FFFh: TEXT VRAM
54 E2000h - E3FFFh: ATTRIBUTE
55 E4000h - E4FFFh: CG WINDOW
61 // This code from NP2.cbus/sasibios.res
62 static const uint8_t pseudo_sasi_bios[] = {
63 0xcb,0x90,0x90,0xcb,0x90,0x90,0xcb,0x90,0x90,0x55,0xaa,0x02,
64 0xeb,0x22,0x90,0xeb,0x23,0x90,0xcb,0x90,0x90,0xeb,0x54,0x90,
65 0xeb,0x33,0x90,0xcb,0x90,0x90,0xcb,0x90,0x90,0xcb,0x90,0x90,
66 0xcb,0x90,0x90,0xcb,0x90,0x90,0xcb,0x90,0x90,0xcb,0x90,0x90,
67 0xc6,0x07,0xd9,0xcb,0x8c,0xc8,0xc7,0x06,0x44,0x00,0x9d,0x00,
68 0xa3,0x46,0x00,0x88,0x26,0xb0,0x04,0x88,0x26,0xb8,0x04,0xb8,
69 0x00,0x03,0xcd,0x1b,0xcb,0xfc,0x8c,0xca,0x8e,0xda,0xb9,0x08,
70 0x00,0xbe,0xcf,0x00,0xba,0xef,0x07,0xfa,0xac,0xee,0xe2,0xfc,
71 0xfb,0x58,0x5b,0x59,0x5a,0x5d,0x07,0x5f,0x5e,0x1f,0xcf,0x3c,
72 0x0a,0x74,0x05,0x3c,0x0b,0x74,0x01,0xcb,0x2c,0x09,0x84,0x06,
73 0x5d,0x05,0x74,0x20,0xfe,0xc8,0xb4,0x06,0xb9,0xc0,0x1f,0x8e,
74 0xc1,0x31,0xed,0xbb,0x00,0x04,0x31,0xc9,0x31,0xd2,0xcd,0x1b,
75 0x72,0x0a,0x0c,0x80,0xa2,0x84,0x05,0x9a,0x00,0x00,0xc0,0x1f,
76 0xcb,0x50,0xe4,0x82,0x24,0xfd,0x3c,0xad,0x74,0x06,0x24,0xf9,
77 0x3c,0xa1,0x75,0x0f,0x1e,0x31,0xc0,0x8e,0xd8,0x80,0x0e,0x5f,
78 0x05,0x01,0xb0,0xc0,0xe6,0x82,0x1f,0xb0,0x20,0xe6,0x08,0xb0,
79 0x0b,0xe6,0x08,0xe4,0x08,0x84,0xc0,0x75,0x04,0xb0,0x20,0xe6,
80 0x00,0x58,0xcf,0x73,0x61,0x73,0x69,0x62,0x69,0x6f,0x73,
82 // Note: Penalty wait values is 4 when not hit accessble.(from upsteam 20221204).
83 void MEMBUS::initialize()
88 memset(ram, 0x00, sizeof(ram));
94 memset(bios, 0xff, sizeof(bios));
95 if(!read_bios(_T("IPL.ROM"), bios, sizeof(bios))) {
96 read_bios(_T("BIOS.ROM"), bios, sizeof(bios));
98 // Check PnP Bios and disable. From NP2 v0.83.
100 #if !defined(SUPPORT_HIRESO) //&& defined(UPPER_I386)
101 for(int ad = 0; ad < 0x10000; ad += 0x10) {
103 magic.b.l = bios[0x8000 + ad + 0];
104 magic.b.h = bios[0x8000 + ad + 1];
105 magic.b.h2 = bios[0x8000 + ad + 2];
106 magic.b.h3 = bios[0x8000 + ad + 3];
107 if(magic.d == 0x506e5024) {
108 out_debug_log(_T("Found PNP BIOS at %05X.Disable this.\n"), ad + 0xf0000);
109 bios[0x8000 + ad + 0] = 0x6e;
110 bios[0x8000 + ad + 2] = 0x24;
115 #if defined(SUPPORT_BIOS_RAM)
116 shadow_ram_selected = true;
118 shadow_ram_selected = false;
121 #if defined(SUPPORT_ITF_ROM)
122 memset(itf, 0xff, sizeof(itf));
123 read_bios(_T("ITF.ROM"), itf, sizeof(itf));
124 // memcpy(itf, pseudo_itfrom, (sizeof(itf) > sizeof(pseudo_itfrom)) ? sizeof(pseudo_itfrom) : sizeof(itf));
130 #if defined(_PC9801) || defined(_PC9801E)
131 memset(fd_bios_2hd, 0xff, sizeof(fd_bios_2hd));
132 if(config.dipswitch & DIPSWITCH_2HD) {
133 read_bios(_T("2HDIF.ROM"), fd_bios_2hd, sizeof(fd_bios_2hd));
135 // read_bios(_T("2HDIF.ROM"), fd_bios_2hd, sizeof(fd_bios_2hd));
137 memset(fd_bios_2dd, 0xff, sizeof(fd_bios_2dd));
138 if(config.dipswitch & DIPSWITCH_2DD) {
139 read_bios(_T("2DDIF.ROM"), fd_bios_2dd, sizeof(fd_bios_2dd));
141 // read_bios(_T("2DDIF.ROM"), fd_bios_2dd, sizeof(fd_bios_2dd));
143 set_memory_r(0xd6000, 0xd6fff, fd_bios_2dd);
144 set_memory_r(0xd7000, 0xd7fff, fd_bios_2hd);
146 memset(sound_bios, 0xff, sizeof(sound_bios));
147 // memset(sound_bios_ram, 0x00, sizeof(sound_bios_ram));
148 sound_bios_selected = false;
149 sound_bios_load = false;
151 // memset(sound_bios_ram, 0x00, sizeof(sound_bios_ram));
152 // sound_bios_ram_selected = false;
153 if((config.sound_type == 0) || (config.sound_type == 1)) {
154 out_debug_log(_T("Loading Sound BIOS \"SOUND.ROM\" type %d"), config.sound_type);
155 sound_bios_load = (read_bios(_T("SOUND.ROM"), sound_bios, sizeof(sound_bios)) != 0);
156 } else if((config.sound_type == 2) || (config.sound_type == 3)) {
157 out_debug_log(_T("Loading Sound BIOS \"MUSIC.ROM\" type %d"), config.sound_type);
158 sound_bios_load = (read_bios(_T("MUSIC.ROM"), sound_bios, sizeof(sound_bios)) != 0);
160 if(sound_bios_load) {
161 if((config.sound_type & 1) == 0) {
162 sound_bios_selected = true;
164 out_debug_log(_T("SUCCESS"));
166 if(sound_bios_selected) {
167 d_display->set_memsw_4(d_display->get_memsw_4() | 8);
169 d_display->set_memsw_4(d_display->get_memsw_4() & ~8);
171 #if defined(SUPPORT_SASI_IF)
172 sasi_bios_load = false;
173 memset(sasi_bios, 0xff, sizeof(sasi_bios));
174 memset(sasi_bios_ram, 0x00, sizeof(sasi_bios_ram));
175 sasi_bios_load = (read_bios(_T("SASI.ROM"), sasi_bios, sizeof(sasi_bios)) != 0);
176 if(!(sasi_bios_load)) {
177 memcpy(sasi_bios, pseudo_sasi_bios, sizeof(pseudo_sasi_bios));
179 sasi_bios_selected = true;
180 sasi_bios_ram_selected = false;
182 #if defined(SUPPORT_SCSI_IF)
183 memset(scsi_bios, 0xff, sizeof(scsi_bios));
184 memset(scsi_bios_ram, 0x00, sizeof(scsi_bios_ram));
185 scsi_bios_selected = (read_bios(_T("SCSI.ROM"), scsi_bios, sizeof(scsi_bios)) != 0);
186 scsi_bios_ram_selected = false;
188 #if defined(SUPPORT_IDE_IF)
189 memset(ide_bios, 0xff, sizeof(ide_bios));
190 memset(ide_bios_ram, 0x00, sizeof(ide_bios_ram));
191 ide_bios_selected = (read_bios(_T("IDE.ROM"), ide_bios, sizeof(ide_bios)) != 0);
194 // page08_intram_selected = false;
195 page08_intram_selected = true;
197 #if defined(SUPPORT_NEC_EMS)
198 memset(nec_ems, 0, sizeof(nec_ems));
200 // Belows are UGLY HACK from mame.
201 #if defined(_PC9801RA)
202 // read_bios(_T("00000.ROM"), &(ram[0x00000]), 0x8000);
203 // read_bios(_T("C0000.ROM"), &(ram[0xC0000]), 0x8000);
204 // read_bios(_T("C8000.ROM"), &(ram[0xC8000]), 0x8000);
205 // read_bios(_T("D0000.ROM"), &(ram[0xD0000]), 0x8000);
206 // read_bios(_T("E8000.ROM"), &(bios_ram[0x00000]), 0x8000);
207 // read_bios(_T("F0000.ROM"), &(bios_ram[0x08000]), 0x8000);
208 // read_bios(_T("F8000.ROM"), &(bios_ram[0x10000]), 0x8000);
210 last_access_is_interam = false;
211 set_wait_rw(0x00000, (uint32_t)(space - 1), 4); // Initialize penalty.
231 #if defined(SUPPORT_BIOS_RAM)
232 bios_ram_selected = false;
233 shadow_ram_selected = true;
234 // memcpy(bios_ram, bios, min((int)sizeof(bios), (int)sizeof(bios_ram))); // ;
236 shadow_ram_selected = false;
239 #if !defined(SUPPORT_HIRESO)
240 if((sound_bios_load) && ((config.sound_type & 1) == 0)){
241 using_sound_bios = true;
242 //d_display->sound_bios_ok();
243 sound_bios_selected = true;
245 using_sound_bios = false;
246 sound_bios_selected = false;
248 #if defined(USE_SOUND_TYPE)
249 if(config.sound_type == (USE_SOUND_TYPE - 1)) {
250 sound_bios_selected = false;
251 using_sound_bios = false;
254 // Re-Update Sound BIOS
255 if(sound_bios_selected) {
256 d_display->set_memsw_4(d_display->get_memsw_4() | 8);
258 d_display->set_memsw_4(d_display->get_memsw_4() & ~8);
261 //out_debug_log("SOUND BIOS=%s", (sound_bios_selected) ? "YES" : "NO");
263 #if defined(SUPPORT_NEC_EMS)
264 nec_ems_selected = false;
266 use_ems_as_protected = false; // OK?
267 ems_protected_base = 0x00;
272 #if defined(SUPPORT_SASI_IF)
273 sasi_bios_selected = true;
274 // sasi_bios_selected = false;
275 sasi_bios_ram_selected = false; // OK?
278 #if defined(SUPPORT_SCSI_IF)
279 scsi_bios_selected = false;
280 scsi_bios_ram_selected = false; // OK?
283 #if defined(SUPPORT_IDE_IF)
284 ide_bios_bank = 0; // ToDo: BANK
286 #if defined(SUPPORT_24BIT_ADDERSS) || defined(SUPPORT_32BIT_ADDRESS)
287 #if !defined(SUPPORT_HIRESO)
288 dma_access_ctrl = 0xfe; // bit2 = 1, bit0 = 0
289 dma_access_a20 = false;
290 // dma_access_ctrl = 0xff; // bit2 = 1, bit0 = 0
291 // dma_access_a20 = true;
292 window_80000h = 0x80000;
293 window_a0000h = 0xa0000;
295 dma_access_ctrl = 0xfb; // bit2 = 0, bit0 = 1
296 dma_access_a20 = true;
297 window_80000h = 0x100000;
298 window_a0000h = 0x120000;
301 page08_intram_selected = true;
306 void MEMBUS::write_io8(uint32_t addr, uint32_t data)
308 //out_debug_log(_T("I/O WRITE $%04x %04x\n"), addr, data);
310 #if defined(SUPPORT_ITF_ROM)
312 switch(data & 0xff) {
313 #if defined(SUPPORT_HIRESO)
317 case 0x10: // Normally BIOS, but, MENU ROM will be selected at H98S.
323 #if defined(SUPPORT_HIRESO)
326 case 0x12: // BIOS ROM
328 itf_selected = false;
335 #if !defined(SUPPORT_HIRESO)
337 switch(data & 0xff) {
339 #if defined(SUPPORT_NEC_EMS)
340 if(nec_ems_selected) {
341 nec_ems_selected = false;
346 // #if !defined(SUPPORT_HIRESO)
347 // unset_memory_rw(0xb0000, 0xbffff);
348 // set_memory_mapped_io_rw(0xb0000, 0xbffff, d_display);
354 #if defined(SUPPORT_NEC_EMS)
355 if(!nec_ems_selected) {
356 nec_ems_selected = true;
361 // #if !defined(SUPPORT_HIRESO)
362 // unset_memory_rw(0xb0000, 0xbffff);
363 // set_memory_rw(0xb0000, 0xbffff, &(ram[0xb0000]));
369 #if defined(SUPPORT_SASI_IF)
370 // Changing ROM/RAM may select SASI I/F board.20190321 K.O
371 if(sasi_bios_selected) {
372 if(sasi_bios_ram_selected) {
373 sasi_bios_ram_selected = false;
379 #if defined(SUPPORT_SCSI_IF)
380 // Changing ROM/RAM maybe select SCSI I/F board.(Still not tested)20190321 K.O
381 //if(scsi_bios_selected) {
382 if(scsi_bios_ram_selected) {
383 scsi_bios_ram_selected = false;
391 #if defined(SUPPORT_SASI_IF)
392 // Changing ROM/RAM may select SASI I/F board.20190321 K.O
393 if(sasi_bios_selected) {
394 if(!sasi_bios_ram_selected) {
395 sasi_bios_ram_selected = true;
403 #if defined(SUPPORT_SCSI_IF)
404 // Changing ROM/RAM maybe select SCSI I/F board.(Still not tested)20190321 K.O
405 if(scsi_bios_selected) {
406 if(!scsi_bios_ram_selected) {
407 scsi_bios_ram_selected = true;
415 if(!(page08_intram_selected)) {
416 page08_intram_selected = true;
417 //#if !defined(_PC9801RA)
423 if(page08_intram_selected) {
424 page08_intram_selected = false;
425 //#if !defined(_PC9801RA)
433 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
434 #if !defined(_PC98XA)
436 dma_access_ctrl = data;
437 dma_access_a20 = ((data & 0x04) != 0) ? false : true;
440 #if defined(SUPPORT_NEC_EMS)
442 use_ems_as_protected = (data != 0) ? true: false;
443 ems_protected_base = (uint32_t)(data & 0x0f) << 20;
447 #if defined(SUPPORT_HIRESO)
450 uint32_t _bak = window_80000h;
457 // http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
458 window_80000h = (data & 0xfe) << 16;
459 if(_bak != window_80000h) {
467 // http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
468 // ToDo: Cache flush for i486 or later.
470 uint32_t _bak = window_80000h;
471 window_80000h = (data & 0xfe) << 16;
472 if(_bak != window_80000h) {
478 #if defined(SUPPORT_HIRESO)
485 // http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
487 uint32_t _bak = window_a0000h;
488 window_a0000h = (data & 0xfe) << 16;
489 if(_bak != window_a0000h) {
497 // http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
498 // ToDo: Cache flush for i486 or later.
500 uint32_t _bak = window_a0000h;
501 window_a0000h = (data & 0xfe) << 16;
502 if(_bak != window_a0000h) {
509 #if defined(UPPER_I386) // ToDo: Upper type
515 //Note: THIS is disabled due to enable bios at startup.
516 #if !defined(SUPPORT_HIRESO) // 20190521 K.O
517 if(sound_bios_load && (using_sound_bios)) {
518 _bak = sound_bios_selected;
519 sound_bios_selected = ((data & 0x80) != 0);
520 if(_bak != sound_bios_selected) result = true;
521 out_debug_log("SOUND BIOS=%s (053Dh)", (sound_bios_selected) ? "YES" : "NO");
525 #if defined(SUPPORT_SASI_IF)
527 _bak = sasi_bios_selected;
528 sasi_bios_selected = ((data & 0x40) != 0);
529 if(_bak != sasi_bios_selected) result = true;
532 #if defined(SUPPORT_SCSI_IF)
534 _bak = scsi_bios_selected;
535 scsi_bios_selected = ((data & 0x20) != 0);
536 if(_bak != scsi_bios_selected) result = true;
539 #if defined(SUPPORT_IDE_IF)
541 _bak = ide_bios_selected;
542 ide_bios_selected = ((data & 0x10) != 0);
543 if(_bak != ide_bios_selected) result = true;
547 _bak = shadow_ram_selected;
548 shadow_ram_selected = ((data & 0x04) == 0);
549 if(_bak != shadow_ram_selected) result = true;
551 #if defined(SUPPORT_BIOS_RAM)
553 _bak = bios_ram_selected;
554 bios_ram_selected = ((data & 0x02) != 0);
555 if(_bak != bios_ram_selected) result = true;
558 if(result) update_bios();
562 // dummy for no cases
568 uint32_t MEMBUS::read_io8(uint32_t addr)
570 //out_debug_log(_T("I/O READ $%04x\n"), addr);
572 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
573 #if !defined(_PC98XA)
575 return dma_access_ctrl;
577 #if !defined(SUPPORT_HIRESO)
578 case 0x0461: // ToDo: Some VMs enable to read value.
579 return window_80000h >> 16;
584 return window_80000h >> 16;
587 #if !defined(SUPPORT_HIRESO)
588 case 0x0463: // ToDo: Some VMs enable to read value.
589 return window_a0000h >> 16;
594 return window_a0000h >> 16;
598 return (uint8_t)((sizeof(ram) - 0x100000) >> 17);
600 // dummy for no cases
607 #if defined(SUPPORT_32BIT_ADDRESS) || defined(SUPPORT_24BIT_ADDRESS)
608 #if !defined(SUPPORT_HIRESO)
609 #define UPPER_MEMORY_24BIT 0x00fa0000
610 #define UPPER_MEMORY_32BIT 0xfffa0000
612 #define UPPER_MEMORY_24BIT 0x00fc0000
613 #define UPPER_MEMORY_32BIT 0xfffc0000
616 // Note: Artane. variant of ePC9801xx changes bank dynamically.
617 // Not need to translate addrsss.
619 inline bool MEMBUS::get_memory_addr(uint32_t *addr)
623 if(*addr < 0x80000) {
626 if(*addr < 0xa0000) {
627 __UNLIKELY_IF((*addr = (*addr & 0x1ffff) | window_80000h) >= UPPER_MEMORY_24BIT) {
632 if(*addr < 0xc0000) {
633 __UNLIKELY_IF((*addr = (*addr & 0x1ffff) | window_a0000h) >= UPPER_MEMORY_24BIT) {
638 __LIKELY_IF(*addr < UPPER_MEMORY_24BIT) {
641 #if defined(SUPPORT_32BIT_ADDRESS)
642 __UNLIKELY_IF(*addr < 0x1000000 || *addr >= UPPER_MEMORY_32BIT) {
656 // 4clk = wait when access memory on expansion board ???
660 // Note: Artane. variant of ePC9801xx changes bank dynamically.
661 // Not need to translate addrsss.
663 uint32_t MEMBUS::read_dma_data8w(uint32_t addr, int *wait)
665 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
666 if(dma_access_ctrl & 4) {
670 return read_data8w(addr, wait);
673 void MEMBUS::write_dma_data8w(uint32_t addr, uint32_t data, int *wait)
675 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
676 if(dma_access_ctrl & 4) {
680 write_data8w(addr, data, wait);
683 uint32_t MEMBUS::read_dma_data16w(uint32_t addr, int *wait)
685 __LIKELY_IF(!(addr & 1)) {
686 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
687 if(dma_access_ctrl & 4) {
691 return read_data16w(addr, wait);
693 int wait_l = 0, wait_h = 0;
695 val = read_dma_data8w(addr , &wait_l);
696 val |= read_dma_data8w(addr + 1, &wait_h) << 8;
697 *wait = wait_l + wait_h;
702 void MEMBUS::write_dma_data16w(uint32_t addr, uint32_t data, int *wait)
704 __LIKELY_IF(!(addr & 1)) {
705 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
706 if(dma_access_ctrl & 4) {
710 write_data16w(addr, data, wait);
712 int wait_l = 0, wait_h = 0;
713 write_dma_data8w(addr , (data ) & 0xff, &wait_l);
714 write_dma_data8w(addr + 1, (data >> 8) & 0xff, &wait_h);
715 *wait = wait_l + wait_h;
720 void MEMBUS::write_signal(int ch, uint32_t data, uint32_t mask)
723 case SIG_INTRAM_WAIT:
724 intram_wait = (int)(data & 0xff);
727 case SIG_BANK08_WAIT:
728 bank08_wait = (int)(data & 0xff);
732 exmem_wait = (int)(data & 0xff);
735 case SIG_SLOTMEM_WAIT:
736 slotmem_wait = (int)(data & 0xff);
739 case SIG_EXBOARDS_WAIT:
740 exboards_wait = (int)(data & 0xff);
743 case SIG_INTROM_WAIT:
744 introm_wait = (int)(data & 0xff);
748 gvram_wait_val = (int)(data & 0xff);
752 tvram_wait_val = (int)(data & 0xff);
761 uint32_t MEMBUS::read_signal(int ch)
764 case SIG_LAST_ACCESS_INTERAM:
765 return ((last_access_is_interam) ? 0xffffffff : 0x00000000);
771 void MEMBUS::config_intram()
773 #if !defined(SUPPORT_HIRESO)
774 // ToDo: Internal ROM wait value.
775 #if defined(SUPPORT_32BIT_ADDRESS) || defined(SUPPORT_24BIT_ADDRESS)
776 set_memory_rw(0x00000, (sizeof(ram) >= 0x80000) ? 0x7ffff : (sizeof(ram) - 1), ram);
777 set_wait_rw(0x00000, (sizeof(ram) >= 0x80000) ? 0x7ffff : (sizeof(ram) - 1), intram_wait);
778 // set_memory_rw(0x00000, (sizeof(ram) >= 0xa0000) ? 0x9ffff : (sizeof(ram) - 1), ram);
780 set_memory_rw(0x00000, (sizeof(ram) >= 0xc0000) ? 0xbffff : (sizeof(ram) - 1), ram);
781 set_wait_rw(0x00000, (sizeof(ram) >= 0xc0000) ? 0xbffff : (sizeof(ram) - 1), intram_wait);
784 set_memory_rw(0x00000, 0xbffff, ram);
786 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
787 set_wait_rw(0x00100000, 0x00efffff, 4);
788 if(sizeof(ram) > 0x100000) {
789 uint32_t _end_addr1 = (sizeof(ram) >= 0xe00000) ? 0xdfffff : (sizeof(ram) - 1);
790 set_memory_rw(0x100000, _end_addr1, ram + 0x100000);
791 set_wait_rw(0x100000, _end_addr1, exmem_wait);
793 uint32_t _begin_addr2 = _end_addr1 + 1;
794 unset_memory_rw(_begin_addr2, 0x00efffff);
796 unset_memory_rw(0x00100000, 0x00efffff);
801 void MEMBUS::update_bios_mainmem()
803 #if !defined(SUPPORT_HIRESO)
804 #if defined(SUPPORT_32BIT_ADDRESS)|| defined(SUPPORT_24BIT_ADDRESS)
805 // unset_memory_rw(0x80000, 0xbffff);
806 unset_memory_rw(0xa0000, 0xbffff);
808 set_memory_mapped_io_rw(0xa0000, 0xa4fff, d_display);
809 set_memory_mapped_io_rw(0xa8000, 0xbffff, d_display);
810 set_wait_rw(0xa0000, 0xa4fff, tvram_wait_val);
811 set_wait_rw(0xa5000, 0xa7fff, 4); // Penalty values.
812 set_wait_rw(0xa8000, 0xbffff, tvram_wait_val);
814 // unset_memory_rw(0xc0000, 0xe4fff);
815 // set_wait_rw(0xc0000, 0xe4fff, 4); // Penalty values.
816 set_memory_mapped_io_rw(0xc0000, 0xe4fff, d_display);
817 set_wait_rw(0xc0000, 0xe4fff, gvram_wait_val); // OK?
818 #if defined(SUPPORT_BIOS_RAM) && defined(SUPPORT_32BIT_ADDRESS)
819 if(shadow_ram_selected) {
820 set_memory_rw(0xc0000, 0xe7fff, &(ram[0xc0000])); // OK?
821 set_wait_rw(0xc0000, 0xe7fff, intram_wait);
827 void MEMBUS::update_bios_extra_boards()
829 #if !defined(SUPPORT_HIRESO)
831 unset_memory_rw(0xc0000, 0xe7fff);
832 set_wait_rw(0xc0000, 0xe7fff, 4);
834 #if defined(_PC9801) || defined(_PC9801E)
835 set_memory_r(0xd6000, 0xd6fff, fd_bios_2dd);
836 set_memory_r(0xd7000, 0xd7fff, fd_bios_2hd);
837 set_wait_r(0xd7000, 0xd7fff, exboards_wait); // OK?
839 #if defined(SUPPORT_16_COLORS)
840 set_memory_mapped_io_rw(0xe0000, 0xe7fff, d_display);
841 set_wait_rw(0xe0000, 0xe7fff, gvram_wait_val); // OK?
845 #if defined(SUPPORT_SASI_IF)
848 #if defined(SUPPORT_SCSI_IF)
851 #if defined(SUPPORT_IDE_IF)
856 // ToDo: For HIRESO VMs
860 void MEMBUS::update_bios_ipl_and_itf()
862 #if defined(SUPPORT_ITF_ROM)
864 // unset_memory_w(0x00100000 - sizeof(bios), 0x000fffff);
865 set_memory_r(0x00100000 - sizeof(itf), 0x000fffff, itf);
866 set_wait_r(0x00100000 - sizeof(itf), 0x000fffff, introm_wait); // OK?
870 #if defined(SUPPORT_BIOS_RAM)
871 if(bios_ram_selected) {
872 set_memory_rw(0x100000 - sizeof(bios), 0xfffff, ram + 0x100000 - sizeof(bios));
873 set_wait_rw(0x00100000 - sizeof(bios), 0x000fffff, intram_wait); // OK?
877 set_memory_r(0x00100000 - sizeof(bios), 0x000fffff, bios);
878 unset_memory_w(0x00100000 - sizeof(bios), 0x000fffff);
879 set_wait_r(0x00100000 - sizeof(bios), 0x000fffff, introm_wait); // OK?
880 set_wait_w(0x00100000 - sizeof(bios), 0x000fffff, 4); // OK?
883 // set_wait_rw(0x00100000 - sizeof(bios), 0xfffff, introm_wait);
886 void MEMBUS::update_bios_window(uint32_t window_addr, uint32_t begin)
888 #if defined(SUPPORT_32BIT_ADDRESS) || defined(SUPPORT_24BIT_ADDRESS)
889 uint32_t end = begin + 0x1ffff;
890 if(sizeof(ram) > 0x10000) {
891 set_wait_rw(0x00100000, (sizeof(ram) >= 0x00e00000) ? 0x00dfffff : (sizeof(ram) - 1), exmem_wait);
893 if((page08_intram_selected) /*&& (shadow_ram_selected)*/){
894 set_wait_rw(begin, end, bank08_wait);
895 if((window_addr == 0x80000) || (window_addr >= 0x100000)) {
896 if((window_addr + 0x1ffff) < sizeof(ram)) {
897 set_memory_rw(begin, end, &(ram[window_addr]));
898 set_wait_rw(begin, end, intram_wait);
900 unset_memory_rw(begin, end);
901 set_wait_rw(begin, end, 4);
903 } else if(window_addr == 0xa0000) {
904 copy_table_rw(begin, 0xa0000, 0xbffff);
905 } else if(window_addr == 0xc0000) {
906 #if defined(SUPPORT_SHADOW_RAM)
907 if(shadow_ram_selected) {
908 set_memory_rw(begin, end, &(ram[window_addr]));
909 set_wait_rw(begin, end, intram_wait);
911 copy_table_rw(begin, 0xc0000, 0xdffff);
914 copy_table_rw(begin, 0xc0000, 0xdffff);
916 } else if(window_addr == 0xe0000) {
917 uint32_t head_address;
918 #if !defined(SUPPORT_HIRESO)
919 head_address = begin + 0x8000;
921 head_address = begin + 0x10000;
923 #if defined(SUPPORT_SHADOW_RAM)
924 if(shadow_ram_selected) {
925 set_memory_rw(begin, head_address - 1, &(ram[window_addr]));
926 set_memory_rw(head_address, end, ram + 0x100000 - sizeof(bios));
927 set_wait_rw(begin, end, intram_wait);
930 #if defined(SUPPORT_BIOS_RAM)
931 if(bios_ram_selected) {
932 unset_memory_rw(begin, head_address - 1);
933 set_memory_rw(head_address, end, ram + 0x100000 - sizeof(bios)); // Q? Will appear BIOS/ITF ROM? 20190730 K.O
934 set_wait_rw(begin, end, intram_wait);
938 unset_memory_rw(begin, end);
939 set_wait_rw(begin, end, 4);
940 #if defined(SUPPORT_ITF_ROM)
942 set_memory_r(end - sizeof(itf) + 1, end , &(itf[0x00000]));
943 set_wait_rw(end - sizeof(itf) + 1, end, introm_wait);
947 set_memory_r(head_address, end, &(bios[0x00000]));
948 set_wait_r(head_address, end, 4);
951 } else { // less than 0x80000h
952 //set_memory_rw(begin, end, &(ram[begin]));
953 unset_memory_rw(begin, end);
954 set_wait_rw(begin, end, 4);
957 // Internal RAM is not selected.
959 set_wait_rw(begin, end, bank08_wait);
960 if(window_addr < 0x80000) {
961 unset_memory_rw(begin, end);
962 //set_memory_rw(0x80000, 0x9ffff, &(ram[window_addr]));
963 } else if(window_addr == 0x80000) {
964 // ToDo: External BUS
965 unset_memory_rw(begin, end);
966 } else if(window_addr == 0xa0000) {
967 copy_table_rw(begin, 0xa0000, 0xbffff); // DISPLAY
968 } else if(window_addr == 0xc0000) {
969 #if defined(SUPPORT_SHADOW_RAM)
970 if(shadow_ram_selected) {
971 set_memory_rw(begin, end, &(ram[window_addr]));
975 copy_table_rw(begin, 0xc0000, 0xdffff); // BOARD
977 } else if(window_addr == 0xe0000) {
978 #if defined(SUPPORT_SHADOW_RAM)
979 if(shadow_ram_selected) {
980 set_memory_rw(begin, end, &(ram[window_addr]));
981 //copy_table_rw(0x00080000, 0xe8000, 0xfffff); // BIOS
985 copy_table_rw(begin, 0xe0000, 0xfffff); // BIOS
987 } else { // Upper 100000h
988 //unset_memory_rw(0x00080000, 0x0009ffff);
989 if((window_addr + 0x1ffff) < sizeof(ram)) {
990 set_memory_rw(begin, end, &(ram[window_addr]));
992 unset_memory_rw(begin, end);
998 void MEMBUS::update_bios()
1000 update_bios_mainmem();
1001 #if !defined(SUPPORT_HIRESO)
1002 update_bios_extra_boards();
1005 update_bios_ipl_and_itf();
1007 #if defined(SUPPORT_32BIT_ADDRESS) || defined(SUPPORT_24BIT_ADDRESS)
1008 #if defined(SUPPORT_NEC_EMS)
1010 if((use_ems_as_protected) && ((ems_protected_base & 0xf00000) != 0)) {
1011 set_memory_rw(ems_protected_base, ems_protected_base + ((sizeof(nec_ems) >= 0x10000) ? 0xffff : (sizeof(nec_ems) - 1)), &(nec_ems[0]));
1012 set_wait_rw(ems_protected_base, ems_protected_base + ((sizeof(nec_ems) >= 0x10000) ? 0xffff : (sizeof(nec_ems) - 1)), exboards_wait);
1013 if(sizeof(nec_ems) < 0x10000) {
1014 unset_memory_rw(ems_protected_base + sizeof(nec_ems), ems_protected_base + 0xffff);
1015 set_wait_rw(ems_protected_base + sizeof(nec_ems), ems_protected_base + 0xffff, exboards_wait);
1018 if(sizeof(ram) > 0x100000) {
1019 set_memory_rw(0x100000, (sizeof(ram) >= 0xe00000) ? 0xdfffff : (sizeof(ram) - 1), ram + 0x100000);
1020 set_wait_rw(0x100000, (sizeof(ram) >= 0xe00000) ? 0xdfffff : (sizeof(ram) - 1), exmem_wait);
1021 unset_memory_rw((sizeof(ram) >= 0x00e00000) ? 0x00e00000 : sizeof(ram), 0x00efffff);
1022 set_wait_rw((sizeof(ram) >= 0x00e00000) ? 0x00e00000 : sizeof(ram), 0x00efffff, 4);
1024 unset_memory_rw(0x00100000, 0x00efffff);
1025 set_wait_rw(0x00100000, 0x00efffff, 4);
1029 if(sizeof(ram) > 0x10000) {
1030 set_wait_rw(0x00100000, (sizeof(ram) >= 0x00e00000) ? 0x00dfffff : (sizeof(ram) - 1), exmem_wait);
1033 if(shadow_ram_selected) {
1034 // set_wait_rw(0xa0000, 0xbffff, bank08_wait);
1035 set_wait_rw(0xa0000, 0xbffff, intram_wait);
1037 set_wait_rw(0xa0000, 0xbffff, intram_wait);
1039 #if defined(SUPPORT_32BIT_ADDRESS) || defined(SUPPORT_24BIT_ADDRESS)
1040 update_bios_window(window_80000h, 0x80000);
1041 update_bios_window(window_a0000h, 0xa0000);
1044 /*if((page08_intram_selected) )*/{
1045 if((window_a0000h == 0xc0000)) {
1046 #if defined(_PC9801RA21) //defined(UPPER_I386) && defined(SUPPORT_BIOS_RAM)
1047 if(shadow_ram_selected) {
1048 //copy_table_rw(0xa0000, 0xc0000, 0xdffff);
1049 set_memory_rw(0xa0000, 0xbffff, &(ram[window_a0000h]));
1051 copy_table_rw(0xa0000, 0xc0000, 0xdffff);
1054 copy_table_rw(0xa0000, 0xc0000, 0xdffff);
1056 } else if(window_a0000h == 0xe0000) {
1057 #if defined(_PC9801RA) || defined(_PC9801RA2) || defined(_PC9801RA21) //defined(UPPER_I386) && defined(SUPPORT_BIOS_RAM)
1058 if(shadow_ram_selected) {
1059 #if !defined(SUPPORT_HIRESO)
1060 //copy_table_rw(0xa0000, 0xe0000, 0xe7fff);
1061 set_memory_rw(0xa0000, 0xa7fff, &(ram[window_a0000h]));
1062 #if defined(SUPPORT_BIOS_RAM)
1063 set_memory_rw(0xa8000, 0xbffff, ram + 0x100000 - sizeof(bios));
1066 //copy_table_rw(0xa0000, 0xe0000, 0xeffff);
1067 set_memory_rw(0xa0000, 0xaffff, &(ram[window_a0000h]));
1068 #if defined(SUPPORT_BIOS_RAM)
1069 set_memory_rw(0xb0000, 0xbffff, ram + 0x100000 - sizeof(bios));
1073 copy_table_rw(0xa0000, 0xe0000, 0xfffff);
1076 copy_table_rw(0xa0000, 0xe0000, 0xfffff);
1078 } else if((window_a0000h >= 0x80000) && ((window_a0000h + 0x1ffff) < sizeof(ram)) && !((window_a0000h >= 0xa0000) && (window_a0000h <= 0xfffff))) {
1079 set_memory_rw(0xa0000, 0xbffff, &(ram[window_a0000h]));
1081 if(window_a0000h >= 0x80000) {
1082 copy_table_rw(0x000a0000, window_a0000h, window_a0000h + 0x1ffff);
1084 unset_memory_rw(0xa0000, 0xbffff);
1092 #if defined(SUPPORT_32BIT_ADDRESS) || defined(SUPPORT_24BIT_ADDRESS)
1093 #if !defined(SUPPORT_HIRESO)
1094 if((window_80000h >= 0xa0000) && (window_80000h <= 0xeffff)) {
1095 d_display->write_signal(SIG_DISPLAY98_SET_PAGE_80, window_80000h, 0xffffffff);
1097 if((window_a0000h >= 0xa0000) && (window_a0000h <= 0xeffff)) {
1098 d_display->write_signal(SIG_DISPLAY98_SET_PAGE_A0, window_a0000h, 0xffffffff);
1105 #if defined(SUPPORT_32BIT_ADDRESS)
1106 unset_memory_rw(0x00f00000, (UPPER_MEMORY_32BIT & 0x00ffffff) - 1);
1107 #if !defined(SUPPORT_HIRESO)
1108 copy_table_rw(0x00ee8000, 0x000e8000, 0x000fffff);
1109 copy_table_rw(0x00fe8000, 0x000e8000, 0x000fffff);
1111 copy_table_rw(UPPER_MEMORY_32BIT, (UPPER_MEMORY_32BIT & 0x000fffff), 0x000fffff);
1112 copy_table_rw((UPPER_MEMORY_32BIT & 0x00ffffff), (UPPER_MEMORY_32BIT & 0x000fffff), 0x000fffff);
1113 #elif defined(SUPPORT_24BIT_ADDRESS)
1114 unset_memory_rw(0x00f00000, UPPER_MEMORY_24BIT - 1);
1115 copy_table_rw(UPPER_MEMORY_24BIT, UPPER_MEMORY_24BIT & 0x000fffff, 0x000fffff);
1116 #if !defined(SUPPORT_HIRESO)
1117 copy_table_rw(0x00ee8000, 0x000e8000, 0x000fffff);
1118 copy_table_rw(0x00fe8000, 0x000e8000, 0x000fffff);
1124 void MEMBUS::update_sound_bios()
1126 if((sound_bios_selected) && (sound_bios_load) && (using_sound_bios)){
1127 // if(sound_bios_selected) {
1128 // set_memory_rw(0xcc000, 0xcffff, sound_bios_ram);
1130 set_memory_r(0xcc000, 0xcffff, sound_bios);
1131 unset_memory_w(0xcc000, 0xcffff);
1132 set_wait_r(0xcc000, 0xcffff, exboards_wait);
1133 set_wait_w(0xcc000, 0xcffff, 4);
1136 set_memory_r(0xcc000, 0xcffff, sound_bios);
1137 unset_memory_w(0xcc000, 0xcffff);
1138 set_wait_r(0xcc000, 0xcffff, exboards_wait);
1139 set_wait_w(0xcc000, 0xcffff, 4);
1143 #if defined(SUPPORT_SASI_IF)
1144 void MEMBUS::update_sasi_bios()
1146 //out_debug_log(_T("SASI BIOS SELECTED: %s RAM=%s\n"), (sasi_bios_selected) ? _T("YES") : _T("NO"),
1147 // (sasi_bios_ram_selected) ? _T("YES") : _T("NO"));
1148 if(sasi_bios_selected) {
1149 if(sasi_bios_ram_selected) {
1150 set_memory_rw(0xd7000, 0xd7fff, sasi_bios_ram);
1151 set_wait_rw(0xd7000, 0xd7fff, exboards_wait);
1153 set_memory_r(0xd7000, 0xd7fff, sasi_bios);
1154 unset_memory_w(0xd7000, 0xd7fff);
1155 set_wait_r(0xd7000, 0xd7fff, exboards_wait);
1156 set_wait_w(0xd7000, 0xd7fff, 4);
1159 unset_memory_rw(0xd7000, 0xd7fff);
1160 set_wait_rw(0xd7000, 0xd7fff, 4);
1166 #if defined(SUPPORT_SCSI_IF)
1167 void MEMBUS::update_scsi_bios()
1169 if(scsi_bios_selected) {
1170 if(scsi_bios_ram_selected) {
1171 set_memory_rw(0xdc000, 0xdcfff, scsi_bios_ram);
1172 set_wait_rw(0xdc000, 0xdcfff, exboards_wait);
1174 set_memory_r(0xdc000, 0xdcfff, scsi_bios);
1175 unset_memory_w(0xdc000, 0xdcfff);
1176 set_wait_r(0xdc000, 0xdcfff, exboards_wait);
1177 set_wait_w(0xdc000, 0xdcfff, 4);
1180 unset_memory_rw(0xdc000, 0xdcfff);
1181 set_wait_rw(0xdc000, 0xdcfff, 4);
1186 #if defined(SUPPORT_IDE_IF)
1187 void MEMBUS::update_ide_bios()
1189 if(ide_bios_selected) {
1190 set_memory_r(0xd8000, 0xd9fff, &(ide_bios[ide_bios_bank * 0x2000]));
1191 unset_memory_w(0xd8000, 0xd9fff);
1192 set_wait_r(0xd8000, 0xd9fff, exboards_wait);
1193 set_wait_w(0xd8000, 0xdbfff, 4);
1194 set_memory_rw(0xda000, 0xdbfff, ide_bios_ram);
1195 set_wait_rw(0xda000, 0xdbfff, exboards_wait);
1198 unset_memory_rw(0xd8000, 0xdbfff);
1199 set_wait_rw(0xd8000, 0xdbfff, 4);
1205 #if defined(SUPPORT_NEC_EMS)
1206 void MEMBUS::update_nec_ems()
1208 if(nec_ems_selected) {
1209 unset_memory_rw(0xb0000, 0xbffff);
1210 set_memory_rw(0xb0000, 0xbffff, nec_ems);
1211 set_wait_rw(0xb0000, 0xbffff, slotmem_wait);
1213 unset_memory_rw(0xb0000, 0xbffff);
1214 set_memory_mapped_io_rw(0xb0000, 0xbffff, d_display);
1215 set_wait_rw(0xb0000, 0xbffff, gvram_wait_val);
1221 #define STATE_VERSION 14
1223 bool MEMBUS::process_state(FILEIO* state_fio, bool loading)
1225 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1228 if(!state_fio->StateCheckInt32(this_device_id)) {
1231 state_fio->StateArray(ram, sizeof(ram), 1);
1232 #if defined(SUPPORT_BIOS_RAM)
1233 state_fio->StateValue(bios_ram_selected);
1235 #if defined(SUPPORT_ITF_ROM)
1236 state_fio->StateValue(itf_selected);
1238 #if !defined(SUPPORT_HIRESO)
1239 // state_fio->StateArray(sound_bios_ram, sizeof(sound_bios_ram), 1);
1240 state_fio->StateValue(sound_bios_selected);
1241 state_fio->StateValue(sound_bios_load);
1242 #if defined(SUPPORT_SASI_IF)
1243 state_fio->StateArray(sasi_bios_ram, sizeof(sasi_bios_ram), 1);
1244 state_fio->StateValue(sasi_bios_selected);
1245 state_fio->StateValue(sasi_bios_ram_selected);
1246 state_fio->StateValue(sasi_bios_load);
1248 #if defined(SUPPORT_SCSI_IF)
1249 state_fio->StateArray(scsi_bios_ram, sizeof(scsi_bios_ram), 1);
1250 state_fio->StateValue(scsi_bios_selected);
1251 state_fio->StateValue(scsi_bios_ram_selected);
1253 #if defined(SUPPORT_IDE_IF)
1254 state_fio->StateValue(ide_bios_bank);
1255 state_fio->StateArray(ide_bios_ram, sizeof(ide_bios_ram), 1);
1256 state_fio->StateValue(ide_bios_selected);
1258 #if defined(SUPPORT_NEC_EMS)
1259 state_fio->StateArray(nec_ems, sizeof(nec_ems), 1);
1260 state_fio->StateValue(nec_ems_selected);
1261 state_fio->StateValue(use_ems_as_protected);
1262 state_fio->StateValue(ems_protected_base);
1265 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
1266 state_fio->StateValue(dma_access_ctrl);
1267 state_fio->StateValue(window_80000h);
1268 state_fio->StateValue(window_a0000h);
1270 state_fio->StateValue(page08_intram_selected);
1271 state_fio->StateValue(shadow_ram_selected);
1272 state_fio->StateValue(last_access_is_interam);
1274 state_fio->StateValue(intram_wait);
1275 state_fio->StateValue(bank08_wait);
1276 state_fio->StateValue(exmem_wait);
1277 state_fio->StateValue(slotmem_wait);
1278 state_fio->StateValue(exboards_wait);
1279 state_fio->StateValue(introm_wait);
1280 state_fio->StateValue(gvram_wait_val);
1281 state_fio->StateValue(tvram_wait_val);
1283 if(!MEMORY::process_state(state_fio, loading)) {
1291 #if !defined(SUPPORT_HIRESO)
1292 using_sound_bios = ((config.sound_type & 1) == 0) ? true : false;
1294 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
1295 dma_access_a20 = ((dma_access_ctrl & 0x04) != 0) ? false : true;