OSDN Git Service

[VM][STATE] Use namespace {VMNAME} to separate per VMs.
[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 #ifdef _MSC_VER
24         // Microsoft Visual C++
25         #pragma warning( disable : 4065 )
26 #endif
27
28 /*
29         NORMAL PC-9801
30                 00000h - 9FFFFh: RAM
31                 A0000h - A1FFFh: TEXT VRAM
32                 A2000h - A3FFFh: ATTRIBUTE
33                 A4000h - A4FFFh: CG WINDOW
34                 A8000h - BFFFFh: VRAM (BRG)
35                 C0000h - DFFFFh: EXT BIOS
36                         CC000h - CFFFFh: SOUND BIOS
37                         D6000h - D6FFFh: 2DD FDD BIOS
38                         D7000h - D7FFFh: 2HD FDD BIOS
39                         D7000h - D7FFFh: SASI BIOS
40                         D8000h - DBFFFh: IDE BIOS
41                         DC000h - DCFFFh: SCSI BIOS
42                 E0000h - E7FFFh: VRAM (I)
43                 E8000h - FFFFFh: BIOS
44
45         HIRESO PC-98XA/XL/XL^2/RL
46                 00000h - 7FFFFh: RAM
47                 80000h - BFFFFh: MEMORY WINDOW
48                 C0000h - DFFFFh: VRAM
49                 E0000h - E1FFFh: TEXT VRAM
50                 E2000h - E3FFFh: ATTRIBUTE
51                 E4000h - E4FFFh: CG WINDOW
52                 F0000h - FFFFFh: BIOS
53 */
54
55 namespace PC9801 {
56
57 void MEMBUS::initialize()
58 {
59         MEMORY::initialize();
60         
61         // RAM
62         memset(ram, 0x00, sizeof(ram));
63 #if !defined(SUPPORT_HIRESO)
64         set_memory_rw(0x00000, 0x9ffff, ram);
65 #else
66         set_memory_rw(0x00000, 0xbffff, ram);
67 #endif
68 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
69         if(sizeof(ram) > 0x100000) {
70                 set_memory_rw(0x100000, sizeof(ram) - 1, ram + 0x100000);
71         }
72 #endif
73         
74         // VRAM
75 #if !defined(SUPPORT_HIRESO)
76         set_memory_mapped_io_rw(0xa0000, 0xa4fff, d_display);
77         set_memory_mapped_io_rw(0xa8000, 0xbffff, d_display);
78 #if defined(SUPPORT_16_COLORS)
79         set_memory_mapped_io_rw(0xe0000, 0xe7fff, d_display);
80 #endif
81 #else
82         set_memory_mapped_io_rw(0xc0000, 0xe4fff, d_display);
83 #endif
84         
85         // BIOS
86         memset(bios, 0xff, sizeof(bios));
87         if(!read_bios(_T("IPL.ROM"), bios, sizeof(bios))) {
88                 read_bios(_T("BIOS.ROM"), bios, sizeof(bios));
89         }
90 #if defined(SUPPORT_BIOS_RAM)
91         memset(bios_ram, 0x00, sizeof(bios_ram));
92 #endif
93 #if defined(SUPPORT_ITF_ROM)
94         memset(itf, 0xff, sizeof(itf));
95         read_bios(_T("ITF.ROM"), itf, sizeof(itf));
96 #endif
97         
98 #if !defined(SUPPORT_HIRESO)
99         // EXT BIOS
100 #if defined(_PC9801) || defined(_PC9801E)
101         memset(fd_bios_2hd, 0xff, sizeof(fd_bios_2hd));
102         read_bios(_T("2HDIF.ROM"), fd_bios_2hd, sizeof(fd_bios_2hd));
103         set_memory_r(0xd6000, 0xd6fff, fd_bios_2dd);
104         
105         memset(fd_bios_2dd, 0xff, sizeof(fd_bios_2dd));
106         read_bios(_T("2DDIF.ROM"), fd_bios_2dd, sizeof(fd_bios_2dd));
107         set_memory_r(0xd7000, 0xd7fff, fd_bios_2hd);
108 #endif
109         memset(sound_bios, 0xff, sizeof(sound_bios));
110 //      memset(sound_bios_ram, 0x00, sizeof(sound_bios_ram));
111         sound_bios_selected = false;
112 //      sound_bios_ram_selected = false;
113         if(config.sound_type == 0) {
114                 sound_bios_selected = (read_bios(_T("SOUND.ROM"), sound_bios, sizeof(sound_bios)) != 0);
115         } else if(config.sound_type == 2) {
116                 sound_bios_selected = (read_bios(_T("MUSIC.ROM"), sound_bios, sizeof(sound_bios)) != 0);
117         }
118         if(sound_bios_selected) {
119                 d_display->sound_bios_ok();
120         }
121         update_sound_bios();
122 #if defined(SUPPORT_SASI_IF)
123         memset(sasi_bios, 0xff, sizeof(sasi_bios));
124         memset(sasi_bios_ram, 0x00, sizeof(sasi_bios_ram));
125         sasi_bios_selected = (read_bios(_T("SASI.ROM"), sasi_bios, sizeof(sasi_bios)) != 0);
126         sasi_bios_ram_selected = false;
127         update_sasi_bios();
128 #endif
129 #if defined(SUPPORT_SCSI_IF)
130         memset(scsi_bios, 0xff, sizeof(scsi_bios));
131         memset(scsi_bios_ram, 0x00, sizeof(scsi_bios_ram));
132         scsi_bios_selected = (read_bios(_T("SCSI.ROM"), scsi_bios, sizeof(scsi_bios)) != 0);
133         scsi_bios_ram_selected = false;
134         update_scsi_bios();
135 #endif
136 #if defined(SUPPORT_IDE_IF)
137         memset(ide_bios, 0xff, sizeof(ide_bios));
138 //      memset(ide_bios_ram, 0x00, sizeof(ide_bios_ram));
139         ide_bios_selected = (read_bios(_T("IDE.ROM"), ide_bios, sizeof(ide_bios)) != 0);
140 //      ide_bios_ram_selected = false;
141         update_ide_bios();
142 #endif
143         
144         // EMS
145 #if defined(SUPPORT_NEC_EMS)
146         memset(nec_ems, 0, sizeof(nec_ems));
147 #endif
148 #endif
149 }
150
151 void MEMBUS::reset()
152 {
153         MEMORY::reset();
154         
155         // BIOS/ITF
156 #if defined(SUPPORT_BIOS_RAM)
157         bios_ram_selected = false;
158 #endif
159 #if defined(SUPPORT_ITF_ROM)
160         itf_selected = true;
161 #endif
162         update_bios();
163         
164 #if !defined(SUPPORT_HIRESO)
165         // EMS
166 #if defined(SUPPORT_NEC_EMS)
167         nec_ems_selected = false;
168         update_nec_ems();
169 #endif
170 #endif
171         
172 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
173 #if !defined(SUPPORT_HIRESO)
174         dma_access_ctrl = 0xfe; // bit2 = 1, bit0 = 0
175         window_80000h = 0x80000;
176         window_a0000h = 0xa0000;
177 #else
178         dma_access_ctrl = 0xfb; // bit2 = 0, bit0 = 1
179         window_80000h = 0x100000;
180         window_a0000h = 0x120000;
181 #endif
182 #endif
183 }
184
185 void MEMBUS::write_io8(uint32_t addr, uint32_t data)
186 {
187         switch(addr) {
188 #if defined(SUPPORT_ITF_ROM)
189         case 0x043d:
190                 switch(data & 0xff) {
191                 case 0x00:
192                 case 0x10:
193                 case 0x18:
194                         if(!itf_selected) {
195                                 itf_selected = true;
196                                 update_bios();
197                         }
198                         break;
199                 case 0x02:
200                 case 0x12:
201                         if(itf_selected) {
202                                 itf_selected = false;
203                                 update_bios();
204                         }
205                         break;
206                 }
207                 break;
208 #endif
209 #if !defined(SUPPORT_HIRESO)
210         case 0x043f:
211                 switch(data & 0xff) {
212                 case 0x20:
213 #if defined(SUPPORT_NEC_EMS)
214                         if(nec_ems_selected) {
215                                 nec_ems_selected = false;
216                                 update_nec_ems();
217                         }
218 #endif
219                         break;
220                 case 0x22:
221 #if defined(SUPPORT_NEC_EMS)
222                         if(!nec_ems_selected) {
223                                 nec_ems_selected = true;
224                                 update_nec_ems();
225                         }
226 #endif
227                         break;
228                 case 0xc0:
229 #if defined(SUPPORT_SASI_IF)
230                         if(sasi_bios_ram_selected) {
231                                 sasi_bios_ram_selected = false;
232                                 if(sasi_bios_selected) {
233                                         update_sasi_bios();
234                                 }
235                         }
236 #endif
237 #if defined(SUPPORT_SCSI_IF)
238                         if(scsi_bios_ram_selected) {
239                                 scsi_bios_ram_selected = false;
240                                 if(scsi_bios_selected) {
241                                         update_scsi_bios();
242                                 }
243                         }
244 #endif
245                         break;
246                 case 0xc2:
247 #if defined(SUPPORT_SASI_IF)
248                         if(!sasi_bios_ram_selected) {
249                                 sasi_bios_ram_selected = true;
250                                 if(sasi_bios_selected) {
251                                         update_sasi_bios();
252                                 }
253                         }
254 #endif
255                         break;
256                 case 0xc4:
257 #if defined(SUPPORT_SCSI_IF)
258                         if(!scsi_bios_ram_selected) {
259                                 scsi_bios_ram_selected = true;
260                                 if(scsi_bios_selected) {
261                                         update_scsi_bios();
262                                 }
263                         }
264 #endif
265                         break;
266                 }
267                 break;
268 #endif
269 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
270 #if !defined(_PC98XA)
271         case 0x0439:
272                 dma_access_ctrl = data;
273                 break;
274 #endif
275 #if !defined(SUPPORT_HIRESO)
276         case 0x0461:
277 #else
278         case 0x0091:
279 #if defined(_PC98XA)
280                 if(data < 0x10) {
281                         break;
282                 }
283 #endif
284 #endif
285                 window_80000h = (data & 0xfe) << 16;
286                 break;
287 #if !defined(SUPPORT_HIRESO)
288         case 0x0463:
289 #else
290         case 0x0093:
291 #if defined(_PC98XA)
292                 if(data < 0x10) {
293                         break;
294                 }
295 #endif
296 #endif
297                 window_a0000h = (data & 0xfe) << 16;
298                 break;
299 #endif
300 #if defined(SUPPORT_32BIT_ADDRESS)
301         case 0x053d:
302 #if !defined(SUPPORT_HIRESO)
303                 if(sound_bios_selected != ((data & 0x80) != 0)) {
304                         sound_bios_selected = ((data & 0x80) != 0);
305                         update_sound_bios();
306                 }
307 #if defined(SUPPORT_SASI_IF)
308                 if(sasi_bios_selected != ((data & 0x40) != 0)) {
309                         sasi_bios_selected = ((data & 0x40) != 0);
310                         update_sasi_bios();
311                 }
312 #endif
313 #if defined(SUPPORT_SCSI_IF)
314                 if(scsi_bios_selected != ((data & 0x20) != 0)) {
315                         scsi_bios_selected = ((data & 0x20) != 0);
316                         update_scsi_bios();
317                 }
318 #endif
319 #if defined(SUPPORT_IDE_IF)
320                 if(ide_bios_selected != ((data & 0x10) != 0)) {
321                         ide_bios_selected = ((data & 0x10) != 0);
322                         update_ide_bios();
323                 }
324 #endif
325 #endif
326 #if defined(SUPPORT_BIOS_RAM)
327                 if(bios_ram_selected != ((data & 0x02) != 0)) {
328                         bios_ram_selected = ((data & 0x02) != 0);
329                         update_bios();
330                 }
331 #endif
332                 break;
333 #endif
334         // dummy for no cases
335         default:
336                 break;
337         }
338 }
339
340 uint32_t MEMBUS::read_io8(uint32_t addr)
341 {
342         switch(addr) {
343 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
344 #if !defined(_PC98XA)
345         case 0x0439:
346                 return dma_access_ctrl;
347 #endif
348 #if !defined(SUPPORT_HIRESO)
349         case 0x0461:
350 #else
351         case 0x0091:
352 #endif
353                 return window_80000h >> 16;
354 #if !defined(SUPPORT_HIRESO)
355         case 0x0463:
356 #else
357         case 0x0093:
358 #endif
359                 return window_a0000h >> 16;
360         case 0x0567:
361                 return (uint8_t)(sizeof(ram) >> 17);
362 #endif
363         // dummy for no cases
364         default:
365                 break;
366         }
367         return 0xff;
368 }
369
370 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
371 #if !defined(SUPPORT_HIRESO)
372         #define UPPER_MEMORY_24BIT      0x00fa0000
373         #define UPPER_MEMORY_32BIT      0xfffa0000
374 #else
375         #define UPPER_MEMORY_24BIT      0x00fc0000
376         #define UPPER_MEMORY_32BIT      0xfffc0000
377 #endif
378
379 uint32_t MEMBUS::read_data8(uint32_t addr)
380 {
381         if(addr < 0x80000) {
382                 return MEMORY::read_data8(addr);
383         } else if(addr < 0xa0000) {
384                 addr = (addr & 0x1ffff) | window_80000h;
385         } else if(addr < 0xc0000) {
386                 addr = (addr & 0x1ffff) | window_a0000h;
387         }
388         if(addr < UPPER_MEMORY_24BIT) {
389                 return MEMORY::read_data8(addr);
390 #if defined(SUPPORT_24BIT_ADDRESS)
391         } else {
392 #else
393         } else if(addr < 0x1000000 || addr >= UPPER_MEMORY_32BIT) {
394 #endif
395                 return MEMORY::read_data8(addr & 0xfffff);
396         }
397         return 0xff;
398 }
399
400 void MEMBUS::write_data8(uint32_t addr, uint32_t data)
401 {
402         if(addr < 0x80000) {
403                 MEMORY::write_data8(addr, data);
404                 return;
405         } else if(addr < 0xa0000) {
406                 addr = (addr & 0x1ffff) | window_80000h;
407         } else if(addr < 0xc0000) {
408                 addr = (addr & 0x1ffff) | window_a0000h;
409         }
410         if(addr < UPPER_MEMORY_24BIT) {
411                 MEMORY::write_data8(addr, data);
412 #if defined(SUPPORT_24BIT_ADDRESS)
413         } else {
414 #else
415         } else if(addr < 0x1000000 || addr >= UPPER_MEMORY_32BIT) {
416 #endif
417                 MEMORY::write_data8(addr & 0xfffff, data);
418         }
419 }
420
421 uint32_t MEMBUS::read_dma_data8(uint32_t addr)
422 {
423         if(dma_access_ctrl & 4) {
424                 addr &= 0x000fffff;
425         }
426         return MEMBUS::read_data8(addr);
427 }
428
429 void MEMBUS::write_dma_data8(uint32_t addr, uint32_t data)
430 {
431         if(dma_access_ctrl & 4) {
432                 addr &= 0x000fffff;
433         }
434         MEMBUS::write_data8(addr, data);
435 }
436 #endif
437
438 void MEMBUS::update_bios()
439 {
440         unset_memory_rw(0x100000 - sizeof(bios), 0xfffff);
441 #if defined(SUPPORT_ITF_ROM)
442         if(itf_selected) {
443                 set_memory_r(0x100000 - sizeof(itf), 0xfffff, itf);
444         } else {
445 #endif
446 #if defined(SUPPORT_BIOS_RAM)
447                 if(bios_ram_selected) {
448                         set_memory_rw(0x100000 - sizeof(bios_ram), 0xfffff, bios_ram);
449                 } else {
450 #endif
451                         set_memory_r(0x100000 - sizeof(bios), 0xfffff, bios);
452 #if defined(SUPPORT_BIOS_RAM)
453 //                      set_memory_w(0x100000 - sizeof(bios_ram), 0xfffff, bios_ram);
454                 }
455 #endif
456 #if defined(SUPPORT_ITF_ROM)
457         }
458 #endif
459 }
460
461 #if !defined(SUPPORT_HIRESO)
462 void MEMBUS::update_sound_bios()
463 {
464         if(sound_bios_selected) {
465 //              if(sound_bios_selected) {
466 //                      set_memory_r(0xcc000, 0xcffff, sound_bios_ram);
467 //              } else {
468                         set_memory_r(0xcc000, 0xcffff, sound_bios);
469                         unset_memory_w(0xcc000, 0xcffff);
470 //              }
471         } else {
472                 unset_memory_rw(0xcc000, 0xcffff);
473         }
474 }
475
476 #if defined(SUPPORT_SASI_IF)
477 void MEMBUS::update_sasi_bios()
478 {
479         if(sasi_bios_selected) {
480                 if(sasi_bios_ram_selected) {
481                         set_memory_rw(0xd7000, 0xd7fff, sasi_bios_ram);
482                 } else {
483                         set_memory_r(0xd7000, 0xd7fff, sasi_bios);
484                         unset_memory_w(0xd7000, 0xd7fff);
485                 }
486         } else {
487                 unset_memory_rw(0xd7000, 0xd7fff);
488         }
489 }
490 #endif
491
492 #if defined(SUPPORT_SCSI_IF)
493 void MEMBUS::update_scsi_bios()
494 {
495         if(scsi_bios_selected) {
496                 if(scsi_bios_ram_selected) {
497                         set_memory_rw(0xdc000, 0xdcfff, scsi_bios_ram);
498                 } else {
499                         set_memory_r(0xdc000, 0xdcfff, scsi_bios);
500                         unset_memory_w(0xdc000, 0xdcfff);
501                 }
502         } else {
503                 unset_memory_rw(0xdc000, 0xdcfff);
504         }
505 }
506 #endif
507
508 #if defined(SUPPORT_IDE_IF)
509 void MEMBUS::update_ide_bios()
510 {
511         if(ide_bios_selected) {
512 //              if(ide_bios_selected) {
513 //                      set_memory_r(0xd8000, 0xdbfff, ide_bios_ram);
514 //              } else {
515                         set_memory_r(0xd8000, 0xdbfff, ide_bios);
516                         unset_memory_w(0xd8000, 0xdbfff);
517 //              }
518         } else {
519                 unset_memory_rw(0xd8000, 0xdbfff);
520         }
521 }
522 #endif
523
524 #if defined(SUPPORT_NEC_EMS)
525 void MEMBUS::update_nec_ems()
526 {
527         if (nec_ems_selected) {
528                 unset_memory_rw(0xb0000, 0xbffff);
529                 set_memory_rw(0xb0000, 0xbffff, nec_ems);
530         } else {
531                 unset_memory_rw(0xb0000, 0xbffff);
532                 set_memory_mapped_io_rw(0xb0000, 0xbffff, d_display);
533         }
534 }
535 #endif
536 #endif
537
538 #define STATE_VERSION   4
539
540 bool MEMBUS::process_state(FILEIO* state_fio, bool loading)
541 {
542         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
543                 return false;
544         }
545         if(!state_fio->StateCheckInt32(this_device_id)) {
546                 return false;
547         }
548         state_fio->StateBuffer(ram, sizeof(ram), 1);
549 #if defined(SUPPORT_BIOS_RAM)
550         state_fio->StateBuffer(bios_ram, sizeof(bios_ram), 1);
551         state_fio->StateBool(bios_ram_selected);
552 #endif
553 #if defined(SUPPORT_ITF_ROM)
554         state_fio->StateBool(itf_selected);
555 #endif
556 #if !defined(SUPPORT_HIRESO)
557 //      state_fio->StateBuffer(sound_bios_ram, sizeof(sound_bios_ram), 1);
558         state_fio->StateBool(sound_bios_selected);
559 //      state_fio->StateBool(sound_bios_ram_selected);
560 #if defined(SUPPORT_SASI_IF)
561         state_fio->StateBuffer(sasi_bios_ram, sizeof(sasi_bios_ram), 1);
562         state_fio->StateBool(sasi_bios_selected);
563         state_fio->StateBool(sasi_bios_ram_selected);
564 #endif
565 #if defined(SUPPORT_SCSI_IF)
566         state_fio->StateBuffer(scsi_bios_ram, sizeof(scsi_bios_ram), 1);
567         state_fio->StateBool(scsi_bios_selected);
568         state_fio->StateBool(scsi_bios_ram_selected);
569 #endif
570 #if defined(SUPPORT_IDE_IF)
571 //      state_fio->StateBuffer(ide_bios_ram, sizeof(ide_bios_ram), 1);
572         state_fio->StateBool(ide_bios_selected);
573 //      state_fio->StateBool(ide_bios_ram_selected);
574 #endif
575 #if defined(SUPPORT_NEC_EMS)
576         state_fio->StateBuffer(nec_ems, sizeof(nec_ems), 1);
577         state_fio->StateBool(nec_ems_selected);
578 #endif
579 #endif
580 #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)
581         state_fio->StateUint8(dma_access_ctrl);
582         state_fio->StateUint32(window_80000h);
583         state_fio->StateUint32(window_a0000h);
584 #endif
585         if(!MEMORY::process_state(state_fio, loading)) {
586                 return false;
587         }
588         
589         // post process
590         if(loading) {
591                 update_bios();
592 #if !defined(SUPPORT_HIRESO)
593                 update_sound_bios();
594 #if defined(SUPPORT_SASI_IF)
595                 update_sasi_bios();
596 #endif
597 #if defined(SUPPORT_SCSI_IF)
598                 update_scsi_bios();
599 #endif
600 #if defined(SUPPORT_IDE_IF)
601                 update_ide_bios();
602 #endif
603 #if defined(SUPPORT_EMS)
604                 update_nec_ems();
605 #endif
606 #endif
607         }
608         return true;
609 }
610
611 }