OSDN Git Service

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