2 * Main memory without MMR for FM-7 [FM7_MAINMEM]
8 #include "fm7_mainmem.h"
10 void FM7_MAINMEM::wait()
12 int waitfactor; // If MMR of TWR enabled, factor = 3.
13 // If memory, factor = 2?
14 if(mainio->read_data8(FM7_MAINIO_CLOCKMODE) == FM7_MAINCLOCK_SLOW) return;
19 } else { // Not MMR, TWR or enabled FAST MMR mode
20 waitfactor = 3; // If(MMR or TWR) and NOT FAST MMR factor = 3, else factor = 2
21 if((mainio->read_data8(FM7_MAINIO_FASTMMR_ENABLED) != 0)) waitfactor = 2;
22 ioaccess_wait = false;
24 if((mainio->read_data8(FM7_MAINIO_WINDOW_ENABLED) == 0) &&
25 (mainio->read_data8(FM7_MAINIO_MMR_ENABLED) == 0)) waitfactor = 2;
29 if(waitfactor <= 0) return;
31 if(waitcount >= waitfactor) {
32 if(maincpu != NULL) maincpu->set_extra_clock(1);
38 int FM7_MAINMEM::window_convert(uint32 addr, uint32 *realaddr)
42 if((addr < 0x8000) && (addr >= 0x7c00) && (window_enabled)) {
44 raddr = ((window_offset << 8) + addr) & 0xffff;
46 #ifdef _FM77AV_VARIANTS
47 return FM7_MAINMEM_MMRBANK_0; // 0x20000 - 0x2ffff
48 #else // FM77(L4 or others)
49 return FM7_MAINMEM_MMRBANK_2; // 0x20000 - 0x2ffff
57 int FM7_MAINMEM::mmr_convert(uint32 addr, uint32 *realaddr)
63 if(addr >= 0xfc00) return -1;
64 mmr_segment = mainio->read_data8(FM7_MAINIO_MMR_SEGMENT);
65 mmr_bank = mainio->read_data8(FM7_MAINIO_MMR_BANK + mmr_segment * 16 + ((addr >> 12) & 0x000f));
66 // Out of EXTRAM : 77AV20/40.
68 #if !defined(_FM77AV_VARIANTS)
72 raddr = addr & 0x0fff;
73 // Bank 3x : Standard memories.
74 if((mmr_bank < 0x3f) && (mmr_bank >= 0x30)) {
75 raddr = (((uint32)mmr_bank & 0x0f) << 12) | raddr;
76 return nonmmr_convert(raddr, realaddr);
79 #ifdef _FM77AV_VARIANTS
80 if(mmr_bank == 0x3f) {
81 if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
83 return FM7_MAINMEM_NULL;
87 if((mmr_bank == 0x3f) && (addr >= 0xc00) && (addr < 0xe00)) {
88 if(mainio->read_data8(FM7_MAINIO_IS_BASICROM) != 0) { // BASICROM enabled
90 return FM7_MAINMEM_ZERO;
92 *realaddr = addr & 0x1ff;
93 return FM7_MAINMEM_SHADOWRAM;
98 #ifdef _FM77AV_VARIANTS
99 if((mmr_bank & 0xf0) == 0x00) { // PAGE 0
100 *realaddr = (((uint32)mmr_bank & 0x0f) << 12) | raddr;
101 return FM7_MAINMEM_77AV_PAGE0;
103 if((mmr_bank & 0xf0) == 0x10) { // PAGE 1
104 *realaddr = (((uint32)mmr_bank & 0x0f) << 12) | raddr;
105 return FM7_MAIMEM_DIRECTACCESS;
107 if((mmr_bank & 0xf0) == 0x20) { // PAGE 2
108 uint32 dbank = mainio->read_data8(FM7_MAINIO_EXTBANK);
111 case 0x29: // Backuped RAM
112 if(((dbank & 0x80) != 0) && (dictrom_connected)){ // Battery backuped RAM
113 raddr = raddr & 0x1ff;
115 return FM7_MAINMEM_BACKUPED_RAM;
119 if(((dbank & 0x40) != 0) && (dictrom_connected)) { // Dictionary ROM
120 dbank = dbank & 0x3f;
121 uint32 extrom = mainio->read_data8(FM7_MAINIO_EXTROM) & 0x80;
122 if(extrom == 0) { // Dictionary selected.
124 *realaddr = raddr | dbank;
125 return FM7_MAINMEM_77AV40_DICTROM;
126 } else if(dbank <= 0x1f) { // KANJI
127 *realaddr = (dbank << 12) | raddr;
128 return FM7_MAINMEM_KANJI_LEVEL1;
129 } else if(dbank <= 0x37) {
131 *realaddr = (dbank - 0x20000) | raddr;
132 return FM7_MAINMEM_77AV40_EXTRAROM;
133 } else if(dbank <= 0x3f) {
134 raddr = ((dbank << 12) - 0x30000) | raddr;
135 if((raddr >= 0xffe0) || (raddr < 0xfd00)) {
136 return nonmmr_convert(raddr, realaddr);
137 } else if((raddr >= 0xfe00) || (raddr < 0xffe0)) {
138 *realaddr = raddr - 0xfe00;
139 return FM7_MAINMEM_BOOTROM_DOS;
141 *realaddr = raddr + 0x10000;
142 return FM7_MAINMEM_77AV40_EXTRAROM;
148 *realaddr = (raddr | (mmr_bank << 12)) & 0x0ffff;
149 return FM7_MAINMEM_77AV_PAGE2;
151 if(extram_connected) { // PAGE 4-
152 if((mmr_bank >> 4) >= (extram_pages + 4)) {
154 return FM7_MAINMEM_NULL; // $FF
156 raddr = ((uint32)mmr_bank << 12) | raddr;
158 return FM7_MAINMEM_EXTRAM;
161 if(mmr_bank >= 0x40) {
163 return FM7_MAINMEM_NULL;
168 if(extram_connected) {
169 if((mmr_bank >> 4) >= extram_pages) {
171 return FM7_MAINMEM_NULL;
172 } else { // EXTRAM Exists.
173 raddr = (((uint32)mmr_bank << 12) & 0x3ffff) | raddr;
175 return FM7_MAINMEM_EXTRAM;
183 int FM7_MAINMEM::nonmmr_convert(uint32 addr, uint32 *realaddr)
186 #ifdef _FM77AV_VARIANTS
187 if(mainio->read_data8(FM7_MAINIO_INITROM_ENABLED) != 0) {
188 if((addr >= 0x6000) && (addr < 0x8000)) {
189 *realaddr = addr - 0x6000;
190 return FM7_MAINMEM_INITROM;
193 *realaddr = addr - 0xe000;
194 return FM7_MAINMEM_INITROM;
200 *realaddr = addr - 0;
201 return FM7_MAINMEM_OMOTE;
204 *realaddr = addr - 0x8000;
205 if(mainio->read_data8(FM7_MAINIO_READ_FD0F) != 0) {
206 return FM7_MAINMEM_BASICROM;
208 return FM7_MAINMEM_URA;
211 *realaddr = addr - 0xfc00;
212 return FM7_MAINMEM_BIOSWORK;
215 *realaddr = addr - 0xfc80;
216 return FM7_MAINMEM_SHAREDRAM;
220 *realaddr = addr - 0xfd00;
221 return FM7_MAINMEM_MMIO;
226 *realaddr = addr - 0xfe00;
228 switch(mainio->read_data8(FM7_MAINIO_BOOTMODE)) {
230 return FM7_MAINMEM_BOOTROM_BAS;
233 //printf("BOOT_DOS ADDR=%04x\n", addr);
234 return FM7_MAINMEM_BOOTROM_DOS;
237 return FM7_MAINMEM_BOOTROM_MMR;
240 return FM7_MAINMEM_BOOTROM_RAM;
243 return FM7_MAINMEM_BOOTROM_BAS; // Really?
247 if(addr < 0xfffe) { // VECTOR
248 //printf("Main: VECTOR\n");
249 *realaddr = addr - 0xffe0;
250 return FM7_MAINMEM_VECTOR;
253 printf("Main: Reset\n");
254 if(mainio->read_data8(FM7_MAINIO_BOOTMODE) == 4) {
255 *realaddr = addr - 0xfe00;
256 return FM7_MAINMEM_BOOTROM_RAM;
258 *realaddr = addr - 0xfffe;
259 return FM7_MAINMEM_RESET_VECTOR;
264 return FM7_MAINMEM_NULL;
267 int FM7_MAINMEM::getbank(uint32 addr, uint32 *realaddr)
269 if(realaddr == NULL) return FM7_MAINMEM_NULL; // Not effect.
270 addr = addr & 0xffff;
272 if(mainio->read_data8(FM7_MAINIO_WINDOW_ENABLED) != 0) {
275 stat = window_convert(addr, &raddr);
281 if(mainio->read_data8(FM7_MAINIO_MMR_ENABLED) != 0) {
284 stat = mmr_convert(addr, &raddr);
292 return nonmmr_convert(addr, realaddr);
295 uint32 FM7_MAINMEM::read_data8(uint32 addr)
301 bank = getbank(addr, &realaddr);
302 if(bank < 0) return 0xff; // Illegal
304 if(bank == FM7_MAINMEM_SHAREDRAM) {
305 if(display->read_signal(SIG_DISPLAY_HALT) != 0) return 0xff; // Not halt
306 return display->read_data8(realaddr + 0xd380); // Okay?
307 } else if(bank == FM7_MAINMEM_MMIO) {
308 return mainio->read_data8(realaddr);
310 #if defined(_FM77AV_VARIANTS)
311 else if(bank == FM7_MAINMEM_77AV_DIRECTACCESS) {
312 if(display->read_signal(SIG_DISPLAY_HALT) != 0) return 0xff; // Not halt
313 return display->read_data8(realaddr); // Okay?
316 if(read_table[bank].dev != NULL) {
317 //printf("READ I/O: %04x is bank %d, %04x HALT=%d\n", addr, bank, realaddr, display->read_signal(SIG_DISPLAY_HALT));
318 return read_table[bank].dev->read_data8(realaddr);
320 if(read_table[bank].memory != NULL) {
321 //printf("READ: %04x is bank %d, %04x data=%02x\n", addr, bank, realaddr, read_table[bank].memory[realaddr]);
322 return read_table[bank].memory[realaddr];
324 return 0xff; // Dummy
328 void FM7_MAINMEM::write_data8(uint32 addr, uint32 data)
334 bank = getbank(addr, &realaddr);
335 if(bank < 0) return; // Illegal
337 if(bank == FM7_MAINMEM_SHAREDRAM) {
338 if(display->read_signal(SIG_DISPLAY_HALT) != 0) return; // Not halt
339 display->write_data8(realaddr + 0xd380, data); // Okay?
341 } else if(bank == FM7_MAINMEM_MMIO) {
342 mainio->write_data8(realaddr, (uint8)data);
345 #if defined(_FM77AV_VARIANTS)
346 else if(bank == FM7_MAINMEM_77AV_DIRECTACCESS) {
347 if(display->read_signal(SIG_DISPLAY_HALT) != 0) return; // Not halt
348 display->write_data8(realaddr, data); // Okay?
352 if(write_table[bank].dev != NULL) {
353 write_table[bank].dev->write_data8(realaddr, data);
355 if(write_table[bank].memory != NULL) {
356 write_table[bank].memory[realaddr] = (uint8)(data & 0x000000ff);
361 // Read / Write data(s) as big endian.
362 uint32 FM7_MAINMEM::read_data16(uint32 addr)
367 hi = read_data8(addr) & 0xff;
368 lo = read_data8(addr + 1) & 0xff;
374 uint32 FM7_MAINMEM::read_data32(uint32 addr)
376 uint32 ah, a2, a3, al;
379 ah = read_data8(addr) & 0xff;
380 a2 = read_data8(addr + 1) & 0xff;
381 a3 = read_data8(addr + 2) & 0xff;
382 al = read_data8(addr + 3) & 0xff;
384 val = ah * (65536 * 256) + a2 * 65536 + a3 * 256 + al;
388 void FM7_MAINMEM::write_data16(uint32 addr, uint32 data)
392 write_data8(addr + 1, d & 0xff);
394 write_data8(addr + 0, d & 0xff);
397 void FM7_MAINMEM::write_data32(uint32 addr, uint32 data)
401 write_data8(addr + 3, d & 0xff);
403 write_data8(addr + 2, d & 0xff);
405 write_data8(addr + 1, d & 0xff);
407 write_data8(addr + 0, d & 0xff);
411 bool FM7_MAINMEM::get_loadstat_basicrom(void)
413 return diag_load_basicrom;
416 bool FM7_MAINMEM::get_loadstat_bootrom_bas(void)
418 return diag_load_bootrom_bas;
421 bool FM7_MAINMEM::get_loadstat_bootrom_dos(void)
423 return diag_load_bootrom_dos;
426 uint32 FM7_MAINMEM::read_bios(const char *name, uint8 *ptr, uint32 size)
432 if((name == NULL) || (ptr == NULL)) return 0;
433 s = emu->bios_path((_TCHAR *)name);
434 if(s == NULL) return 0;
436 if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
437 blocks = fio.Fread(ptr, size, 1);
440 return blocks * size;
443 FM7_MAINMEM::FM7_MAINMEM(VM* parent_vm, EMU* parent_emu) : MEMORY(parent_vm, parent_emu)
448 for(i = 0; i < 4; i++) fm7_bootroms[i] = (uint8 *)malloc(0x200);
451 FM7_MAINMEM::~FM7_MAINMEM()
454 for(i = 0; i < 4; i++) {
455 if(fm7_bootroms[i] != NULL) free(fm7_bootroms[i]);
456 fm7_bootroms[i] = NULL;
460 void FM7_MAINMEM::initialize(void)
463 diag_load_basicrom = false;
464 diag_load_bootrom_bas = false;
465 diag_load_bootrom_dos = false;
466 diag_load_bootrom_mmr = false;
470 ioaccess_wait = false;
474 memset(read_table, 0x00, sizeof(read_table));
475 memset(write_table, 0x00, sizeof(write_table));
476 i = FM7_MAINMEM_OMOTE;
477 memset(fm7_mainmem_omote, 0x00, 0x8000 * sizeof(uint8));
478 read_table[i].memory = fm7_mainmem_omote;
479 write_table[i].memory = fm7_mainmem_omote;
483 memset(fm7_mainmem_ura, 0x00, 0x7c00 * sizeof(uint8));
484 read_table[i].memory = fm7_mainmem_ura;
485 write_table[i].memory = fm7_mainmem_ura;
487 #if defined(_FM77AV_VARIANTS)
488 i = FM7_MAINMEM_MMRBANK_0;
489 memset(fm7_mainmem_mmrbank_0, 0xff, 0x10000 * sizeof(uint8));
490 read_table[i].memory = fm7_mainmem_mmrbank_0;
491 write_table[i].memory = fm7_mainmem_mmrbank_0;
493 i = FM7_MAINMEM_MMRBANK_2;
494 memset(fm7_mainmem_mmrbank_2, 0xff, 0x10000 * sizeof(uint8));
495 read_table[i].memory = fm7_mainmem_mmrbank_0;
496 write_table[i].memory = fm7_mainmem_mmrbank_0;
498 i = FM7_MAINMEM_VECTOR;
499 memset(fm7_mainmem_bootrom_vector, 0x00, 0x1e);
500 read_table[i].memory = fm7_mainmem_bootrom_vector;
501 write_table[i].memory = fm7_mainmem_bootrom_vector;
503 i = FM7_MAINMEM_VECTOR;
504 memset(fm7_mainmem_bootrom_vector, 0x00, 0x1e);
505 read_table[i].memory = fm7_mainmem_bootrom_vector;
506 write_table[i].memory = fm7_mainmem_bootrom_vector;
508 i = FM7_MAINMEM_KANJI_LEVEL1;
509 read_table[i].dev = kanjiclass1;
510 write_table[i].dev = kanjiclass1;
512 #if defined(_FM77AV_VARIANTS)
513 i = FM7_MAINMEM_KANJI_LEVEL2;
514 read_table[i].dev = kanjiclass2;
515 write_table[i].dev = kanjiclass2;
517 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20)
518 i = FM7_MAINMEM_77AV40_DICTROM;
519 memset(fm7_mainmem_extrarom, 0xff, 0x40000 * sizeof(uint8));
520 read_table[i].memory = fm7_mainmem_dictrom;
521 write_table[i].memory = NULL;
522 if(read_bios("DICROM.ROM", read_table[i].memory, 0x40000) == 0x40000) diag_load_dictrom = true;
524 i = FM7_MAINMEM_77AV40_EXTRAROM;
525 memset(fm7_mainmem_extrarom, 0xff, 0x20000 * sizeof(uint8));
526 read_table[i].memory = fm7_mainmem_extrarom;
527 write_table[i].memory = NULL;
528 if(read_bios("EXTSUB.ROM", read_table[i].memory, 0xc000) >= 0xc000) diag_load_extrarom = true;
530 if(config.extram_pages > 0) {
531 i = FM7_MAINMEM_EXTRAM;
532 extram_pages = config.extram_pages;
533 if(extram_pages >= 12) extram_pages = 12;
534 fm7_mainmem_extram = malloc(extram_pages * 0x10000);
535 if(fm7_mainmem_extram != NULL) {
536 memset(fm7_mainmem_extram, 0x00, extram_pages * 0x10000);
537 read_table[i].memory = fm7_mainmem_extram;
538 write_table[i].memory = fm7_mainmem_extram;
544 // Both 77AV and AV40
545 for(i = FM7_MAINMEM_BOOTROM_BAS; i <= FM7_MAINMEM_BOOTROM_RAM; i++) {
546 read_table[i].memory = fm7_bootroms[i - FM7_MAINMEM_BOOTROM_BAS];
547 write_table[i].memory = NULL;
549 memcpy(fm7_bootroms[0], &fm7_mainmem_initiate[0x1800], 0x200 * sizeof(uint8));
550 memcpy(fm7_bootroms[1], &fm7_mainmem_initiate[0x1a00], 0x200 * sizeof(uint8));
551 read_table[FM7_MAINMEM_BOOTROM_MMR].memory = NULL; // Not connected.
553 memset(fm7_bootroms[3], 0x00, 0x200 * sizeof(uint8)); // RAM
554 if(diag_load_extrom) diag_load_bootrom_bas = true;
555 if(diag_load_extrom) diag_load_bootrom_dos = true;
556 write_table[FM7_BAINMEM_BOOTRAM].memory = read_table[FM7_BAINMEM_BOOTROM_RAM].memory; // Write enabled on BOOTRAM.
559 if(read_bios("BOOT_BAS.ROM", fm7_bootroms[0], 0x200) >= 0x1e0) {
560 diag_load_bootrom_bas = true;
562 diag_load_bootrom_bas = false;
563 //memset(fm7_bootroms[0], 0xff, 0x200);
565 if(read_bios("BOOT_DOS.ROM", fm7_bootroms[1], 0x200) >= 0x1e0) {
566 diag_load_bootrom_dos = true;
568 diag_load_bootrom_dos = false;
569 //memset(fm7_bootroms[1], 0xff, 0x200);
572 # if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4)
573 if(read_bios("BOOT_MMR.ROM", fm7_bootroms[2], 0x200) >= 0x1e0) {
574 diag_load_bootrom_mmr = true;
576 diag_load_bootrom_mmr = false;
577 //memset(fm7_bootroms[2], 0xff, 0x200);
580 if(config.extram_pages > 0) {
581 i = FM7_MAINMEM_EXTRAM;
582 extram_pages = config.extram_pages;
583 if(extram_pages >= 3) pages = 3;
584 fm7_mainmem_extram = malloc(extram_pages * 0x10000);
585 if(fm7_mainmem_extram != NULL) {
586 memset(fm7_mainmem_extram, 0x00, extram_pages * 0x10000);
587 read_table[i].memory = fm7_mainmem_extram;
588 write_table[i].memory = fm7_mainmem_extram;
593 diag_load_bootrom_mmr = false;
594 memset(fm7_bootroms[2], 0xff, 0x200);
597 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4)
598 for(i = FM7_MAINMEM_BOOTROM_BAS; i <= FM7_MAINMEM_BOOTRAM; i++) {
599 read_table[i].memory = fm7_bootroms[i - FM7_MAINMEM_BOOTROM_BAS];
600 write_table[i].memory = NULL;
602 memset(fm7_bootroms[3], 0x00, 0x200 * sizeof(uint8)); // RAM
603 write_table[FM7_BAINMEM_BOOTRAM].memory = read_table[FM7_BAINMEM_BOOTROM_RAM].memory; // Write enabled on BOOTRAM.
606 for(i = FM7_MAINMEM_BOOTROM_BAS; i <= FM7_MAINMEM_BOOTROM_DOS; i++) {
607 read_table[i].memory = fm7_bootroms[i - FM7_MAINMEM_BOOTROM_BAS];
608 write_table[i].memory = NULL;
612 i = FM7_MAINMEM_VECTOR;
613 memset(fm7_mainmem_bootrom_vector, 0x00, 0x1e);
614 read_table[i].memory = fm7_mainmem_bootrom_vector;
615 write_table[i].memory = fm7_mainmem_bootrom_vector;
617 for(i = 0; i <= 3; i++) {
618 uint8 *p = fm7_bootroms[i];
619 p[0x1fe] = 0xfe; // Set reset vector.
623 i = FM7_MAINMEM_RESET_VECTOR;
624 fm7_mainmem_reset_vector[0] = 0xfe;
625 fm7_mainmem_reset_vector[1] = 0x00;
627 read_table[i].memory = fm7_mainmem_reset_vector;
628 write_table[i].memory = NULL;
630 i = FM7_MAINMEM_BASICROM;
631 memset(fm7_mainmem_basicrom, 0xff, 0x7c00 * sizeof(uint8));
632 read_table[i].dev = NULL;
633 read_table[i].memory = fm7_mainmem_basicrom;
634 write_table[i].dev = NULL;
635 write_table[i].memory = NULL;
636 if(read_bios("FBASIC30.ROM", fm7_mainmem_basicrom, 0x7c00) == 0x7c00) diag_load_basicrom = true;
637 printf("BASIC ROM READING : %d\n", diag_load_basicrom);
639 i = FM7_MAINMEM_BIOSWORK;
640 memset(fm7_mainmem_bioswork, 0x00, 0x80 * sizeof(uint8));
641 read_table[i].dev = NULL;
642 read_table[i].memory = fm7_mainmem_bioswork;
643 write_table[i].dev = NULL;
644 write_table[i].memory = fm7_mainmem_bioswork;
646 i = FM7_MAINMEM_SHAREDRAM;
647 read_table[i].dev = display;
648 write_table[i].dev = display;
650 #if defined(_FM77AV_VARIANTS)
651 i = FM7_MAINMEM_DIRECTACCESS;
652 read_table[i].dev = display;
653 write_table[i].dev = display;