OSDN Git Service

0f79bafcbb169fffdad70f530a6dbf2521b82b85
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / fm7_mainmem.cpp
1 /*
2  * Main memory MMR for FM-7 [FM7_MAINMEM]
3  *  Author: K.Ohta
4  *  Date  : 2015.01.01-
5  *  License: GPLv2
6  *
7  */
8 #include "vm.h"
9 #include "emu.h"
10 #include "fm7_mainmem.h"
11 #include "fm7_mainio.h"
12 #include "fm7_display.h"
13 #if defined(CAPABLE_DICTROM)
14 #include "kanjirom.h"
15 #endif
16 FM7_MAINMEM::FM7_MAINMEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
17 {
18 #if !defined(_FM77AV_VARIANTS)
19         for(int i = 0; i < 8; i++) fm7_bootroms[i] = (uint8_t *)malloc(0x200);
20 #endif
21         mainio = NULL;
22         display = NULL;
23         maincpu = NULL;
24 #if defined(CAPABLE_DICTROM)
25         kanjiclass1 = NULL;
26 #endif  
27 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)  || \
28     defined(_FM77_VARIANTS)
29         fm7_mainmem_extram = NULL;
30 #endif
31         cpu_clocks = CPU_CLOCKS;
32         // Initialize table
33         set_device_name(_T("MAIN MEMORY"));
34 }
35
36 FM7_MAINMEM::~FM7_MAINMEM()
37 {
38 #if !defined(_FM77AV_VARIANTS)
39         for(int i = 0; i < 8; i++) if(fm7_bootroms[i] != NULL) free(fm7_bootroms[i]);
40 #endif
41 }
42
43 void FM7_MAINMEM::reset()
44 {
45         waitfactor = 0;
46         waitcount = 0;
47         mem_waitfactor = 0;
48         mem_waitcount = 0;
49         ioaccess_wait = false;
50         sub_halted = (display->read_signal(SIG_DISPLAY_HALT) == 0) ? false : true;
51         //sub_halted = false;
52         memset(fm7_mainmem_bootrom_vector, 0x00, 0x10); // Clear without vector
53
54 #if defined(_FM77AV_VARIANTS)
55         memset(fm7_bootram, 0x00, 0x1f0);
56         initiator_enabled = true;
57         boot_ram_write = true;
58 #elif defined(_FM77_VARIANTS)
59         boot_ram_write = false;
60 #endif
61 #if defined(_FM77_VARIANTS) || defined(_FM8)
62         bootmode = config.boot_mode & 7;
63 #else
64         bootmode = config.boot_mode & 3;
65 #endif
66 #if defined(HAS_MMR)
67         if((config.dipswitch & FM7_DIPSW_EXTRAM) != 0) {
68                 extram_connected = true;
69         } else {
70                 extram_connected = false;
71         }
72 #endif
73 #if defined(_FM77AV_VARIANTS)
74         if(dictrom_connected) {
75                 use_page2_extram = true;
76         } else {
77                 use_page2_extram = ((config.dipswitch & FM7_DIPSW_EXTRAM_AV) != 0) ? true : false;
78         }
79 #endif   
80 #ifdef HAS_MMR
81         mmr_extend = false;
82         mmr_segment = 0;
83         window_offset = 0;
84         mmr_enabled = false;
85         mmr_fast = false;
86         window_enabled = false;
87         window_fast = false;
88         refresh_fast = false;
89 #endif
90         if((bootmode & 0x03) == 0) { // IF BASIC BOOT THEN ROM
91                 basicrom_fd0f = true;
92         } else { // ELSE RAM
93                 basicrom_fd0f = false;
94         }
95         clockmode = (config.cpu_type == 0) ? true : false;
96         is_basicrom = ((bootmode & 0x03) == 0) ? true : false;
97         setclock(clockmode ? 0 : 1);
98         init_data_table();
99         update_all_mmr_jumptable();
100         maincpu->reset();
101 }
102
103
104 void FM7_MAINMEM::setclock(int mode)
105 {
106         uint32_t clock = MAINCLOCK_SLOW;
107         if(mode == 1) { // SLOW
108                 clock = MAINCLOCK_SLOW; // Temporally
109 #if defined(HAS_MMR)            
110                 if(!mmr_fast && !window_fast) {
111                         if(refresh_fast) {
112                                 if(mmr_enabled || window_enabled) {
113                                         clock = (uint32_t)((double)clock * 1.089);
114                                 } else {
115                                         clock = (uint32_t)((double)clock * 1.086);
116                                 }                                       
117                         }
118                 }
119 #endif          
120         } else {
121 #if defined(HAS_MMR)
122 #  if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
123                 // Thanks to Ryu Takegami, around DRAM refresh.
124                 // DRAM refresh makes halting MAIN MPU per 13.02uS.
125                 if(!mmr_fast && !window_fast) { // SLOW
126                         if(refresh_fast) {
127                                 clock = MAINCLOCK_FAST_MMR - ((100000000 / 1302) * 1);  // Fast Refresh: 1wait
128                         } else {
129                                 clock = MAINCLOCK_FAST_MMR - ((100000000 / 1302) * 3);  // Slow Refresh: 3Wait(!)
130                         }                               
131                         if(mmr_enabled || window_enabled) {
132                                 clock = (uint32_t)((double)clock * 0.87);
133                         }                                       
134                 } else {
135                         clock = MAINCLOCK_FAST_MMR;
136                         //if(!(mmr_enabled) && !(window_enabled)) clock = MAINCLOCK_NORMAL;
137                 }
138 #  else
139                 if(mmr_enabled || window_enabled) {
140                         clock = MAINCLOCK_MMR;
141                 } else {
142                         clock = MAINCLOCK_NORMAL;
143                 }
144 #  endif
145 #else
146                 clock = MAINCLOCK_NORMAL;
147 #endif                          
148         }
149         //mem_waitcount = 0;
150         uint32_t before_waitfactor = mem_waitfactor;
151         if(CPU_CLOCKS > clock) {
152                 mem_waitfactor = (uint32_t)(65536.0 * ((1.0 - (double)clock / (double)CPU_CLOCKS)));
153                 //out_debug_log(_T("CLOCK=%d WAIT FACTOR=%d"), clock, mem_waitfactor);
154         } else {
155                 mem_waitfactor = 0;
156                 //out_debug_log(_T("CLOCK=%d WAIT FACTOR=%d"), clock, mem_waitfactor);
157         }
158         cpu_clocks = clock;
159         // Below is ugly hack cause of CPU#0 cannot modify clock.
160         if(before_waitfactor != mem_waitfactor) maincpu->write_signal(SIG_CPU_WAIT_FACTOR, mem_waitfactor, 0xffffffff);
161 }
162                 
163
164 void FM7_MAINMEM::iowait()
165 {
166         int _waitfactor = 0;
167         if(config.cpu_type == 1) return; // SLOW
168 #ifdef HAS_MMR
169         if((window_enabled) || (mmr_enabled)) {
170                 if(!ioaccess_wait) {
171                         _waitfactor = 2;
172                 } else { // Not MMR, TWR or enabled FAST MMR mode
173                         _waitfactor = 3; // If(MMR or TWR) and NOT FAST MMR factor = 3, else factor = 2
174                         if(mmr_fast) _waitfactor = 2;
175                 }
176         } else {
177                 _waitfactor = 2;
178         }
179 #else
180         _waitfactor = 2;
181 #endif    
182         if(_waitfactor <= 0) return;
183         waitcount++;
184         if(waitcount >= _waitfactor) {
185                 maincpu->set_extra_clock(1);
186                 waitcount = 0;
187                 ioaccess_wait = !ioaccess_wait;
188         }
189 }
190
191
192
193 int FM7_MAINMEM::check_extrom(uint32_t raddr, uint32_t *realaddr)
194 {
195 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
196         if(extrom_bank) { // Extra ROM selected.
197                 uint32_t dbank = extcard_bank & 0x3f;
198                 if(dbank < 0x20) { // KANJI
199                         if((dbank == 0x07) || (dbank == 0x06)) {
200                                 // NOT KANJI AS IS.Thanks Ryu.
201                                 *realaddr = raddr & 0x01;
202                                 return FM7_MAINMEM_KANJI_DUMMYADDR;
203                         }
204                         *realaddr = (dbank << 12) | raddr;
205                         return FM7_MAINMEM_KANJI_LEVEL1;
206                 } else if(dbank < 0x2c) {
207                         raddr = ((dbank << 12) - 0x20000) | raddr;
208                         *realaddr = raddr;
209                         return FM7_MAINMEM_77AV40_EXTRAROM;
210                 } else if(dbank < 0x30) {
211                         *realaddr = 0;
212                         return FM7_MAINMEM_NULL;
213                 } else {
214                         raddr = ((dbank << 12) - 0x30000) | raddr;
215                         if((raddr >= 0x8000)  && (raddr < 0xfc00)) {
216                                 *realaddr = raddr - 0x8000;
217                                 return FM7_MAINMEM_BASICROM;
218                         } else if((raddr >= 0xfe00) && (raddr < 0xffe0)) {
219                                 *realaddr = raddr - 0xfe00;
220                                 return FM7_MAINMEM_BOOTROM_MMR;
221                         } else if(raddr >= 0xfffe) {
222                                 *realaddr = raddr - 0xfffe;
223                                 return FM7_MAINMEM_RESET_VECTOR;
224                         }
225                         //*realaddr = raddr + 0x10000;
226                         //return FM7_MAINMEM_77AV40_EXTRAROM;
227                         *realaddr = 0;
228                         return FM7_MAINMEM_NULL;
229                 }
230         }
231 #endif  
232         return -1;
233 }
234
235
236 uint32_t FM7_MAINMEM::read_signal(int sigid)
237 {
238         uint32_t value = 0x00000000;
239         switch(sigid) {
240         case FM7_MAINIO_PUSH_FD0F:
241                 value = (basicrom_fd0f) ? 0xffffffff : 0x00000000;
242                 break;
243         case FM7_MAINIO_IS_BASICROM:
244                 value = (is_basicrom) ? 0xffffffff : 0x00000000;
245                 break;
246         case FM7_MAINIO_CLOCKMODE:
247                 value = (clockmode) ? 0xffffffff : 0x00000000;
248                 break;
249         case FM7_MAINIO_BOOTMODE:
250                 value = (uint32_t)bootmode & 0x07;
251                 break;
252 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
253         case FM7_MAINIO_BOOTRAM_RW:
254                 value = (boot_ram_write) ? 0xffffffff : 0x00000000;
255                 break;
256 #endif                  
257 #ifdef HAS_MMR                  
258         case FM7_MAINIO_WINDOW_ENABLED:
259                 value = (window_enabled) ? 0xffffffff : 0x00000000;
260                 break;
261         case FM7_MAINIO_WINDOW_FAST:
262                 value = (window_fast) ? 0xffffffff : 0x00000000;
263                 break;
264         case FM7_MAINIO_FASTMMR_ENABLED:
265                 value = (mmr_fast) ? 0xffffffff : 0x00000000;
266                 break;
267         case FM7_MAINIO_MMR_ENABLED:
268                 value = (mmr_enabled) ? 0xffffffff : 0x00000000;
269                 break;
270         case FM7_MAINIO_MMR_EXTENDED:
271                 value = (mmr_extend) ? 0xffffffff : 0x00000000;
272                 break;
273         case FM7_MAINIO_MEM_REFRESH_FAST:
274                 value = (refresh_fast) ? 0xffffffff : 0x00000000;
275                 break;
276 #endif                  
277 #if defined(_FM77AV_VARIANTS)
278         case FM7_MAINIO_INITROM_ENABLED:
279                 value = (initiator_enabled) ? 0xffffffff: 0x00000000;
280                 break;
281 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)          
282         case FM7_MAINIO_EXTROM:
283                 value = (extrom_bank) ? 0xffffffff: 0x00000000;
284                 break;
285 # endif    
286         case FM7_MAINIO_EXTBANK:
287                 value = extcard_bank & 0x3f;
288                 value |= (dictram_enabled) ? 0x80 : 0;
289                 value |= (dictrom_enabled) ? 0x40 : 0;
290                 break;
291 #endif
292         }
293         return value;
294 }
295
296
297 void FM7_MAINMEM::write_signal(int sigid, uint32_t data, uint32_t mask)
298 {
299         bool flag = ((data & mask) != 0);
300         switch(sigid) {
301                 case SIG_FM7_SUB_HALT:
302                         sub_halted = flag;
303                         break;
304                 case FM7_MAINIO_IS_BASICROM:
305                         is_basicrom = flag;
306                         break;
307                 case FM7_MAINIO_PUSH_FD0F:
308                         basicrom_fd0f = flag;
309                         break;
310                 case FM7_MAINIO_CLOCKMODE:
311                         clockmode = flag;
312                         setclock(clockmode ? 0 : 1);
313                         break;
314                 case FM7_MAINIO_BOOTMODE:
315                         bootmode = data & 0x07;
316                         break;
317 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
318                 case FM7_MAINIO_BOOTRAM_RW:
319                         boot_ram_write = flag;
320                         break;
321 #endif                  
322 #ifdef _FM77AV_VARIANTS
323                 case FM7_MAINIO_INITROM_ENABLED:
324                         initiator_enabled = flag;
325                         break;
326                 case FM7_MAINIO_EXTBANK:
327                         extcard_bank = data & 0x3f;
328                         dictram_enabled = ((data & 0x80) != 0) ? true : false;
329                         dictrom_enabled = ((data & 0x40) != 0) ? true : false;
330                         break;
331 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)          
332                 case FM7_MAINIO_EXTROM:
333                         extrom_bank = flag;
334                         break;
335 # endif    
336 #endif                  
337 #ifdef HAS_MMR                  
338                 case FM7_MAINIO_WINDOW_ENABLED:
339                         window_enabled = flag;
340                         setclock(config.cpu_type);
341                         break;
342                 case FM7_MAINIO_WINDOW_FAST:
343                         window_fast = flag;
344                         setclock(config.cpu_type);
345                         break;
346                 case FM7_MAINIO_FASTMMR_ENABLED:
347                         mmr_fast = flag;
348                         setclock(config.cpu_type);
349                         break;
350                 case FM7_MAINIO_MMR_ENABLED:
351                         mmr_enabled = flag;
352                         setclock(config.cpu_type);
353                         break;
354                 case FM7_MAINIO_MMR_EXTENDED:
355                         mmr_extend = flag;
356                         break;
357                 case FM7_MAINIO_MEM_REFRESH_FAST:
358                         refresh_fast = flag;
359                         setclock(config.cpu_type);
360                         break;
361 #endif                  
362         }
363 }
364
365 uint32_t FM7_MAINMEM::read_io8(uint32_t addr)
366 {
367         return mainio->read_io8(addr);
368 }
369
370 void FM7_MAINMEM::write_io8(uint32_t addr, uint32_t data)
371 {
372         return mainio->write_io8(addr, data);
373 }
374
375 uint32_t FM7_MAINMEM::read_dma_data8(uint32_t addr)
376 {
377 #if defined(HAS_MMR)    
378         uint32_t val;
379         val = this->read_data8_main(addr & 0xffff, true);
380         return val;
381 #else
382         return this->read_data8(addr & 0xffff);
383 #endif  
384 }
385
386 uint32_t FM7_MAINMEM::read_dma_io8(uint32_t addr)
387 {
388 #if defined(HAS_MMR)    
389         uint32_t val;
390         val = this->read_data8_main(addr & 0xffff, true);
391         return val;
392 #else
393         return this->read_data8(addr & 0xffff);
394 #endif  
395 }
396
397 uint32_t FM7_MAINMEM::read_data8(uint32_t addr)
398 {
399 #if defined(HAS_MMR)   
400         if(addr >= FM7_MAINIO_WINDOW_OFFSET) {
401                 switch(addr) {
402                 case FM7_MAINIO_WINDOW_OFFSET:
403                         return (uint32_t)window_offset;
404                         break;
405                 case FM7_MAINIO_MMR_SEGMENT:
406                         return (uint32_t)mmr_segment;
407                         break;
408                 default:
409                         if((addr >= FM7_MAINIO_MMR_BANK) && (addr < (FM7_MAINIO_MMR_BANK + 0x80))){
410                                 return mmr_map_data[addr - FM7_MAINIO_MMR_BANK];
411                         }
412                         break;
413                 }
414                 return 0xff;
415         }
416 #endif   
417         return read_data8_main(addr, false);
418 }
419
420 void FM7_MAINMEM::write_dma_data8(uint32_t addr, uint32_t data)
421 {
422 #if defined(HAS_MMR)
423         write_data8_main(addr & 0xffff, data, true);
424 #else
425         write_data8(addr & 0xffff, data);
426 #endif  
427 }
428
429 void FM7_MAINMEM::write_dma_io8(uint32_t addr, uint32_t data)
430 {
431 #if defined(HAS_MMR)
432         write_data8_main(addr & 0xffff, data, true);
433 #else
434         write_data8(addr & 0xffff, data);
435 #endif  
436 }
437
438 void FM7_MAINMEM::write_data8(uint32_t addr, uint32_t data)
439 {
440 #if defined(HAS_MMR)   
441         if(addr >= FM7_MAINIO_WINDOW_OFFSET) {
442                 switch(addr) {
443                 case FM7_MAINIO_WINDOW_OFFSET:
444                         window_offset = data;
445                         break;
446                 case FM7_MAINIO_MMR_SEGMENT:
447                         if(mmr_extend) {
448                                 mmr_segment = data & 0x07;
449                         } else {
450                                 mmr_segment = data & 0x03;
451                         }
452                         break;
453                 default:
454                         if((addr >= FM7_MAINIO_MMR_BANK) && (addr < (FM7_MAINIO_MMR_BANK + 0x80))){
455                                 mmr_map_data[addr - FM7_MAINIO_MMR_BANK] = (uint8_t)data;
456                                 update_mmr_jumptable(addr - FM7_MAINIO_MMR_BANK);
457                         }
458                         break;
459                 }
460                 return;
461         }
462 #endif
463         write_data8_main(addr, data, false);
464 }
465
466 // Read / Write data(s) as big endian.
467 uint32_t FM7_MAINMEM::read_data16(uint32_t addr)
468 {
469         uint32_t hi, lo;
470         uint32_t val;
471    
472         hi = read_data8(addr) & 0xff;
473         lo = read_data8(addr + 1) & 0xff;
474    
475         val = hi * 256 + lo;
476         return val;
477 }
478
479 uint32_t FM7_MAINMEM::read_data32(uint32_t addr)
480 {
481         uint32_t ah, a2, a3, al;
482         uint32_t val;
483    
484         ah = read_data8(addr) & 0xff;
485         a2 = read_data8(addr + 1) & 0xff;
486         a3 = read_data8(addr + 2) & 0xff;
487         al = read_data8(addr + 3) & 0xff;
488    
489         val = ah * (65536 * 256) + a2 * 65536 + a3 * 256 + al;
490         return val;
491 }
492
493 void FM7_MAINMEM::write_data16(uint32_t addr, uint32_t data)
494 {
495         uint32_t d = data;
496    
497         write_data8(addr + 1, d & 0xff);
498         d = d / 256;
499         write_data8(addr + 0, d & 0xff);
500 }
501
502 void FM7_MAINMEM::write_data32(uint32_t addr, uint32_t data)
503 {
504         uint32_t d = data;
505    
506         write_data8(addr + 3, d & 0xff);
507         d = d / 256;
508         write_data8(addr + 2, d & 0xff);
509         d = d / 256;
510         write_data8(addr + 1, d & 0xff);
511         d = d / 256;
512         write_data8(addr + 0, d & 0xff);
513 }
514
515
516 void FM7_MAINMEM::update_config()
517 {
518         setclock(config.cpu_type);
519 }
520
521 #define STATE_VERSION 7
522
523 #include "../../statesub.h"
524
525 void FM7_MAINMEM::decl_state(void)
526 {
527         enter_decl_state(STATE_VERSION);
528         
529         DECL_STATE_ENTRY_BOOL(ioaccess_wait);
530         DECL_STATE_ENTRY_INT32(waitfactor);
531         DECL_STATE_ENTRY_INT32(waitcount);
532         DECL_STATE_ENTRY_BOOL(sub_halted);
533         
534         DECL_STATE_ENTRY_BOOL(diag_load_basicrom);
535         DECL_STATE_ENTRY_BOOL(diag_load_bootrom_bas);
536         DECL_STATE_ENTRY_BOOL(diag_load_bootrom_dos);
537         DECL_STATE_ENTRY_BOOL(diag_load_bootrom_mmr);
538         DECL_STATE_ENTRY_BOOL(diag_load_bootrom_bubble);
539         DECL_STATE_ENTRY_BOOL(diag_load_bootrom_bubble_128k);
540         DECL_STATE_ENTRY_BOOL(diag_load_bootrom_sfd8);
541         DECL_STATE_ENTRY_BOOL(diag_load_bootrom_2hd);
542
543         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_omote, sizeof(fm7_mainmem_omote));
544         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_ura, sizeof(fm7_mainmem_ura));
545         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_basicrom, sizeof(fm7_mainmem_basicrom));
546         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_bioswork, sizeof(fm7_mainmem_bioswork));
547         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_bootrom_vector, sizeof(fm7_mainmem_bootrom_vector));
548         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_reset_vector, sizeof(fm7_mainmem_reset_vector));
549         
550         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_null, sizeof(fm7_mainmem_null));
551
552 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
553         DECL_STATE_ENTRY_1D_ARRAY(fm7_bootram, sizeof(fm7_bootram));
554 #endif  
555 #if defined(_FM77_VARIANTS) || defined(_FM8)
556         for(int i = 0; i < 8; i++) DECL_STATE_ENTRY_1D_ARRAY_MEMBER(fm7_bootroms[i], 0x200, i);
557 #elif defined(_FM7) || defined(_FMNEW7)
558         for(int i = 0; i < 4; i++) DECL_STATE_ENTRY_1D_ARRAY_MEMBER(fm7_bootroms[i], 0x200, i);
559 #endif  
560
561 #if defined(_FM8)
562         DECL_STATE_ENTRY_BOOL(diag_load_sm11_14);
563         DECL_STATE_ENTRY_BOOL(diag_load_sm11_15);
564 #elif defined(_FM77_VARIANTS)
565         DECL_STATE_ENTRY_BOOL(diag_load_wb11_12);
566 #elif defined(_FM7) || defined(_FMNEW7)
567         DECL_STATE_ENTRY_BOOL(diag_load_tl11_11);
568 #  if defined(_FMNEW7)
569         DECL_STATE_ENTRY_BOOL(diag_load_tl11_12);
570 #  endif        
571 #elif defined(_FM77AV_VARIANTS)
572         DECL_STATE_ENTRY_BOOL(dictrom_connected);
573         DECL_STATE_ENTRY_BOOL(use_page2_extram);
574         
575         DECL_STATE_ENTRY_BOOL(diag_load_initrom);
576         DECL_STATE_ENTRY_BOOL(diag_load_dictrom);
577         DECL_STATE_ENTRY_BOOL(diag_load_learndata);
578         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_initrom, sizeof(fm7_mainmem_initrom));
579         DECL_STATE_ENTRY_1D_ARRAY(fm77av_hidden_bootmmr, sizeof(fm77av_hidden_bootmmr));
580         
581         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_mmrbank_0, sizeof(fm7_mainmem_mmrbank_0));
582         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_mmrbank_2, sizeof(fm7_mainmem_mmrbank_2));
583         
584 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
585         DECL_STATE_ENTRY_BOOL(diag_load_extrarom);
586         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_extrarom, sizeof(fm7_mainmem_extrarom));
587 # endif
588 # if defined(CAPABLE_DICTROM)
589         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_dictrom, sizeof(fm7_mainmem_dictrom));
590         DECL_STATE_ENTRY_1D_ARRAY(fm7_mainmem_learndata, sizeof(fm7_mainmem_learndata));
591 # endif
592 #endif
593
594 #ifdef HAS_MMR
595         DECL_STATE_ENTRY_BOOL(extram_connected);
596 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
597          defined(_FM77_VARIANTS)
598         DECL_STATE_ENTRY_INT32(extram_pages);
599         DECL_STATE_ENTRY_VARARRAY_VAR(fm7_mainmem_extram, extram_size);
600 #  if defined(_FM77_VARIANTS)
601         DECL_STATE_ENTRY_1D_ARRAY(fm77_shadowram, sizeof(fm77_shadowram));
602 #  endif
603 # endif
604 #endif
605                                                           
606         { // V2;
607                 DECL_STATE_ENTRY_BOOL(is_basicrom);
608                 DECL_STATE_ENTRY_BOOL(clockmode);
609                 DECL_STATE_ENTRY_BOOL(basicrom_fd0f);
610                 DECL_STATE_ENTRY_UINT32(bootmode);
611 #if defined(_FM77AV_VARIANTS)
612                 DECL_STATE_ENTRY_UINT32(extcard_bank);
613                 DECL_STATE_ENTRY_BOOL(extrom_bank);
614                 DECL_STATE_ENTRY_BOOL(initiator_enabled);
615                 DECL_STATE_ENTRY_BOOL(dictrom_enabled);
616                 DECL_STATE_ENTRY_BOOL(dictram_enabled);
617 #endif
618 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
619                 DECL_STATE_ENTRY_BOOL(boot_ram_write);
620 #endif          
621 #if defined(HAS_MMR)
622                 DECL_STATE_ENTRY_BOOL(window_enabled);
623                 DECL_STATE_ENTRY_BOOL(mmr_enabled);
624                 DECL_STATE_ENTRY_BOOL(mmr_fast);
625                 DECL_STATE_ENTRY_BOOL(mmr_extend);
626                 
627                 DECL_STATE_ENTRY_UINT16(window_offset);
628                 DECL_STATE_ENTRY_BOOL(window_fast);
629                 DECL_STATE_ENTRY_BOOL(refresh_fast);
630                 DECL_STATE_ENTRY_UINT8(mmr_segment);
631                 DECL_STATE_ENTRY_1D_ARRAY(mmr_map_data, sizeof(mmr_map_data));
632 #endif
633         }
634         DECL_STATE_ENTRY_UINT32(mem_waitfactor); // OK?
635         DECL_STATE_ENTRY_UINT32(mem_waitcount); // OK?
636
637         DECL_STATE_ENTRY_UINT32(cpu_clocks); // OK?
638
639         leave_decl_state();
640 }
641
642 void FM7_MAINMEM::save_state(FILEIO *state_fio)
643 {
644         if(state_entry != NULL) {
645                 state_entry->save_state(state_fio);
646         }
647 #if defined(HAS_MMR)
648 #  if defined(_FM77_VARIANTS)
649         if(extram_pages > 3) extram_pages = 3;
650 #  elif defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) 
651         if(extram_pages > 12) extram_pages = 12;
652 #  endif
653 #endif
654         //extram_size = extram_pages * 0x10000;
655 }
656
657 bool FM7_MAINMEM::load_state(FILEIO *state_fio)
658 {
659         bool mb = false;
660         if(state_entry != NULL) {
661                 mb = state_entry->load_state(state_fio);
662                 this->out_debug_log(_T("Load State: MAINIO: id=%d stat=%s\n"), this_device_id, (mb) ? _T("OK") : _T("NG"));
663                 if(!mb) return false;
664         }
665 #if defined(HAS_MMR)
666 #  if defined(_FM77_VARIANTS)
667         if(extram_pages > 3) extram_pages = 3;
668 #  elif defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) 
669         if(extram_pages > 12) extram_pages = 12;
670 #  endif
671 #endif
672         //extram_size = extram_pages * 0x10000;
673         init_data_table();
674         update_all_mmr_jumptable();
675         return true;
676 }