OSDN Git Service

[VM}[FM7][PC8801][X1] At least enable to build FM7,PC8801 and X1 (excepts X!Twin).
[csp-qt/common_source_project-fm7.git] / source / src / vm / x1 / display.cpp
index 969725a..643213e 100644 (file)
@@ -20,6 +20,8 @@
 #define EVENT_AFTER_BLANK      0
 #endif
 
+namespace X1 {
+
 #ifdef _X1TURBOZ
 #define AEN    ((zmode1 & 0x80) != 0)
 #define C64    ((zmode1 & 0x10) != 0)
@@ -123,6 +125,27 @@ void DISPLAY::initialize()
        // register event
        register_frame_event(this);
        register_vline_event(this);
+
+       // Copy images to draw buffers.
+       my_memcpy(dr_text, text, sizeof(dr_text));
+       my_memcpy(dr_cg, cg, sizeof(dr_cg));
+       my_memcpy(dr_pri_line, pri_line, sizeof(dr_pri_line));
+       my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
+       dr_priority = priority;
+#ifdef _X1TURBOZ
+       dr_zpriority = zpriority;
+       my_memcpy(dr_zcg, zcg, sizeof(dr_zcg));
+       my_memcpy(dr_aen_line, aen_line, sizeof(dr_aen_line));
+       my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
+       zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
+       zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
+       zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
+       zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
+       zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
+       zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
+       zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
+       zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
+#endif 
 }
 
 void DISPLAY::reset()
@@ -149,6 +172,27 @@ void DISPLAY::reset()
        
        kaddr = kofs = kflag = 0;
        kanji_ptr = &kanji[0];
+
+       // Copy images to draw buffers.
+       my_memcpy(dr_text, text, sizeof(dr_text));
+       my_memcpy(dr_cg, cg, sizeof(dr_cg));
+       my_memcpy(dr_pri_line, pri_line, sizeof(dr_pri_line));
+       my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
+       dr_priority = priority;
+#ifdef _X1TURBOZ
+       dr_zpriority = zpriority;
+       my_memcpy(dr_zcg, zcg, sizeof(dr_zcg));
+       my_memcpy(dr_aen_line, aen_line, sizeof(dr_aen_line));
+       my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
+       zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
+       zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
+       zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
+       zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
+       zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
+       zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
+       zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
+       zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
+#endif 
 }
 
 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
@@ -541,12 +585,42 @@ void DISPLAY::event_frame()
        int vt_total = ((regs[4] & 0x7f) + 1) * ch_height + (regs[5] & 0x1f);
        hireso = (vt_total > 400);
 #endif
-       
+       int vlen;
+#ifdef _X1TURBO_FEATURE
+       vlen = (hireso) ? 400 : 200;
+#else
+       vlen = 200;
+#endif
+       if(vlen > 0) {
+               // Copy images to draw buffers.
+               my_memcpy(dr_text, text, sizeof(uint8_t) * vlen * (640 + 8));
+               my_memcpy(dr_cg, cg, sizeof(uint8_t) * vlen * 640);
+               my_memcpy(dr_pri_line, pri_line, sizeof(uint8_t) * vlen * 8 * 8);
+       }
+       my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
+       dr_priority = priority;
        // initialize draw screen
        memset(text, 0, sizeof(text));
        memset(cg, 0, sizeof(cg));
        memset(pri_line, 0, sizeof(pri_line));
 #ifdef _X1TURBOZ
+       if(vlen > 0) {
+       // Copy images to draw buffers.
+               my_memcpy(&(dr_zcg[0][0][0]), &(zcg[0][0][0]), sizeof(uint8_t) * vlen * 640);
+               //my_memcpy(dr_aen_line, aen_line, sizeof(bool) * vlen);
+       }
+       my_memcpy(dr_aen_line, aen_line, sizeof(aen_line));
+       dr_zpriority = zpriority;
+       my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
+       zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
+       zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
+       zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
+       zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
+       zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
+       zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
+       zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
+       zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
+       
        memset(zcg, 0, sizeof(zcg));
        memset(aen_line, 0, sizeof(aen_line));
 #endif
