2 * Main memory without MMR for FM-7 [FM7_MAINMEM]
8 #include "fm7_mainmem.h"
11 void FM7_MAINMEM::reset()
15 ioaccess_wait = false;
16 //sub_halted = (display->read_signal(SIG_DISPLAY_HALT) == 0) ? false : true;
18 memset(fm7_mainmem_bootrom_vector, 0x00, 0x10); // Clear without vector
20 #if defined(_FM77AV_VARIANTS)
21 memset(fm7_bootram, 0x00, 0x1f0);
22 initiator_enabled = true;
23 boot_ram_write = true;
24 #elif defined(_FM77_VARIANTS)
25 boot_ram_write = false;
27 bootmode = config.boot_mode & 3;
29 if((config.dipswitch & FM7_DIPSW_EXTRAM) != 0) {
30 extram_connected = true;
32 extram_connected = false;
35 #if defined(_FM77AV_VARIANTS)
36 if(dictrom_connected) {
37 use_page2_extram = true;
39 use_page2_extram = ((config.dipswitch & FM7_DIPSW_EXTRAM_AV) != 0) ? true : false;
48 window_enabled = false;
52 if((bootmode & 0x03) == 0) { // IF BASIC BOOT THEN ROM
55 basicrom_fd0f = false;
57 clockmode = (config.cpu_type == 0) ? true : false;
58 is_basicrom = ((bootmode & 0x03) == 0) ? true : false;
59 setclock(clockmode ? 0 : 1);
63 void FM7_MAINMEM::setclock(int mode)
65 uint32_t clock = MAINCLOCK_SLOW;
66 if(mode == 1) { // SLOW
67 clock = MAINCLOCK_SLOW; // Temporally
69 if(!mmr_fast && !window_fast) {
71 if(mmr_enabled || window_enabled) {
72 clock = (uint32_t)((double)clock * 1.089);
74 clock = (uint32_t)((double)clock * 1.086);
83 clock = MAINCLOCK_FAST_MMR;
85 clock = MAINCLOCK_MMR;
87 } else if(mmr_enabled) {
89 clock = MAINCLOCK_FAST_MMR;
91 clock = MAINCLOCK_MMR;
94 clock = MAINCLOCK_NORMAL;
96 if(!mmr_fast && !window_fast) {
98 if(mmr_enabled || window_enabled) {
99 clock = (uint32_t)((double)clock * 1.089);
101 clock = (uint32_t)((double)clock * 1.086);
106 clock = MAINCLOCK_NORMAL;
109 p_vm->set_cpu_clock(this->maincpu, clock);
113 void FM7_MAINMEM::wait()
115 int waitfactor; // If MMR of TWR enabled, factor = 3.
116 // If memory, factor = 2?
117 if(!clockmode) return; // SLOW
119 //if(!mmr_fast && !window_fast && (window_enabled || mmr_enabled)) waitfactor = 2;
122 ioaccess_wait = true;
123 } else { // Not MMR, TWR or enabled FAST MMR mode
124 waitfactor = 3; // If(MMR or TWR) and NOT FAST MMR factor = 3, else factor = 2
125 if(mmr_fast) waitfactor = 2;
126 ioaccess_wait = false;
131 if(waitfactor <= 0) return;
133 if(waitcount >= waitfactor) {
134 if(maincpu != NULL) maincpu->set_extra_clock(1);
140 int FM7_MAINMEM::window_convert(uint32_t addr, uint32_t *realaddr)
142 uint32_t raddr = addr;
144 if((addr < 0x8000) && (addr >= 0x7c00)) {
145 raddr = ((window_offset * 256) + addr) & 0x0ffff;
147 #ifdef _FM77AV_VARIANTS
148 //printf("TWR hit %04x -> %04x\n", addr, raddr);
149 return FM7_MAINMEM_AV_PAGE0; // 0x00000 - 0x0ffff
150 #else // FM77(L4 or others)
151 *realaddr |= 0x20000;
152 return FM7_MAINMEM_EXTRAM; // 0x20000 - 0x2ffff
161 int FM7_MAINMEM::check_extrom(uint32_t raddr, uint32_t *realaddr)
163 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
164 if(extrom_bank) { // Extra ROM selected.
165 uint32_t dbank = extcard_bank & 0x3f;
166 if(dbank < 0x20) { // KANJI
167 if((dbank == 0x07) || (dbank == 0x06)) {
168 // NOT KANJI AS IS.Thanks Ryu.
169 *realaddr = raddr & 0x01;
170 return FM7_MAINMEM_KANJI_DUMMYADDR;
172 *realaddr = (dbank << 12) | raddr;
173 return FM7_MAINMEM_KANJI_LEVEL1;
174 } else if(dbank < 0x2c) {
175 raddr = ((dbank << 12) - 0x20000) | raddr;
177 return FM7_MAINMEM_77AV40_EXTRAROM;
178 } else if(dbank < 0x30) {
180 return FM7_MAINMEM_NULL;
182 raddr = ((dbank << 12) - 0x30000) | raddr;
183 if((raddr >= 0x8000) && (raddr < 0xfc00)) {
184 *realaddr = raddr - 0x8000;
185 return FM7_MAINMEM_BASICROM;
186 } else if((raddr >= 0xfe00) && (raddr < 0xffe0)) {
187 *realaddr = raddr - 0xfe00;
188 return FM7_MAINMEM_BOOTROM_MMR;
189 } else if(raddr >= 0xfffe) {
190 *realaddr = raddr - 0xfffe;
191 return FM7_MAINMEM_RESET_VECTOR;
193 //*realaddr = raddr + 0x10000;
194 //return FM7_MAINMEM_77AV40_EXTRAROM;
196 return FM7_MAINMEM_NULL;
204 int FM7_MAINMEM::mmr_convert(uint32_t addr, uint32_t *realaddr, bool write_state, bool dmamode)
206 uint32_t raddr = addr & 0x0fff;
215 segment = mmr_segment;
217 if(addr >= 0xfc00) return -1;
219 mmr_bank = mmr_map_data[(addr >> 12) & 0x000f | ((segment & 0x03) << 4)] & 0x003f;
221 mmr_bank = mmr_map_data[(addr >> 12) & 0x000f | ((segment & 0x07) << 4)] & 0x007f;
223 // Reallocated by MMR
224 // Bank 3x : Standard memories.
225 if((mmr_bank < 0x3f) && (mmr_bank >= 0x30)) {
226 raddr = ((mmr_bank << 12) | raddr) & 0xffff;
227 return nonmmr_convert(raddr, realaddr);
229 # ifdef _FM77AV_VARIANTS
230 else if(mmr_bank == 0x3f) {
231 if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
233 return FM7_MAINMEM_NULL;
235 raddr = raddr | 0xf000;
236 return nonmmr_convert(raddr, realaddr); // Access I/O, Bootrom, even via MMR.
239 # elif defined(_FM77_VARIANTS)
240 else if(mmr_bank == 0x3f) {
241 if((raddr >= 0xc00) && (raddr < 0xe00)) {
244 return FM7_MAINMEM_ZERO;
246 *realaddr = raddr - 0xc00;
247 return FM7_MAINMEM_SHADOWRAM;
249 } else if(raddr >= 0xe00) {
250 *realaddr = addr - 0x0e00;
252 if(diag_load_bootrom_mmr) {
253 return FM7_MAINMEM_BOOTROM_MMR;
255 return FM7_MAINMEM_BOOTROM_BAS;
258 return FM7_MAINMEM_BOOTROM_RAM;
261 raddr = raddr | 0xf000;
262 return nonmmr_convert(raddr, realaddr); // Access I/O, Bootrom, even via MMR.
266 major_bank = (mmr_bank >> 4) & 0x0f;
268 # ifdef _FM77AV_VARIANTS
269 if(major_bank == 0x0) { // PAGE 0
270 *realaddr = ((mmr_bank << 12) | raddr) & 0x0ffff;
271 return FM7_MAINMEM_AV_PAGE0;
272 } else if(major_bank == 0x1) { // PAGE 1
273 *realaddr = ((mmr_bank << 12) | raddr) & 0x0ffff;
274 return FM7_MAINMEM_AV_DIRECTACCESS;
275 } else if(major_bank == 0x2) { // PAGE 2
276 if((mmr_bank == 0x2e) && (!write_state)) {
277 int banknum = check_extrom(raddr, realaddr);
281 # if defined(CAPABLE_DICTROM)
282 if(dictrom_connected && dictrom_enabled) { // Dictionary ROM
283 uint32_t dbank = extcard_bank & 0x3f;
284 *realaddr = raddr | (dbank << 12);
285 return FM7_MAINMEM_DICTROM;
289 return FM7_MAINMEM_NULL;
293 # if defined(CAPABLE_DICTROM)
296 case 0x29: // Backuped RAM
297 if(dictrom_connected && dictram_enabled){ // Battery backuped RAM
298 raddr = (((uint32_t)mmr_bank & 0x01) << 12) | raddr;
299 raddr = raddr & 0x1fff;
301 return FM7_MAINMEM_BACKUPED_RAM;
305 *realaddr = (raddr | (mmr_bank << 12)) & 0x0ffff;
306 return FM7_MAINMEM_AV_PAGE2;
308 if(use_page2_extram) {
309 *realaddr = ((mmr_bank << 12) | raddr) & 0x0ffff;
310 return FM7_MAINMEM_AV_PAGE2;
313 return FM7_MAINMEM_NULL;
319 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
320 else if(extram_connected && mmr_extend) { // PAGE 4-
321 if((major_bank >= (extram_pages + 4)) || (fm7_mainmem_extram == NULL) ) {
323 return FM7_MAINMEM_NULL; // $FF
325 raddr = ((uint32_t)(mmr_bank - 0x40) << 12) | raddr;
327 return FM7_MAINMEM_EXTRAM;
331 return FM7_MAINMEM_NULL;
333 # elif defined(_FM77_VARIANTS)
334 if(extram_connected) { // PAGE 4-
335 if((major_bank > (extram_pages - 1)) || (major_bank >= 3)) {
337 return FM7_MAINMEM_NULL; // $FF
339 raddr = ((uint32_t)mmr_bank << 12) | raddr;
341 return FM7_MAINMEM_EXTRAM;
345 return FM7_MAINMEM_NULL; // $FF
347 # else // _FM77AV_VARIANTS
350 return FM7_MAINMEM_NULL; // $FF
358 int FM7_MAINMEM::nonmmr_convert(uint32_t addr, uint32_t *realaddr)
361 #ifdef _FM77AV_VARIANTS
362 if(initiator_enabled) {
363 if((addr >= 0x6000) && (addr < 0x8000)) {
364 //printf("HIT %02x\n", read_table[FM7_MAINMEM_INITROM].memory[addr - 0x6000]);
365 *realaddr = addr - 0x6000;
366 return FM7_MAINMEM_INITROM;
369 //printf("HIT %02x\n", read_table[FM7_MAINMEM_INITROM].memory[addr - 0xe000]);
370 *realaddr = addr - 0xe000;
371 return FM7_MAINMEM_INITROM;
376 uint32_t addr_major, addr_minor;
377 addr_major = (addr >> 12) & 0x0f;
379 switch (addr_major) {
389 return FM7_MAINMEM_OMOTE;
398 *realaddr = addr - 0x8000;
400 return FM7_MAINMEM_BASICROM;
402 return FM7_MAINMEM_URA;
405 addr_minor = (addr >> 8) & 0x0f;
419 *realaddr = addr - 0x8000;
421 return FM7_MAINMEM_BASICROM;
423 return FM7_MAINMEM_URA;
427 *realaddr = addr - 0xfc00;
428 return FM7_MAINMEM_BIOSWORK;
431 *realaddr = addr - 0xfc80;
432 return FM7_MAINMEM_SHAREDRAM;
437 *realaddr = addr - 0xfd00;
438 return FM7_MAINMEM_MMIO;
443 *realaddr = addr - 0xfe00;
444 #if defined(_FM77AV_VARIANTS)
445 return FM7_MAINMEM_BOOTROM_RAM;
449 return FM7_MAINMEM_BOOTROM_BAS;
452 //printf("BOOT_DOS ADDR=%04x\n", addr);
453 return FM7_MAINMEM_BOOTROM_DOS;
456 return FM7_MAINMEM_BOOTROM_MMR;
459 return FM7_MAINMEM_BOOTROM_EXTRA;
461 # if defined(_FM77_VARIANTS)
463 return FM7_MAINMEM_BOOTROM_RAM;
467 return FM7_MAINMEM_BOOTROM_BAS; // Really?
472 else if (addr < 0xfffe) { // VECTOR
473 *realaddr = addr - 0xffe0;
474 return FM7_MAINMEM_VECTOR;
476 #if defined(_FM77AV_VARIANTS)
477 else if(addr < 0x10000) {
479 *realaddr = addr - 0xfe00;
480 return FM7_MAINMEM_BOOTROM_RAM;
483 else if (addr < 0x10000) {
484 *realaddr = addr - 0xfffe;
485 return FM7_MAINMEM_RESET_VECTOR;
492 emu->out_debug_log(_T("Main: Over run ADDR = %08x"), addr);
494 return FM7_MAINMEM_NULL;
497 int FM7_MAINMEM::getbank(uint32_t addr, uint32_t *realaddr, bool write_state, bool dmamode)
499 if(realaddr == NULL) return FM7_MAINMEM_NULL; // Not effect.
504 stat = window_convert(addr, &raddr);
505 //if(stat >= 0) printf("WINDOW CONVERT: %04x to %04x, bank = %02x\n", addr, raddr, stat);
514 stat = mmr_convert(addr, &raddr, write_state, dmamode);
516 //printf("MMR CONVERT: %04x to %05x, bank = %02x\n", addr, raddr, stat);
522 addr = addr & 0xffff;
524 return nonmmr_convert(addr, realaddr);
527 uint32_t FM7_MAINMEM::read_signal(int sigid)
529 uint32_t value = 0x00000000;
531 case FM7_MAINIO_PUSH_FD0F:
532 value = (basicrom_fd0f) ? 0xffffffff : 0x00000000;
534 case FM7_MAINIO_IS_BASICROM:
535 value = (is_basicrom) ? 0xffffffff : 0x00000000;
537 case FM7_MAINIO_CLOCKMODE:
538 value = (clockmode) ? 0xffffffff : 0x00000000;
540 case FM7_MAINIO_BOOTMODE:
541 value = (uint32_t)bootmode & 0x07;
543 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
544 case FM7_MAINIO_BOOTRAM_RW:
545 value = (boot_ram_write) ? 0xffffffff : 0x00000000;
549 case FM7_MAINIO_WINDOW_ENABLED:
550 value = (window_enabled) ? 0xffffffff : 0x00000000;
552 case FM7_MAINIO_WINDOW_FAST:
553 value = (window_fast) ? 0xffffffff : 0x00000000;
555 case FM7_MAINIO_FASTMMR_ENABLED:
556 value = (mmr_fast) ? 0xffffffff : 0x00000000;
558 case FM7_MAINIO_MMR_ENABLED:
559 value = (mmr_enabled) ? 0xffffffff : 0x00000000;
561 case FM7_MAINIO_MMR_EXTENDED:
562 value = (mmr_extend) ? 0xffffffff : 0x00000000;
564 case FM7_MAINMEM_REFRESH_FAST:
565 value = (refresh_fast) ? 0xffffffff : 0x00000000;
568 #if defined(_FM77AV_VARIANTS)
569 case FM7_MAINIO_INITROM_ENABLED:
570 value = (initiator_enabled) ? 0xffffffff: 0x00000000;
572 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
573 case FM7_MAINIO_EXTROM:
574 value = (extrom_bank) ? 0xffffffff: 0x00000000;
577 case FM7_MAINIO_EXTBANK:
578 value = extcard_bank & 0x3f;
579 value |= (dictram_enabled) ? 0x80 : 0;
580 value |= (dictrom_enabled) ? 0x40 : 0;
588 void FM7_MAINMEM::write_signal(int sigid, uint32_t data, uint32_t mask)
590 bool flag = ((data & mask) != 0);
592 case SIG_FM7_SUB_HALT:
595 case FM7_MAINIO_IS_BASICROM:
598 case FM7_MAINIO_PUSH_FD0F:
599 basicrom_fd0f = flag;
601 case FM7_MAINIO_CLOCKMODE:
603 setclock(clockmode ? 0 : 1);
605 case FM7_MAINIO_BOOTMODE:
606 bootmode = data & 0x07;
608 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
609 case FM7_MAINIO_BOOTRAM_RW:
610 boot_ram_write = flag;
613 #ifdef _FM77AV_VARIANTS
614 case FM7_MAINIO_INITROM_ENABLED:
615 initiator_enabled = flag;
617 case FM7_MAINIO_EXTBANK:
618 extcard_bank = data & 0x3f;
619 dictram_enabled = ((data & 0x80) != 0) ? true : false;
620 dictrom_enabled = ((data & 0x40) != 0) ? true : false;
622 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
623 case FM7_MAINIO_EXTROM:
629 case FM7_MAINIO_WINDOW_ENABLED:
630 window_enabled = flag;
631 setclock(config.cpu_type);
633 case FM7_MAINIO_WINDOW_FAST:
635 setclock(config.cpu_type);
637 case FM7_MAINIO_FASTMMR_ENABLED:
639 setclock(config.cpu_type);
641 case FM7_MAINIO_MMR_ENABLED:
643 setclock(config.cpu_type);
645 case FM7_MAINIO_MMR_EXTENDED:
648 case FM7_MAINMEM_REFRESH_FAST:
650 setclock(config.cpu_type);
657 uint32_t FM7_MAINMEM::read_dma_data8(uint32_t addr)
661 val = this->read_data8_main(addr & 0xffff, true);
664 return this->read_data8(addr & 0xffff);
668 uint32_t FM7_MAINMEM::read_dma_io8(uint32_t addr)
672 val = this->read_data8_main(addr & 0xffff, true);
675 return this->read_data8(addr & 0xffff);
680 uint32_t FM7_MAINMEM::read_data8_main(uint32_t addr, bool dmamode)
685 bank = getbank(addr, &realaddr, false, dmamode);
687 emu->out_debug_log(_T("Illegal BANK: ADDR = %04x"), addr);
688 return 0xff; // Illegal
690 if(bank == FM7_MAINMEM_SHAREDRAM) {
691 if(!sub_halted) return 0xff; // Not halt
692 return display->read_data8(realaddr + 0xd380); // Okay?
693 } else if(bank == FM7_MAINMEM_NULL) {
696 #if defined(_FM77AV_VARIANTS)
697 else if(bank == FM7_MAINMEM_AV_DIRECTACCESS) {
698 if(!sub_halted) return 0xff; // Not halt
700 return display->read_dma_data8(realaddr); // Okay?
702 return display->read_data8(realaddr); // Okay?
704 } else if(bank == FM7_MAINMEM_KANJI_DUMMYADDR) {
705 return (realaddr & 0x01);
708 #if defined(CAPABLE_DICTROM)
709 else if(bank == FM7_MAINMEM_KANJI_LEVEL1) {
710 return kanjiclass1->read_data8(KANJIROM_DIRECTADDR + realaddr);
713 else if(read_table[bank].dev != NULL) {
714 return read_table[bank].dev->read_data8(realaddr);
715 } else if(read_table[bank].memory != NULL) {
716 return read_table[bank].memory[realaddr];
718 return 0xff; // Dummy
721 uint32_t FM7_MAINMEM::read_data8(uint32_t addr)
724 if(addr >= FM7_MAINIO_WINDOW_OFFSET) {
726 case FM7_MAINIO_WINDOW_OFFSET:
727 return (uint32_t)window_offset;
729 case FM7_MAINIO_MMR_SEGMENT:
730 return (uint32_t)mmr_segment;
733 if((addr >= FM7_MAINIO_MMR_BANK) && (addr < (FM7_MAINIO_MMR_BANK + 0x80))){
734 return mmr_map_data[addr - FM7_MAINIO_MMR_BANK];
741 return this->read_data8_main(addr, false);
744 void FM7_MAINMEM::write_dma_data8(uint32_t addr, uint32_t data)
747 this->write_data8_main(addr & 0xffff, data, true);
749 this->write_data8(addr & 0xffff, data);
753 void FM7_MAINMEM::write_dma_io8(uint32_t addr, uint32_t data)
756 this->write_data8_main(addr & 0xffff, data, true);
758 this->write_data8(addr & 0xffff, data);
762 void FM7_MAINMEM::write_data8_main(uint32_t addr, uint32_t data, bool dmamode)
766 bank = getbank(addr, &realaddr, true, dmamode);
768 emu->out_debug_log(_T("Illegal BANK: ADDR = %04x"), addr);
771 if(bank == FM7_MAINMEM_SHAREDRAM) {
772 if(!sub_halted) return; // Not halt
773 display->write_data8(realaddr + 0xd380, data); // Okay?
775 } else if(bank == FM7_MAINMEM_NULL) {
778 //#if defined(_FM7) || defined(_FMNEW7)
779 // else if(bank == FM7_MAINMEM_BASICROM) {
780 // bank = FM7_MAINMEM_URA; // FM-7/NEW7 write to ura-ram even enabled basic-rom.
784 #if defined(_FM77AV_VARIANTS)
785 else if(bank == FM7_MAINMEM_AV_DIRECTACCESS) {
786 if(!sub_halted) return; // Not halt
788 display->write_dma_data8(realaddr, data); // Okay?
790 display->write_data8(realaddr, data); // Okay?
796 else if(bank == FM7_MAINMEM_BOOTROM_RAM) {
797 if(!boot_ram_write) return;
800 if(write_table[bank].dev != NULL) {
801 write_table[bank].dev->write_data8(realaddr, data);
802 } else if(write_table[bank].memory != NULL) {
803 write_table[bank].memory[realaddr] = (uint8_t)data;
807 void FM7_MAINMEM::write_data8(uint32_t addr, uint32_t data)
810 if(addr >= FM7_MAINIO_WINDOW_OFFSET) {
812 case FM7_MAINIO_WINDOW_OFFSET:
813 window_offset = data;
815 case FM7_MAINIO_MMR_SEGMENT:
817 mmr_segment = data & 0x07;
819 mmr_segment = data & 0x03;
823 if((addr >= FM7_MAINIO_MMR_BANK) && (addr < (FM7_MAINIO_MMR_BANK + 0x80))){
824 mmr_map_data[addr - FM7_MAINIO_MMR_BANK] = (uint8_t)data;
831 write_data8_main(addr, data, false);
834 // Read / Write data(s) as big endian.
835 uint32_t FM7_MAINMEM::read_data16(uint32_t addr)
840 hi = read_data8(addr) & 0xff;
841 lo = read_data8(addr + 1) & 0xff;
847 uint32_t FM7_MAINMEM::read_data32(uint32_t addr)
849 uint32_t ah, a2, a3, al;
852 ah = read_data8(addr) & 0xff;
853 a2 = read_data8(addr + 1) & 0xff;
854 a3 = read_data8(addr + 2) & 0xff;
855 al = read_data8(addr + 3) & 0xff;
857 val = ah * (65536 * 256) + a2 * 65536 + a3 * 256 + al;
861 void FM7_MAINMEM::write_data16(uint32_t addr, uint32_t data)
865 write_data8(addr + 1, d & 0xff);
867 write_data8(addr + 0, d & 0xff);
870 void FM7_MAINMEM::write_data32(uint32_t addr, uint32_t data)
874 write_data8(addr + 3, d & 0xff);
876 write_data8(addr + 2, d & 0xff);
878 write_data8(addr + 1, d & 0xff);
880 write_data8(addr + 0, d & 0xff);
884 bool FM7_MAINMEM::get_loadstat_basicrom(void)
886 return diag_load_basicrom;
889 bool FM7_MAINMEM::get_loadstat_bootrom_bas(void)
891 return diag_load_bootrom_bas;
894 bool FM7_MAINMEM::get_loadstat_bootrom_dos(void)
896 return diag_load_bootrom_dos;
899 uint32_t FM7_MAINMEM::read_bios(const _TCHAR *name, uint8_t *ptr, uint32_t size)
905 if((name == NULL) || (ptr == NULL)) return 0;
906 s = create_local_path(name);
907 if(s == NULL) return 0;
909 if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
910 blocks = fio.Fread(ptr, size, 1);
913 return blocks * size;
916 uint32_t FM7_MAINMEM::write_bios(const _TCHAR *name, uint8_t *ptr, uint32_t size)
922 if((name == NULL) || (ptr == NULL)) return 0;
923 s = create_local_path(name);
924 if(s == NULL) return 0;
926 fio.Fopen(s, FILEIO_WRITE_BINARY);
927 blocks = fio.Fwrite(ptr, size, 1);
930 return blocks * size;
933 void FM7_MAINMEM::update_config()
935 //setclock(config.cpu_type);
938 FM7_MAINMEM::FM7_MAINMEM(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
942 #if !defined(_FM77AV_VARIANTS)
943 for(int i = 0; i < 4; i++) fm7_bootroms[i] = (uint8_t *)malloc(0x200);
948 #if defined(CAPABLE_DICTROM)
951 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
952 defined(_FM77_VARIANTS)
953 fm7_mainmem_extram = NULL;
956 memset(read_table, 0x00, sizeof(read_table));
957 memset(write_table, 0x00, sizeof(write_table));
960 FM7_MAINMEM::~FM7_MAINMEM()
964 void FM7_MAINMEM::initialize(void)
967 diag_load_basicrom = false;
968 diag_load_bootrom_bas = false;
969 diag_load_bootrom_dos = false;
970 diag_load_bootrom_mmr = false;
972 #if defined(_FM77AV_VARIANTS)
973 dictrom_connected = false;
976 for(i = 0x00; i < 0x80; i++) {
983 window_enabled = false;
985 #ifdef _FM77AV_VARIANTS
988 dictrom_enabled = false;
989 dictram_enabled = false;
991 initiator_enabled = true;
992 boot_ram_write = true;
994 bootmode = config.boot_mode & 3;
995 basicrom_fd0f = false;
996 is_basicrom = ((bootmode & 0x03) == 0) ? true : false;
999 i = FM7_MAINMEM_OMOTE;
1000 memset(fm7_mainmem_omote, 0x00, 0x8000 * sizeof(uint8_t));
1001 read_table[i].memory = fm7_mainmem_omote;
1002 write_table[i].memory = fm7_mainmem_omote;
1005 i = FM7_MAINMEM_URA;
1006 memset(fm7_mainmem_ura, 0x00, 0x7c00 * sizeof(uint8_t));
1007 read_table[i].memory = fm7_mainmem_ura;
1008 write_table[i].memory = fm7_mainmem_ura;
1010 i = FM7_MAINMEM_VECTOR;
1011 memset(fm7_mainmem_bootrom_vector, 0x00, 0x1e);
1012 read_table[i].memory = fm7_mainmem_bootrom_vector;
1013 write_table[i].memory = fm7_mainmem_bootrom_vector;
1016 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1017 defined(_FM77_VARIANTS)
1018 extram_pages = FM77_EXRAM_BANKS;
1019 #if defined(_FM77_VARIANTS)
1020 if(extram_pages > 3) extram_pages = 3;
1022 if(extram_pages > 12) extram_pages = 12;
1024 if(extram_pages > 0) {
1025 i = FM7_MAINMEM_EXTRAM;
1026 fm7_mainmem_extram = (uint8_t *)malloc(extram_pages * 0x10000);
1027 if(fm7_mainmem_extram != NULL) {
1028 memset(fm7_mainmem_extram, 0x00, extram_pages * 0x10000);
1029 read_table[i].memory = fm7_mainmem_extram;
1030 write_table[i].memory = fm7_mainmem_extram;
1035 #if defined(_FM77_VARIANTS)
1036 memset(fm77_shadowram, 0x00, 0x200);
1037 read_table[FM7_MAINMEM_SHADOWRAM].memory = fm77_shadowram;
1038 write_table[FM7_MAINMEM_SHADOWRAM].memory = fm77_shadowram;
1040 #if !defined(_FM77AV_VARIANTS)
1041 for(i = FM7_MAINMEM_BOOTROM_BAS; i <= FM7_MAINMEM_BOOTROM_EXTRA; i++) {
1042 memset(fm7_bootroms[i - FM7_MAINMEM_BOOTROM_BAS], 0xff, 0x200);
1043 read_table[i].memory = fm7_bootroms[i - FM7_MAINMEM_BOOTROM_BAS];
1047 if(read_bios(_T("BOOT_BAS8.ROM"), fm7_bootroms[0], 0x200) >= 0x1e0) {
1048 diag_load_bootrom_bas = true;
1050 diag_load_bootrom_bas = false;
1052 if(read_bios(_T("BOOT_DOS8.ROM"), fm7_bootroms[1], 0x200) >= 0x1e0) {
1053 diag_load_bootrom_dos = true;
1055 diag_load_bootrom_dos = false;
1057 diag_load_bootrom_mmr = false;
1058 # elif defined(_FM7) || defined(_FMNEW7) || defined(_FM77_VARIANTS)
1059 if(read_bios(_T("BOOT_BAS.ROM"), fm7_bootroms[0], 0x200) >= 0x1e0) {
1060 diag_load_bootrom_bas = true;
1062 diag_load_bootrom_bas = false;
1064 if(read_bios(_T("BOOT_DOS.ROM"), fm7_bootroms[1], 0x200) >= 0x1e0) {
1065 diag_load_bootrom_dos = true;
1067 diag_load_bootrom_dos = false;
1069 # if defined(_FM77_VARIANTS)
1070 if(read_bios(_T("BOOT_MMR.ROM"), fm7_bootroms[2], 0x200) >= 0x1e0) {
1071 diag_load_bootrom_mmr = true;
1073 diag_load_bootrom_mmr = false;
1076 i = FM7_MAINMEM_BOOTROM_RAM;
1077 memset(fm7_bootram, 0x00, 0x200 * sizeof(uint8_t)); // RAM
1078 read_table[i].memory = fm7_bootram;
1079 write_table[i].memory = fm7_bootram;
1082 diag_load_bootrom_mmr = false;
1084 # elif defined(_FM77AV_VARIANTS)
1085 i = FM7_MAINMEM_AV_PAGE0;
1086 memset(fm7_mainmem_mmrbank_0, 0x00, 0x10000 * sizeof(uint8_t));
1087 read_table[i].memory = fm7_mainmem_mmrbank_0;
1088 write_table[i].memory = fm7_mainmem_mmrbank_0;
1090 i = FM7_MAINMEM_AV_PAGE2;
1091 memset(fm7_mainmem_mmrbank_2, 0x00, 0x10000 * sizeof(uint8_t));
1092 read_table[i].memory = fm7_mainmem_mmrbank_2;
1093 write_table[i].memory = fm7_mainmem_mmrbank_2;
1095 i = FM7_MAINMEM_INITROM;
1096 diag_load_initrom = false;
1097 memset(fm7_mainmem_initrom, 0xff, 0x2000 * sizeof(uint8_t));
1098 read_table[i].memory = fm7_mainmem_initrom;
1100 if(read_bios(_T("INITIATE.ROM"), read_table[i].memory, 0x2000) >= 0x2000) diag_load_initrom = true;
1101 emu->out_debug_log(_T("77AV INITIATOR ROM READING : %s"), diag_load_initrom ? "OK" : "NG");
1103 read_table[FM7_MAINMEM_BOOTROM_BAS].memory = NULL; // Not connected.
1104 read_table[FM7_MAINMEM_BOOTROM_DOS].memory = NULL; // Not connected.
1105 read_table[FM7_MAINMEM_BOOTROM_MMR].memory = NULL; // Not connected.
1107 if(read_bios(_T("BOOT_MMR.ROM"), fm77av_hidden_bootmmr, 0x200) < 0x1e0) {
1108 memcpy(fm77av_hidden_bootmmr, &fm7_mainmem_initrom[0x1a00], 0x200);
1110 read_table[FM7_MAINMEM_BOOTROM_MMR].memory = fm77av_hidden_bootmmr; // Not connected.
1111 fm77av_hidden_bootmmr[0x1fe] = 0xfe;
1112 fm77av_hidden_bootmmr[0x1fe] = 0x00;
1114 i = FM7_MAINMEM_BOOTROM_RAM;
1115 memset(fm7_bootram, 0x00, 0x200 * sizeof(uint8_t)); // RAM
1116 read_table[i].memory = fm7_bootram;
1117 write_table[i].memory = fm7_bootram;
1119 if(diag_load_initrom) diag_load_bootrom_bas = true;
1120 if(diag_load_initrom) diag_load_bootrom_dos = true;
1122 if((config.boot_mode & 0x03) == 0) {
1123 memcpy(fm7_bootram, &fm7_mainmem_initrom[0x1800], 0x1e0 * sizeof(uint8_t));
1125 memcpy(fm7_bootram, &fm7_mainmem_initrom[0x1a00], 0x1e0 * sizeof(uint8_t));
1127 fm7_bootram[0x1fe] = 0xfe; // Set reset vector.
1128 fm7_bootram[0x1ff] = 0x00; //
1131 emu->out_debug_log(_T("BOOT ROM (basic mode) READING : %s"), diag_load_bootrom_bas ? "OK" : "NG");
1132 emu->out_debug_log(_T("BOOT ROM (DOS mode) READING : %s"), diag_load_bootrom_dos ? "OK" : "NG");
1133 #if defined(_FM77_VARIANTS)
1134 emu->out_debug_log(_T("BOOT ROM (MMR mode) READING : %s"), diag_load_bootrom_mmr ? "OK" : "NG");
1138 #if !defined(_FM77AV_VARIANTS)
1139 for(i = 0; i <= 3; i++) {
1140 uint8_t *p = fm7_bootroms[i];
1141 p[0x1fe] = 0xfe; // Set reset vector.
1146 i = FM7_MAINMEM_RESET_VECTOR;
1147 fm7_mainmem_reset_vector[0] = 0xfe;
1148 fm7_mainmem_reset_vector[1] = 0x00;
1150 read_table[i].memory = fm7_mainmem_reset_vector;
1152 i = FM7_MAINMEM_BASICROM;
1153 memset(fm7_mainmem_basicrom, 0xff, 0x7c00 * sizeof(uint8_t));
1155 read_table[i].memory = fm7_mainmem_basicrom;
1157 if(read_bios(_T("FBASIC302.ROM"), fm7_mainmem_basicrom, 0x7c00) == 0x7c00) {
1158 diag_load_basicrom = true;
1159 } else if(read_bios(_T("FBASIC300.ROM"), fm7_mainmem_basicrom, 0x7c00) == 0x7c00) {
1160 diag_load_basicrom = true;
1161 } else if(read_bios(_T("FBASIC30.ROM"), fm7_mainmem_basicrom, 0x7c00) == 0x7c00) {
1162 diag_load_basicrom = true;
1166 if(read_bios(_T("FBASIC10.ROM"), fm7_mainmem_basicrom, 0x7c00) == 0x7c00) diag_load_basicrom = true;
1168 emu->out_debug_log(_T("BASIC ROM READING : %s"), diag_load_basicrom ? "OK" : "NG");
1170 i = FM7_MAINMEM_BIOSWORK;
1171 memset(fm7_mainmem_bioswork, 0x00, 0x80 * sizeof(uint8_t));
1172 read_table[i].memory = fm7_mainmem_bioswork;
1173 write_table[i].memory = fm7_mainmem_bioswork;
1174 #if defined(CAPABLE_DICTROM)
1175 diag_load_dictrom = false;
1176 i = FM7_MAINMEM_DICTROM;
1177 memset(fm7_mainmem_dictrom, 0xff, 0x40000 * sizeof(uint8_t));
1178 read_table[i].memory = fm7_mainmem_dictrom;
1179 if(read_bios(_T("DICROM.ROM"), fm7_mainmem_dictrom, 0x40000) == 0x40000) diag_load_dictrom = true;
1180 emu->out_debug_log(_T("DICTIONARY ROM READING : %s"), diag_load_dictrom ? "OK" : "NG");
1181 dictrom_connected = diag_load_dictrom;
1183 i = FM7_MAINMEM_BACKUPED_RAM;
1184 diag_load_learndata = false;
1185 memset(fm7_mainmem_learndata, 0x00, 0x2000 * sizeof(uint8_t));
1186 read_table[i].memory = fm7_mainmem_learndata;
1187 write_table[i].memory = fm7_mainmem_learndata;
1188 if(read_bios(_T("USERDIC.DAT"), read_table[i].memory, 0x2000) == 0x2000) diag_load_learndata = true;
1189 emu->out_debug_log(_T("DICTIONARY BACKUPED RAM READING : %s"), diag_load_learndata ? "OK" : "NG");
1190 if(!diag_load_learndata) write_bios(_T("USERDIC.DAT"), fm7_mainmem_learndata, 0x2000);
1193 i = FM7_MAINMEM_77AV40_EXTRAROM;
1194 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1195 diag_load_extrarom = false;
1196 memset(fm7_mainmem_extrarom, 0xff, sizeof(fm7_mainmem_extrarom));
1197 read_table[i].memory = fm7_mainmem_extrarom;
1198 if(read_bios(_T("EXTSUB.ROM"), read_table[i].memory, 0xc000) == 0xc000) diag_load_extrarom = true;
1199 emu->out_debug_log(_T("AV40SX/EX EXTRA ROM READING : %s"), diag_load_extrarom ? "OK" : "NG");
1203 void FM7_MAINMEM::release()
1205 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1206 defined(_FM77_VARIANTS)
1207 if(fm7_mainmem_extram != NULL) free(fm7_mainmem_extram);
1209 #if !defined(_FM77AV_VARIANTS)
1211 for(i = 0; i < 4; i++) {
1212 if(fm7_bootroms[i] != NULL) free(fm7_bootroms[i]);
1213 fm7_bootroms[i] = NULL;
1216 #if defined(CAPABLE_DICTROM)
1217 write_bios(_T("USERDIC.DAT"), fm7_mainmem_learndata, 0x2000);
1219 // MEMORY::release();
1222 #define STATE_VERSION 2
1223 void FM7_MAINMEM::save_state(FILEIO *state_fio)
1225 state_fio->FputUint32_BE(STATE_VERSION);
1226 state_fio->FputInt32_BE(this_device_id);
1229 state_fio->FputBool(ioaccess_wait);
1230 state_fio->FputInt32_BE(waitfactor);
1231 state_fio->FputInt32_BE(waitcount);
1233 state_fio->FputBool(sub_halted);
1235 state_fio->FputBool(diag_load_basicrom);
1236 state_fio->FputBool(diag_load_bootrom_bas);
1237 state_fio->FputBool(diag_load_bootrom_dos);
1238 state_fio->FputBool(diag_load_bootrom_mmr);
1239 state_fio->Fwrite(fm7_mainmem_omote, sizeof(fm7_mainmem_omote), 1);
1240 state_fio->Fwrite(fm7_mainmem_ura, sizeof(fm7_mainmem_ura), 1);
1241 state_fio->Fwrite(fm7_mainmem_basicrom, sizeof(fm7_mainmem_basicrom), 1);
1242 state_fio->Fwrite(fm7_mainmem_bioswork, sizeof(fm7_mainmem_bioswork), 1);
1243 state_fio->Fwrite(fm7_mainmem_bootrom_vector, sizeof(fm7_mainmem_bootrom_vector), 1);
1244 state_fio->Fwrite(fm7_mainmem_reset_vector, sizeof(fm7_mainmem_reset_vector), 1);
1246 state_fio->Fwrite(fm7_mainmem_null, sizeof(fm7_mainmem_null), 1);
1247 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
1248 state_fio->Fwrite(fm7_bootram, sizeof(fm7_bootram), 1);
1250 #if !defined(_FM77AV_VARIANTS)
1252 for(addr = 0; addr < 4; addr++) state_fio->Fwrite(fm7_bootroms[addr], sizeof(0x200), 1);
1254 #ifdef _FM77AV_VARIANTS
1255 state_fio->FputBool(dictrom_connected);
1256 state_fio->FputBool(use_page2_extram);
1258 state_fio->FputBool(diag_load_initrom);
1259 state_fio->FputBool(diag_load_dictrom);
1260 state_fio->FputBool(diag_load_learndata);
1261 state_fio->Fwrite(fm7_mainmem_initrom, sizeof(fm7_mainmem_initrom), 1);
1262 state_fio->Fwrite(fm77av_hidden_bootmmr, sizeof(fm77av_hidden_bootmmr), 1);
1264 state_fio->Fwrite(fm7_mainmem_mmrbank_0, sizeof(fm7_mainmem_mmrbank_0), 1);
1265 state_fio->Fwrite(fm7_mainmem_mmrbank_2, sizeof(fm7_mainmem_mmrbank_2), 1);
1267 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1268 state_fio->FputBool(diag_load_extrarom);
1269 state_fio->Fwrite(fm7_mainmem_extrarom, sizeof(fm7_mainmem_extrarom), 1);
1271 # if defined(CAPABLE_DICTROM)
1272 state_fio->Fwrite(fm7_mainmem_dictrom, sizeof(fm7_mainmem_dictrom), 1);
1273 state_fio->Fwrite(fm7_mainmem_learndata, sizeof(fm7_mainmem_learndata), 1);
1278 state_fio->FputBool(extram_connected);
1279 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1280 defined(_FM77_VARIANTS)
1282 state_fio->FputInt32_BE(extram_pages);
1283 pages = extram_pages;
1284 # if defined(_FM77_VARIANTS)
1285 if(pages > 3) pages = 3;
1287 if(pages > 12) pages = 12;
1289 if(pages > 0) state_fio->Fwrite(fm7_mainmem_extram, pages * 0x10000, 1);
1290 # if defined(_FM77_VARIANTS)
1291 state_fio->Fwrite(fm77_shadowram, sizeof(fm77_shadowram), 1);
1297 state_fio->FputBool(is_basicrom);
1298 state_fio->FputBool(clockmode);
1299 state_fio->FputBool(basicrom_fd0f);
1300 state_fio->FputUint32_BE(bootmode);
1301 #if defined(_FM77AV_VARIANTS)
1302 state_fio->FputUint32_BE(extcard_bank);
1303 state_fio->FputBool(extrom_bank);
1304 state_fio->FputBool(initiator_enabled);
1305 state_fio->FputBool(dictrom_enabled);
1306 state_fio->FputBool(dictram_enabled);
1308 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
1309 state_fio->FputBool(boot_ram_write);
1311 #if defined(HAS_MMR)
1312 state_fio->FputBool(window_enabled);
1313 state_fio->FputBool(mmr_enabled);
1314 state_fio->FputBool(mmr_fast);
1315 state_fio->FputBool(mmr_extend);
1317 state_fio->FputUint16_BE(window_offset);
1318 state_fio->FputBool(window_fast);
1319 state_fio->FputBool(refresh_fast);
1320 state_fio->FputUint8(mmr_segment);
1321 state_fio->Fwrite(mmr_map_data, sizeof(mmr_map_data), 1);
1326 bool FM7_MAINMEM::load_state(FILEIO *state_fio)
1329 version = state_fio->FgetUint32_BE();
1330 if(this_device_id != state_fio->FgetInt32_BE()) return false;
1333 ioaccess_wait = state_fio->FgetBool();
1334 waitfactor = state_fio->FgetInt32_BE();
1335 waitcount = state_fio->FgetInt32_BE();
1337 sub_halted = state_fio->FgetBool();
1339 diag_load_basicrom = state_fio->FgetBool();
1340 diag_load_bootrom_bas = state_fio->FgetBool();
1341 diag_load_bootrom_dos = state_fio->FgetBool();
1342 diag_load_bootrom_mmr = state_fio->FgetBool();
1344 state_fio->Fread(fm7_mainmem_omote, sizeof(fm7_mainmem_omote), 1);
1345 state_fio->Fread(fm7_mainmem_ura, sizeof(fm7_mainmem_ura), 1);
1346 state_fio->Fread(fm7_mainmem_basicrom, sizeof(fm7_mainmem_basicrom), 1);
1347 state_fio->Fread(fm7_mainmem_bioswork, sizeof(fm7_mainmem_bioswork), 1);
1348 state_fio->Fread(fm7_mainmem_bootrom_vector, sizeof(fm7_mainmem_bootrom_vector), 1);
1349 state_fio->Fread(fm7_mainmem_reset_vector, sizeof(fm7_mainmem_reset_vector), 1);
1351 state_fio->Fread(fm7_mainmem_null, sizeof(fm7_mainmem_null), 1);
1352 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
1353 state_fio->Fread(fm7_bootram, sizeof(fm7_bootram), 1);
1355 #if !defined(_FM77AV_VARIANTS)
1357 for(addr = 0; addr < 4; addr++) state_fio->Fread(fm7_bootroms[addr], sizeof(0x200), 1);
1359 #ifdef _FM77AV_VARIANTS
1360 dictrom_connected = state_fio->FgetBool();
1361 use_page2_extram = state_fio->FgetBool();
1363 diag_load_initrom = state_fio->FgetBool();
1364 diag_load_dictrom = state_fio->FgetBool();
1365 diag_load_learndata = state_fio->FgetBool();
1366 state_fio->Fread(fm7_mainmem_initrom, sizeof(fm7_mainmem_initrom), 1);
1367 state_fio->Fread(fm77av_hidden_bootmmr, sizeof(fm77av_hidden_bootmmr), 1);
1369 state_fio->Fread(fm7_mainmem_mmrbank_0, sizeof(fm7_mainmem_mmrbank_0), 1);
1370 state_fio->Fread(fm7_mainmem_mmrbank_2, sizeof(fm7_mainmem_mmrbank_2), 1);
1372 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
1373 diag_load_extrarom = state_fio->FgetBool();
1374 state_fio->Fread(fm7_mainmem_extrarom, sizeof(fm7_mainmem_extrarom), 1);
1376 # if defined(CAPABLE_DICTROM)
1377 state_fio->Fread(fm7_mainmem_dictrom, sizeof(fm7_mainmem_dictrom), 1);
1378 state_fio->Fread(fm7_mainmem_learndata, sizeof(fm7_mainmem_learndata), 1);
1383 extram_connected = state_fio->FgetBool();
1384 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1385 defined(_FM77_VARIANTS)
1387 extram_pages = state_fio->FgetInt32_BE();
1388 pages = extram_pages;
1389 # if defined(_FM77_VARIANTS)
1390 if(pages > 3) pages = 3;
1392 if(pages > 12) pages = 12;
1394 if(pages > 0) state_fio->Fread(fm7_mainmem_extram, pages * 0x10000, 1);
1395 # if defined(_FM77_VARIANTS)
1396 state_fio->Fread(fm77_shadowram, sizeof(fm77_shadowram), 1);
1400 if(version == 1) return true;
1402 if(version >= 2) { // V2;
1403 is_basicrom = state_fio->FgetBool();
1404 clockmode = state_fio->FgetBool();
1405 basicrom_fd0f = state_fio->FgetBool();
1406 bootmode = state_fio->FgetUint32_BE();
1407 #if defined(_FM77AV_VARIANTS)
1408 extcard_bank = state_fio->FgetUint32_BE();
1409 extrom_bank = state_fio->FgetBool();
1410 initiator_enabled = state_fio->FgetBool();
1411 dictrom_enabled = state_fio->FgetBool();
1412 dictram_enabled = state_fio->FgetBool();
1414 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
1415 boot_ram_write = state_fio->FgetBool();
1417 #if defined(HAS_MMR)
1418 window_enabled = state_fio->FgetBool();
1419 mmr_enabled = state_fio->FgetBool();
1420 mmr_fast = state_fio->FgetBool();
1421 mmr_extend = state_fio->FgetBool();
1423 window_offset = state_fio->FgetUint16_BE();
1424 window_fast = state_fio->FgetBool();
1425 refresh_fast = state_fio->FgetBool();
1426 mmr_segment = state_fio->FgetUint8();
1427 state_fio->Fread(mmr_map_data, sizeof(mmr_map_data), 1);