OSDN Git Service

8de5bc53e09b1a4a53d1538f808a9e5ea3c4fa09
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmr30 / memory.cpp
1 /*
2         FUJITSU FMR-30 Emulator 'eFMR-30'
3
4         Author : Takeda.Toshiya
5         Date   : 2008.12.30 -
6
7         [ memory and crtc ]
8 */
9
10 #include "../vm.h"
11 #include "../../emu.h"
12 #include "memory.h"
13 #include "../i8237.h"
14 #include "../i286.h"
15
16 static const uint8_t bios1[] = {
17         0xFA,                           // cli
18         0xDB,0xE3,                      // fninit
19         0xB8,0x00,0x7F,                 // mov  ax,7F00
20         0x8E,0xD0,                      // mov  ss,ax
21         0xBC,0x64,0x0F,                 // mov  sp,0F64
22         // init i/o
23         0xB4,0x80,                      // mov  ah,80
24         0x9A,0x14,0x00,0xFB,0xFF,       // call far FFFB:0014
25         // boot from fdd
26         0xB4,0x81,                      // mov  ah,81
27         0x9A,0x14,0x00,0xFB,0xFF,       // call far FFFB:0014
28         0x73,0x0B,                      // jnb  $+11
29         0x74,0xF5,                      // jz   $-11
30         // boot from scsi-hdd
31         0xB4,0x82,                      // mov  ah,82
32         0x9A,0x14,0x00,0xFB,0xFF,       // call far FFFB:0014
33         0x72,0xEC,                      // jb   $-20
34         // goto ipl
35         0x9A,0x04,0x00,0x00,0xB0,       // call far B000:0004
36         0xEB,0xE7                       // jmp $-25
37 };
38
39 static const uint8_t bios2[] = {
40         0xEA,0x00,0x00,0x00,0xFC,       // jmp  FC00:0000
41         0x00,0x00,0x00,
42         0xcf                            // iret
43 };
44
45 #define SET_BANK(s, e, w, r) { \
46         int sb = (s) >> 12, eb = (e) >> 12; \
47         for(int i = sb; i <= eb; i++) { \
48                 if((w) == wdmy) { \
49                         wbank[i] = wdmy; \
50                 } else { \
51                         wbank[i] = (w) + 0x1000 * (i - sb); \
52                 } \
53                 if((r) == rdmy) { \
54                         rbank[i] = rdmy; \
55                 } else { \
56                         rbank[i] = (r) + 0x1000 * (i - sb); \
57                 } \
58         } \
59 }
60
61 void MEMORY::initialize()
62 {
63         // init memory
64         memset(ram, 0, sizeof(ram));
65         memset(vram, 0, sizeof(vram));
66         memset(cvram, 0, sizeof(cvram));
67         memset(kvram, 0, sizeof(kvram));
68         memset(ipl, 0xff, sizeof(ipl));
69         memset(kanji16, 0xff, sizeof(kanji16));
70         memset(rdmy, 0xff, sizeof(rdmy));
71         
72         // load rom image
73         FILEIO* fio = new FILEIO();
74         if(fio->Fopen(create_local_path(_T("IPL.ROM")), FILEIO_READ_BINARY)) {
75                 fio->Fread(ipl, sizeof(ipl), 1);
76                 fio->Fclose();
77         } else {
78                 // load pseudo ipl
79                 memcpy(ipl + 0xc000, bios1, sizeof(bios1));
80                 memcpy(ipl + 0xfff0, bios2, sizeof(bios2));
81                 
82                 // ank8/16
83                 if(fio->Fopen(create_local_path(_T("ANK8.ROM")), FILEIO_READ_BINARY)) {
84                         fio->Fread(ipl, 0x800, 1);
85                         fio->Fclose();
86                 }
87                 if(fio->Fopen(create_local_path(_T("ANK16.ROM")), FILEIO_READ_BINARY)) {
88                         fio->Fread(ipl + 0x800, 0x1000, 1);
89                         fio->Fclose();
90                 }
91         }
92         if(fio->Fopen(create_local_path(_T("KANJI16.ROM")), FILEIO_READ_BINARY)) {
93                 fio->Fread(kanji16, sizeof(kanji16), 1);
94                 fio->Fclose();
95         }
96         delete fio;
97         
98         // set memory
99         SET_BANK(0x000000, 0xffffff, wdmy, rdmy);
100         SET_BANK(0x000000, sizeof(ram) - 1, ram, ram);
101         SET_BANK(0x0f0000, 0x0fffff, wdmy, ipl);
102         SET_BANK(0xff0000, 0xffffff, wdmy, ipl);
103         
104         // register event
105         register_frame_event(this);
106 }
107
108 void MEMORY::reset()
109 {
110         // reset crtc
111         lcdadr = 0;
112         memset(lcdreg, 0, sizeof(lcdreg));
113         dcr1 = dcr2 = 0;
114         kj_l = kj_h = kj_ofs = kj_row = 0;
115         blinkcnt = 0;
116         
117         // reset memory
118         mcr1 = 2;
119         mcr2 = a20 = 0;
120         update_bank();
121 }
122
123 void MEMORY::write_data8(uint32_t addr, uint32_t data)
124 {
125         addr &= 0xffffff;
126         wbank[addr >> 12][addr & 0xfff] = data;
127 }
128
129 uint32_t MEMORY::read_data8(uint32_t addr)
130 {
131         addr &= 0xffffff;
132         return rbank[addr >> 12][addr & 0xfff];
133 }
134
135 void MEMORY::write_io8(uint32_t addr, uint32_t data)
136 {
137         switch(addr & 0xffff) {
138         // memory controller
139         case 0x1d:
140 #ifdef HAS_I286
141                 // protect mode ???
142 //              d_cpu->write_signal(SIG_I286_A20, data, 0x10);
143 #endif
144                 mcr1 = data;
145                 update_bank();
146                 break;
147         case 0x1e:
148                 mcr2 = data;
149                 update_bank();
150                 break;
151         case 0x26:
152 #ifdef HAS_I286
153                 // protect mode ???
154                 d_cpu->write_signal(SIG_I286_A20, data, 0x80);
155 #endif
156                 a20 = data;
157                 break;
158         // dma bank
159         case 0x120:
160         case 0x121:
161         case 0x122:
162         case 0x123:
163                 d_dma->write_signal(SIG_I8237_BANK0 + (addr & 3), data, 0x0f);
164                 break;
165         // lcd controller
166         case 0x300:
167                 lcdadr = data;
168                 break;
169         case 0x302:
170                 lcdreg[lcdadr & 31] = data;
171                 break;
172         case 0x308:
173                 dcr1 = (dcr1 & 0xff00) | data;
174                 break;
175         case 0x309:
176                 dcr1 = (dcr1 & 0xff) | (data << 8);
177                 // bit11-10: vram bank
178                 update_bank();
179                 break;
180         case 0x30a:
181                 dcr1 = (dcr1 & 0xff00) | data;
182                 break;
183         case 0x30b:
184                 dcr1 = (dcr1 & 0xff) | (data << 8);
185                 break;
186         // kanji rom
187         case 0x30c:
188                 kj_h = data & 0x7f;
189                 break;
190         case 0x30d:
191                 kj_l = data & 0x7f;
192                 kj_row = 0;
193                 if(kj_h < 0x30) {
194                         kj_ofs = (((kj_l - 0x00) & 0x1f) <<  5) | (((kj_l - 0x20) & 0x20) <<  9) | (((kj_l - 0x20) & 0x40) <<  7) | (((kj_h - 0x00) & 0x07) << 10);
195                 } else if(kj_h < 0x70) {
196                         kj_ofs = (((kj_l - 0x00) & 0x1f) <<  5) + (((kj_l - 0x20) & 0x60) <<  9) + (((kj_h - 0x00) & 0x0f) << 10) + (((kj_h - 0x30) & 0x70) * 0xc00) + 0x08000;
197                 } else {
198                         kj_ofs = (((kj_l - 0x00) & 0x1f) <<  5) | (((kj_l - 0x20) & 0x20) <<  9) | (((kj_l - 0x20) & 0x40) <<  7) | (((kj_h - 0x00) & 0x07) << 10) | 0x38000;
199                 }
200                 break;
201         case 0x30e:
202                 kanji16[(kj_ofs | ((kj_row & 0x0f) << 1)) & 0x3ffff] = data;
203                 break;
204         case 0x30f:
205                 kanji16[(kj_ofs | ((kj_row++ & 0x0f) << 1) | 1) & 0x3ffff] = data;
206                 break;
207         }
208 }
209
210 uint32_t MEMORY::read_io8(uint32_t addr)
211 {
212         uint32_t val = 0xff;
213         
214         switch(addr & 0xffff) {
215         case 0x1d:
216                 return mcr1;
217         case 0x1e:
218                 return mcr2;
219         case 0x26:
220                 return a20;
221         // lcd controller
222         case 0x300:
223                 return lcdadr;
224         case 0x302:
225                 return lcdreg[lcdadr & 31];
226         case 0x308:
227                 return dcr1 & 0xff;
228         case 0x309:
229                 return (dcr1 >> 8) & 0xff;
230         case 0x30a:
231                 return dcr2 & 0xff;
232         case 0x30b:
233                 return (dcr2 >> 8) & 0xff;
234         // kanji rom
235         case 0x30c:
236                 return kj_h;
237         case 0x30d:
238                 return kj_l;
239         case 0x30e:
240                 return kanji16[(kj_ofs | ((kj_row & 0x0f) << 1)) & 0x3ffff];
241         case 0x30f:
242                 return kanji16[(kj_ofs | ((kj_row++ & 0x0f) << 1) | 1) & 0x3ffff];
243         }
244         return 0xff;
245 }
246
247 void MEMORY::event_frame()
248 {
249         blinkcnt++;
250 }
251
252 void MEMORY::update_bank()
253 {
254         if(!(mcr2 & 1)) {
255                 // $c0000-$cffff: vram
256                 SET_BANK(0xc0000, 0xcffff, wdmy, rdmy);
257                 int bank = 0x8000 * ((dcr1 >> 10) & 3);
258                 SET_BANK(0xc0000, 0xc7fff, vram + bank, vram + bank);
259                 SET_BANK(0xc8000, 0xc8fff, cvram, cvram);
260                 SET_BANK(0xca000, 0xcafff, kvram, kvram);
261         } else {
262                 SET_BANK(0xc0000, 0xcffff, ram + 0xc0000, ram + 0xc0000);
263         }
264         if(!(mcr1 & 1)) {
265                 // $f000-$ffff: rom
266                 SET_BANK(0xf0000, 0xfffff, wdmy, ipl);
267         } else {
268                 SET_BANK(0xf0000, 0xfffff, ram + 0xf0000, ram + 0xf0000);
269         }
270 }
271
272 void MEMORY::draw_screen()
273 {
274         // render screen
275         memset(screen_txt, 0, sizeof(screen_txt));
276         memset(screen_cg, 0, sizeof(screen_cg));
277         if(dcr1 & 2) {
278                 if(dcr1 & 8) {
279                         draw_text40();
280                 } else {
281                         draw_text80();
282                 }
283         }
284         if(dcr1 & 1) {
285                 draw_cg();
286         }
287         
288         scrntype_t cd = RGB_COLOR(48, 56, 16);
289         scrntype_t cb = RGB_COLOR(160, 168, 160);
290         for(int y = 0; y < 400; y++) {
291                 scrntype_t* dest = emu->get_screen_buffer(y);
292                 uint8_t* txt = screen_txt[y];
293                 uint8_t* cg = screen_cg[y];
294                 
295                 for(int x = 0; x < 640; x++) {
296                         dest[x] = (txt[x] || cg[x]) ? cd : cb;
297                 }
298         }
299 }
300
301 void MEMORY::draw_text40()
302 {
303         uint8_t *ank8 = ipl;
304         uint8_t *ank16 = ipl + 0x800;
305         
306         int src = 0;//((lcdreg[12] << 9) | (lcdreg[13] << 1)) & 0xfff;
307         int caddr = (lcdreg[10] & 0x20) ? -1 : (((lcdreg[14] << 9) | (lcdreg[15] << 1)) & 0xfff);
308         int yofs = lcdreg[9] + 1;
309         int ymax = 400 / yofs;
310         int freq = (dcr1 >> 4) & 3;
311         bool blink = !((freq == 3) || (blinkcnt & (32 >> freq)));
312         
313         for(int y = 0; y < ymax; y++) {
314                 for(int x = 0; x < 40; x++) {
315                         bool cursor = (src == caddr);
316                         int cx = x;
317                         uint8_t code = cvram[src];
318                         uint8_t h = kvram[src] & 0x7f;
319                         src = (src + 1) & 0xfff;
320                         uint8_t attr = cvram[src];
321                         uint8_t l = kvram[src] & 0x7f;
322                         src = (src + 1) & 0xfff;
323                         uint8_t col = attr & 0x27;
324                         bool blnk = blink && (attr & 0x10);
325                         bool rev = ((attr & 8) != 0);
326                         
327                         if(attr & 0x40) {
328                                 // kanji
329                                 int ofs;
330                                 if(h < 0x30) {
331                                         ofs = (((l - 0x00) & 0x1f) <<  5) | (((l - 0x20) & 0x20) <<  9) | (((l - 0x20) & 0x40) <<  7) | (((h - 0x00) & 0x07) << 10);
332                                 } else if(h < 0x70) {
333                                         ofs = (((l - 0x00) & 0x1f) <<  5) + (((l - 0x20) & 0x60) <<  9) + (((h - 0x00) & 0x0f) << 10) + (((h - 0x30) & 0x70) * 0xc00) + 0x08000;
334                                 } else {
335                                         ofs = (((l - 0x00) & 0x1f) <<  5) | (((l - 0x20) & 0x20) <<  9) | (((l - 0x20) & 0x40) <<  7) | (((h - 0x00) & 0x07) << 10) | 0x38000;
336                                 }
337                                 
338                                 for(int l = 0; l < 16 && l < yofs; l++) {
339                                         uint8_t pat0 = kanji16[ofs + (l << 1) + 0];
340                                         uint8_t pat1 = kanji16[ofs + (l << 1) + 1];
341                                         pat0 = blnk ? 0 : rev ? ~pat0 : pat0;
342                                         pat1 = blnk ? 0 : rev ? ~pat1 : pat1;
343                                         int yy = y * yofs + l;
344                                         if(yy >= 400) {
345                                                 break;
346                                         }
347                                         uint8_t* d = &screen_txt[yy][x << 4];
348                                         
349                                         d[ 0] = d[ 1] = (pat0 & 0x80) ? col : 0;
350                                         d[ 2] = d[ 3] = (pat0 & 0x40) ? col : 0;
351                                         d[ 4] = d[ 5] = (pat0 & 0x20) ? col : 0;
352                                         d[ 6] = d[ 7] = (pat0 & 0x10) ? col : 0;
353                                         d[ 8] = d[ 9] = (pat0 & 0x08) ? col : 0;
354                                         d[10] = d[11] = (pat0 & 0x04) ? col : 0;
355                                         d[12] = d[13] = (pat0 & 0x02) ? col : 0;
356                                         d[14] = d[15] = (pat0 & 0x01) ? col : 0;
357                                         d[16] = d[17] = (pat1 & 0x80) ? col : 0;
358                                         d[18] = d[19] = (pat1 & 0x40) ? col : 0;
359                                         d[20] = d[21] = (pat1 & 0x20) ? col : 0;
360                                         d[22] = d[23] = (pat1 & 0x10) ? col : 0;
361                                         d[24] = d[25] = (pat1 & 0x08) ? col : 0;
362                                         d[26] = d[27] = (pat1 & 0x04) ? col : 0;
363                                         d[28] = d[29] = (pat1 & 0x02) ? col : 0;
364                                         d[30] = d[31] = (pat1 & 0x01) ? col : 0;
365                                 }
366                                 src = (src + 2) & 0xfff;
367                                 x++;
368                         } else {
369                                 for(int l = 0; l < 16 && l < yofs; l++) {
370                                         uint8_t pat = ank16[(code << 4) + l];
371                                         pat = blnk ? 0 : rev ? ~pat : pat;
372                                         int yy = y * yofs + l;
373                                         if(yy >= 400) {
374                                                 break;
375                                         }
376                                         uint8_t* d = &screen_txt[yy][x << 4];
377                                         
378                                         d[ 0] = d[ 1] = (pat & 0x80) ? col : 0;
379                                         d[ 2] = d[ 3] = (pat & 0x40) ? col : 0;
380                                         d[ 4] = d[ 5] = (pat & 0x20) ? col : 0;
381                                         d[ 6] = d[ 7] = (pat & 0x10) ? col : 0;
382                                         d[ 8] = d[ 9] = (pat & 0x08) ? col : 0;
383                                         d[10] = d[11] = (pat & 0x04) ? col : 0;
384                                         d[12] = d[13] = (pat & 0x02) ? col : 0;
385                                         d[14] = d[15] = (pat & 0x01) ? col : 0;
386                                 }
387                         }
388                         if(cursor && !blink) {
389                                 int st = lcdreg[10] & 0x1f;
390                                 int ed = lcdreg[11] & 0x1f;
391                                 for(int i = st; i <= ed && i < yofs; i++) {
392                                         memset(&screen_txt[y * yofs + i][cx << 4], 7, 8);
393                                 }
394                         }
395                 }
396         }
397 }
398
399 void MEMORY::draw_text80()
400 {
401         uint8_t *ank8 = ipl;
402         uint8_t *ank16 = ipl + 0x800;
403         
404         int src = 0;//((lcdreg[12] << 9) | (lcdreg[13] << 1)) & 0xfff;
405         int caddr = (lcdreg[10] & 0x20) ? -1 : (((lcdreg[14] << 9) | (lcdreg[15] << 1)) & 0xfff);
406         int yofs = lcdreg[9] + 1;
407         int ymax = 400 / yofs;
408         int freq = (dcr1 >> 4) & 3;
409         bool blink = !((freq == 3) || (blinkcnt & (32 >> freq)));
410         
411         for(int y = 0; y < ymax; y++) {
412                 for(int x = 0; x < 80; x++) {
413                         bool cursor = (src == caddr);
414                         int cx = x;
415                         uint8_t code = cvram[src];
416                         uint8_t h = kvram[src] & 0x7f;
417                         src = (src + 1) & 0xfff;
418                         uint8_t attr = cvram[src];
419                         uint8_t l = kvram[src] & 0x7f;
420                         src = (src + 1) & 0xfff;
421                         uint8_t col = attr & 0x27;
422                         bool blnk = blink && (attr & 0x10);
423                         bool rev = ((attr & 8) != 0);
424                         
425                         if(attr & 0x40) {
426                                 // kanji
427                                 int ofs;
428                                 if(h < 0x30) {
429                                         ofs = (((l - 0x00) & 0x1f) <<  5) | (((l - 0x20) & 0x20) <<  9) | (((l - 0x20) & 0x40) <<  7) | (((h - 0x00) & 0x07) << 10);
430                                 } else if(h < 0x70) {
431                                         ofs = (((l - 0x00) & 0x1f) <<  5) + (((l - 0x20) & 0x60) <<  9) + (((h - 0x00) & 0x0f) << 10) + (((h - 0x30) & 0x70) * 0xc00) + 0x08000;
432                                 } else {
433                                         ofs = (((l - 0x00) & 0x1f) <<  5) | (((l - 0x20) & 0x20) <<  9) | (((l - 0x20) & 0x40) <<  7) | (((h - 0x00) & 0x07) << 10) | 0x38000;
434                                 }
435                                 
436                                 for(int l = 0; l < 16 && l < yofs; l++) {
437                                         uint8_t pat0 = kanji16[ofs + (l << 1) + 0];
438                                         uint8_t pat1 = kanji16[ofs + (l << 1) + 1];
439                                         pat0 = blnk ? 0 : rev ? ~pat0 : pat0;
440                                         pat1 = blnk ? 0 : rev ? ~pat1 : pat1;
441                                         int yy = y * yofs + l;
442                                         if(yy >= 400) {
443                                                 break;
444                                         }
445                                         uint8_t* d = &screen_txt[yy][x << 3];
446                                         
447                                         d[ 0] = (pat0 & 0x80) ? col : 0;
448                                         d[ 1] = (pat0 & 0x40) ? col : 0;
449                                         d[ 2] = (pat0 & 0x20) ? col : 0;
450                                         d[ 3] = (pat0 & 0x10) ? col : 0;
451                                         d[ 4] = (pat0 & 0x08) ? col : 0;
452                                         d[ 5] = (pat0 & 0x04) ? col : 0;
453                                         d[ 6] = (pat0 & 0x02) ? col : 0;
454                                         d[ 7] = (pat0 & 0x01) ? col : 0;
455                                         d[ 8] = (pat1 & 0x80) ? col : 0;
456                                         d[ 9] = (pat1 & 0x40) ? col : 0;
457                                         d[10] = (pat1 & 0x20) ? col : 0;
458                                         d[11] = (pat1 & 0x10) ? col : 0;
459                                         d[12] = (pat1 & 0x08) ? col : 0;
460                                         d[13] = (pat1 & 0x04) ? col : 0;
461                                         d[14] = (pat1 & 0x02) ? col : 0;
462                                         d[15] = (pat1 & 0x01) ? col : 0;
463                                 }
464                                 src = (src + 2) & 0xfff;
465                                 x++;
466                         } else {
467                                 for(int l = 0; l < 16 && l < yofs; l++) {
468                                         uint8_t pat = ank16[(code << 4) + l];
469                                         pat = blnk ? 0 : rev ? ~pat : pat;
470                                         int yy = y * yofs + l;
471                                         if(yy >= 400) {
472                                                 break;
473                                         }
474                                         uint8_t* d = &screen_txt[yy][x << 3];
475                                         
476                                         d[0] = (pat & 0x80) ? col : 0;
477                                         d[1] = (pat & 0x40) ? col : 0;
478                                         d[2] = (pat & 0x20) ? col : 0;
479                                         d[3] = (pat & 0x10) ? col : 0;
480                                         d[4] = (pat & 0x08) ? col : 0;
481                                         d[5] = (pat & 0x04) ? col : 0;
482                                         d[6] = (pat & 0x02) ? col : 0;
483                                         d[7] = (pat & 0x01) ? col : 0;
484                                 }
485                         }
486                         if(cursor && !blink) {
487                                 int st = lcdreg[10] & 0x1f;
488                                 int ed = lcdreg[11] & 0x1f;
489                                 for(int i = st; i <= ed && i < yofs; i++) {
490                                         memset(&screen_txt[y * yofs + i][cx << 3], 7, 8);
491                                 }
492                         }
493                 }
494         }
495 }
496
497 void MEMORY::draw_cg()
498 {
499         uint8_t* plane = vram + ((dcr1 >> 8) & 3) * 0x8000;
500         int ptr = 0;
501         
502         for(int y = 0; y < 400; y++) {
503                 for(int x = 0; x < 640; x += 8) {
504                         uint8_t pat = plane[ptr++];
505                         uint8_t* d = &screen_cg[y][x];
506                         
507                         d[0] = pat & 0x80;
508                         d[1] = pat & 0x40;
509                         d[2] = pat & 0x20;
510                         d[3] = pat & 0x10;
511                         d[4] = pat & 0x08;
512                         d[5] = pat & 0x04;
513                         d[6] = pat & 0x02;
514                         d[7] = pat & 0x01;
515                 }
516         }
517 }
518
519 #define STATE_VERSION   2
520
521 #include "../../statesub.h"
522
523 void MEMORY::decl_state()
524 {
525         enter_decl_state(STATE_VERSION);
526
527         DECL_STATE_ENTRY_1D_ARRAY(ram, sizeof(ram));
528         DECL_STATE_ENTRY_1D_ARRAY(vram, sizeof(vram));
529         DECL_STATE_ENTRY_1D_ARRAY(cvram, sizeof(cvram));
530         DECL_STATE_ENTRY_1D_ARRAY(kvram, sizeof(kvram));
531         DECL_STATE_ENTRY_UINT8(mcr1);
532         DECL_STATE_ENTRY_UINT8(mcr2);
533         DECL_STATE_ENTRY_UINT8(a20);
534         DECL_STATE_ENTRY_UINT8(lcdadr);
535         DECL_STATE_ENTRY_1D_ARRAY(lcdreg, sizeof(lcdreg));
536         DECL_STATE_ENTRY_UINT16(dcr1);
537         DECL_STATE_ENTRY_UINT16(dcr2);
538         DECL_STATE_ENTRY_INT32(kj_h);
539         DECL_STATE_ENTRY_INT32(kj_l);
540         DECL_STATE_ENTRY_INT32(kj_ofs);
541         DECL_STATE_ENTRY_INT32(kj_row);
542         DECL_STATE_ENTRY_INT32(blinkcnt);
543         
544         leave_decl_state();
545 }
546
547 void MEMORY::save_state(FILEIO* state_fio)
548 {
549         if(state_entry != NULL) {
550                 state_entry->save_state(state_fio);
551         }
552
553 //      state_fio->FputUint32(STATE_VERSION);
554 //      state_fio->FputInt32(this_device_id);
555         
556 //      state_fio->Fwrite(ram, sizeof(ram), 1);
557 //      state_fio->Fwrite(vram, sizeof(vram), 1);
558 //      state_fio->Fwrite(cvram, sizeof(cvram), 1);
559 //      state_fio->Fwrite(kvram, sizeof(kvram), 1);
560 //      state_fio->FputUint8(mcr1);
561 //      state_fio->FputUint8(mcr2);
562 //      state_fio->FputUint8(a20);
563 //      state_fio->FputUint8(lcdadr);
564 //      state_fio->Fwrite(lcdreg, sizeof(lcdreg), 1);
565 //      state_fio->FputUint16(dcr1);
566 //      state_fio->FputUint16(dcr2);
567 //      state_fio->FputInt32(kj_h);
568 //      state_fio->FputInt32(kj_l);
569 //      state_fio->FputInt32(kj_ofs);
570 //      state_fio->FputInt32(kj_row);
571 //      state_fio->FputInt32(blinkcnt);
572 }
573
574 bool MEMORY::load_state(FILEIO* state_fio)
575 {
576         bool mb = false;
577         if(state_entry != NULL) {
578                 mb = state_entry->load_state(state_fio);
579         }
580         if(!mb) {
581                 return false;
582         }
583
584 //      if(state_fio->FgetUint32() != STATE_VERSION) {
585 //              return false;
586 //      }
587 //      if(state_fio->FgetInt32() != this_device_id) {
588 //              return false;
589 //      }
590 //      state_fio->Fread(ram, sizeof(ram), 1);
591 //      state_fio->Fread(vram, sizeof(vram), 1);
592 //      state_fio->Fread(cvram, sizeof(cvram), 1);
593 //      state_fio->Fread(kvram, sizeof(kvram), 1);
594 //      mcr1 = state_fio->FgetUint8();
595 //      mcr2 = state_fio->FgetUint8();
596 //      a20 = state_fio->FgetUint8();
597 //      lcdadr = state_fio->FgetUint8();
598 //      state_fio->Fread(lcdreg, sizeof(lcdreg), 1);
599 //      dcr1 = state_fio->FgetUint16();
600 //      dcr2 = state_fio->FgetUint16();
601 //      kj_h = state_fio->FgetInt32();
602 //      kj_l = state_fio->FgetInt32();
603 //      kj_ofs = state_fio->FgetInt32();
604 //      kj_row = state_fio->FgetInt32();
605 //      blinkcnt = state_fio->FgetInt32();
606         
607         // post process
608         update_bank();
609         return true;
610 }
611
612 bool MEMORY::process_state(FILEIO* state_fio, bool loading)
613 {
614         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
615                 return false;
616         }
617         if(!state_fio->StateCheckInt32(this_device_id)) {
618                 return false;
619         }
620         state_fio->StateBuffer(ram, sizeof(ram), 1);
621         state_fio->StateBuffer(vram, sizeof(vram), 1);
622         state_fio->StateBuffer(cvram, sizeof(cvram), 1);
623         state_fio->StateBuffer(kvram, sizeof(kvram), 1);
624         state_fio->StateUint8(mcr1);
625         state_fio->StateUint8(mcr2);
626         state_fio->StateUint8(a20);
627         state_fio->StateUint8(lcdadr);
628         state_fio->StateBuffer(lcdreg, sizeof(lcdreg), 1);
629         state_fio->StateUint16(dcr1);
630         state_fio->StateUint16(dcr2);
631         state_fio->StateInt32(kj_h);
632         state_fio->StateInt32(kj_l);
633         state_fio->StateInt32(kj_ofs);
634         state_fio->StateInt32(kj_row);
635         state_fio->StateInt32(blinkcnt);
636         
637         // post process
638         if(loading) {
639                 update_bank();
640         }
641         return true;
642 }