OSDN Git Service

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