@@ -557,6 +631,46 @@ void DISPLAY::event_frame()
 void DISPLAY::event_vline(int v, int clock)
 {
        cur_vline = v;
+
+#if 0
+       // Copy images to draw buffers.
+       int vlimit;
+#ifdef _X1TURBO_FEATURE
+       vlimit = (hireso) ? 400 : 200;
+#else
+       vlimit = 200;
+#endif
+       if((v > vlimit) || (v < 0)) return;
+       
+       if(v == vlimit) {
+               my_memcpy(dr_palette_pc, palette_pc, sizeof(palette_pc));
+#ifdef _X1TURBOZ
+               my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
+#endif
+               // Copy images to draw buffers.
+               //my_memcpy(&(dr_text[v][0]), &(text[v][0]), sizeof(uint8_t) * (640 + 8));
+               //my_memcpy(&(dr_cg[v][0]), &(cg[v][0]), sizeof(uint8_t) * 640);
+               //my_memcpy(&(dr_pri_line[v][0][0]), &(pri_line[v][0][0]), sizeof(uint8_t) * 8 * 8);
+#ifdef _X1TURBOZ
+               //my_memcpy(&(dr_zcg[0][v][0]), &(zcg[0][v][0]), sizeof(uint8_t) * 640);
+               //my_memcpy(&(dr_zcg[1][v][0]), &(zcg[1][v][0]), sizeof(uint8_t) * 640);
+               //dr_aen_line[v] = aen_line[v];
+#endif
+       } else if(v == 0) {
+               return;
+       }
+       // Copy images to draw buffers.
+       my_memcpy(&(dr_text[v - 1][0]), &(text[v - 1][0]), sizeof(uint8_t) * (640 + 8));
+       my_memcpy(&(dr_cg[v - 1][0]), &(cg[v -1 ][0]), sizeof(uint8_t) * 640);
+       my_memcpy(&(dr_pri_line[v - 1][0][0]), &(pri_line[v - 1][0][0]), sizeof(uint8_t) * 8 * 8);
+       dr_priority = priority;
+#ifdef _X1TURBOZ
+       my_memcpy(&(dr_zcg[0][v - 1 ][0]), &(zcg[0][v - 1][0]), sizeof(uint8_t) * 640);
+       my_memcpy(&(dr_zcg[1][v - 1][0]), &(zcg[1][v - 1][0]), sizeof(uint8_t) * 640);
+       dr_zpriority = zpriority;
+       dr_aen_line[v - 1] = aen_line[v - 1];
+#endif
+#endif
 }
 
 #ifdef _X1TURBO_FEATURE
