OSDN Git Service

[VM][FM7] Write to URA-RAM even BASICROM enabled.Maybe only FM-7/NEW7.
[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         int i;
14         waitfactor = 0;
15         waitcount = 0;
16         ioaccess_wait = false;
17         sub_halted = (display->read_signal(SIG_DISPLAY_HALT) == 0) ? false : true;
18         //sub_halted = false;
19 #if defined(_FM77AV_VARIANTS)
20         memset(fm7_bootram, 0x00, 0x1f0);
21         if((config.boot_mode & 3) == 0) {
22                 memcpy(fm7_bootram, &fm7_mainmem_initrom[0x1800], 0x1e0 * sizeof(uint8));
23         } else {
24                 memcpy(fm7_bootram, &fm7_mainmem_initrom[0x1a00], 0x1e0 * sizeof(uint8));
25         }
26         fm7_bootram[0x1fe] = 0xfe; // Set reset vector.
27         fm7_bootram[0x1ff] = 0x00; //
28         initiator_enabled = true;
29         boot_ram_write = true;
30 #elif defined(_FM77_VARIANTS)
31         boot_ram_write = false;
32 #endif  
33         bootmode = config.boot_mode & 3;
34 #if defined(HAS_MMR)
35         if((config.dipswitch & FM7_DIPSW_EXTRAM) != 0) {
36                 extram_connected = true;
37         } else {
38                 extram_connected = false;
39         }
40 #endif
41 #if defined(_FM77AV_VARIANTS)
42         if(dictrom_connected) {
43                 use_page2_extram = true;
44         } else {
45                 use_page2_extram = ((config.dipswitch & FM7_DIPSW_EXTRAM_AV) != 0) ? true : false;
46         }
47 #endif   
48 #ifdef HAS_MMR
49         for(i = 0x00; i < 0x80; i++) {
50                 mmr_map_data[i] = 0;
51         }
52         mmr_segment = 0;
53         window_offset = 0;
54         mmr_enabled = false;
55         mmr_fast = false;
56         window_enabled = false;
57 #endif
58         if((bootmode & 0x03) == 0) { // IF BASIC BOOT THEN ROM
59                 basicrom_fd0f = true;
60         } else { // ELSE RAM
61                 basicrom_fd0f = false;
62         }
63         clockmode = (config.cpu_type == 0) ? true : false;
64         is_basicrom = ((bootmode & 0x03) == 0) ? true : false;
65 }
66
67
68
69 void FM7_MAINMEM::wait()
70 {
71         int waitfactor; // If MMR of TWR enabled, factor = 3.
72                             // If memory, factor = 2?
73         if(!clockmode) return; // SLOW
74 #ifdef HAS_MMR
75         if(!ioaccess_wait) {
76                 waitfactor = 2;
77                 ioaccess_wait = true;
78         } else { // Not MMR, TWR or enabled FAST MMR mode
79                 waitfactor = 3; // If(MMR or TWR) and NOT FAST MMR factor = 3, else factor = 2
80                 if(mmr_fast) waitfactor = 2;
81                 ioaccess_wait = false;
82         } 
83         if((window_enabled) &&
84            (mmr_enabled)) waitfactor = 2;
85 #else
86         waitfactor = 2;
87 #endif    
88         if(waitfactor <= 0) return;
89         waitcount++;
90         if(waitcount >= waitfactor) {
91                 if(maincpu != NULL) maincpu->set_extra_clock(1);
92                 waitcount = 0;
93         }
94 }
95
96
97 int FM7_MAINMEM::window_convert(uint32 addr, uint32 *realaddr)
98 {
99         uint32 raddr = addr;
100 #ifdef HAS_MMR
101         if((addr < 0x8000) && (addr >= 0x7c00)) {
102                 raddr = ((window_offset * 256) + addr) & 0x0ffff; 
103                 *realaddr = raddr;
104 #ifdef _FM77AV_VARIANTS
105                 //printf("TWR hit %04x -> %04x\n", addr, raddr);
106                 return FM7_MAINMEM_AV_PAGE0; // 0x00000 - 0x0ffff
107 #else // FM77(L4 or others)
108                 *realaddr |= 0x20000;
109                 return FM7_MAINMEM_EXTRAM; // 0x20000 - 0x2ffff
110 #endif
111         }
112         // Window not hit.
113 #endif
114         return -1;
115 }
116
117 int FM7_MAINMEM::mmr_convert(uint32 addr, uint32 *realaddr)
118 {
119         uint32  raddr = addr & 0x0fff;
120         uint32  mmr_bank;
121         uint32  major_bank;
122    
123 #ifdef HAS_MMR
124         if(addr >= 0xfc00) return -1;
125         mmr_bank = mmr_map_data[(addr >> 12) & 0x000f | (mmr_segment << 4)] & 0x007f;
126         
127         // Reallocated by MMR
128         // Bank 3x : Standard memories.
129         if((mmr_bank < 0x3f) && (mmr_bank >= 0x30)) {
130                 raddr = ((mmr_bank << 12) | raddr) & 0xffff;
131                 return nonmmr_convert(raddr, realaddr);
132         }
133 #ifdef _FM77AV_VARIANTS
134         else if(mmr_bank == 0x3f) {
135                 if((raddr >= 0xd80) && (raddr <= 0xd97)) { // MMR AREA
136                         *realaddr = 0;
137                         return FM7_MAINMEM_NULL;
138                 } else {
139                         raddr = raddr | 0xf000;
140                         return nonmmr_convert(raddr, realaddr); // Access I/O, Bootrom, even via MMR.
141                 }
142         }
143 #elif defined(_FM77_VARIANTS)
144         else if(mmr_bank == 0x3f) {
145                 if((raddr >= 0xc00) && (raddr < 0xe00)) {
146                         if(is_basicrom) {
147                                 *realaddr = 0;
148                                 return FM7_MAINMEM_ZERO;
149                         } else {
150                                 *realaddr = raddr - 0xc00;
151                                 return FM7_MAINMEM_SHADOWRAM;
152                         }
153                 } else if(raddr >= 0xe00) {
154                         *realaddr = addr - 0x0e00;
155                         if(is_basicrom) {
156                                 if(diag_load_bootrom_mmr) {
157                                         return FM7_MAINMEM_BOOTROM_MMR;
158                                 } else {
159                                         return FM7_MAINMEM_BOOTROM_BAS;
160                                 }
161                         } else {
162                                 return FM7_MAINMEM_BOOTROM_RAM;
163                         }
164                 } else {
165                         raddr = raddr | 0xf000;
166                         return nonmmr_convert(raddr, realaddr); // Access I/O, Bootrom, even via MMR.
167                 } 
168         }
169 #endif
170         major_bank = (mmr_bank >> 4) & 0x0f;
171     
172 #ifdef _FM77AV_VARIANTS
173         if(major_bank == 0x0) { // PAGE 0
174                 *realaddr = ((mmr_bank << 12) | raddr) & 0x0ffff;
175                 return FM7_MAINMEM_AV_PAGE0;
176         } else if(major_bank == 0x1) { // PAGE 1                
177                 *realaddr = ((mmr_bank << 12) | raddr) & 0x0ffff;
178                 return FM7_MAINMEM_AV_DIRECTACCESS;
179         } else  if(major_bank == 0x2) { // PAGE 2
180 #if defined(CAPABLE_DICTROM)
181                         //uint32 dbank = mainio->read_data8(FM7_MAINIO_EXTBANK);
182                         uint32 dbank = extbank;
183                         switch(mmr_bank) {
184                         case 0x28:
185                         case 0x29: // Backuped RAM
186                                 if(((dbank & 0x80) != 0) && (dictrom_connected)){ // Battery backuped RAM
187                                         raddr =  raddr & 0x1ff;
188                                         *realaddr = raddr;
189                                         return FM7_MAINMEM_BACKUPED_RAM;
190                                 }
191                                 break;
192                         case 0x2e:
193                                 if(((dbank & 0x40) != 0) && (dictrom_connected)) { // Dictionary ROM
194                                         dbank = dbank & 0x3f;
195                                         uint32 extrom = mainio->read_data8(FM7_MAINIO_EXTROM) & 0x80;
196                                         //uint32 extrom = extrom_bank;
197                                         if(extrom == 0) { // Dictionary selected.
198                                                 dbank = dbank << 12;
199                                                 *realaddr = raddr | dbank;
200                                                 return FM7_MAINMEM_DICTROM;
201                                         } else if(dbank <= 0x1f) { // KANJI
202                                                 *realaddr = (dbank << 12) | raddr;
203                                                 return FM7_MAINMEM_KANJI_LEVEL1;
204                                         } else if(dbank <= 0x37) { 
205                                                 dbank = dbank << 12;
206                                                 *realaddr = (dbank - 0x20000) | raddr;
207                                                 return FM7_MAINMEM_77AV40_EXTRAROM;
208                                         } else if(dbank <= 0x3f) {
209                                                 raddr = ((dbank << 12) - 0x30000) | raddr;
210                                                 if((raddr >= 0xffe0) || (raddr < 0xfd00)) { 
211                                                         return nonmmr_convert(raddr, realaddr);
212                                                 } else if((raddr >= 0xfe00) || (raddr < 0xffe0)) {
213                                                         *realaddr = raddr - 0xfe00;
214                                                         return FM7_MAINMEM_BOOTROM_DOS;
215                                                 }
216                                                 *realaddr = raddr + 0x10000;
217                                                 return FM7_MAINMEM_77AV40_EXTRAROM;
218                                         }
219                                 }
220                                 break;
221                         }
222                         *realaddr = (raddr | (mmr_bank << 12)) & 0x0ffff;
223                         return FM7_MAINMEM_AV_PAGE2;
224 #else
225                 //*realaddr = (raddr | (mmr_bank << 12)) & 0x0ffff;
226                 if(use_page2_extram) {
227                         *realaddr = ((mmr_bank << 12) | raddr) & 0x0ffff;
228                         return FM7_MAINMEM_AV_PAGE2;
229                 } else {
230                         *realaddr = 0;
231                         return FM7_MAINMEM_NULL;
232                 }
233 #endif
234         }
235 #endif
236 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
237         else if(extram_connected) { // PAGE 4-
238                 if(major_bank >= (extram_pages + 4)) {
239                         *realaddr = 0;
240                         return FM7_MAINMEM_NULL; // $FF
241                 } else {
242                         raddr = ((uint32)(mmr_bank - 0x40) << 12) | raddr;
243                         *realaddr = raddr;
244                         return FM7_MAINMEM_EXTRAM;
245                 }
246         } else {
247                 if(mmr_bank >= 0x40) {
248                         *realaddr = 0;
249                         return FM7_MAINMEM_NULL;
250                 }
251         }
252 #elif defined(_FM77_VARIANTS)
253         if(extram_connected) { // PAGE 4-
254                 if((major_bank > extram_pages) || (major_bank >= 3)) {
255                         *realaddr = 0;
256                         return FM7_MAINMEM_NULL; // $FF
257                 } else {
258                         raddr = ((uint32)mmr_bank << 12) | raddr;
259                         *realaddr = raddr;
260                         return FM7_MAINMEM_EXTRAM;
261                 }
262         } else {
263                 *realaddr = 0;
264                 return FM7_MAINMEM_NULL; // $FF
265         }
266 #else // _FM77AV_VARIANTS
267         if(major_bank > 3) {
268                 *realaddr = 0;
269                 return FM7_MAINMEM_NULL; // $FF
270         }
271 #endif
272 #endif // HAS_MMR
273         *realaddr = 0;
274         return -1;
275 }
276
277 int FM7_MAINMEM::nonmmr_convert(uint32 addr, uint32 *realaddr)
278 {
279         addr &= 0x0ffff;
280 #ifdef _FM77AV_VARIANTS
281         if(initiator_enabled) {
282                 if((addr >= 0x6000) && (addr < 0x8000)) {
283                     //printf("HIT %02x\n", read_table[FM7_MAINMEM_INITROM].memory[addr - 0x6000]);
284                         *realaddr = addr - 0x6000;
285                         return FM7_MAINMEM_INITROM;
286                 }
287                 if(addr >= 0xfffe) {
288                   //printf("HIT %02x\n", read_table[FM7_MAINMEM_INITROM].memory[addr - 0xe000]);
289                         *realaddr = addr - 0xe000;
290                         return FM7_MAINMEM_INITROM;
291                 }
292         }
293 #endif  
294 #if 1
295         uint32 addr_major, addr_minor;
296         addr_major = (addr >> 12) & 0x0f;
297
298         switch (addr_major) {
299         case 0x00:
300         case 0x01:
301         case 0x02:
302         case 0x03:
303         case 0x04:
304         case 0x05:
305         case 0x06:
306         case 0x07:
307                 *realaddr = addr;
308                 return FM7_MAINMEM_OMOTE;
309                 break;
310         case 0x08:
311         case 0x09:
312         case 0x0a:
313         case 0x0b:
314         case 0x0c:
315         case 0x0d:
316         case 0x0e:
317                 *realaddr = addr - 0x8000;
318                 if (basicrom_fd0f) {
319                         return FM7_MAINMEM_BASICROM;
320                 }
321                 return FM7_MAINMEM_URA;
322                 break;
323         case 0x0f:
324                 addr_minor = (addr >> 8) & 0x0f;
325                 switch (addr_minor){
326                 case 0x00:
327                 case 0x01:
328                 case 0x02:
329                 case 0x03:
330                 case 0x04:
331                 case 0x05:
332                 case 0x06:
333                 case 0x07:
334                 case 0x08:
335                 case 0x09:
336                 case 0x0a:
337                 case 0x0b:
338                         *realaddr = addr - 0x8000;
339                         if (basicrom_fd0f) {
340                                 return FM7_MAINMEM_BASICROM;
341                         }
342                         return FM7_MAINMEM_URA;
343                         break;
344                 case 0x0c:
345                         if (addr < 0xfc80) {
346                                 *realaddr = addr - 0xfc00;
347                                 return FM7_MAINMEM_BIOSWORK;
348                         }
349                         else {
350                                 *realaddr = addr - 0xfc80;
351                                 return FM7_MAINMEM_SHAREDRAM;
352                         }
353                         break;
354                 case 0x0d:
355                         wait();
356                         *realaddr = addr - 0xfd00;
357                         return FM7_MAINMEM_MMIO;
358                         break;
359                 default:
360                         if (addr < 0xffe0){
361                                 wait();
362                                 *realaddr = addr - 0xfe00;
363 #if defined(_FM77AV_VARIANTS)
364                                 return FM7_MAINMEM_BOOTROM_RAM;
365 #else
366                                 switch(bootmode) {
367                                 case 0:
368                                         return FM7_MAINMEM_BOOTROM_BAS;
369                                         break;
370                                 case 1:
371                                         //printf("BOOT_DOS ADDR=%04x\n", addr);
372                                         return FM7_MAINMEM_BOOTROM_DOS;
373                                         break;
374                                 case 2:
375                                         return FM7_MAINMEM_BOOTROM_MMR;
376                                         break;
377                                 case 3:
378                                         return FM7_MAINMEM_BOOTROM_EXTRA;
379                                         break;
380 #if defined(_FM77_VARIANTS)
381                                 case 4:
382                                         return FM7_MAINMEM_BOOTROM_RAM;
383                                         break;
384 #endif                          
385                                 default:
386                                         return FM7_MAINMEM_BOOTROM_BAS; // Really?
387                                         break;
388                                 }
389 #endif
390                         }
391                         else if (addr < 0xfffe) { // VECTOR
392                                 *realaddr = addr - 0xffe0;
393                                 return FM7_MAINMEM_VECTOR;
394                         }
395                         else if (addr < 0x10000) {
396                                 *realaddr = addr - 0xfffe;
397                                 return FM7_MAINMEM_RESET_VECTOR;
398                         }
399                         break;
400                 }
401                 break;
402         }
403 #else
404         if(addr < 0x8000) {
405                 *realaddr = addr;
406                 return FM7_MAINMEM_OMOTE;
407         } else if(addr < 0xfc00) {
408                 *realaddr = addr - 0x8000;
409                 if(basicrom_fd0f) {
410                         return FM7_MAINMEM_BASICROM;
411                 }
412                 return FM7_MAINMEM_URA;
413         } else  if(addr < 0xfc80) {
414                 *realaddr = addr - 0xfc00;
415                 return FM7_MAINMEM_BIOSWORK;
416         }else if(addr < 0xfd00) {
417                 *realaddr = addr - 0xfc80;
418                 return FM7_MAINMEM_SHAREDRAM;
419         } else if(addr < 0xfe00) {
420                 wait();
421                 *realaddr = addr - 0xfd00;
422                 return FM7_MAINMEM_MMIO;
423         }else if(addr < 0xffe0){
424                 wait();
425                 *realaddr = addr - 0xfe00;
426 #if defined(_FM77AV_VARIANTS)
427                 return FM7_MAINMEM_BOOTROM_RAM;
428 #else
429 #if defined(_FM77_VARIANTS)
430                 if(boot_ram_write) {
431                                 return FM7_MAINMEM_BOOTROM_RAM;
432                 }
433 #endif
434                 switch(bootmode) {
435                         case 0:
436                                 return FM7_MAINMEM_BOOTROM_BAS;
437                                 break;
438                         case 1:
439                           //printf("BOOT_DOS ADDR=%04x\n", addr);
440                                 return FM7_MAINMEM_BOOTROM_DOS;
441                                 break;
442                         case 2:
443                                 return FM7_MAINMEM_BOOTROM_MMR;
444                                 break;
445                         case 3:
446                                 return FM7_MAINMEM_BOOTROM_EXTRA;
447                                 break;
448                         default:
449                                 return FM7_MAINMEM_BOOTROM_BAS; // Really?
450                                 break;
451                 }
452 #endif
453         } else if(addr < 0xfffe) { // VECTOR
454                 *realaddr = addr - 0xffe0;
455                 return FM7_MAINMEM_VECTOR;
456         } else if(addr < 0x10000) {
457                 *realaddr = addr - 0xfffe;
458                 return FM7_MAINMEM_RESET_VECTOR;
459         }
460 #endif   
461         emu->out_debug_log("Main: Over run ADDR = %08x", addr);
462         *realaddr = addr;
463         return FM7_MAINMEM_NULL;
464 }
465      
466 int FM7_MAINMEM::getbank(uint32 addr, uint32 *realaddr)
467 {
468         if(realaddr == NULL) return FM7_MAINMEM_NULL; // Not effect.
469 #ifdef HAS_MMR
470         if(window_enabled) {
471                 int stat;
472                 uint32 raddr;
473                 stat = window_convert(addr, &raddr);
474                 //if(stat >= 0) printf("WINDOW CONVERT: %04x to %04x, bank = %02x\n", addr, raddr, stat);
475                 if(stat >= 0) {
476                         *realaddr = raddr;
477                         return stat;
478                 }
479         }
480         if(mmr_enabled) {
481                 int stat;
482                 uint32 raddr;
483                 stat = mmr_convert(addr, &raddr);
484                 if(stat >= 0) {
485                   //printf("MMR CONVERT: %04x to %05x, bank = %02x\n", addr, raddr, stat);
486                         *realaddr = raddr;
487                         return stat;
488                 }
489         }
490 #endif
491         addr = addr & 0xffff;
492         // NOT MMR.
493         return nonmmr_convert(addr, realaddr);
494 }
495
496 void FM7_MAINMEM::write_signal(int sigid, uint32 data, uint32 mask)
497 {
498         bool flag = ((data & mask) != 0);
499         switch(sigid) {
500                 case SIG_FM7_SUB_HALT:
501                         sub_halted = flag;
502                         break;
503                 case FM7_MAINIO_IS_BASICROM:
504                         is_basicrom = flag;
505                         break;
506                 case FM7_MAINIO_PUSH_FD0F:
507                         basicrom_fd0f = flag;
508                         break;
509                 case FM7_MAINIO_CLOCKMODE:
510                         clockmode = flag;
511                         break;
512                 case FM7_MAINIO_BOOTMODE:
513                         bootmode = data & 0x07;
514                         break;
515 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
516                 case FM7_MAINIO_BOOTRAM_RW:
517                         boot_ram_write = flag;
518                         
519                         break;
520 #endif                  
521 #ifdef _FM77AV_VARIANTS
522                 case FM7_MAINIO_INITROM_ENABLED:
523                         initiator_enabled = flag;
524                         break;
525                 case FM7_MAINIO_EXTBANK:
526                         extcard_bank = data & 0xff;
527                         break;
528                 case FM7_MAINIO_EXTROM:
529                         extrom_bank = data & 0xff;
530                         break;
531 #endif                  
532 #ifdef HAS_MMR                  
533                 case FM7_MAINIO_WINDOW_ENABLED:
534                         window_enabled = flag;
535                         break;
536                 case FM7_MAINIO_FASTMMR_ENABLED:
537                         mmr_fast = flag;
538                         break;
539                 case FM7_MAINIO_MMR_ENABLED:
540                         mmr_enabled = flag;
541                         break;
542 #endif                  
543         }
544 }
545
546
547 uint32 FM7_MAINMEM::read_data8(uint32 addr)
548 {
549         uint32 realaddr;
550         int bank;
551
552 #if defined(HAS_MMR)   
553         if(addr >= FM7_MAINIO_WINDOW_OFFSET) {
554                 switch(addr) {
555                 case FM7_MAINIO_WINDOW_OFFSET:
556                         return (uint32)window_offset;
557                         break;
558                 case FM7_MAINIO_MMR_SEGMENT:
559                         return (uint32)mmr_segment;
560                         break;
561                 default:
562                         if((addr >= FM7_MAINIO_MMR_BANK) && (addr < (FM7_MAINIO_MMR_BANK + 0x80))){
563                                 return mmr_map_data[addr - FM7_MAINIO_MMR_BANK];
564                         }
565                         break;
566                 }
567                 return;
568         }
569 #endif   
570         bank = getbank(addr, &realaddr);
571         if(bank < 0) {
572                 emu->out_debug_log("Illegal BANK: ADDR = %04x", addr);
573                 return 0xff; // Illegal
574         }
575         if(bank == FM7_MAINMEM_SHAREDRAM) {
576                 if(!sub_halted) return 0xff; // Not halt
577                 return display->read_data8(realaddr  + 0xd380); // Okay?
578         } else if(bank == FM7_MAINMEM_NULL) {
579                 return 0xff;
580         }
581 #if defined(_FM77AV_VARIANTS)
582         else if(bank == FM7_MAINMEM_AV_DIRECTACCESS) {
583                 if(!sub_halted) return 0xff; // Not halt
584                 return display->read_data8(realaddr); // Okay?
585         }
586 #endif
587         else if(read_table[bank].dev != NULL) {
588                 return read_table[bank].dev->read_data8(realaddr);
589         } else if(read_table[bank].memory != NULL) {
590                 return read_table[bank].memory[realaddr];
591         }
592         return 0xff; // Dummy
593 }
594
595 void FM7_MAINMEM::write_data8(uint32 addr, uint32 data)
596 {
597         uint32 realaddr;
598         int bank;
599 #if defined(HAS_MMR)   
600         if(addr >= FM7_MAINIO_WINDOW_OFFSET) {
601                 switch(addr) {
602                 case FM7_MAINIO_WINDOW_OFFSET:
603                         window_offset = data;
604                         break;
605                 case FM7_MAINIO_MMR_SEGMENT:
606                         mmr_segment = data & 0x0f;
607                         break;
608                 default:
609                         if((addr >= FM7_MAINIO_MMR_BANK) && (addr < (FM7_MAINIO_MMR_BANK + 0x80))){
610                                 mmr_map_data[addr - FM7_MAINIO_MMR_BANK] = (uint8)data;
611                         }
612                         break;
613                 }
614                 return;
615         }
616 #endif   
617         bank = getbank(addr, &realaddr);
618         if(bank < 0) {
619                 emu->out_debug_log("Illegal BANK: ADDR = %04x", addr);
620                 return; // Illegal
621         }
622         if(bank == FM7_MAINMEM_SHAREDRAM) {
623                 if(!sub_halted) return; // Not halt
624                 display->write_data8(realaddr + 0xd380, data); // Okay?
625                 return;
626         } else if(bank == FM7_MAINMEM_NULL) {
627                 return;
628         }
629 #if defined(_FM7) || defined(_FMNEW7)
630         else if(bank == FM7_MAINMEM_BASICROM) {
631                 bank = FM7_MAINMEM_URA; // FM-7/NEW7 write to ura-ram even enabled basic-rom. 
632         }
633 #endif   
634    
635 #if defined(_FM77AV_VARIANTS)
636         else if(bank == FM7_MAINMEM_AV_DIRECTACCESS) {
637                 if(!sub_halted) return; // Not halt
638                 display->write_data8(realaddr, data); // Okay?
639                 return;
640         }
641 #endif
642 #if defined(HAS_MMR)    
643         else if(bank == FM7_MAINMEM_BOOTROM_RAM) {
644                 if(!boot_ram_write) return;
645         }
646 #endif
647         if(write_table[bank].dev != NULL) {
648                 write_table[bank].dev->write_data8(realaddr, data);
649         } else if(write_table[bank].memory != NULL) {
650                 write_table[bank].memory[realaddr] = (uint8)data;
651         }
652 }
653
654 // Read / Write data(s) as big endian.
655 uint32 FM7_MAINMEM::read_data16(uint32 addr)
656 {
657         uint32 hi, lo;
658         uint32 val;
659    
660         hi = read_data8(addr) & 0xff;
661         lo = read_data8(addr + 1) & 0xff;
662    
663         val = hi * 256 + lo;
664         return val;
665 }
666
667 uint32 FM7_MAINMEM::read_data32(uint32 addr)
668 {
669         uint32 ah, a2, a3, al;
670         uint32 val;
671    
672         ah = read_data8(addr) & 0xff;
673         a2 = read_data8(addr + 1) & 0xff;
674         a3 = read_data8(addr + 2) & 0xff;
675         al = read_data8(addr + 3) & 0xff;
676    
677         val = ah * (65536 * 256) + a2 * 65536 + a3 * 256 + al;
678         return val;
679 }
680
681 void FM7_MAINMEM::write_data16(uint32 addr, uint32 data)
682 {
683         uint32 d = data;
684    
685         write_data8(addr + 1, d & 0xff);
686         d = d / 256;
687         write_data8(addr + 0, d & 0xff);
688 }
689
690 void FM7_MAINMEM::write_data32(uint32 addr, uint32 data)
691 {
692         uint32 d = data;
693    
694         write_data8(addr + 3, d & 0xff);
695         d = d / 256;
696         write_data8(addr + 2, d & 0xff);
697         d = d / 256;
698         write_data8(addr + 1, d & 0xff);
699         d = d / 256;
700         write_data8(addr + 0, d & 0xff);
701 }
702
703
704 bool FM7_MAINMEM::get_loadstat_basicrom(void)
705 {
706         return diag_load_basicrom;
707 }
708
709 bool FM7_MAINMEM::get_loadstat_bootrom_bas(void)
710 {
711         return diag_load_bootrom_bas;
712 }
713
714 bool FM7_MAINMEM::get_loadstat_bootrom_dos(void)
715 {
716         return diag_load_bootrom_dos;
717 }
718
719 uint32 FM7_MAINMEM::read_bios(const char *name, uint8 *ptr, uint32 size)
720 {
721         FILEIO fio;
722         uint32 blocks;
723         _TCHAR *s;
724   
725         if((name == NULL) || (ptr == NULL))  return 0;
726         s = emu->bios_path((_TCHAR *)name);
727         if(s == NULL) return 0;
728   
729         if(!fio.Fopen(s, FILEIO_READ_BINARY)) return 0;
730         blocks = fio.Fread(ptr, size, 1);
731         fio.Fclose();
732
733         return blocks * size;
734 }
735
736 uint32 FM7_MAINMEM::write_bios(const char *name, uint8 *ptr, uint32 size)
737 {
738         FILEIO fio;
739         uint32 blocks;
740         _TCHAR *s;
741   
742         if((name == NULL) || (ptr == NULL))  return 0;
743         s = emu->bios_path((_TCHAR *)name);
744         if(s == NULL) return 0;
745   
746         fio.Fopen(s, FILEIO_WRITE_BINARY);
747         blocks = fio.Fwrite(ptr, size, 1);
748         fio.Fclose();
749
750         return blocks * size;
751 }
752
753 FM7_MAINMEM::FM7_MAINMEM(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
754 {
755         p_vm = parent_vm;
756         p_emu = parent_emu;
757 #if !defined(_FM77AV_VARIANTS)
758         for(int i = 0; i < 4; i++) fm7_bootroms[i] = (uint8 *)malloc(0x200);
759 #endif  
760         mainio = NULL;
761         display = NULL;
762         maincpu = NULL;
763         kanjiclass1 = NULL;
764         kanjiclass2 = NULL;
765 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20) ||  defined(_FM77_VARIANTS)
766         fm7_mainmem_extram = NULL;
767 #endif  
768         // Initialize table
769         memset(read_table, 0x00, sizeof(read_table));
770         memset(write_table, 0x00, sizeof(write_table));
771 }
772
773 FM7_MAINMEM::~FM7_MAINMEM()
774 {
775 }
776
777 void FM7_MAINMEM::initialize(void)
778 {
779         int i;
780         diag_load_basicrom = false;
781         diag_load_bootrom_bas = false;
782         diag_load_bootrom_dos = false;
783         diag_load_bootrom_mmr = false;
784 #if defined(_FM77AV_VARIANTS)
785         dictrom_connected = false;
786 #endif
787 #ifdef HAS_MMR  
788         for(i = 0x00; i < 0x80; i++) {
789                 mmr_map_data[i] = 0;
790         }
791         mmr_segment = 0;
792         window_offset = 0;
793         mmr_enabled = false;
794         mmr_fast = false;
795         window_enabled = false;
796 #endif  
797 #ifdef _FM77AV_VARIANTS
798         extcard_bank = 0;
799         extrom_bank = 0;
800         initiator_enabled = true;
801         boot_ram_write = false;
802 #endif  
803         bootmode = config.boot_mode & 3;
804         basicrom_fd0f = false;
805         is_basicrom = ((bootmode & 0x03) == 0) ? true : false;
806    
807         // $0000-$7FFF
808         i = FM7_MAINMEM_OMOTE;
809         memset(fm7_mainmem_omote, 0x00, 0x8000 * sizeof(uint8));
810         read_table[i].memory = fm7_mainmem_omote;
811         write_table[i].memory = fm7_mainmem_omote;
812
813         // $8000-$FBFF
814         i = FM7_MAINMEM_URA;
815         memset(fm7_mainmem_ura, 0x00, 0x7c00 * sizeof(uint8));
816         read_table[i].memory = fm7_mainmem_ura;
817         write_table[i].memory = fm7_mainmem_ura;
818         
819         i = FM7_MAINMEM_VECTOR;
820         memset(fm7_mainmem_bootrom_vector, 0x00, 0x1e);
821         read_table[i].memory = fm7_mainmem_bootrom_vector;
822         write_table[i].memory = fm7_mainmem_bootrom_vector;
823         
824 #if defined(CAPABLE_DICTROM)
825         diag_load_dictrom = false;
826         i = FM7_MAINMEM_DICTROM;
827         memset(fm7_mainmem_extrarom, 0xff, 0x40000 * sizeof(uint8));
828         read_table[i].memory = fm7_mainmem_dictrom;
829         write_table[i].memory = NULL;
830         if(read_bios("DICROM.ROM", fm7_mainmem_dictrom, 0x40000) == 0x40000) diag_load_dictrom = true;
831         emu->out_debug_log("DICTIONARY ROM READING : %s", diag_load_dictrom ? "OK" : "NG");
832         dictrom_connected = diag_load_dictrom;
833         
834         i = FM7_MAINMEM_BACKUPED_RAM;
835         diag_load_learndata = false;
836         memset(fm7_mainmem_learndata, 0x00, 0x2000 * sizeof(uint8));
837         read_table[i].memory = fm7_mainmem_learndata;
838         write_table[i].memory = fm7_mainmem_learndata;
839         if(read_bios("USERDIC.DAT", read_table[i].memory, 0x2000) == 0x2000) diag_load_learndata = true;
840         emu->out_debug_log("DICTIONARY ROM READING : %s", diag_load_learndata ? "OK" : "NG");
841         if(!diag_load_learndata) write_bios("USERDIC.DAT", fm7_mainmem_learndata, 0x2000);
842 #endif
843         
844 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20)
845         i = FM7_MAINMEM_77AV40_EXTRAROM;
846         diag_load_extrarom = false;
847         memset(fm7_mainmem_extrarom, 0xff, 0x20000 * sizeof(uint8));
848         read_table[i].memory = fm7_mainmem_extrarom;
849         write_table[i].memory = NULL;
850         if(read_bios("EXTSUB.ROM", read_table[i].memory, 0xc000) >= 0xc000) diag_load_extrarom = true;
851         emu->out_debug_log("AV40 EXTRA ROM READING : %s", diag_load_extrarom ? "OK" : "NG");
852 #endif
853         
854 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20) || defined(_FM77_VARIANTS)
855         extram_pages = FM77_EXRAM_BANKS;
856 #if defined(_FM77_VARIANTS)
857         if(extram_pages > 3) extram_pages = 3;
858 #else
859         if(extram_pages > 12) extram_pages = 12;
860 #endif 
861         if(extram_pages > 0) {
862                 i = FM7_MAINMEM_EXTRAM;
863                 fm7_mainmem_extram = (uint8 *)malloc(extram_pages * 0x10000);
864                 if(fm7_mainmem_extram != NULL) {
865                         memset(fm7_mainmem_extram, 0x00, extram_pages * 0x10000);
866                         read_table[i].memory = fm7_mainmem_extram;
867                         write_table[i].memory = fm7_mainmem_extram;
868                 }
869         }
870 #endif  
871
872 #if defined(_FM77_VARIANTS)
873         memset(fm77_shadowram, 0x00, 0x200);
874         read_table[FM7_MAINMEM_SHADOWRAM].memory = fm77_shadowram;
875         write_table[FM7_MAINMEM_SHADOWRAM].memory = fm77_shadowram;
876 #endif
877 #if !defined(_FM77AV_VARIANTS)  
878         for(i = FM7_MAINMEM_BOOTROM_BAS; i <= FM7_MAINMEM_BOOTROM_EXTRA; i++) {
879                  memset(fm7_bootroms[i - FM7_MAINMEM_BOOTROM_BAS], 0xff, 0x200);
880                  read_table[i].memory = fm7_bootroms[i - FM7_MAINMEM_BOOTROM_BAS];
881                  write_table[i].memory = NULL;
882         }
883 #endif  
884 #if defined(_FM8)
885         if(read_bios("BOOT_BAS8.ROM", fm7_bootroms[0], 0x200) >= 0x1e0) {
886                 diag_load_bootrom_bas = true;
887         } else {
888                 diag_load_bootrom_bas = false;
889         }
890         if(read_bios("BOOT_DOS8.ROM", fm7_bootroms[1], 0x200) >= 0x1e0) {
891                 diag_load_bootrom_dos = true;
892         } else {
893                 diag_load_bootrom_dos = false;
894         }
895         diag_load_bootrom_mmr = false;
896 # elif defined(_FM7) || defined(_FMNEW7) || defined(_FM77_VARIANTS)
897         if(read_bios("BOOT_BAS.ROM", fm7_bootroms[0], 0x200) >= 0x1e0) {
898                 diag_load_bootrom_bas = true;
899         } else {
900                 diag_load_bootrom_bas = false;
901         }
902         if(read_bios("BOOT_DOS.ROM", fm7_bootroms[1], 0x200) >= 0x1e0) {
903                 diag_load_bootrom_dos = true;
904         } else {
905                 diag_load_bootrom_dos = false;
906         }
907 #  if defined(_FM77_VARIANTS)
908         if(read_bios("BOOT_MMR.ROM", fm7_bootroms[2], 0x200) >= 0x1e0) {
909                 diag_load_bootrom_mmr = true;
910         } else {
911                 diag_load_bootrom_mmr = false;
912         }
913    
914         i = FM7_MAINMEM_BOOTROM_RAM;
915         memset(fm7_bootram, 0x00, 0x200 * sizeof(uint8)); // RAM
916         read_table[i].memory = fm7_bootram;
917         write_table[i].memory = fm7_bootram;
918 #  else
919        // FM-7/8
920         diag_load_bootrom_mmr = false;
921 #  endif
922 # elif defined(_FM77AV_VARIANTS)
923         i = FM7_MAINMEM_AV_PAGE0;
924         memset(fm7_mainmem_mmrbank_0, 0x00, 0x10000 * sizeof(uint8));
925         read_table[i].memory = fm7_mainmem_mmrbank_0;
926         write_table[i].memory = fm7_mainmem_mmrbank_0;
927         
928         i = FM7_MAINMEM_AV_PAGE2;
929         memset(fm7_mainmem_mmrbank_2, 0x00, 0x10000 * sizeof(uint8));
930         read_table[i].memory = fm7_mainmem_mmrbank_2;
931         write_table[i].memory = fm7_mainmem_mmrbank_2;
932         
933         i = FM7_MAINMEM_INITROM;
934         diag_load_initrom = false;
935         memset(fm7_mainmem_initrom, 0xff, 0x2000 * sizeof(uint8));
936         read_table[i].memory = fm7_mainmem_initrom;
937         write_table[i].memory = NULL;
938         if(read_bios("INITIATE.ROM", read_table[i].memory, 0x2000) >= 0x2000) diag_load_initrom = true;
939         emu->out_debug_log("77AV INITIATOR ROM READING : %s", diag_load_initrom ? "OK" : "NG");
940
941         read_table[FM7_MAINMEM_BOOTROM_BAS].memory = NULL; // Not connected.
942         read_table[FM7_MAINMEM_BOOTROM_DOS].memory = NULL; // Not connected.
943         read_table[FM7_MAINMEM_BOOTROM_MMR].memory = NULL; // Not connected.
944
945         i = FM7_MAINMEM_BOOTROM_RAM;
946         memset(fm7_bootram, 0x00, 0x200 * sizeof(uint8)); // RAM
947         read_table[i].memory = fm7_bootram;
948         write_table[i].memory = fm7_bootram;
949         if(diag_load_initrom) diag_load_bootrom_bas = true;
950         if(diag_load_initrom) diag_load_bootrom_dos = true;
951         if((config.boot_mode & 0x03) == 0) {
952                 memcpy(fm7_bootram, &fm7_mainmem_initrom[0x1800], 0x1e0 * sizeof(uint8));
953         } else {
954                 memcpy(fm7_bootram, &fm7_mainmem_initrom[0x1a00], 0x1e0 * sizeof(uint8));
955         }
956         fm7_bootram[0x1fe] = 0xfe; // Set reset vector.
957         fm7_bootram[0x1ff] = 0x00; //
958         // FM-7
959 #endif
960         emu->out_debug_log("BOOT ROM (basic mode) READING : %s", diag_load_bootrom_bas ? "OK" : "NG");
961         emu->out_debug_log("BOOT ROM (DOS   mode) READING : %s", diag_load_bootrom_dos ? "OK" : "NG");
962 #if defined(_FM77_VARIANTS)
963         emu->out_debug_log("BOOT ROM (MMR   mode) READING : %s", diag_load_bootrom_mmr ? "OK" : "NG");
964 #endif
965
966         i = FM7_MAINMEM_VECTOR;
967         memset(fm7_mainmem_bootrom_vector, 0x00, 0x1e);
968         read_table[i].memory = fm7_mainmem_bootrom_vector;
969         write_table[i].memory = fm7_mainmem_bootrom_vector;
970
971 #if !defined(_FM77AV_VARIANTS)
972         for(i = 0; i <= 3; i++) {
973                 uint8 *p = fm7_bootroms[i];
974                 p[0x1fe] = 0xfe; // Set reset vector.
975                 p[0x1ff] = 0x00; //
976         }
977 #endif  
978         i = FM7_MAINMEM_RESET_VECTOR;
979         fm7_mainmem_reset_vector[0] = 0xfe;
980         fm7_mainmem_reset_vector[1] = 0x00;
981    
982         read_table[i].memory = fm7_mainmem_reset_vector;
983         write_table[i].memory = NULL;
984    
985         i = FM7_MAINMEM_BASICROM;
986         memset(fm7_mainmem_basicrom, 0xff, 0x7c00 * sizeof(uint8));
987         read_table[i].dev = NULL;
988         read_table[i].memory = fm7_mainmem_basicrom;
989         write_table[i].dev = NULL;
990         write_table[i].memory = NULL;
991 #if !defined(_FM8)
992         if(read_bios("FBASIC302.ROM", fm7_mainmem_basicrom, 0x7c00) == 0x7c00) {
993                 diag_load_basicrom = true;
994         } else if(read_bios("FBASIC300.ROM", fm7_mainmem_basicrom, 0x7c00) == 0x7c00) {
995                 diag_load_basicrom = true;
996         } else if(read_bios("FBASIC30.ROM", fm7_mainmem_basicrom, 0x7c00) == 0x7c00) {
997                 diag_load_basicrom = true;
998         }
999    
1000 #else // FM8
1001         if(read_bios("FBASIC10.ROM", fm7_mainmem_basicrom, 0x7c00) == 0x7c00) diag_load_basicrom = true;
1002 #endif  
1003         emu->out_debug_log("BASIC ROM READING : %s", diag_load_basicrom ? "OK" : "NG");
1004    
1005         i = FM7_MAINMEM_BIOSWORK;
1006         memset(fm7_mainmem_bioswork, 0x00, 0x80 * sizeof(uint8));
1007         read_table[i].dev = NULL;
1008         read_table[i].memory = fm7_mainmem_bioswork;
1009         write_table[i].dev = NULL;
1010         write_table[i].memory = fm7_mainmem_bioswork;
1011 }
1012
1013 void FM7_MAINMEM::release()
1014 {
1015 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20) || defined(_FM77_VARIANTS)
1016         if(fm7_mainmem_extram != NULL) free(fm7_mainmem_extram);
1017 #endif  
1018 #if !defined(_FM77AV_VARIANTS)
1019         int i;
1020         for(i = 0; i < 4; i++) {
1021                 if(fm7_bootroms[i] != NULL) free(fm7_bootroms[i]);
1022                 fm7_bootroms[i] = NULL;
1023         }
1024 #endif
1025 //      MEMORY::release();
1026 }
1027
1028 #define STATE_VERSION 2
1029 void FM7_MAINMEM::save_state(FILEIO *state_fio)
1030 {
1031         state_fio->FputUint32_BE(STATE_VERSION);
1032         state_fio->FputInt32_BE(this_device_id);
1033
1034         // V1
1035         state_fio->FputBool(ioaccess_wait);
1036         state_fio->FputInt32_BE(waitfactor);
1037         state_fio->FputInt32_BE(waitcount);
1038
1039         state_fio->FputBool(sub_halted);
1040         
1041         state_fio->FputBool(diag_load_basicrom);
1042         state_fio->FputBool(diag_load_bootrom_bas);
1043         state_fio->FputBool(diag_load_bootrom_dos);
1044         state_fio->FputBool(diag_load_bootrom_mmr);
1045         state_fio->Fwrite(fm7_mainmem_omote, sizeof(fm7_mainmem_omote), 1);
1046         state_fio->Fwrite(fm7_mainmem_ura, sizeof(fm7_mainmem_ura), 1);
1047         state_fio->Fwrite(fm7_mainmem_basicrom, sizeof(fm7_mainmem_basicrom), 1);
1048         state_fio->Fwrite(fm7_mainmem_bioswork, sizeof(fm7_mainmem_bioswork), 1);
1049         state_fio->Fwrite(fm7_mainmem_bootrom_vector, sizeof(fm7_mainmem_bootrom_vector), 1);
1050         state_fio->Fwrite(fm7_mainmem_reset_vector, sizeof(fm7_mainmem_reset_vector), 1);
1051         
1052         state_fio->Fwrite(fm7_mainmem_null, sizeof(fm7_mainmem_null), 1);
1053 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
1054         state_fio->Fwrite(fm7_bootram, sizeof(fm7_bootram), 1);
1055 #endif  
1056 #if !defined(_FM77AV_VARIANTS)
1057         int addr;
1058         for(addr = 0; addr < 4; addr++) state_fio->Fwrite(fm7_bootroms[addr], sizeof(0x200), 1);
1059 #endif  
1060 #ifdef _FM77AV_VARIANTS
1061         state_fio->FputBool(dictrom_connected);
1062         state_fio->FputBool(use_page2_extram);
1063         
1064         state_fio->FputBool(diag_load_initrom);
1065         state_fio->FputBool(diag_load_dictrom);
1066         state_fio->FputBool(diag_load_learndata);
1067         state_fio->Fwrite(fm7_mainmem_initrom, sizeof(fm7_mainmem_initrom), 1);
1068         state_fio->Fwrite(fm7_mainmem_mmrbank_0, sizeof(fm7_mainmem_mmrbank_0), 1);
1069         state_fio->Fwrite(fm7_mainmem_mmrbank_2, sizeof(fm7_mainmem_mmrbank_2), 1);
1070         
1071 # if defined(CAPABLE_DICTROM)
1072         state_fio->FputBool(diag_load_extrarom);
1073         state_fio->Fwrite(fm7_mainmem_extrarom, sizeof(fm7_mainmem_extrarom), 1);
1074         state_fio->Fwrite(fm7_mainmem_dictrom, sizeof(fm7_mainmem_dictrom), 1);
1075         state_fio->Fwrite(fm7_mainmem_learndata, sizeof(fm7_mainmem_learndata), 1);
1076 # endif
1077 #endif
1078         
1079 #ifdef HAS_MMR
1080         state_fio->FputBool(extram_connected);
1081 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20) || defined(_FM77_VARIANTS)
1082         int pages;
1083         state_fio->FputInt32_BE(extram_pages);
1084         pages = extram_pages;
1085 #  if defined(_FM77_VARIANTS)
1086         if(pages > 3) pages = 3;
1087 #  else
1088         if(pages > 12) pages = 12;
1089 #  endif        
1090         if(pages > 0) state_fio->Fwrite(fm7_mainmem_extram, pages * 0x10000, 1);
1091 #  if defined(_FM77_VARIANTS)
1092         state_fio->Fwrite(fm77_shadowram, sizeof(fm77_shadowram), 1);
1093 #  endif
1094 # endif
1095 #endif
1096         
1097         { // V2;
1098                 state_fio->FputBool(is_basicrom);
1099                 state_fio->FputBool(clockmode);
1100                 state_fio->FputBool(basicrom_fd0f);
1101                 state_fio->FputUint32_BE(bootmode);
1102 #if defined(_FM77AV_VARIANTS)
1103                 state_fio->FputUint32_BE(extcard_bank);
1104                 state_fio->FputUint32_BE(extrom_bank);
1105                 state_fio->FputBool(initiator_enabled);
1106 #endif
1107 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
1108                 state_fio->FputBool(boot_ram_write);
1109 #endif          
1110 #if defined(HAS_MMR)
1111                 state_fio->FputBool(window_enabled);
1112                 state_fio->FputBool(mmr_enabled);
1113                 state_fio->FputBool(mmr_fast);
1114                 state_fio->FputUint16_BE(window_offset);
1115                 state_fio->FputUint8(mmr_segment);
1116                 state_fio->Fwrite(mmr_map_data, sizeof(mmr_map_data), 1);
1117 #endif
1118         }
1119 }
1120
1121 bool FM7_MAINMEM::load_state(FILEIO *state_fio)
1122 {
1123         bool stat = false;
1124         uint32 version;
1125         version = state_fio->FgetUint32_BE();
1126         if(this_device_id != state_fio->FgetInt32_BE()) return false;
1127         if(version >= 1) {
1128                 // V1
1129                 ioaccess_wait = state_fio->FgetBool();
1130                 waitfactor = state_fio->FgetInt32_BE();
1131                 waitcount = state_fio->FgetInt32_BE();
1132
1133                 sub_halted = state_fio->FgetBool();
1134         
1135                 diag_load_basicrom = state_fio->FgetBool();
1136                 diag_load_bootrom_bas = state_fio->FgetBool();
1137                 diag_load_bootrom_dos = state_fio->FgetBool();
1138                 diag_load_bootrom_mmr = state_fio->FgetBool();
1139                 
1140                 state_fio->Fread(fm7_mainmem_omote, sizeof(fm7_mainmem_omote), 1);
1141                 state_fio->Fread(fm7_mainmem_ura, sizeof(fm7_mainmem_ura), 1);
1142                 state_fio->Fread(fm7_mainmem_basicrom, sizeof(fm7_mainmem_basicrom), 1);
1143                 state_fio->Fread(fm7_mainmem_bioswork, sizeof(fm7_mainmem_bioswork), 1);
1144                 state_fio->Fread(fm7_mainmem_bootrom_vector, sizeof(fm7_mainmem_bootrom_vector), 1);
1145                 state_fio->Fread(fm7_mainmem_reset_vector, sizeof(fm7_mainmem_reset_vector), 1);
1146         
1147                 state_fio->Fread(fm7_mainmem_null, sizeof(fm7_mainmem_null), 1);
1148 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
1149                 state_fio->Fread(fm7_bootram, sizeof(fm7_bootram), 1);
1150 #endif  
1151 #if !defined(_FM77AV_VARIANTS)
1152                 int addr;
1153                 for(addr = 0; addr < 4; addr++) state_fio->Fread(fm7_bootroms[addr], sizeof(0x200), 1);
1154 #endif  
1155 #ifdef _FM77AV_VARIANTS
1156                 dictrom_connected = state_fio->FgetBool();
1157                 use_page2_extram = state_fio->FgetBool();
1158         
1159                 diag_load_initrom = state_fio->FgetBool();
1160                 diag_load_dictrom = state_fio->FgetBool();
1161                 diag_load_learndata = state_fio->FgetBool();
1162                 state_fio->Fread(fm7_mainmem_initrom, sizeof(fm7_mainmem_initrom), 1);
1163                 state_fio->Fread(fm7_mainmem_mmrbank_0, sizeof(fm7_mainmem_mmrbank_0), 1);
1164                 state_fio->Fread(fm7_mainmem_mmrbank_2, sizeof(fm7_mainmem_mmrbank_2), 1);
1165         
1166 # if defined(CAPABLE_DICTROM)
1167                 diag_load_extrarom = state_fio->FgetBool();
1168                 state_fio->Fread(fm7_mainmem_extrarom, sizeof(fm7_mainmem_extrarom), 1);
1169                 state_fio->Fread(fm7_mainmem_dictrom, sizeof(fm7_mainmem_dictrom), 1);
1170                 state_fio->Fread(fm7_mainmem_learndata, sizeof(fm7_mainmem_learndata), 1);
1171 # endif
1172 #endif
1173         
1174 #ifdef HAS_MMR
1175                 extram_connected = state_fio->FgetBool();
1176 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20) || defined(_FM77_VARIANTS)
1177                 int pages;
1178                 extram_pages = state_fio->FgetInt32_BE();
1179                 pages = extram_pages;
1180 #  if defined(_FM77_VARIANTS)
1181                 if(pages > 3) pages = 3;
1182 #  else
1183                 if(pages > 12) pages = 12;
1184 #  endif        
1185                 if(pages > 0) state_fio->Fread(fm7_mainmem_extram, pages * 0x10000, 1);
1186 #  if defined(_FM77_VARIANTS)
1187                 state_fio->Fread(fm77_shadowram, sizeof(fm77_shadowram), 1);
1188 #  endif
1189 # endif
1190 #endif
1191                 if(version == 1) return true;
1192         }
1193         if(version >= 2) { // V2;
1194                 is_basicrom = state_fio->FgetBool();
1195                 clockmode = state_fio->FgetBool();
1196                 basicrom_fd0f = state_fio->FgetBool();
1197                 bootmode = state_fio->FgetUint32_BE();
1198 #if defined(_FM77AV_VARIANTS)
1199                 extcard_bank = state_fio->FgetUint32_BE();
1200                 extrom_bank = state_fio->FgetUint32_BE();
1201                 initiator_enabled = state_fio->FgetBool();
1202 #endif
1203 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
1204                 boot_ram_write = state_fio->FgetBool();
1205 #endif          
1206 #if defined(HAS_MMR)
1207                 window_enabled = state_fio->FgetBool();
1208                 mmr_enabled = state_fio->FgetBool();
1209                 mmr_fast = state_fio->FgetBool();
1210                 window_offset = state_fio->FgetUint16_BE();
1211                 mmr_segment = state_fio->FgetUint8();
1212                 state_fio->Fread(mmr_map_data, sizeof(mmr_map_data), 1);
1213 #endif
1214         }
1215         return true;
1216 }