OSDN Git Service

[VM][FMTOWNS][MEMORY] Fix setup around memory banks by I/O 0404h and 0480h.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc9801 / membus.cpp
1 /*
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'
13
14         Author : Takeda.Toshiya
15         Date   : 2017.06.22-
16
17         [ memory bus ]
18 */
19
20 #include "membus.h"
21 #include "display.h"
22
23 #if defined(_PC9801RA) || defined(_PC9801RA2) || defined(_PC9801RA21) //defined(UPPER_I386)  && defined(SUPPORT_BIOS_RAM)
24 #define SUPPORT_SHADOW_RAM
25 #endif
26
27 #ifdef _MSC_VER
28         // Microsoft Visual C++
29         #pragma warning( disable : 4065 )
30 #endif
31
32 /*
33         NORMAL PC-9801
34                 00000h - 9FFFFh: RAM
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)
47                 E8000h - FFFFFh: BIOS
48
49         HIRESO PC-98XA/XL/XL^2/RL
50                 00000h - 7FFFFh: RAM
51                 80000h - BFFFFh: MEMORY WINDOW
52                 C0000h - DFFFFh: VRAM
53                 E0000h - E1FFFh: TEXT VRAM
54                 E2000h - E3FFFh: ATTRIBUTE
55                 E4000h - E4FFFh: CG WINDOW
56                 F0000h - FFFFFh: BIOS
57 */
58
59 namespace PC9801 {
60
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,
81 };
82  // Note: Penalty wait values is 4 when not hit accessble.(from upsteam 20221204).
83 void MEMBUS::initialize()
84 {
85         MEMORY::initialize();
86
87         // RAM
88         memset(ram, 0x00, sizeof(ram));
89         // VRAM
90         gvram_wait_val = 0;
91         tvram_wait_val = 0;
92
93         // BIOS
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));
97         }
98         // Check PnP Bios and disable. From NP2 v0.83.
99 #if 0
100 #if !defined(SUPPORT_HIRESO) //&& defined(UPPER_I386)
101         for(int ad = 0; ad < 0x10000; ad += 0x10) {
102                 pair32_t magic;
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;
111                 }
112         }
113 #endif
114 #endif
115 #if defined(SUPPORT_BIOS_RAM)
116         shadow_ram_selected = true;
117 #else
118         shadow_ram_selected = false;
119 #endif
120
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));
125
126         itf_selected = true;
127 #endif
128
129         // EXT BIOS
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));
134         }
135 //      read_bios(_T("2HDIF.ROM"), fd_bios_2hd, sizeof(fd_bios_2hd));
136
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));
140         }
141 //      read_bios(_T("2DDIF.ROM"), fd_bios_2dd, sizeof(fd_bios_2dd));
142
143         set_memory_r(0xd6000, 0xd6fff, fd_bios_2dd);
144         set_memory_r(0xd7000, 0xd7fff, fd_bios_2hd);
145 #endif
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;
150
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);
159         }
160         if(sound_bios_load) {
161                 if((config.sound_type & 1) == 0) {
162                         sound_bios_selected = true;
163                 }
164                 out_debug_log(_T("SUCCESS"));
165         }
166         if(sound_bios_selected) {
167                 d_display->set_memsw_4(d_display->get_memsw_4() |  8);
168         } else {
169                 d_display->set_memsw_4(d_display->get_memsw_4() & ~8);
170         }
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));
178         }
179         sasi_bios_selected = true;
180         sasi_bios_ram_selected = false;
181 #endif
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;
187 #endif
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);
192         ide_bios_bank = 0;
193 #endif
194 //      page08_intram_selected = false;
195         page08_intram_selected = true;
196         // EMS
197 #if defined(SUPPORT_NEC_EMS)
198         memset(nec_ems, 0, sizeof(nec_ems));
199 #endif
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);
209 #endif
210         last_access_is_interam = false;
211         set_wait_rw(0x00000, (uint32_t)(space - 1), 4); // Initialize penalty.
212
213         intram_wait = 0;
214         bank08_wait = 0;
215
216         exmem_wait = 0;
217         slotmem_wait = 0;
218         exboards_wait = 0;
219         introm_wait = 0;
220
221         config_intram();
222         update_bios();
223
224 }
225
226 void MEMBUS::reset()
227 {
228         MEMORY::reset();
229         config_intram();
230         // BIOS/ITF
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))); // ;
235 #else
236         shadow_ram_selected = false;
237 #endif
238
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;
244         } else {
245                 using_sound_bios = false;
246                 sound_bios_selected = false;
247         }
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;
252         }
253 #endif
254         // Re-Update Sound BIOS
255         if(sound_bios_selected) {
256                 d_display->set_memsw_4(d_display->get_memsw_4() |  8);
257         } else {
258                 d_display->set_memsw_4(d_display->get_memsw_4() & ~8);
259         }
260
261         //out_debug_log("SOUND BIOS=%s", (sound_bios_selected) ? "YES" : "NO");
262         // EMS
263 #if defined(SUPPORT_NEC_EMS)
264         nec_ems_selected = false;
265         update_nec_ems();
266         use_ems_as_protected = false; // OK?
267         ems_protected_base = 0x00;
268 #endif
269 #endif
270
271         // SASI
272 #if defined(SUPPORT_SASI_IF)
273         sasi_bios_selected = true;
274 //      sasi_bios_selected = false;
275         sasi_bios_ram_selected = false; // OK?
276 #endif
277         // SASI
278 #if defined(SUPPORT_SCSI_IF)
279         scsi_bios_selected = false;
280         scsi_bios_ram_selected = false; // OK?
281 #endif
282         // ToDo: IDE
283 #if defined(SUPPORT_IDE_IF)
284         ide_bios_bank = 0; // ToDo: BANK
285 #endif
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;
294 #else
295         dma_access_ctrl = 0xfb; // bit2 = 0, bit0 = 1
296         dma_access_a20 = true;
297         window_80000h = 0x100000;
298         window_a0000h = 0x120000;
299 #endif
300 #endif
301         page08_intram_selected = true;
302
303         update_bios();
304 }
305
306 void MEMBUS::write_io8(uint32_t addr, uint32_t data)
307 {
308         //out_debug_log(_T("I/O WRITE $%04x %04x\n"), addr, data);
309         switch(addr) {
310 #if defined(SUPPORT_ITF_ROM)
311         case 0x043d:
312                 switch(data & 0xff) {
313         #if defined(SUPPORT_HIRESO)
314                 case 0x00: // HIRESO
315                 case 0x18: // H98S
316         #endif
317                 case 0x10: // Normally BIOS, but, MENU ROM will be selected at H98S.
318                         if(!itf_selected) {
319                                 itf_selected = true;
320                                 update_bios();
321                         }
322                         break;
323         #if defined(SUPPORT_HIRESO)
324                 case 0x02:
325         #endif
326                 case 0x12: // BIOS ROM
327                         if(itf_selected) {
328                                 itf_selected = false;
329                                 update_bios();
330                         }
331                         break;
332                 }
333                 break;
334 #endif
335 #if !defined(SUPPORT_HIRESO)
336         case 0x043f:
337                 switch(data & 0xff) {
338                 case 0x20:
339 #if defined(SUPPORT_NEC_EMS)
340                         if(nec_ems_selected) {
341                                 nec_ems_selected = false;
342                                 update_nec_ems();
343                                 //update_bios();
344                         }
345 #else
346 //      #if !defined(SUPPORT_HIRESO)
347 //                      unset_memory_rw(0xb0000, 0xbffff);
348 //                      set_memory_mapped_io_rw(0xb0000, 0xbffff, d_display);
349 //                      update_bios();
350 //      #endif
351 #endif
352                         break;
353                 case 0x22:
354 #if defined(SUPPORT_NEC_EMS)
355                         if(!nec_ems_selected) {
356                                 nec_ems_selected = true;
357                                 update_nec_ems();
358 //                              update_bios();
359                         }
360 #else
361 //      #if !defined(SUPPORT_HIRESO)
362 //                      unset_memory_rw(0xb0000, 0xbffff);
363 //                      set_memory_rw(0xb0000, 0xbffff, &(ram[0xb0000]));
364 //                      update_bios();
365 //      #endif
366 #endif
367                         break;
368                 case 0xc0:
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;
374                                         update_sasi_bios();
375                                         //update_bios();
376                                 }
377                         }
378 #endif
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;
384                                         update_scsi_bios();
385                                         //update_bios();
386                                 }
387                         //}
388 #endif
389                         break;
390                 case 0xc2:
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;
396                                         update_sasi_bios();
397                                         //update_bios();
398                                 }
399                         }
400 #endif
401                         break;
402                 case 0xc4:
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;
408                                         update_scsi_bios();
409                                         //update_bios();
410                                 }
411                         }
412 #endif
413                         break;
414                 case 0x80:
415                         if(!(page08_intram_selected)) {
416                                 page08_intram_selected = true;
417 //#if !defined(_PC9801RA)
418                                 update_bios();
419 //#endif
420                         }
421                         break;
422                 case 0x82:
423                         if(page08_intram_selected) {
424                                 page08_intram_selected = false;
425 //#if !defined(_PC9801RA)
426                                 update_bios();
427 //#endif
428                         }
429                         break;
430                 }
431                 break;
432 #endif
433 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
434 #if !defined(_PC98XA)
435         case 0x0439:
436                 dma_access_ctrl = data;
437                 dma_access_a20 = ((data & 0x04) != 0) ? false : true;
438                 break;
439 #endif
440 #if defined(SUPPORT_NEC_EMS)
441         case 0x08e9:
442                 use_ems_as_protected = (data != 0) ? true: false;
443                 ems_protected_base = (uint32_t)(data & 0x0f) << 20;
444                 update_bios();
445                 break;
446 #endif
447 #if defined(SUPPORT_HIRESO)
448         case 0x0091:
449                 {
450                         uint32_t _bak = window_80000h;
451 #if defined(_PC98XA)
452                         if(data < 0x10) {
453                                 //update_bios();
454                                 break;
455                         }
456 #endif
457                         // http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
458                         window_80000h = (data & 0xfe) << 16;
459                         if(_bak != window_80000h) {
460                                 update_bios();
461                         }
462                 }
463                 break;
464 #endif
465 #if 1
466         case 0x0461:
467                 // http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
468                 // ToDo: Cache flush for i486 or later.
469                 if(data >= 0x08) {
470                         uint32_t _bak = window_80000h;
471                         window_80000h = (data & 0xfe) << 16;
472                         if(_bak != window_80000h) {
473                                 update_bios();
474                         }
475                 }
476                 break;
477 #endif
478 #if defined(SUPPORT_HIRESO)
479         case 0x0093:
480 #if defined(_PC98XA)
481                 if(data < 0x10) {
482                         break;
483                 }
484 #endif
485                 // http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
486                 {
487                         uint32_t _bak = window_a0000h;
488                         window_a0000h = (data & 0xfe) << 16;
489                         if(_bak != window_a0000h) {
490                                 update_bios();
491                         }
492                 }
493                 break;
494 #endif
495 #if 1
496         case 0x0463:
497                 // http://www.webtech.co.jp/company/doc/undocumented_mem/io_mem.txt
498                 // ToDo: Cache flush for i486 or later.
499                 if(data >= 0x08) {
500                         uint32_t _bak = window_a0000h;
501                         window_a0000h = (data & 0xfe) << 16;
502                         if(_bak != window_a0000h) {
503                                 update_bios();
504                         }
505                 }
506                 break;
507 #endif
508 #endif
509 #if defined(UPPER_I386) // ToDo: Upper type
510         case 0x053d:
511                 {
512                         bool result = false;
513                         bool _bak;
514 /*
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");
522                         }
523 #endif
524 */
525 #if defined(SUPPORT_SASI_IF)
526                         {
527                                 _bak = sasi_bios_selected;
528                                 sasi_bios_selected = ((data & 0x40) != 0);
529                                 if(_bak != sasi_bios_selected) result = true;
530                         }
531 #endif
532 #if defined(SUPPORT_SCSI_IF)
533                         {
534                                 _bak = scsi_bios_selected;
535                                 scsi_bios_selected = ((data & 0x20) != 0);
536                                 if(_bak != scsi_bios_selected) result = true;
537                         }
538 #endif
539 #if defined(SUPPORT_IDE_IF)
540                         {
541                                 _bak = ide_bios_selected;
542                                 ide_bios_selected = ((data & 0x10) != 0);
543                                 if(_bak != ide_bios_selected) result = true;
544                         }
545 #endif
546                         {
547                                 _bak = shadow_ram_selected;
548                                 shadow_ram_selected = ((data & 0x04) == 0);
549                                 if(_bak != shadow_ram_selected) result = true;
550                         }
551 #if defined(SUPPORT_BIOS_RAM)
552                         {
553                                 _bak = bios_ram_selected;
554                                 bios_ram_selected = ((data & 0x02) != 0);
555                                 if(_bak != bios_ram_selected) result = true;
556                         }
557 #endif
558                         if(result) update_bios();
559                 }
560                 break;
561 #endif
562         // dummy for no cases
563         default:
564                 break;
565         }
566 }
567
568 uint32_t MEMBUS::read_io8(uint32_t addr)
569 {
570         //out_debug_log(_T("I/O READ $%04x\n"), addr);
571         switch(addr) {
572 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
573 #if !defined(_PC98XA)
574         case 0x0439:
575                 return dma_access_ctrl;
576 #endif
577 #if !defined(SUPPORT_HIRESO)
578         case 0x0461: // ToDo: Some VMs enable to read value.
579                 return window_80000h >> 16;
580 //              return 0xff;
581                 break;
582 #else
583         case 0x0091:
584                 return window_80000h >> 16;
585                 break;
586 #endif
587 #if !defined(SUPPORT_HIRESO)
588         case 0x0463: // ToDo: Some VMs enable to read value.
589                 return window_a0000h >> 16;
590 //              return 0xff;
591                 break;
592 #else
593         case 0x0093:
594                 return window_a0000h >> 16;
595                 break;
596 #endif
597         case 0x0567:
598                 return (uint8_t)((sizeof(ram) - 0x100000) >> 17);
599 #endif
600         // dummy for no cases
601         default:
602                 break;
603         }
604         return 0xff;
605 }
606
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
611 #else
612         #define UPPER_MEMORY_24BIT      0x00fc0000
613         #define UPPER_MEMORY_32BIT      0xfffc0000
614 #endif
615
616         // Note: Artane. variant of ePC9801xx changes bank dynamically.
617         // Not need to translate addrsss.
618         // - 20230323 K.O
619 inline bool MEMBUS::get_memory_addr(uint32_t *addr)
620 {
621 #if 0
622         for(;;) {
623                 if(*addr < 0x80000) {
624                         return true;
625                 }
626                 if(*addr < 0xa0000) {
627                         __UNLIKELY_IF((*addr = (*addr & 0x1ffff) | window_80000h) >= UPPER_MEMORY_24BIT) {
628                                 *addr &= 0xfffff;
629                         }
630                         return true;
631                 }
632                 if(*addr < 0xc0000) {
633                         __UNLIKELY_IF((*addr = (*addr & 0x1ffff) | window_a0000h) >= UPPER_MEMORY_24BIT) {
634                                 *addr &= 0xfffff;
635                         }
636                         return true;
637                 }
638                 __LIKELY_IF(*addr < UPPER_MEMORY_24BIT) {
639                         return true;
640                 }
641         #if defined(SUPPORT_32BIT_ADDRESS)
642                 __UNLIKELY_IF(*addr < 0x1000000 || *addr >= UPPER_MEMORY_32BIT) {
643                         *addr &= 0xfffff;
644                 } else {
645                         return false;
646                 }
647         #else
648                 *addr &= 0xfffff;
649         #endif
650         }
651 #else
652 #endif
653         return false;
654 }
655
656 // 4clk = wait when access memory on expansion board ???
657
658 #endif
659
660 // Note: Artane. variant of ePC9801xx changes bank dynamically.
661 // Not need to translate addrsss.
662 // - 20230323 K.O
663 uint32_t MEMBUS::read_dma_data8w(uint32_t addr, int *wait)
664 {
665 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
666         if(dma_access_ctrl & 4) {
667                 addr &= 0x000fffff;
668         }
669 #endif
670         return read_data8w(addr, wait);
671 }
672
673 void MEMBUS::write_dma_data8w(uint32_t addr, uint32_t data, int *wait)
674 {
675 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
676         if(dma_access_ctrl & 4) {
677                 addr &= 0x000fffff;
678         }
679 #endif
680         write_data8w(addr, data, wait);
681 }
682
683 uint32_t MEMBUS::read_dma_data16w(uint32_t addr, int *wait)
684 {
685         __LIKELY_IF(!(addr & 1)) {
686 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
687                 if(dma_access_ctrl & 4) {
688                         addr &= 0x000fffff;
689                 }
690 #endif
691                 return read_data16w(addr, wait);
692         } else {
693                 int wait_l = 0, wait_h = 0;
694                 uint32_t val;
695                 val  = read_dma_data8w(addr    , &wait_l);
696                 val |= read_dma_data8w(addr + 1, &wait_h) << 8;
697                 *wait = wait_l + wait_h;
698                 return val;
699         }
700 }
701
702 void MEMBUS::write_dma_data16w(uint32_t addr, uint32_t data, int *wait)
703 {
704         __LIKELY_IF(!(addr & 1)) {
705 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
706                 if(dma_access_ctrl & 4) {
707                         addr &= 0x000fffff;
708                 }
709 #endif
710                 write_data16w(addr, data, wait);
711         } else {
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;
716         }
717 }
718
719
720 void MEMBUS::write_signal(int ch, uint32_t data, uint32_t mask)
721 {
722         switch(ch) {
723         case SIG_INTRAM_WAIT:
724                 intram_wait = (int)(data & 0xff);
725                 update_bios();
726                 break;
727         case SIG_BANK08_WAIT:
728                 bank08_wait = (int)(data & 0xff);
729                 update_bios();
730                 break;
731         case SIG_EXMEM_WAIT:
732                 exmem_wait = (int)(data & 0xff);
733                 update_bios();
734                 break;
735         case SIG_SLOTMEM_WAIT:
736                 slotmem_wait = (int)(data & 0xff);
737                 update_bios();
738                 break;
739         case SIG_EXBOARDS_WAIT:
740                 exboards_wait = (int)(data & 0xff);
741                 update_bios();
742                 break;
743         case SIG_INTROM_WAIT:
744                 introm_wait = (int)(data & 0xff);
745                 update_bios();
746                 break;
747         case SIG_GVRAM_WAIT:
748                 gvram_wait_val = (int)(data & 0xff);
749                 update_bios();
750                 break;
751         case SIG_TVRAM_WAIT:
752                 tvram_wait_val = (int)(data & 0xff);
753                 update_bios();
754                 break;
755         default:
756                 break;
757         }
758 }
759
760
761 uint32_t MEMBUS::read_signal(int ch)
762 {
763         switch(ch) {
764         case SIG_LAST_ACCESS_INTERAM:
765                 return ((last_access_is_interam) ? 0xffffffff : 0x00000000);
766                 break;
767         }
768         return 0;
769 }
770
771 void MEMBUS::config_intram()
772 {
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);
779         #else
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);
782         #endif
783 #else
784         set_memory_rw(0x00000, 0xbffff, ram);
785 #endif
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);
792
793                 uint32_t _begin_addr2 = _end_addr1 + 1;
794                 unset_memory_rw(_begin_addr2, 0x00efffff);
795         } else {
796                 unset_memory_rw(0x00100000, 0x00efffff);
797         }
798 #endif
799 }
800
801 void MEMBUS::update_bios_mainmem()
802 {
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);
807         #endif
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);
813 #else
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);
822         }
823         #endif
824 #endif
825 }
826
827 void MEMBUS::update_bios_extra_boards()
828 {
829 #if !defined(SUPPORT_HIRESO)
830         {
831                 unset_memory_rw(0xc0000, 0xe7fff);
832                 set_wait_rw(0xc0000, 0xe7fff, 4);
833                 //#endif
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?
838                 #endif
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?
842                 #endif
843                 update_sound_bios();
844
845                 #if defined(SUPPORT_SASI_IF)
846                 update_sasi_bios();
847                 #endif
848                 #if defined(SUPPORT_SCSI_IF)
849                 update_scsi_bios();
850                 #endif
851                 #if defined(SUPPORT_IDE_IF)
852                 update_ide_bios();
853                 #endif
854         }
855 #else
856         // ToDo: For HIRESO VMs
857 #endif
858 }
859
860 void MEMBUS::update_bios_ipl_and_itf()
861 {
862 #if defined(SUPPORT_ITF_ROM)
863         if(itf_selected) {
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?
867         } else
868 #endif
869         {
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?
874                 } else
875 #endif
876                 {
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?
881                 }
882         }
883 //      set_wait_rw(0x00100000 - sizeof(bios), 0xfffff, introm_wait);
884 }
885
886 void MEMBUS::update_bios_window(uint32_t window_addr, uint32_t begin)
887 {
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);
892         }
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);
899                         } else {
900                                 unset_memory_rw(begin, end);
901                                 set_wait_rw(begin, end, 4);
902                         }
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);
910                         } else {
911                                 copy_table_rw(begin, 0xc0000, 0xdffff);
912                         }
913                 #else
914                         copy_table_rw(begin, 0xc0000, 0xdffff);
915                 #endif
916                 } else if(window_addr == 0xe0000) {
917                         uint32_t head_address;
918         #if !defined(SUPPORT_HIRESO)
919                         head_address = begin + 0x8000;
920         #else
921                         head_address = begin + 0x10000;
922         #endif
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);
928                         } else
929         #endif
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);
935                         } else
936                 #endif
937                         {
938                                 unset_memory_rw(begin, end);
939                                 set_wait_rw(begin, end, 4);
940 #if defined(SUPPORT_ITF_ROM)
941                                 if(itf_selected) {
942                                         set_memory_r(end - sizeof(itf) + 1, end , &(itf[0x00000]));
943                                         set_wait_rw(end - sizeof(itf) + 1, end, introm_wait);
944                                 } else
945                         #endif
946                                 {
947                                         set_memory_r(head_address, end, &(bios[0x00000]));
948                                         set_wait_r(head_address, end, 4);
949                                 }
950                         }
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);
955                 }
956         } else {
957                 // Internal RAM is not selected.
958                 // ToDo: Hi reso
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]));
972                         } else
973                 #endif
974                         {
975                                 copy_table_rw(begin, 0xc0000, 0xdffff); // BOARD
976                         }
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
982                         } else
983                 #endif
984                         {
985                                 copy_table_rw(begin, 0xe0000, 0xfffff); // BIOS
986                         }
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]));
991                         } else {
992                                 unset_memory_rw(begin, end);
993                         }
994                 }
995         }
996 #endif
997 }
998 void MEMBUS::update_bios()
999 {
1000         update_bios_mainmem();
1001 #if !defined(SUPPORT_HIRESO)
1002         update_bios_extra_boards();
1003 #else // HIRESO
1004 #endif
1005         update_bios_ipl_and_itf();
1006
1007 #if defined(SUPPORT_32BIT_ADDRESS) || defined(SUPPORT_24BIT_ADDRESS)
1008         #if defined(SUPPORT_NEC_EMS)
1009         // Is It right?
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);
1016                 }
1017         } else {
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);
1023                 } else {
1024                         unset_memory_rw(0x00100000, 0x00efffff);
1025                         set_wait_rw(0x00100000, 0x00efffff, 4);
1026                 }
1027         }
1028         #endif
1029         if(sizeof(ram) > 0x10000) {
1030                 set_wait_rw(0x00100000, (sizeof(ram) >= 0x00e00000) ? 0x00dfffff : (sizeof(ram) - 1), exmem_wait);
1031         }
1032 #endif
1033         if(shadow_ram_selected) {
1034 //              set_wait_rw(0xa0000, 0xbffff, bank08_wait);
1035                 set_wait_rw(0xa0000, 0xbffff, intram_wait);
1036         } else {
1037                 set_wait_rw(0xa0000, 0xbffff, intram_wait);
1038         }
1039 #if defined(SUPPORT_32BIT_ADDRESS) || defined(SUPPORT_24BIT_ADDRESS)
1040         update_bios_window(window_80000h, 0x80000);
1041         update_bios_window(window_a0000h, 0xa0000);
1042 #endif
1043 #if 0
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]));
1050                         } else {
1051                                 copy_table_rw(0xa0000, 0xc0000, 0xdffff);
1052                         }
1053         #else
1054                         copy_table_rw(0xa0000, 0xc0000, 0xdffff);
1055         #endif
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));
1064                         #endif
1065                 #else
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));
1070                         #endif
1071                 #endif
1072                         } else {
1073                                 copy_table_rw(0xa0000, 0xe0000, 0xfffff);
1074                         }
1075         #else
1076                         copy_table_rw(0xa0000, 0xe0000, 0xfffff);
1077         #endif
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]));
1080                 } else {
1081                         if(window_a0000h >= 0x80000) {
1082                                 copy_table_rw(0x000a0000, window_a0000h, window_a0000h + 0x1ffff);
1083                         } else {
1084                                 unset_memory_rw(0xa0000, 0xbffff);
1085                         }
1086
1087                 }
1088         } //else {
1089         //      // NOOP
1090         //}
1091 #endif
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);
1096         }
1097         if((window_a0000h >= 0xa0000) && (window_a0000h <= 0xeffff)) {
1098                 d_display->write_signal(SIG_DISPLAY98_SET_PAGE_A0, window_a0000h, 0xffffffff);
1099         }
1100         #else
1101         // ToDo
1102         #endif
1103 #endif
1104         // ToDo: PC9821
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);
1110         #endif
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);
1119         #endif
1120 #endif
1121 }
1122
1123
1124 void MEMBUS::update_sound_bios()
1125 {
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);
1129 //              } else {
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);
1134 //              }
1135         } else {
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);
1140         }
1141 }
1142
1143 #if defined(SUPPORT_SASI_IF)
1144 void MEMBUS::update_sasi_bios()
1145 {
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);
1152                 } else {
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);
1157                 }
1158         } else {
1159                 unset_memory_rw(0xd7000, 0xd7fff);
1160                 set_wait_rw(0xd7000, 0xd7fff, 4);
1161         }
1162
1163 }
1164 #endif
1165
1166 #if defined(SUPPORT_SCSI_IF)
1167 void MEMBUS::update_scsi_bios()
1168 {
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);
1173                 } else {
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);
1178                 }
1179         } else {
1180                 unset_memory_rw(0xdc000, 0xdcfff);
1181                 set_wait_rw(0xdc000, 0xdcfff, 4);
1182         }
1183 }
1184 #endif
1185
1186 #if defined(SUPPORT_IDE_IF)
1187 void MEMBUS::update_ide_bios()
1188 {
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);
1196 //              }
1197         } else {
1198                 unset_memory_rw(0xd8000, 0xdbfff);
1199                 set_wait_rw(0xd8000, 0xdbfff, 4);
1200         }
1201
1202 }
1203 #endif
1204
1205 #if defined(SUPPORT_NEC_EMS)
1206 void MEMBUS::update_nec_ems()
1207 {
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);
1212         } else {
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);
1216         }
1217 }
1218 #endif
1219
1220
1221 #define STATE_VERSION   14
1222
1223 bool MEMBUS::process_state(FILEIO* state_fio, bool loading)
1224 {
1225         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1226                 return false;
1227         }
1228         if(!state_fio->StateCheckInt32(this_device_id)) {
1229                 return false;
1230         }
1231         state_fio->StateArray(ram, sizeof(ram), 1);
1232  #if defined(SUPPORT_BIOS_RAM)
1233         state_fio->StateValue(bios_ram_selected);
1234  #endif
1235  #if defined(SUPPORT_ITF_ROM)
1236         state_fio->StateValue(itf_selected);
1237  #endif
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);
1247  #endif
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);
1252  #endif
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);
1257  #endif
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);
1263  #endif
1264  #endif
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);
1269  #endif
1270         state_fio->StateValue(page08_intram_selected);
1271         state_fio->StateValue(shadow_ram_selected);
1272         state_fio->StateValue(last_access_is_interam);
1273
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);
1282
1283         if(!MEMORY::process_state(state_fio, loading)) {
1284                 return false;
1285         }
1286
1287         // post process
1288         if(loading) {
1289                 config_intram();
1290                 update_bios();
1291 #if !defined(SUPPORT_HIRESO)
1292                 using_sound_bios = ((config.sound_type & 1) == 0) ? true : false;
1293 #endif
1294 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
1295                 dma_access_a20 = ((dma_access_ctrl & 0x04) != 0) ? false : true;
1296 #endif
1297         }
1298         return true;
1299 }
1300
1301 }