@@ -572,13 +686,13 @@ void DISPLAY::event_callback(int event_id, int err)
 void DISPLAY::update_crtc()
 {
 #ifdef _X1TURBO_FEATURE
-       if (column40) {
+       if(column40) {
                d_crtc->set_char_clock((mode1 & 1) ? VDP_CLOCK * 1.5 / 32.0 : VDP_CLOCK / 32.0);
        } else {
                d_crtc->set_char_clock((mode1 & 1) ? VDP_CLOCK * 1.5 / 16.0 : VDP_CLOCK / 16.0);
        }
 #else
-       if (column40) {
+       if(column40) {
                d_crtc->set_char_clock(VDP_CLOCK / 32.0);
        } else {
                d_crtc->set_char_clock(VDP_CLOCK / 16.0);
@@ -732,14 +846,14 @@ void DISPLAY::draw_screen()
 {
        // copy to real screen
 #ifdef _X1TURBOZ
-       zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
-       zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
-       zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
-       zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
-       zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
-       zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
-       zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
-       zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
+       dr_zpalette_pc[8 + 0] = dr_zpalette_pc[16 + 0x000];
+       dr_zpalette_pc[8 + 1] = dr_zpalette_pc[16 + 0x00f];
+       dr_zpalette_pc[8 + 2] = dr_zpalette_pc[16 + 0x0f0];
+       dr_zpalette_pc[8 + 3] = dr_zpalette_pc[16 + 0x0ff];
+       dr_zpalette_pc[8 + 4] = dr_zpalette_pc[16 + 0xf00];
+       dr_zpalette_pc[8 + 5] = dr_zpalette_pc[16 + 0xf0f];
+       dr_zpalette_pc[8 + 6] = dr_zpalette_pc[16 + 0xff0];
+       dr_zpalette_pc[8 + 7] = dr_zpalette_pc[16 + 0xfff];
 #endif
 #ifdef _X1TURBO_FEATURE
        if(hireso) {
@@ -749,10 +863,10 @@ void DISPLAY::draw_screen()
                        // 40 columns
                        for(int y = 0; y < 400; y++) {
                                scrntype_t* dest = emu->get_screen_buffer(y);
-                               uint8_t* src_text = text[y];
+                               uint8_t* src_text = dr_text[y];
 #ifdef _X1TURBOZ
-                               if(aen_line[y]) {
-                                       uint16_t* src_cg0 = zcg[0][y];
+                               if(dr_aen_line[y]) {
+                                       uint16_t* src_cg0 = dr_zcg[0][y];
                                        
                                        for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
                                                uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2);
@@ -761,13 +875,13 @@ void DISPLAY::draw_screen()
                                        }
                                } else {
 #endif
-                                       uint8_t* src_cg = cg[y];
+                                       uint8_t* src_cg = dr_cg[y];
                                        
                                        for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
 #ifdef _X1TURBOZ
-                                               dest[x2] = dest[x2 + 1] = zpalette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+                                               dest[x2] = dest[x2 + 1] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
 #else
-                                               dest[x2] = dest[x2 + 1] =  palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+                                               dest[x2] = dest[x2 + 1] =  dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
 #endif
                                        }
 #ifdef _X1TURBOZ
@@ -778,10 +892,10 @@ void DISPLAY::draw_screen()
                        // 80 columns
                        for(int y = 0; y < 400; y++) {
                                scrntype_t* dest = emu->get_screen_buffer(y);
-                               uint8_t* src_text = text[y];
+                               uint8_t* src_text = dr_text[y];
 #ifdef _X1TURBOZ
-                               if(aen_line[y]) {
-                                       uint16_t* src_cg0 = zcg[0][y];
+                               if(dr_aen_line[y]) {
+                                       uint16_t* src_cg0 = dr_zcg[0][y];
                                        
                                        for(int x = 0; x < 640; x++) {
                                                uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2);
@@ -790,13 +904,13 @@ void DISPLAY::draw_screen()
                                        }
                                } else {
 #endif
-                                       uint8_t* src_cg = cg[y];
+                                       uint8_t* src_cg = dr_cg[y];
                                        
                                        for(int x = 0; x < 640; x++) {
 #ifdef _X1TURBOZ
-                                               dest[x] = zpalette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+                                               dest[x] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
 #else
-                                               dest[x] =  palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+                                               dest[x] =  dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
 #endif
                                        }
 #ifdef _X1TURBOZ
@@ -816,11 +930,11 @@ void DISPLAY::draw_screen()
                        for(int y = 0; y < 200; y++) {
                                scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
                                scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
-                               uint8_t* src_text = text[y];
+                               uint8_t* src_text = dr_text[y];
 #ifdef _X1TURBOZ
-                               if(aen_line[y]) {
-                                       uint16_t* src_cg0 = zcg[0][y];
-                                       uint16_t* src_cg1 = zcg[1][y];
+                               if(dr_aen_line[y]) {
+                                       uint16_t* src_cg0 = dr_zcg[0][y];
+                                       uint16_t* src_cg1 = dr_zcg[1][y];
                                        
                                        if(C64) {
                                                for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
@@ -839,13 +953,13 @@ void DISPLAY::draw_screen()
                                } else {
 #endif
                                        scrntype_t* dest = emu->get_screen_buffer(y);
-                                       uint8_t* src_cg = cg[y];
+                                       uint8_t* src_cg = dr_cg[y];
                                
                                        for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) {
 #ifdef _X1TURBOZ
-                                               dest0[x2] = dest0[x2 + 1] = zpalette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+                                               dest0[x2] = dest0[x2 + 1] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
 #else
-                                               dest0[x2] = dest0[x2 + 1] =  palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+                                               dest0[x2] = dest0[x2 + 1] =  dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
 #endif
                                        }
 #ifdef _X1TURBOZ
@@ -862,10 +976,10 @@ void DISPLAY::draw_screen()
                        for(int y = 0; y < 200; y++) {
                                scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
                                scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
-                               uint8_t* src_text = text[y];
+                               uint8_t* src_text = dr_text[y];
 #ifdef _X1TURBOZ
                                if(aen_line[y]) {
-                                       uint16_t* src_cg0 = zcg[0][y];
+                                       uint16_t* src_cg0 = dr_zcg[0][y];
                                        
                                        for(int x = 0; x < 640; x++) {
                                                uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2);
@@ -874,13 +988,13 @@ void DISPLAY::draw_screen()
                                        }
                                } else {
 #endif
-                                       uint8_t* src_cg = cg[y];
+                                       uint8_t* src_cg = dr_cg[y];
                                        
                                        for(int x = 0; x < 640; x++) {
 #ifdef _X1TURBOZ
-                                               dest0[x] = zpalette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+                                               dest0[x] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
 #else
-                                               dest0[x] =  palette_pc[pri_line[y][src_cg[x]][src_text[x]]];
+                                               dest0[x] =  dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]];
 #endif
                                        }
 #ifdef _X1TURBOZ
@@ -1182,15 +1296,15 @@ scrntype_t DISPLAY::get_zpriority(uint8_t text, uint16_t cg0, uint16_t cg1)
 {
        if((mode2 & 8) && (text == (mode2 & 7))) {
                int digital = ((cg0 >> 9) & 4) | ((cg0 >> 6) & 2) | ((cg0 >> 3) & 1);
-               if(!(priority & (1 << digital))) {
+               if(!(dr_priority & (1 << digital))) {
                        return 0;
                }
        }
-       uint16_t fore = ((zpriority & 0x18) != 0x18) ? cg0 : cg1;
-       uint16_t back = ((zpriority & 0x18) != 0x18) ? cg1 : cg0;
+       uint16_t fore = ((dr_zpriority & 0x18) != 0x18) ? cg0 : cg1;
+       uint16_t back = ((dr_zpriority & 0x18) != 0x18) ? cg1 : cg0;
        uint16_t disp;
        
-       switch(zpriority & 0x13) {
+       switch(dr_zpriority & 0x13) {
        case 0x00:
        case 0x02:
                disp = text ? text : (fore + 16);
@@ -1218,7 +1332,7 @@ scrntype_t DISPLAY::get_zpriority(uint8_t text, uint16_t cg0, uint16_t cg1)
 //     if((mode2 & 0x20) && disp == (0x00f + 16)) {
 //             return 0;
 //     }
-       return zpalette_pc[disp];
+       return dr_zpalette_pc[disp];
 }
 #endif
 
@@ -1399,129 +1513,117 @@ uint16_t DISPLAY::jis2sjis(uint16_t jis)
        return (c1 << 8) | c2;
 }
 
-#define STATE_VERSION  4
+#define STATE_VERSION  5
 
-void DISPLAY::save_state(FILEIO* state_fio)
+bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
 {
-       state_fio->FputUint32(STATE_VERSION);
-       state_fio->FputInt32(this_device_id);
-       
-       state_fio->Fwrite(vram_t, sizeof(vram_t), 1);
-       state_fio->Fwrite(vram_a, sizeof(vram_a), 1);
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       state_fio->StateArray(vram_t, sizeof(vram_t), 1);
+       state_fio->StateArray(vram_a, sizeof(vram_a), 1);
 #ifdef _X1TURBO_FEATURE
-       state_fio->Fwrite(vram_k, sizeof(vram_k), 1);
+       state_fio->StateArray(vram_k, sizeof(vram_k), 1);
 #endif
-       state_fio->Fwrite(pcg_b, sizeof(pcg_b), 1);
-       state_fio->Fwrite(pcg_r, sizeof(pcg_r), 1);
-       state_fio->Fwrite(pcg_g, sizeof(pcg_g), 1);
+       state_fio->StateArray(&pcg_b[0][0], sizeof(pcg_b), 1);
+       state_fio->StateArray(&pcg_r[0][0], sizeof(pcg_r), 1);
+       state_fio->StateArray(&pcg_g[0][0], sizeof(pcg_g), 1);
 #ifdef _X1TURBO_FEATURE
-       state_fio->Fwrite(gaiji_b, sizeof(gaiji_b), 1);
-       state_fio->Fwrite(gaiji_r, sizeof(gaiji_r), 1);
-       state_fio->Fwrite(gaiji_g, sizeof(gaiji_g), 1);
-#endif
-       state_fio->FputUint8(cur_code);
-       state_fio->FputUint8(cur_line);
-       state_fio->FputInt32(kaddr);
-       state_fio->FputInt32(kofs);
-       state_fio->FputInt32(kflag);
-       state_fio->FputInt32((int)(kanji_ptr - &kanji[0]));
-       state_fio->Fwrite(pal, sizeof(pal), 1);
-       state_fio->FputUint8(priority);
-       state_fio->Fwrite(pri, sizeof(pri), 1);
-       state_fio->FputBool(column40);
+       state_fio->StateArray(&gaiji_b[0][0], sizeof(gaiji_b), 1);
+       state_fio->StateArray(&gaiji_r[0][0], sizeof(gaiji_r), 1);
+       state_fio->StateArray(&gaiji_g[0][0], sizeof(gaiji_g), 1);
+#endif
+       state_fio->StateValue(cur_code);
+       state_fio->StateValue(cur_line);
+       state_fio->StateValue(kaddr);
+       state_fio->StateValue(kofs);
+       state_fio->StateValue(kflag);
+       if(loading) {
+               intptr_t p = (intptr_t)(&kanji[0]);
+               kanji_ptr = (uint8_t*)(p + state_fio->FgetInt32_LE());
+       } else {
+               intptr_t p = (intptr_t)(&kanji[0]);
+               intptr_t q = (intptr_t)kanji_ptr;
+               state_fio->FputInt32_LE((int)(q - p));
+       }
+       state_fio->StateArray(pal, sizeof(pal), 1);
+       state_fio->StateValue(priority);
+       state_fio->StateArray(&pri[0][0], sizeof(pri), 1);
+       state_fio->StateValue(column40);
 #ifdef _X1TURBO_FEATURE
-       state_fio->FputUint8(mode1);
-       state_fio->FputUint8(mode2);
-       state_fio->FputBool(hireso);
+       state_fio->StateValue(mode1);
+       state_fio->StateValue(mode2);
+       state_fio->StateValue(hireso);
 #endif
 #ifdef _X1TURBOZ
-       state_fio->FputUint8(zmode1);
-       state_fio->FputUint8(zpriority);
-       state_fio->FputUint8(zadjust);
-       state_fio->FputUint8(zmosaic);
-       state_fio->FputUint8(zchromakey);
-       state_fio->FputUint8(zscroll);
-       state_fio->FputUint8(zmode2);
-       state_fio->Fwrite(ztpal, sizeof(ztpal), 1);
-       state_fio->Fwrite(zpal, sizeof(zpal), 1);
-       state_fio->FputInt32(zpal_num);
-       state_fio->Fwrite(zpalette_pc, sizeof(zpalette_pc), 1);
-#endif
-       state_fio->FputBool(prev_vert_double);
-       state_fio->FputInt32(raster);
-       state_fio->FputInt32(cblink);
-       state_fio->FputInt32(ch_height);
-       state_fio->FputInt32(hz_total);
-       state_fio->FputInt32(hz_disp);
-       state_fio->FputInt32(vt_disp);
-       state_fio->FputInt32(st_addr);
-       state_fio->FputUint32(vblank_clock);
-       state_fio->FputBool(cur_blank);
-}
-
-bool DISPLAY::load_state(FILEIO* state_fio)
-{
-       if(state_fio->FgetUint32() != STATE_VERSION) {
-               return false;
-       }
-       if(state_fio->FgetInt32() != this_device_id) {
-               return false;
+       state_fio->StateValue(zmode1);
+       state_fio->StateValue(zpriority);
+       state_fio->StateValue(zadjust);
+       state_fio->StateValue(zmosaic);
+       state_fio->StateValue(zchromakey);
+       state_fio->StateValue(zscroll);
+       state_fio->StateValue(zmode2);
+       state_fio->StateArray(ztpal, sizeof(ztpal), 1);
+       for(int i = 0; i < array_length(zpal); i++){
+               state_fio->StateValue(zpal[i].r);
+               state_fio->StateValue(zpal[i].g);
+               state_fio->StateValue(zpal[i].b);
        }
-       state_fio->Fread(vram_t, sizeof(vram_t), 1);
-       state_fio->Fread(vram_a, sizeof(vram_a), 1);
-#ifdef _X1TURBO_FEATURE
-       state_fio->Fread(vram_k, sizeof(vram_k), 1);
-#endif
-       state_fio->Fread(pcg_b, sizeof(pcg_b), 1);
-       state_fio->Fread(pcg_r, sizeof(pcg_r), 1);
-       state_fio->Fread(pcg_g, sizeof(pcg_g), 1);
-#ifdef _X1TURBO_FEATURE
-       state_fio->Fread(gaiji_b, sizeof(gaiji_b), 1);
-       state_fio->Fread(gaiji_r, sizeof(gaiji_r), 1);
-       state_fio->Fread(gaiji_g, sizeof(gaiji_g), 1);
-#endif
-       cur_code = state_fio->FgetUint8();
-       cur_line = state_fio->FgetUint8();
-       kaddr = state_fio->FgetInt32();
-       kofs = state_fio->FgetInt32();
-       kflag = state_fio->FgetInt32();
-       kanji_ptr = &kanji[0] + state_fio->FgetInt32();
-       state_fio->Fread(pal, sizeof(pal), 1);
-       priority = state_fio->FgetUint8();
-       state_fio->Fread(pri, sizeof(pri), 1);
-       column40 = state_fio->FgetBool();
+       state_fio->StateValue(zpal_num);
+       state_fio->StateArrayScrnType_t(zpalette_pc, sizeof(zpalette_pc), 1);
+#endif
+       state_fio->StateValue(prev_vert_double);
+       state_fio->StateValue(raster);
+       state_fio->StateValue(cblink);
+       state_fio->StateValue(ch_height);
+       state_fio->StateValue(hz_total);
+       state_fio->StateValue(hz_disp);
+       state_fio->StateValue(vt_disp);
+       state_fio->StateValue(st_addr);
+       state_fio->StateValue(vblank_clock);
+       state_fio->StateValue(cur_blank);
+       
+       // post process
+       if(loading) {
+               for(int i = 0; i < 8; i++) {
+                       palette_pc[i    ] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // text
+                       palette_pc[i + 8] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // cg
+               }
+               // Copy images to draw buffers.
+               my_memcpy(dr_text, text, sizeof(dr_text));
+               my_memcpy(dr_cg, cg, sizeof(dr_cg));
 #ifdef _X1TURBO_FEATURE
-       mode1 = state_fio->FgetUint8();
-       mode2 = state_fio->FgetUint8();
-       hireso = state_fio->FgetBool();
+               for(int v = 0; v < 400; v++) {
+                       memcpy(&pri_line[v][0][0], &pri[0][0], sizeof(pri));
+               }
+#else
+               for(int v = 0; v < 200; v++) {
+                       memcpy(&pri_line[v][0][0], &pri[0][0], sizeof(pri));
+               }
 #endif
+               my_memcpy(dr_pri_line, pri_line, sizeof(dr_pri_line));
+               my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc));
+               dr_priority = priority;
 #ifdef _X1TURBOZ
-       zmode1 = state_fio->FgetUint8();
-       zpriority = state_fio->FgetUint8();
-       zadjust = state_fio->FgetUint8();
-       zmosaic = state_fio->FgetUint8();
-       zchromakey = state_fio->FgetUint8();
-       zscroll = state_fio->FgetUint8();
-       zmode2 = state_fio->FgetUint8();
-       state_fio->Fread(ztpal, sizeof(ztpal), 1);
-       state_fio->Fread(zpal, sizeof(zpal), 1);
-       zpal_num = state_fio->FgetInt32();
-       state_fio->Fread(zpalette_pc, sizeof(zpalette_pc), 1);
-#endif
-       prev_vert_double = state_fio->FgetBool();
-       raster = state_fio->FgetInt32();
-       cblink = state_fio->FgetInt32();
-       ch_height = state_fio->FgetInt32();
-       hz_total = state_fio->FgetInt32();
-       hz_disp = state_fio->FgetInt32();
-       vt_disp = state_fio->FgetInt32();
-       st_addr = state_fio->FgetInt32();
-       vblank_clock = state_fio->FgetUint32();
-       cur_blank = state_fio->FgetBool();
-       
-       // post process
-       update_crtc(); // force update timing
-       
-       return true;
+               dr_zpriority = zpriority;
+               my_memcpy(dr_zcg, zcg, sizeof(dr_zcg));
+               my_memcpy(dr_aen_line, aen_line, sizeof(dr_aen_line));
+               my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc));
+               zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000];
+               zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f];
+               zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0];
+               zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff];
+               zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00];
+               zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f];
+               zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0];
+               zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff];
+#endif 
+               update_crtc(); // force update timing
+       }
+       return true;
 }
 
+}