OSDN Git Service

903796a96fb8c680e5f0f26a4d360c5b2c8eb583
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / fm7_mainmem.cpp
1 /*
2  * Main memory without MMR for FM-7 [FM7_MAINMEM]
3  *  Author: K.Ohta
4  *  Date  : 2015.01.01-
5  *
6  */
7
8 #include "fm7_mainmem.h"
9
10
11 void FM7_MAINMEM::reset()
12 {
13         waitfactor = 0;
14         waitcount = 0;
15         ioaccess_wait = false;
16         sub_halted = false;
17         first_pass = true;
18         flag_debug = false;
19 }
20
21 void FM7_MAINMEM::wait()
22 {
23         int waitfactor; // If MMR of TWR enabled, factor = 3.
24                             // If memory, factor = 2?
25         if(mainio->read_data8(FM7_MAINIO_CLOCKMODE) == FM7_MAINCLOCK_SLOW) return;
26 #ifdef HAS_MMR
27         if(!ioaccess_wait) {
28                 waitfactor = 2;
29                 ioaccess_wait = true;
30         } else { // Not MMR, TWR or enabled FAST MMR mode
31                 waitfactor = 3; // If(MMR or TWR) and NOT FAST MMR factor = 3, else factor = 2
32                 if((mainio->read_data8(FM7_MAINIO_FASTMMR_ENABLED) != 0)) waitfactor = 2;
33                 ioaccess_wait = false;
34         } 
35         if((mainio->read_data8(FM7_MAINIO_WINDOW_ENABLED) == 0) &&
36            (mainio->read_data8(FM7_MAINIO_MMR_ENABLED) == 0)) waitfactor = 2;
37 #else
38         waitfactor = 2;
39 #endif    
40         if(waitfactor <= 0) return;
41         waitcount++;
42         if(waitcount >= waitfactor) {
43                 if(maincpu != NULL) maincpu->set_extra_clock(1);
44                 waitcount = 0;
45         }
46 }
47
48
49 int FM7_MAINMEM::window_convert(uint32 addr, uint32 *realaddr)
50 {
51         uint32 raddr = addr;
52 #ifdef HAS_MMR
53         if((addr < 0x8000) && (addr >= 0x7c00) && (mainio->read_data8(FM7_MAINIO_WINDOW_ENABLED) != 0)) {
54           //            addr &= 0x03ff;
55                 raddr = ((mainio->read_data8(FM7_MAINIO_WINDOW_OFFSET) << 8) + addr) & 0xffff;
56                 *realaddr = raddr;
57 #ifdef _FM77AV_VARIANTS
58                 //printf("TWR hit %04x -> %04x\n", addr, raddr);
59                 return FM7_MAINMEM_AV_PAGE0; // 0x00000 - 0x0ffff
60 #else // FM77(L4 or others)
61                 *realaddr |= 0x20000;
62                 return FM7_MAINMEM_EXTRAM; // 0x20000 - 0x2ffff
63 #endif
64         }
65         // Window not hit.
66 #endif
67         return -1;
68 }
69
70 int FM7_MAINMEM::mmr_convert(uint32 addr, uint32 *realaddr)
71 {
72         uint32 raddr = 0;
73         uint32  mmr_segment;
74         uint32  mmr_bank;
75         
76 #ifdef _FM77AV_VARIANTS   
77         if(mainio->read_data8(FM7_MAINIO_INITROM_ENABLED) != 0) {
78                 if((addr >= 0x6000) && (addr < 0x8000)) {
79                         *realaddr = addr - 0x6000;
80                         return FM7_MAINMEM_INITROM;
81                 }
82                 if(addr >= 0xfffe) {
83                         *realaddr = addr - 0xe000;
84                         return FM7_MAINMEM_INITROM;
85                 }
86         }
87 #endif  
88 #ifdef HAS_MMR
89         //mmr_segment = mainio->read_data8(FM7_MAINIO_MMR_SEGMENT);
90         mmr_bank = mainio->read_data8(FM7_MAINIO_MMR_BANK + ((addr >> 12) & 0x000f));
91         // Out of EXTRAM : 77AV20/40.
92         
93 #if !defined(_FM77AV_VARIANTS)
94         if(addr >= 0xfc00) return -1;
95         mmr_bank &= 0x3f;
96 #else
97         if(addr >= 0xfc00) return -1;
98         //      mmr_bank &= 0xff;
99         mmr_bank &= 0x3f;
100 #endif
101         // Reallocated by MMR
102         raddr = addr & 0x0fff;
103         // Bank 3x : Standard memories.
104         if((mmr_bank < 0x3f) && (mmr_bank >= 0x30)) {
105                 raddr = ((mmr_bank << 12) | raddr) & 0xffff;
106                 return nonmmr_convert(raddr, realaddr);
107         }
108   
109 #ifdef _FM77AV_VARIANTS
110         if(mmr_bank == 0x3f) {
111                 if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
112                         *realaddr = 0;
113                         return FM7_MAINMEM_NULL;
114                 }
115         }
116 #else
117         if((mmr_bank == 0x3f) && (addr >= 0xc00) && (addr < 0xe00)) {
118                 if(mainio->read_data8(FM7_MAINIO_IS_BASICROM) != 0) { // BASICROM enabled
119                         *realaddr = 0;
120                         return FM7_MAINMEM_ZERO;
121                 } else {
122                         *realaddr = addr & 0x1ff;
123                         return FM7_MAINMEM_SHADOWRAM;
124                 }
125         }
126 #endif
127         
128 #ifdef _FM77AV_VARIANTS
129         if((mmr_bank & 0xf0) == 0x00) { // PAGE 0
130                 *realaddr = ((mmr_bank << 12) | raddr) & 0xffff;
131                 return FM7_MAINMEM_AV_PAGE0;
132         }
133         if((mmr_bank & 0xf0) == 0x10) { // PAGE 1
134                 *realaddr = (mmr_bank << 12) | raddr;
135                 return FM7_MAINMEM_AV_DIRECTACCESS;
136         }
137         if((mmr_bank & 0xf0) == 0x20) { // PAGE 2
138 #if 0
139                 uint32 dbank = mainio->read_data8(FM7_MAINIO_EXTBANK);
140                 switch(mmr_bank) {
141                         case 0x28:
142                         case 0x29: // Backuped RAM
143                                 if(((dbank & 0x80) != 0) && (dictrom_connected)){ // Battery backuped RAM
144                                         raddr =  raddr & 0x1ff;
145                                         *realaddr = raddr;
146                                         return FM7_MAINMEM_BACKUPED_RAM;
147                                 }
148                                 break;
149                         case 0x2e:
150                                 if(((dbank & 0x40) != 0) && (dictrom_connected)) { // Dictionary ROM
151                                         dbank = dbank & 0x3f;
152                                         uint32 extrom = mainio->read_data8(FM7_MAINIO_EXTROM) & 0x80;
153                                         if(extrom == 0) { // Dictionary selected.
154                                                 dbank = dbank << 12;
155                                                 *realaddr = raddr | dbank;
156                                                 return FM7_MAINMEM_DICTROM;
157                                         } else if(dbank <= 0x1f) { // KANJI
158                                                 *realaddr = (dbank << 12) | raddr;
159                                                 return FM7_MAINMEM_KANJI_LEVEL1;
160                                         } else if(dbank <= 0x37) { 
161                                                 dbank = dbank << 12;
162                                                 *realaddr = (dbank - 0x20000) | raddr;
163                                                 return FM7_MAINMEM_77AV40_EXTRAROM;
164                                         } else if(dbank <= 0x3f) {
165                                                 raddr = ((dbank << 12) - 0x30000) | raddr;
166                                                 if((raddr >= 0xffe0) || (raddr < 0xfd00)) { 
167                                                         return nonmmr_convert(raddr, realaddr);
168                                                 } else if((raddr >= 0xfe00) || (raddr < 0xffe0)) {
169                                                         *realaddr = raddr - 0xfe00;
170                                                         return FM7_MAINMEM_BOOTROM_DOS;
171                                                 }
172                                                 *realaddr = raddr + 0x10000;
173                                                 return FM7_MAINMEM_77AV40_EXTRAROM;
174                                         }
175                                 }
176                                 break;
177                 }
178                 *realaddr = (raddr | (mmr_bank << 12)) & 0x0ffff;
179                 return FM7_MAINMEM_AV_PAGE2;
180 #else
181                 *realaddr = (raddr | (mmr_bank << 12)) & 0x0ffff;
182                 return FM7_MAINMEM_NULL;
183
184 #endif
185                 // RAM
186         }
187 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20)
188         if(extram_connected) { // PAGE 4-
189                 if((mmr_bank >> 4) >= (extram_pages + 4)) {
190                         *realaddr = 0;
191                         return FM7_MAINMEM_NULL; // $FF
192                 } else {
193                         raddr = ((uint32)mmr_bank << 12) | raddr;
194                         *realaddr = raddr;
195                         return FM7_MAINMEM_EXTRAM;
196                 }
197         } else {
198                 if(mmr_bank >= 0x40) {
199                         *realaddr = 0;
200                         return FM7_MAINMEM_NULL;
201                 }
202         }
203 #endif
204 #else // 77
205         // page 0 or 1 or 2.
206         if(extram_connected) {
207                 if((mmr_bank >> 4) >= extram_pages) {
208                         *realaddr = 0;
209                         return FM7_MAINMEM_NULL;
210                 } else { // EXTRAM Exists.
211                         raddr = (((uint32)mmr_bank << 12) & 0x3ffff) | raddr;
212                         *realaddr = raddr;
213                         return FM7_MAINMEM_EXTRAM;
214                 }
215         }
216 #endif
217 #endif
218         return -1;
219 }
220
221 int FM7_MAINMEM::nonmmr_convert(uint32 addr, uint32 *realaddr)
222 {
223         addr &= 0x0ffff;
224 #ifdef _FM77AV_VARIANTS
225         if(mainio->read_data8(FM7_MAINIO_INITROM_ENABLED) != 0) {
226                 if((addr >= 0x6000) && (addr < 0x8000)) {
227                         *realaddr = addr - 0x6000;
228                         return FM7_MAINMEM_INITROM;
229                 }
230                 if(addr >= 0xfffe) {
231                   // printf("HIT %02x\n", read_table[FM7_MAINMEM_INITROM].memory[addr - 0xe000]);
232                         *realaddr = addr - 0xe000;
233                         return FM7_MAINMEM_INITROM;
234                 }
235         }
236 #endif  
237
238         if(addr < 0x8000) {
239                 *realaddr = addr;
240                 return FM7_MAINMEM_OMOTE;
241         } else if(addr < 0xfc00) {
242                 *realaddr = addr - 0x8000;
243                 if(mainio->read_data8(FM7_MAINIO_READ_FD0F) != 0) {
244                         return FM7_MAINMEM_BASICROM;
245                 }
246                 return FM7_MAINMEM_URA;
247         } else  if(addr < 0xfc80) {
248                 *realaddr = addr - 0xfc00;
249                 return FM7_MAINMEM_BIOSWORK;
250         }else if(addr < 0xfd00) {
251                 *realaddr = addr - 0xfc80;
252                 return FM7_MAINMEM_SHAREDRAM;
253         } else if(addr < 0xfe00) {
254                 wait();
255                 *realaddr = addr - 0xfd00;
256                 return FM7_MAINMEM_MMIO;
257         }else if(addr < 0xffe0){
258                 wait();
259                 *realaddr = addr - 0xfe00;
260                 switch(mainio->read_data8(FM7_MAINIO_BOOTMODE)) {
261                         case 0:
262                                 return FM7_MAINMEM_BOOTROM_BAS;
263                                 break;
264                         case 1:
265                           //printf("BOOT_DOS ADDR=%04x\n", addr);
266                                 return FM7_MAINMEM_BOOTROM_DOS;
267                                 break;
268                         case 2:
269                                 return FM7_MAINMEM_BOOTROM_MMR;
270                                 break;
271                         case 4:
272                                 return FM7_MAINMEM_BOOTROM_RAM;
273                                 break;
274                         default:
275                                 return FM7_MAINMEM_BOOTROM_BAS; // Really?
276                                 break;
277                 }
278         } else if(addr < 0xfffe) { // VECTOR
279                 //printf("Main: VECTOR\n");
280                 *realaddr = addr - 0xffe0;
281                 return FM7_MAINMEM_VECTOR;
282         } else if(addr < 0x10000) {
283           //if(mainio->read_data8(FM7_MAINIO_BOOTMODE) == 4) {
284           //    *realaddr = addr - 0xfe00;
285           //            return FM7_MAINMEM_BOOTROM_RAM;
286           //    }
287                 *realaddr = addr - 0xfffe;
288                 return FM7_MAINMEM_RESET_VECTOR;
289         }
290    
291         emu->out_debug_log("Main: Over run ADDR = %08x\n", addr);
292         *realaddr = addr;
293         return FM7_MAINMEM_NULL;
294 }
295      
296 int FM7_MAINMEM::getbank(uint32 addr, uint32 *realaddr)
297 {
298         if(realaddr == NULL) return FM7_MAINMEM_NULL; // Not effect.
299         addr = addr & 0xffff;
300 #ifdef HAS_MMR
301         if(mainio->read_data8(FM7_MAINIO_WINDOW_ENABLED) != 0) {
302                 int stat;
303                 uint32 raddr;
304                 stat = window_convert(addr, &raddr);
305                 //if(stat >= 0) printf("WINDOW CONVERT: %04x to %04x, bank = %02x\n", addr, raddr, stat);
306                 if(stat >= 0) {
307                         *realaddr = raddr;
308                         return stat;
309                 }
310         }
311         if(mainio->read_data8(FM7_MAINIO_MMR_ENABLED) != 0) {
312                 int stat;
313                 uint32 raddr;
314                 stat = mmr_convert(addr, &raddr);
315                 if(stat >= 0) {
316                         *realaddr = raddr;
317                         return stat;
318                 }
319         }
320 #endif
321         // NOT MMR.
322         return nonmmr_convert(addr, realaddr);
323 }
324
325 void FM7_MAINMEM::write_signal(int sigid, uint32 data, uint32 mask)
326 {
327         bool flag = ((data & mask) != 0);
328         switch(sigid) {
329                 case SIG_FM7_SUB_HALT:
330                         sub_halted = flag;
331                         break;
332         }
333 }
334
335
336 uint32 FM7_MAINMEM::read_data8(uint32 addr)
337 {
338         uint32 ret;
339         uint32 realaddr;
340         int bank;
341
342         bank = getbank(addr, &realaddr);
343         if(bank < 0) {
344                 emu->out_debug_log("Illegal BANK: ADDR = %04x\n", addr);
345                 return 0xff; // Illegal
346         }
347    
348         if(bank == FM7_MAINMEM_SHAREDRAM) {
349                 if(!sub_halted) return 0xff; // Not halt
350                 return display->read_data8((realaddr & 0x7f) + 0xd380); // Okay?
351         } else if(bank == FM7_MAINMEM_MMIO) {
352                 return mainio->read_data8(realaddr);
353 //              return mainio->read_data8(addr);
354         }
355 #if defined(_FM77AV_VARIANTS)
356         else if(bank == FM7_MAINMEM_AV_DIRECTACCESS) {
357           if(display->read_signal(SIG_DISPLAY_HALT) != 0) return 0xff; // Not halt
358                 //printf("READ MMR : %04x to %05x\n", addr, realaddr);
359                 return display->read_data8(realaddr & 0x0ffff); // Okay?
360         }
361 #endif
362         else if(read_table[bank].memory != NULL) {
363                 if(bank == FM7_MAINMEM_BOOTROM_BAS) {
364 #if 0
365                         uint32 i;
366                         uint32 pc;
367                         uint32 ix;
368                         uint32 us;
369                         uint32 ss;
370                         pc = maincpu->get_pc();
371                         if(pc == 0xfe02) {
372                                 ix = maincpu->get_ix();
373                                 ss = maincpu->get_sstack();
374                                 printf("IPL: SEEK PC=%04x S=%04x X=%04x RCB=", pc, ss, ix);
375                                 for(i = 0; i < 12; i++) printf("%02x ", read_data8(i + ix));
376                                 printf("\n");
377                         } else if((pc == 0xfe05) || (pc == 0xfe08)){
378                                 ix = maincpu->get_ix();
379                                 us = maincpu->get_ustack();
380                                 ss = maincpu->get_sstack();
381                                 printf("IPL: READ WRITE PC=%04x S=%04x X=%04x U=%04x RCB=", pc, ss, ix, us);
382                                 for(i = 0; i < 12; i++) printf("%02x ", read_data8(i + ix));
383                                 printf("\n");
384                                 printf("STACK DUMP: ");
385                                 for(i = 0; i < 32; i++) printf("%02x ", read_data8((ss + i) & 0xffff));
386                                 printf("\n");
387                         }
388 #endif
389                 } else {
390                         uint32 pc = maincpu->get_pc();
391                         uint32 ss = maincpu->get_sstack();
392                         uint32 i;
393                         //if(pc == 0x4afb) {
394                         //      if(flag_debug != true) {
395                         //              flag_debug = true;
396                         //              for(i = 0; i < 64; i++) printf("%04x : %02x\n", i + pc, read_data8((pc + i) & 0xffff));
397                         //      }
398                         //}
399                         //if((pc >= 0x1900) && (pc <= 0xfcff)){
400                         //if(flag_debug != true) {
401                         //              flag_debug = true;
402                         //              printf("PC=%04x \n", pc);
403                         //      }
404                         //}
405                 }
406                 //printf("READ: %04x is bank %d, %04x data=%02x\n", addr, bank, realaddr, read_table[bank].memory[realaddr]);
407                 //if(bank == FM7_MAINMEM_VECTOR) printf("VECTOR: ADDR = %04x, data = %02x\n", addr, read_table[bank].memory[realaddr]);
408                 return read_table[bank].memory[realaddr];
409         }
410         return 0xff; // Dummy
411 }
412
413 void FM7_MAINMEM::write_data8(uint32 addr, uint32 data)
414 {
415         uint32 ret;
416         uint32 realaddr;
417         int bank;
418    
419         bank = getbank(addr, &realaddr);
420         if(bank < 0) {
421                 emu->out_debug_log("Illegal BANK: ADDR = %04x\n", addr);
422                 return; // Illegal
423         }
424    
425         if(bank == FM7_MAINMEM_SHAREDRAM) {
426                 if(!sub_halted) return; // Not halt
427                 display->write_data8((realaddr & 0x7f) + 0xd380, data); // Okay?
428                 return;
429         } else if(bank == FM7_MAINMEM_MMIO) {
430                 mainio->write_data8(realaddr & 0x00ff, (uint8)data);
431 //              mainio->write_data8(addr, (uint8)data);
432                 return;
433         }
434 #if defined(_FM77AV_VARIANTS)
435         else if(bank == FM7_MAINMEM_AV_DIRECTACCESS) {
436                 if(display->read_signal(SIG_DISPLAY_HALT) != 0) return; // Not halt
437                 //printf("WRITE MMR : %04x to %05x\n", addr, realaddr);
438                 display->write_data8(realaddr & 0x0ffff, data); // Okay?
439                 return;
440         }
441 #endif
442         else if(write_table[bank].memory != NULL) {
443                         write_table[bank].memory[realaddr] = (uint8)(data & 0x000000ff);
444         }
445 }
446
447 // Read / Write data(s) as big endian.
448 uint32 FM7_MAINMEM::read_data16(uint32 addr)
449 {
450         uint32 hi, lo;
451         uint32 val;
452    
453         hi = read_data8(addr) & 0xff;
454         lo = read_data8(addr + 1) & 0xff;
455    
456         val = hi * 256 + lo;
457         return val;
458 }
459
460 uint32 FM7_MAINMEM::read_data32(uint32 addr)
461 {
462         uint32 ah, a2, a3, al;
463         uint32 val;
464    
465         ah = read_data8(addr) & 0xff;
466         a2 = read_data8(addr + 1) & 0xff;
467         a3 = read_data8(addr + 2) & 0xff;
468         al = read_data8(addr + 3) & 0xff;
469    
470         val = ah * (65536 * 256) + a2 * 65536 + a3 * 256 + al;
471         return val;
472 }
473
474 void FM7_MAINMEM::write_data16(uint32 addr, uint32 data)
475 {
476         uint32 d = data;
477    
478         write_data8(addr + 1, d & 0xff);
479         d = d / 256;
480         write_data8(addr + 0, d & 0xff);
481 }
482
483 void FM7_MAINMEM::write_data32(uint32 addr, uint32 data)
484 {
485         uint32 d = data;
486    
487         write_data8(addr + 3, d & 0xff);
488         d = d / 256;
489         write_data8(addr + 2, d & 0xff);
490         d = d / 256;
491         write_data8(addr + 1, d & 0xff);
492         d = d / 256;
493         write_data8(addr + 0, d & 0xff);
494 }
495
496
497 bool FM7_MAINMEM::get_loadstat_basicrom(void)
498 {
499         return diag_load_basicrom;
500 }
501
502 bool FM7_MAINMEM::get_loadstat_bootrom_bas(void)
503 {
504         return diag_load_bootrom_bas;
505 }
506
507 bool FM7_MAINMEM::get_loadstat_bootrom_dos(void)
508 {
509         return diag_load_bootrom_dos;
510 }
511
512 uint32 FM7_MAINMEM::read_bios(const char *name, uint8 *ptr, uint32 size)
513 {
514         FILEIO fio;
515         uint32 blocks;
516         _TCHAR *s;
517   
518         if((name == NULL) || (ptr == NULL))  return 0;
519         s = emu->bios_path((_TCHAR *)name);
520         if(s == NULL) return 0;
521   
522         if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
523         blocks = fio.Fread(ptr, size, 1);
524         fio.Fclose();
525
526         return blocks * size;
527 }
528
529 uint32 FM7_MAINMEM::write_bios(const char *name, uint8 *ptr, uint32 size)
530 {
531         FILEIO fio;
532         uint32 blocks;
533         _TCHAR *s;
534   
535         if((name == NULL) || (ptr == NULL))  return 0;
536         s = emu->bios_path((_TCHAR *)name);
537         if(s == NULL) return 0;
538   
539         fio.Fopen(s, FILEIO_WRITE_BINARY);
540         blocks = fio.Fwrite(ptr, size, 1);
541         fio.Fclose();
542
543         return blocks * size;
544 }
545
546 FM7_MAINMEM::FM7_MAINMEM(VM* parent_vm, EMU* parent_emu) : MEMORY(parent_vm, parent_emu)
547 {
548         int i;
549         p_vm = parent_vm;
550         p_emu = parent_emu;
551         for(i = 0; i < 4; i++) fm7_bootroms[i] = (uint8 *)malloc(0x200);
552         mainio = NULL;
553         display = NULL;
554         maincpu = NULL;
555         kanjiclass1 = NULL;
556         kanjiclass2 = NULL;
557 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20)
558         fm7_mainmem_extram = NULL;
559 #endif
560 }
561
562 FM7_MAINMEM::~FM7_MAINMEM()
563 {
564         int i;
565         for(i = 0; i < 4; i++) {
566                 if(fm7_bootroms[i] != NULL) free(fm7_bootroms[i]);
567                 fm7_bootroms[i] = NULL;
568         }
569 }
570
571 void FM7_MAINMEM::initialize(void)
572 {
573         int i;
574         diag_load_basicrom = false;
575         diag_load_bootrom_bas = false;
576         diag_load_bootrom_dos = false;
577         diag_load_bootrom_mmr = false;
578 #if defined(_FM77AV_VARIANTS)
579         dictrom_connected = false;
580 #endif
581         // Initialize table
582         // $0000-$7FFF
583         memset(read_table, 0x00, sizeof(read_table));
584         memset(write_table, 0x00, sizeof(write_table));
585         i = FM7_MAINMEM_OMOTE;
586         memset(fm7_mainmem_omote, 0x00, 0x8000 * sizeof(uint8));
587         read_table[i].memory = fm7_mainmem_omote;
588         write_table[i].memory = fm7_mainmem_omote;
589
590         // $8000-$FBFF
591         i = FM7_MAINMEM_URA;
592         memset(fm7_mainmem_ura, 0x00, 0x7c00 * sizeof(uint8));
593         read_table[i].memory = fm7_mainmem_ura;
594         write_table[i].memory = fm7_mainmem_ura;
595
596         
597         i = FM7_MAINMEM_VECTOR;
598         memset(fm7_mainmem_bootrom_vector, 0x00, 0x1e);
599         read_table[i].memory = fm7_mainmem_bootrom_vector;
600         write_table[i].memory = fm7_mainmem_bootrom_vector;
601         
602 #if defined(CAPABLE_DICTROM)
603         diag_load_dictrom = false;
604         i = FM7_MAINMEM_DICTROM;
605         memset(fm7_mainmem_extrarom, 0xff, 0x40000 * sizeof(uint8));
606         read_table[i].memory = fm7_mainmem_dictrom;
607         write_table[i].memory = NULL;
608         if(read_bios("DICROM.ROM", fm7_mainmem_dictrom, 0x40000) == 0x40000) diag_load_dictrom = true;
609         emu->out_debug_log("DICTIONARY ROM READING : %s\n", diag_load_dictrom ? "OK" : "NG");
610         dictrom_connected = diag_load_dictrom;
611         
612         i = FM7_MAINMEM_BACKUPED_RAM;
613         diag_load_learndata = false;
614         memset(fm7_mainmem_learndata, 0x00, 0x2000 * sizeof(uint8));
615         read_table[i].memory = fm7_mainmem_learndata;
616         write_table[i].memory = fm7_mainmem_learndata;
617         if(read_bios("USERDIC.DAT", read_table[i].memory, 0x2000) == 0x2000) diag_load_learndata = true;
618         emu->out_debug_log("DICTIONARY ROM READING : %s\n", diag_load_learndata ? "OK" : "NG");
619         if(!diag_load_learndata) write_bios("USERDIC.DAT", fm7_mainmem_learndata, 0x2000);
620 #endif
621         
622 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20)
623         i = FM7_MAINMEM_77AV40_EXTRAROM;
624         diag_load_extrarom = false;
625         memset(fm7_mainmem_extrarom, 0xff, 0x20000 * sizeof(uint8));
626         read_table[i].memory = fm7_mainmem_extrarom;
627         write_table[i].memory = NULL;
628         if(read_bios("EXTSUB.ROM", read_table[i].memory, 0xc000) >= 0xc000) diag_load_extrarom = true;
629         emu->out_debug_log("AV40 EXTRA ROM READING : %s\n", diag_load_extrarom ? "OK" : "NG");
630         
631         if(config.extram_pages > 0) {
632                 i = FM7_MAINMEM_EXTRAM;
633                 extram_pages = config.extram_pages;
634                 if(extram_pages >= 12) extram_pages = 12;
635                 fm7_mainmem_extram = malloc(extram_pages * 0x10000);
636                 if(fm7_mainmem_extram != NULL) {
637                         memset(fm7_mainmem_extram, 0x00, extram_pages * 0x10000);
638                         read_table[i].memory = fm7_mainmem_extram;
639                         write_table[i].memory = fm7_mainmem_extram;
640                 }
641         }
642 #endif  
643         
644         for(i = FM7_MAINMEM_BOOTROM_BAS; i <= FM7_MAINMEM_BOOTROM_EXTRA; i++) {
645             memset(fm7_bootroms[i - FM7_MAINMEM_BOOTROM_BAS], 0xff, 0x200);
646             read_table[i].memory = fm7_bootroms[i - FM7_MAINMEM_BOOTROM_BAS];
647             write_table[i].memory = NULL;
648         }
649 #if defined(_FM8)
650         if(read_bios("BOOT_BAS8.ROM", fm7_bootroms[0], 0x200) >= 0x1e0) {
651                 diag_load_bootrom_bas = true;
652         } else {
653                 diag_load_bootrom_bas = false;
654         }
655         if(read_bios("BOOT_DOS8.ROM", fm7_bootroms[1], 0x200) >= 0x1e0) {
656                 diag_load_bootrom_dos = true;
657         } else {
658                 diag_load_bootrom_dos = false;
659         }
660         diag_load_bootrom_mmr = false;
661 # elif defined(_FM77_VARIANTS)
662         i = FM7_MAINMEM_BOOTROM_RAM;
663         memset(fm7_bootram, 0x00, 0x200 * sizeof(uint8)); // RAM
664         read_table[i].memory = fm7_bootram;
665         write_table[i].memory = fm7_bootram;
666         
667         if(read_bios("BOOT_BAS.ROM", fm7_bootroms[0], 0x200) >= 0x1e0) {
668                 diag_load_bootrom_bas = true;
669         } else {
670                 diag_load_bootrom_bas = false;
671         }
672         if(read_bios("BOOT_DOS.ROM", fm7_bootroms[1], 0x200) >= 0x1e0) {
673                 diag_load_bootrom_dos = true;
674         } else {
675                 diag_load_bootrom_dos = false;
676         }
677         if(read_bios("BOOT_MMR.ROM", fm7_bootroms[2], 0x200) >= 0x1e0) {
678                 diag_load_bootrom_mmr = true;
679         } else {
680                 diag_load_bootrom_mmr = false;
681                 //memset(fm7_bootroms[2], 0xff, 0x200);
682         }
683         if(config.extram_pages > 0) {
684                 i = FM7_MAINMEM_EXTRAM;
685                 extram_pages = config.extram_pages;
686                 if(extram_pages >= 3) pages = 3;
687                 fm7_mainmem_extram = malloc(extram_pages * 0x10000);
688                 if(fm7_mainmem_extram != NULL) {
689                         memset(fm7_mainmem_extram, 0x00, extram_pages * 0x10000);
690                         read_table[i].memory = fm7_mainmem_extram;
691                         write_table[i].memory = fm7_mainmem_extram;
692                 }
693         }
694 # elif defined(_FM7) || defined(_FMNEW7)
695         if(read_bios("BOOT_BAS.ROM", fm7_bootroms[0], 0x200) >= 0x1e0) {
696                 diag_load_bootrom_bas = true;
697         } else {
698                 diag_load_bootrom_bas = false;
699         }
700         if(read_bios("BOOT_DOS.ROM", fm7_bootroms[1], 0x200) >= 0x1e0) {
701                 diag_load_bootrom_dos = true;
702         } else {
703                 diag_load_bootrom_dos = false;
704         }
705         // FM-7/8
706         diag_load_bootrom_mmr = false;
707 # elif defined(_FM77AV_VARIANTS)
708         i = FM7_MAINMEM_AV_PAGE0;
709         memset(fm7_mainmem_mmrbank_0, 0x00, 0x10000 * sizeof(uint8));
710         read_table[i].memory = fm7_mainmem_mmrbank_0;
711         write_table[i].memory = fm7_mainmem_mmrbank_0;
712         
713
714         i = FM7_MAINMEM_INITROM;
715         diag_load_initrom = false;
716         memset(fm7_mainmem_initrom, 0xff, 0x2000 * sizeof(uint8));
717         read_table[i].memory = fm7_mainmem_initrom;
718         write_table[i].memory = NULL;
719         if(read_bios("INITIATE.ROM", read_table[i].memory, 0x2000) >= 0x2000) diag_load_initrom = true;
720         emu->out_debug_log("77AV INITIATOR ROM READING : %s\n", diag_load_initrom ? "OK" : "NG");
721         
722         memcpy(fm7_bootroms[0], &fm7_mainmem_initrom[0x1800], 0x200 * sizeof(uint8));
723         memcpy(fm7_bootroms[1], &fm7_mainmem_initrom[0x1a00], 0x200 * sizeof(uint8));
724         read_table[FM7_MAINMEM_BOOTROM_MMR].memory = NULL; // Not connected.
725
726         i = FM7_MAINMEM_BOOTROM_RAM;
727         memset(fm7_bootram, 0x00, 0x200 * sizeof(uint8)); // RAM
728         read_table[i].memory = fm7_bootram;
729         write_table[i].memory = fm7_bootram;
730         if(diag_load_initrom) diag_load_bootrom_bas = true;
731         if(diag_load_initrom) diag_load_bootrom_dos = true;
732         // FM-7
733 #endif
734         emu->out_debug_log("BOOT ROM (basic mode) READING : %s\n", diag_load_bootrom_bas ? "OK" : "NG");
735         emu->out_debug_log("BOOT ROM (DOS   mode) READING : %s\n", diag_load_bootrom_dos ? "OK" : "NG");
736 #if defined(_FM77_VARIANTS)
737         emu->out_debug_log("BOOT ROM (MMR   mode) READING : %s\n", diag_load_bootrom_mmr ? "OK" : "NG");
738 #endif
739
740         i = FM7_MAINMEM_VECTOR;
741         memset(fm7_mainmem_bootrom_vector, 0x00, 0x1e);
742         read_table[i].memory = fm7_mainmem_bootrom_vector;
743         write_table[i].memory = fm7_mainmem_bootrom_vector;
744
745         for(i = 0; i <= 3; i++) {
746                 uint8 *p = fm7_bootroms[i];
747                 p[0x1fe] = 0xfe; // Set reset vector.
748                 p[0x1ff] = 0x00; //
749         }
750         
751         i = FM7_MAINMEM_RESET_VECTOR;
752         fm7_mainmem_reset_vector[0] = 0xfe;
753         fm7_mainmem_reset_vector[1] = 0x00;
754    
755         read_table[i].memory = fm7_mainmem_reset_vector;
756         write_table[i].memory = NULL;
757    
758         i = FM7_MAINMEM_BASICROM;
759         memset(fm7_mainmem_basicrom, 0xff, 0x7c00 * sizeof(uint8));
760         read_table[i].dev = NULL;
761         read_table[i].memory = fm7_mainmem_basicrom;
762         write_table[i].dev = NULL;
763         write_table[i].memory = NULL;
764 #if !defined(_FM8)
765         if(read_bios("FBASIC30.ROM", fm7_mainmem_basicrom, 0x7c00) == 0x7c00) diag_load_basicrom = true;
766 #else // FM8
767         if(read_bios("FBASIC10.ROM", fm7_mainmem_basicrom, 0x7c00) == 0x7c00) diag_load_basicrom = true;
768 #endif  
769         emu->out_debug_log("BASIC ROM READING : %s\n", diag_load_basicrom ? "OK" : "NG");
770    
771         i = FM7_MAINMEM_BIOSWORK;
772         memset(fm7_mainmem_bioswork, 0x00, 0x80 * sizeof(uint8));
773         read_table[i].dev = NULL;
774         read_table[i].memory = fm7_mainmem_bioswork;
775         write_table[i].dev = NULL;
776         write_table[i].memory = fm7_mainmem_bioswork;
777         
778 }