OSDN Git Service

3f49abf884e3c9bfc473d6589fa2765a6f9279d2
[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 void FM7_MAINMEM::wait()
11 {
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;
15 #ifdef HAS_MMR
16         if(!ioaccess_wait) {
17                 waitfactor = 2;
18                 ioaccess_wait = true;
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;
23         } 
24         if((mainio->read_data8(FM7_MAINIO_WINDOW_ENABLED) == 0) &&
25            (mainio->read_data8(FM7_MAINIO_MMR_ENABLED) == 0)) waitfactor = 2;
26 #else
27         waitfactor = 2;
28 #endif    
29         if(waitfactor <= 0) return;
30         waitcount++;
31         if(waitcount >= waitfactor) {
32                 if(maincpu != NULL) maincpu->set_extra_clock(1);
33                 waitcount = 0;
34         }
35 }
36
37
38 int FM7_MAINMEM::window_convert(uint32 addr, uint32 *realaddr)
39 {
40         uint32 raddr = addr;
41 #ifdef HAS_MMR
42         if((addr < 0x8000) && (addr >= 0x7c00) && (window_enabled)) {
43                 addr &= 0x03ff;
44                 raddr = ((window_offset << 8) + addr) & 0xffff;
45                 *realaddr = raddr;
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
50 #endif
51         }
52         // Window not hit.
53 #endif
54         return -1;
55 }
56
57 int FM7_MAINMEM::mmr_convert(uint32 addr, uint32 *realaddr)
58 {
59         uint32 raddr = 0;
60         uint8  mmr_segment;
61         uint8  mmr_bank;
62 #ifdef HAS_MMR
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.
67         
68 #if !defined(_FM77AV_VARIANTS)
69         mmr_bank &= 0x3f;
70 #endif
71         // Reallocated by MMR
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);
77         }
78   
79 #ifdef _FM77AV_VARIANTS
80         if(mmr_bank == 0x3f) {
81                 if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
82                         *realaddr = 0;
83                         return FM7_MAINMEM_NULL;
84                 }
85         }
86 #else
87         if((mmr_bank == 0x3f) && (addr >= 0xc00) && (addr < 0xe00)) {
88                 if(mainio->read_data8(FM7_MAINIO_IS_BASICROM) != 0) { // BASICROM enabled
89                         *realaddr = 0;
90                         return FM7_MAINMEM_ZERO;
91                 } else {
92                         *realaddr = addr & 0x1ff;
93                         return FM7_MAINMEM_SHADOWRAM;
94                 }
95         }
96 #endif
97         
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;
102         }
103         if((mmr_bank & 0xf0) == 0x10) { // PAGE 1
104                 *realaddr = (((uint32)mmr_bank & 0x0f) << 12) | raddr;
105                 return FM7_MAIMEM_DIRECTACCESS;
106         }
107         if((mmr_bank & 0xf0) == 0x20) { // PAGE 2
108                 uint32 dbank = mainio->read_data8(FM7_MAINIO_EXTBANK);
109                 switch(mmr_bank) {
110                         case 0x28:
111                         case 0x29: // Backuped RAM
112                                 if(((dbank & 0x80) != 0) && (dictrom_connected)){ // Battery backuped RAM
113                                         raddr =  raddr & 0x1ff;
114                                         *readladdr = raddr;
115                                         return FM7_MAINMEM_BACKUPED_RAM;
116                                 }
117                                 break;
118                         case 0x2e:
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.
123                                                 dbank = dbank << 12;
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) { 
130                                                 dbank = dbank << 12;
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;
140                                                 }
141                                                 *realaddr = raddr + 0x10000;
142                                                 return FM7_MAINMEM_77AV40_EXTRAROM;
143                                         }
144                                 }
145                                 break;
146                 }
147                 // RAM
148                 *realaddr = (raddr | (mmr_bank << 12)) & 0x0ffff;
149                 return FM7_MAINMEM_77AV_PAGE2;
150         }
151         if(extram_connected) { // PAGE 4-
152                 if((mmr_bank >> 4) >= (extram_pages + 4)) {
153                         *realaddr = 0;
154                         return FM7_MAINMEM_NULL; // $FF
155                 } else {
156                         raddr = ((uint32)mmr_bank << 12) | raddr;
157                         *realaddr = raddr;
158                         return FM7_MAINMEM_EXTRAM;
159                 }
160         } else {
161                 if(mmr_bank >= 0x40) {
162                         *realaddr = 0;
163                         return FM7_MAINMEM_NULL;
164                 }
165         }
166 #else // 77
167         // page 0 or 1 or 2.
168         if(extram_connected) {
169                 if((mmr_bank >> 4) >= extram_pages) {
170                         *realaddr = 0;
171                         return FM7_MAINMEM_NULL;
172                 } else { // EXTRAM Exists.
173                         raddr = (((uint32)mmr_bank << 12) & 0x3ffff) | raddr;
174                         *realaddr = raddr;
175                         return FM7_MAINMEM_EXTRAM;
176                 }
177         }
178 #endif
179 #endif
180         return -1;
181 }
182
183 int FM7_MAINMEM::nonmmr_convert(uint32 addr, uint32 *realaddr)
184 {
185         addr &= 0x0ffff;
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;
191                 }
192                 if(addr >= 0xfffe) {
193                         *realaddr = addr - 0xe000;
194                         return FM7_MAINMEM_INITROM;
195                 }
196         }
197 #endif  
198
199         if(addr < 0x8000) {
200                 *realaddr = addr - 0;
201                 return FM7_MAINMEM_OMOTE;
202         }
203         if(addr < 0xfc00) {
204                 *realaddr = addr - 0x8000;
205                 if(mainio->read_data8(FM7_MAINIO_READ_FD0F) != 0) {
206                    return FM7_MAINMEM_BASICROM;
207                 }
208                 return FM7_MAINMEM_URA;
209         }
210         if(addr < 0xfc80) {
211                 *realaddr = addr - 0xfc00;
212                 return FM7_MAINMEM_BIOSWORK;
213         }
214         if(addr < 0xfd00) {
215                 *realaddr = addr - 0xfc80;
216                 return FM7_MAINMEM_SHAREDRAM;
217         }
218         if(addr < 0xfe00) {
219                 wait();
220                 *realaddr = addr - 0xfd00;
221                 return FM7_MAINMEM_MMIO;
222         }
223         
224         if(addr < 0xffe0){
225                 wait();
226                 *realaddr = addr - 0xfe00;
227                 
228                 switch(mainio->read_data8(FM7_MAINIO_BOOTMODE)) {
229                         case 0:
230                                 return FM7_MAINMEM_BOOTROM_BAS;
231                                 break;
232                         case 1:
233                           //printf("BOOT_DOS ADDR=%04x\n", addr);
234                                 return FM7_MAINMEM_BOOTROM_DOS;
235                                 break;
236                         case 2:
237                                 return FM7_MAINMEM_BOOTROM_MMR;
238                                 break;
239                         case 4:
240                                 return FM7_MAINMEM_BOOTROM_RAM;
241                                 break;
242                         default:
243                                 return FM7_MAINMEM_BOOTROM_BAS; // Really?
244                                 break;
245                 }
246         }
247         if(addr < 0xfffe) { // VECTOR
248                 //printf("Main: VECTOR\n");
249                 *realaddr = addr - 0xffe0;
250                 return FM7_MAINMEM_VECTOR;
251         }
252         if(addr < 0x10000) {
253                 printf("Main: Reset\n");
254                 if(mainio->read_data8(FM7_MAINIO_BOOTMODE) == 4) {
255                         *realaddr = addr - 0xfe00;
256                         return FM7_MAINMEM_BOOTROM_RAM;
257                 }
258                 *realaddr = addr - 0xfffe;
259                 return FM7_MAINMEM_RESET_VECTOR;
260         }
261    
262       
263         *realaddr = addr;
264         return FM7_MAINMEM_NULL;
265 }
266      
267 int FM7_MAINMEM::getbank(uint32 addr, uint32 *realaddr)
268 {
269         if(realaddr == NULL) return FM7_MAINMEM_NULL; // Not effect.
270         addr = addr & 0xffff;
271 #ifdef HAS_MMR
272         if(mainio->read_data8(FM7_MAINIO_WINDOW_ENABLED) != 0) {
273                 int stat;
274                 uint32 raddr;
275                 stat = window_convert(addr, &raddr);
276                 if(stat >= 0) {
277                         *realaddr = raddr;
278                         return stat;
279                 }
280         }
281         if(mainio->read_data8(FM7_MAINIO_MMR_ENABLED) != 0) {
282                 int stat;
283                 uint32 raddr;
284                 stat = mmr_convert(addr, &raddr);
285                 if(stat >= 0) {
286                         *realaddr = raddr;
287                         return stat;
288                 }
289         }
290 #endif
291         // NOT MMR.
292         return nonmmr_convert(addr, realaddr);
293 }
294
295 uint32 FM7_MAINMEM::read_data8(uint32 addr)
296 {
297         uint32 ret;
298         uint32 realaddr;
299         int bank;
300
301         bank = getbank(addr, &realaddr);
302         if(bank < 0) return 0xff; // Illegal
303
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);
309         }
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?
314         }
315 #endif
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);
319         } else {
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];
323                 }
324                 return 0xff; // Dummy
325         }
326 }
327
328 void FM7_MAINMEM::write_data8(uint32 addr, uint32 data)
329 {
330         uint32 ret;
331         uint32 realaddr;
332         int bank;
333    
334         bank = getbank(addr, &realaddr);
335         if(bank < 0) return; // Illegal
336    
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?
340                 return;
341         } else if(bank == FM7_MAINMEM_MMIO) {
342                 mainio->write_data8(realaddr, (uint8)data);
343                 return;
344         }
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?
349                 return;
350         }
351 #endif
352         if(write_table[bank].dev != NULL) {
353                 write_table[bank].dev->write_data8(realaddr, data);
354         } else {
355                 if(write_table[bank].memory != NULL) {
356                   write_table[bank].memory[realaddr] = (uint8)(data & 0x000000ff);
357                 }
358         }
359 }
360
361 // Read / Write data(s) as big endian.
362 uint32 FM7_MAINMEM::read_data16(uint32 addr)
363 {
364         uint32 hi, lo;
365         uint32 val;
366    
367         hi = read_data8(addr) & 0xff;
368         lo = read_data8(addr + 1) & 0xff;
369    
370         val = hi * 256 + lo;
371         return val;
372 }
373
374 uint32 FM7_MAINMEM::read_data32(uint32 addr)
375 {
376         uint32 ah, a2, a3, al;
377         uint32 val;
378    
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;
383    
384         val = ah * (65536 * 256) + a2 * 65536 + a3 * 256 + al;
385         return val;
386 }
387
388 void FM7_MAINMEM::write_data16(uint32 addr, uint32 data)
389 {
390         uint32 d = data;
391    
392         write_data8(addr + 1, d & 0xff);
393         d = d / 256;
394         write_data8(addr + 0, d & 0xff);
395 }
396
397 void FM7_MAINMEM::write_data32(uint32 addr, uint32 data)
398 {
399         uint32 d = data;
400    
401         write_data8(addr + 3, d & 0xff);
402         d = d / 256;
403         write_data8(addr + 2, d & 0xff);
404         d = d / 256;
405         write_data8(addr + 1, d & 0xff);
406         d = d / 256;
407         write_data8(addr + 0, d & 0xff);
408 }
409
410
411 bool FM7_MAINMEM::get_loadstat_basicrom(void)
412 {
413         return diag_load_basicrom;
414 }
415
416 bool FM7_MAINMEM::get_loadstat_bootrom_bas(void)
417 {
418         return diag_load_bootrom_bas;
419 }
420
421 bool FM7_MAINMEM::get_loadstat_bootrom_dos(void)
422 {
423         return diag_load_bootrom_dos;
424 }
425
426 uint32 FM7_MAINMEM::read_bios(const char *name, uint8 *ptr, uint32 size)
427 {
428         FILEIO fio;
429         uint32 blocks;
430         _TCHAR *s;
431   
432         if((name == NULL) || (ptr == NULL))  return 0;
433         s = emu->bios_path((_TCHAR *)name);
434         if(s == NULL) return 0;
435   
436         if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
437         blocks = fio.Fread(ptr, size, 1);
438         fio.Fclose();
439
440         return blocks * size;
441 }
442
443 FM7_MAINMEM::FM7_MAINMEM(VM* parent_vm, EMU* parent_emu) : MEMORY(parent_vm, parent_emu)
444 {
445         int i;
446         p_vm = parent_vm;
447         p_emu = parent_emu;
448         for(i = 0; i < 4; i++) fm7_bootroms[i] = (uint8 *)malloc(0x200);
449 }
450
451 FM7_MAINMEM::~FM7_MAINMEM()
452 {
453         int i;
454         for(i = 0; i < 4; i++) {
455                 if(fm7_bootroms[i] != NULL) free(fm7_bootroms[i]);
456                 fm7_bootroms[i] = NULL;
457         }
458 }
459
460 void FM7_MAINMEM::initialize(void)
461 {
462         int i;
463         diag_load_basicrom = false;
464         diag_load_bootrom_bas = false;
465         diag_load_bootrom_dos = false;
466         diag_load_bootrom_mmr = false;
467
468         waitfactor = 2;
469         waitcount = 0;
470         ioaccess_wait = false;
471         
472         // Initialize table
473         // $0000-$7FFF
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;
480
481         // $8000-$FBFF
482         i = FM7_MAINMEM_URA;
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;
486
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;
492         
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;
497         
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;
502         
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;
507         
508         i = FM7_MAINMEM_KANJI_LEVEL1;
509         read_table[i].dev = kanjiclass1;
510         write_table[i].dev = kanjiclass1;
511                                    
512 #if defined(_FM77AV_VARIANTS)
513         i = FM7_MAINMEM_KANJI_LEVEL2;
514         read_table[i].dev = kanjiclass2;
515         write_table[i].dev = kanjiclass2;
516 #endif
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;
523         
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;
529         
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;
539                 }
540         }
541 # else
542         // 77AV Only
543 # endif
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;
548         }
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.
552         
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.
557 #else
558         // FM-7/77
559         if(read_bios("BOOT_BAS.ROM", fm7_bootroms[0], 0x200) >= 0x1e0) {
560                 diag_load_bootrom_bas = true;
561         } else {
562                 diag_load_bootrom_bas = false;
563                 //memset(fm7_bootroms[0], 0xff, 0x200);
564         }
565         if(read_bios("BOOT_DOS.ROM", fm7_bootroms[1], 0x200) >= 0x1e0) {
566                 diag_load_bootrom_dos = true;
567         } else {
568                 diag_load_bootrom_dos = false;
569                 //memset(fm7_bootroms[1], 0xff, 0x200);
570         }
571         
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;
575         } else {
576                 diag_load_bootrom_mmr = false;
577                 //memset(fm7_bootroms[2], 0xff, 0x200);
578         }
579         
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;
589                 }
590         }
591 #else
592         // FM-7
593         diag_load_bootrom_mmr = false;
594         memset(fm7_bootroms[2], 0xff, 0x200);
595 #endif
596
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;
601         }
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.
604 #else   
605         // FM-7/8
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;
609         }
610 #endif
611         
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;
616 #endif 
617         for(i = 0; i <= 3; i++) {
618                 uint8 *p = fm7_bootroms[i];
619                 p[0x1fe] = 0xfe; // Set reset vector.
620                 p[0x1ff] = 0x00; //
621         }
622         
623         i = FM7_MAINMEM_RESET_VECTOR;
624         fm7_mainmem_reset_vector[0] = 0xfe;
625         fm7_mainmem_reset_vector[1] = 0x00;
626    
627         read_table[i].memory = fm7_mainmem_reset_vector;
628         write_table[i].memory = NULL;
629    
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);
638    
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;
645         
646         i = FM7_MAINMEM_SHAREDRAM;
647         read_table[i].dev = display;
648         write_table[i].dev = display;
649         
650 #if defined(_FM77AV_VARIANTS)
651         i = FM7_MAINMEM_DIRECTACCESS;
652         read_table[i].dev = display;
653         write_table[i].dev = display;
654 #endif
655 }