OSDN Git Service

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