OSDN Git Service

[VM][WIP] Pre-process to apply new state framework.Still not buildable.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc100 / crtc.cpp
index 7ddbf05..6aca8eb 100644 (file)
-/*\r
-       NEC PC-100 Emulator 'ePC-100'\r
-\r
-       Author : Takeda.Toshiya\r
-       Date   : 2008.07.14 -\r
-\r
-       [ crtc ]\r
-*/\r
-\r
-#include "crtc.h"\r
-#include "../i8259.h"\r
-\r
-void CRTC::initialize()\r
-{\r
-       // init vram\r
-       memset(vram, 0, sizeof(vram));\r
-       \r
-       // init bit control\r
-       shift = 0;\r
-       maskl = maskh = busl = bush = 0;\r
-       \r
-       // init vram plane\r
-       write_plane = 1;\r
-       read_plane = 0;\r
-       \r
-       // init pallete\r
-       for(int i = 1; i < 16; i++) {\r
-               palette[i] = 0x1ff;\r
-               update_palette(i);\r
-       }\r
-       palette[0] = 0;\r
-       update_palette(0);\r
-       \r
-       // register event\r
-       register_vline_event(this);\r
-}\r
-\r
-void CRTC::event_vline(int v, int clock)\r
-{\r
-       if(v == 512) {\r
-               d_pic->write_signal(SIG_I8259_IR4, 1, 1);\r
-       }\r
-}\r
-\r
-void CRTC::write_io8(uint32 addr, uint32 data)\r
-{\r
-       switch(addr & 0xff) {\r
-       case 0x30:\r
-               shift = data & 0x0f;\r
-               break;\r
-       case 0x38:\r
-               sel = data;\r
-               break;\r
-       case 0x3a:\r
-               regs[sel & 7] = data;\r
-               break;\r
-       case 0x3c:\r
-               vs = (vs & 0xff00) | data;\r
-               break;\r
-       case 0x3e:\r
-               vs = (vs & 0xff) | (data << 8);\r
-               break;\r
-       case 0x40:\r
-       case 0x42:\r
-       case 0x44:\r
-       case 0x46:\r
-       case 0x48:\r
-       case 0x4a:\r
-       case 0x4c:\r
-       case 0x4e:\r
-       case 0x50:\r
-       case 0x52:\r
-       case 0x54:\r
-       case 0x56:\r
-       case 0x58:\r
-       case 0x5a:\r
-       case 0x5c:\r
-       case 0x5e:\r
-               palette[(addr >> 1) & 0x0f] = (palette[(addr >> 1) & 0x0f] & 0xff00) | data;\r
-               update_palette((addr >> 1) & 0x0f);\r
-               break;\r
-       case 0x41:\r
-       case 0x43:\r
-       case 0x45:\r
-       case 0x47:\r
-       case 0x49:\r
-       case 0x4b:\r
-       case 0x4d:\r
-       case 0x4f:\r
-       case 0x51:\r
-       case 0x53:\r
-       case 0x55:\r
-       case 0x57:\r
-       case 0x59:\r
-       case 0x5b:\r
-       case 0x5d:\r
-       case 0x5f:\r
-               palette[(addr >> 1) & 0x0f] = (palette[(addr >> 1) & 0x0f] & 0xff) | (data << 8);\r
-               update_palette((addr >> 1) & 0x0f);\r
-               break;\r
-       case 0x60:\r
-               cmd = (cmd & 0xff00) | data;\r
-               break;\r
-       case 0x61:\r
-               cmd = (cmd & 0xff) | (data << 8);\r
-               break;\r
-       }\r
-}\r
-\r
-uint32 CRTC::read_io8(uint32 addr)\r
-{\r
-       uint32 val = 0xff;\r
-       \r
-       switch(addr & 0x3ff) {\r
-       case 0x30:\r
-               return shift;\r
-       case 0x38:\r
-               return sel;\r
-       case 0x3a:\r
-               return regs[sel & 7];\r
-       case 0x3c:\r
-               return vs & 0xff;\r
-       case 0x3e:\r
-               return vs >> 8;\r
-       case 0x40:\r
-       case 0x42:\r
-       case 0x44:\r
-       case 0x46:\r
-       case 0x48:\r
-       case 0x4a:\r
-       case 0x4c:\r
-       case 0x4e:\r
-       case 0x50:\r
-       case 0x52:\r
-       case 0x54:\r
-       case 0x56:\r
-       case 0x58:\r
-       case 0x5a:\r
-       case 0x5c:\r
-       case 0x5e:\r
-               return palette[(addr >> 1) & 0x0f] & 0xff;\r
-       case 0x41:\r
-       case 0x43:\r
-       case 0x45:\r
-       case 0x47:\r
-       case 0x49:\r
-       case 0x4b:\r
-       case 0x4d:\r
-       case 0x4f:\r
-       case 0x51:\r
-       case 0x53:\r
-       case 0x55:\r
-       case 0x57:\r
-       case 0x59:\r
-       case 0x5b:\r
-       case 0x5d:\r
-       case 0x5f:\r
-               return palette[(addr >> 1) & 0x0f] >> 8;\r
-       case 0x60:\r
-               return cmd & 0xff;\r
-       case 0x61:\r
-               return cmd >> 8;\r
-       }\r
-       return 0xff;\r
-}\r
-\r
-void CRTC::write_memory_mapped_io8(uint32 addr, uint32 data)\r
-{\r
-       if(addr & 1) {\r
-               bush = data;\r
-       } else {\r
-               busl = data;\r
-       }\r
-       uint32 bus = busl | (bush << 8) | (busl << 16) | (bush << 24);\r
-       bus >>= shift;\r
-       \r
-       if(addr & 1) {\r
-               uint32 h = (bus >> 8) & 0xff;\r
-               for(int pl = 0; pl < 4; pl++) {\r
-                       if(write_plane & (1 << pl)) {\r
-                               int ofsh = (addr & 0x1ffff) | (0x20000 * pl);\r
-                               vram[ofsh] = (vram[ofsh] & maskh) | (h & ~maskh);\r
-                       }\r
-               }\r
-       } else {\r
-               uint32 l = bus & 0xff;\r
-               for(int pl = 0; pl < 4; pl++) {\r
-                       if(write_plane & (1 << pl)) {\r
-                               int ofsl = (addr & 0x1ffff) | (0x20000 * pl);\r
-                               vram[ofsl] = (vram[ofsl] & maskl) | (l & ~maskl);\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-uint32 CRTC::read_memory_mapped_io8(uint32 addr)\r
-{\r
-       return vram[(addr & 0x1ffff) | (0x20000 * read_plane)];\r
-}\r
-\r
-void CRTC::write_memory_mapped_io16(uint32 addr, uint32 data)\r
-{\r
-       busl = (addr & 1) ? (data >> 8) : (data & 0xff);\r
-       bush = (addr & 1) ? (data & 0xff) : (data >> 8);\r
-       uint32 bus = busl | (bush << 8) | (busl << 16) | (bush << 24);\r
-       bus >>= shift;\r
-       uint32 l = bus & 0xff;\r
-       uint32 h = (bus >> 8) & 0xff;\r
-       \r
-       for(int pl = 0; pl < 4; pl++) {\r
-               if(write_plane & (1 << pl)) {\r
-                       int ofsl = ((addr & 1 ? (addr + 1) : addr) & 0x1ffff) | (0x20000 * pl);\r
-                       int ofsh = ((addr & 1 ? addr : (addr + 1)) & 0x1ffff) | (0x20000 * pl);\r
-                       vram[ofsl] = (vram[ofsl] & maskl) | (l & ~maskl);\r
-                       vram[ofsh] = (vram[ofsh] & maskh) | (h & ~maskh);\r
-               }\r
-       }\r
-}\r
-\r
-uint32 CRTC::read_memory_mapped_io16(uint32 addr)\r
-{\r
-       uint32 val = read_memory_mapped_io8(addr);\r
-       val |= read_memory_mapped_io8(addr + 1) << 8;\r
-       return val;\r
-}\r
-\r
-void CRTC::write_signal(int id, uint32 data, uint32 mask)\r
-{\r
-       if(id == SIG_CRTC_BITMASK_LOW) {\r
-               // $18: 8255 PA\r
-               maskl = data & 0xff;\r
-       } else if(id == SIG_CRTC_BITMASK_HIGH) {\r
-               // $1A: 8255 PB\r
-               maskh = data & 0xff;\r
-       } else if(id == SIG_CRTC_VRAM_PLANE) {\r
-               // $1C: 8255 PC\r
-               write_plane = data & 0x0f;\r
-               read_plane = (data >> 4) & 3;\r
-       }\r
-}\r
-\r
-void CRTC::draw_screen()\r
-{\r
-       // display region\r
-       int hd = (regs[2] >> 1) & 0x3f;\r
-       int vd = (regs[6] >> 1) & 0x3f;\r
-       int hs = (int)(int8)((regs[0] & 0x40) ? (regs[0] | 0x80) : (regs[0] & 0x3f));\r
-//     int hs = (int)(int8)regs[0];\r
-       int vs_tmp = (int)(int16)((vs & 0x400) ? (vs | 0xf800) : (vs & 0x3ff));\r
-       int sa = (hs + hd + 1) * 2 + (vs_tmp + vd) * 0x80;\r
-//     int sa = (hs + hd + 1) * 2 + ((vs & 0x3ff) + vd) * 0x80;\r
-       \r
-       if(cmd != 0xffff) {\r
-               // mono\r
-               scrntype col = RGB_COLOR(255, 255, 255);\r
-               for(int y = 0; y < 512; y++) {\r
-                       int ptr = sa & 0x1ffff;\r
-                       sa += 0x80;\r
-                       scrntype *dest = emu->screen_buffer(y);\r
-                       \r
-                       for(int x = 0; x < 720; x += 8) {\r
-                               uint8 pat = vram[ptr];\r
-                               ptr = (ptr + 1) & 0x1ffff;\r
-                               \r
-                               dest[x + 0] = pat & 0x01 ? col : 0;\r
-                               dest[x + 1] = pat & 0x02 ? col : 0;\r
-                               dest[x + 2] = pat & 0x04 ? col : 0;\r
-                               dest[x + 3] = pat & 0x08 ? col : 0;\r
-                               dest[x + 4] = pat & 0x10 ? col : 0;\r
-                               dest[x + 5] = pat & 0x20 ? col : 0;\r
-                               dest[x + 6] = pat & 0x40 ? col : 0;\r
-                               dest[x + 7] = pat & 0x80 ? col : 0;\r
-                       }\r
-               }\r
-       } else {\r
-               // color\r
-               for(int y = 0; y < 512; y++) {\r
-                       int ptr = sa & 0x1ffff;\r
-                       sa += 0x80;\r
-                       scrntype *dest = emu->screen_buffer(y);\r
-                       \r
-                       for(int x = 0; x < 720; x += 8) {\r
-                               uint8 p0 = vram[0x00000 | ptr];\r
-                               uint8 p1 = vram[0x20000 | ptr];\r
-                               uint8 p2 = vram[0x40000 | ptr];\r
-                               uint8 p3 = vram[0x60000 | ptr];\r
-                               ptr = (ptr + 1) & 0x1ffff;\r
-                               \r
-                               dest[x + 0] = palette_pc[((p0 & 0x01) << 0) | ((p1 & 0x01) << 1) | ((p2 & 0x01) << 2) | ((p3 & 0x01) << 3)];\r
-                               dest[x + 1] = palette_pc[((p0 & 0x02) >> 1) | ((p1 & 0x02) << 0) | ((p2 & 0x02) << 1) | ((p3 & 0x02) << 2)];\r
-                               dest[x + 2] = palette_pc[((p0 & 0x04) >> 2) | ((p1 & 0x04) >> 1) | ((p2 & 0x04) << 0) | ((p3 & 0x04) << 1)];\r
-                               dest[x + 3] = palette_pc[((p0 & 0x08) >> 3) | ((p1 & 0x08) >> 2) | ((p2 & 0x08) >> 1) | ((p3 & 0x08) << 0)];\r
-                               dest[x + 4] = palette_pc[((p0 & 0x10) >> 4) | ((p1 & 0x10) >> 3) | ((p2 & 0x10) >> 2) | ((p3 & 0x10) >> 1)];\r
-                               dest[x + 5] = palette_pc[((p0 & 0x20) >> 5) | ((p1 & 0x20) >> 4) | ((p2 & 0x20) >> 3) | ((p3 & 0x20) >> 2)];\r
-                               dest[x + 6] = palette_pc[((p0 & 0x40) >> 6) | ((p1 & 0x40) >> 5) | ((p2 & 0x40) >> 4) | ((p3 & 0x40) >> 3)];\r
-                               dest[x + 7] = palette_pc[((p0 & 0x80) >> 7) | ((p1 & 0x80) >> 6) | ((p2 & 0x80) >> 5) | ((p3 & 0x80) >> 4)];\r
-                       }\r
-               }\r
-       }\r
-       emu->screen_skip_line = false;\r
-}\r
-\r
-void CRTC::update_palette(int num)\r
-{\r
-       int r = (palette[num] >> 0) & 7;\r
-       int g = (palette[num] >> 3) & 7;\r
-       int b = (palette[num] >> 6) & 7;\r
-       palette_pc[num] = RGB_COLOR(r << 5, g << 5, b << 5);\r
-}\r
-\r
+/*
+       NEC PC-100 Emulator 'ePC-100'
+
+       Author : Takeda.Toshiya
+       Date   : 2008.07.14 -
+
+       [ crtc ]
+*/
+
+#include "crtc.h"
+#include "../i8259.h"
+
+void CRTC::initialize()
+{
+       // init vram
+       memset(vram, 0, sizeof(vram));
+       
+       // init bit control
+       shift = 0;
+       maskl = maskh = busl = bush = 0;
+       
+       // init vram plane
+       write_plane = 1;
+       read_plane = 0;
+       
+       // init pallete
+       for(int i = 1; i < 16; i++) {
+               palette[i] = 0x1ff;
+               update_palette(i);
+       }
+       palette[0] = 0;
+       update_palette(0);
+       
+       // register event
+       register_vline_event(this);
+}
+
+void CRTC::event_vline(int v, int clock)
+{
+       if(v == 512) {
+               d_pic->write_signal(SIG_I8259_IR4, 1, 1);
+       }
+}
+
+void CRTC::write_io8(uint32_t addr, uint32_t data)
+{
+       switch(addr & 0xff) {
+       case 0x30:
+               shift = data & 0x0f;
+               break;
+       case 0x38:
+               sel = data;
+               break;
+       case 0x3a:
+               regs[sel & 7] = data;
+               break;
+       case 0x3c:
+               vs = (vs & 0xff00) | data;
+               break;
+       case 0x3e:
+               vs = (vs & 0xff) | (data << 8);
+               break;
+       case 0x40:
+       case 0x42:
+       case 0x44:
+       case 0x46:
+       case 0x48:
+       case 0x4a:
+       case 0x4c:
+       case 0x4e:
+       case 0x50:
+       case 0x52:
+       case 0x54:
+       case 0x56:
+       case 0x58:
+       case 0x5a:
+       case 0x5c:
+       case 0x5e:
+               palette[(addr >> 1) & 0x0f] = (palette[(addr >> 1) & 0x0f] & 0xff00) | data;
+               update_palette((addr >> 1) & 0x0f);
+               break;
+       case 0x41:
+       case 0x43:
+       case 0x45:
+       case 0x47:
+       case 0x49:
+       case 0x4b:
+       case 0x4d:
+       case 0x4f:
+       case 0x51:
+       case 0x53:
+       case 0x55:
+       case 0x57:
+       case 0x59:
+       case 0x5b:
+       case 0x5d:
+       case 0x5f:
+               palette[(addr >> 1) & 0x0f] = (palette[(addr >> 1) & 0x0f] & 0xff) | (data << 8);
+               update_palette((addr >> 1) & 0x0f);
+               break;
+       case 0x60:
+               cmd = (cmd & 0xff00) | data;
+               break;
+       case 0x61:
+               cmd = (cmd & 0xff) | (data << 8);
+               break;
+       }
+}
+
+uint32_t CRTC::read_io8(uint32_t addr)
+{
+       uint32_t val = 0xff;
+       
+       switch(addr & 0x3ff) {
+       case 0x30:
+               return shift;
+       case 0x38:
+               return sel;
+       case 0x3a:
+               return regs[sel & 7];
+       case 0x3c:
+               return vs & 0xff;
+       case 0x3e:
+               return vs >> 8;
+       case 0x40:
+       case 0x42:
+       case 0x44:
+       case 0x46:
+       case 0x48:
+       case 0x4a:
+       case 0x4c:
+       case 0x4e:
+       case 0x50:
+       case 0x52:
+       case 0x54:
+       case 0x56:
+       case 0x58:
+       case 0x5a:
+       case 0x5c:
+       case 0x5e:
+               return palette[(addr >> 1) & 0x0f] & 0xff;
+       case 0x41:
+       case 0x43:
+       case 0x45:
+       case 0x47:
+       case 0x49:
+       case 0x4b:
+       case 0x4d:
+       case 0x4f:
+       case 0x51:
+       case 0x53:
+       case 0x55:
+       case 0x57:
+       case 0x59:
+       case 0x5b:
+       case 0x5d:
+       case 0x5f:
+               return palette[(addr >> 1) & 0x0f] >> 8;
+       case 0x60:
+               return cmd & 0xff;
+       case 0x61:
+               return cmd >> 8;
+       }
+       return 0xff;
+}
+
+void CRTC::write_memory_mapped_io8(uint32_t addr, uint32_t data)
+{
+       if(addr & 1) {
+               bush = data;
+       } else {
+               busl = data;
+       }
+       uint32_t bus = busl | (bush << 8) | (busl << 16) | (bush << 24);
+       bus >>= shift;
+       
+       if(addr & 1) {
+               uint32_t h = (bus >> 8) & 0xff;
+               for(int pl = 0; pl < 4; pl++) {
+                       if(write_plane & (1 << pl)) {
+                               int ofsh = (addr & 0x1ffff) | (0x20000 * pl);
+                               vram[ofsh] = (vram[ofsh] & maskh) | (h & ~maskh);
+                       }
+               }
+       } else {
+               uint32_t l = bus & 0xff;
+               for(int pl = 0; pl < 4; pl++) {
+                       if(write_plane & (1 << pl)) {
+                               int ofsl = (addr & 0x1ffff) | (0x20000 * pl);
+                               vram[ofsl] = (vram[ofsl] & maskl) | (l & ~maskl);
+                       }
+               }
+       }
+}
+
+uint32_t CRTC::read_memory_mapped_io8(uint32_t addr)
+{
+       return vram[(addr & 0x1ffff) | (0x20000 * read_plane)];
+}
+
+void CRTC::write_memory_mapped_io16(uint32_t addr, uint32_t data)
+{
+       busl = (addr & 1) ? (data >> 8) : (data & 0xff);
+       bush = (addr & 1) ? (data & 0xff) : (data >> 8);
+       uint32_t bus = busl | (bush << 8) | (busl << 16) | (bush << 24);
+       bus >>= shift;
+       uint32_t l = bus & 0xff;
+       uint32_t h = (bus >> 8) & 0xff;
+       
+       for(int pl = 0; pl < 4; pl++) {
+               if(write_plane & (1 << pl)) {
+                       int ofsl = ((addr & 1 ? (addr + 1) : addr) & 0x1ffff) | (0x20000 * pl);
+                       int ofsh = ((addr & 1 ? addr : (addr + 1)) & 0x1ffff) | (0x20000 * pl);
+                       vram[ofsl] = (vram[ofsl] & maskl) | (l & ~maskl);
+                       vram[ofsh] = (vram[ofsh] & maskh) | (h & ~maskh);
+               }
+       }
+}
+
+uint32_t CRTC::read_memory_mapped_io16(uint32_t addr)
+{
+       uint32_t val = read_memory_mapped_io8(addr);
+       val |= read_memory_mapped_io8(addr + 1) << 8;
+       return val;
+}
+
+void CRTC::write_signal(int id, uint32_t data, uint32_t mask)
+{
+       if(id == SIG_CRTC_BITMASK_LOW) {
+               // $18: 8255 PA
+               maskl = data & 0xff;
+       } else if(id == SIG_CRTC_BITMASK_HIGH) {
+               // $1A: 8255 PB
+               maskh = data & 0xff;
+       } else if(id == SIG_CRTC_VRAM_PLANE) {
+               // $1C: 8255 PC
+               write_plane = data & 0x0f;
+               read_plane = (data >> 4) & 3;
+       }
+}
+
+void CRTC::draw_screen()
+{
+       // display region
+       int hd = (regs[2] >> 1) & 0x3f;
+       int vd = (regs[6] >> 1) & 0x3f;
+       int hs = (int)(int8_t)((regs[0] & 0x40) ? (regs[0] | 0x80) : (regs[0] & 0x3f));
+//     int hs = (int)(int8_t)regs[0];
+       int vs_tmp = (int)(int16_t)((vs & 0x400) ? (vs | 0xf800) : (vs & 0x3ff));
+       int sa = (hs + hd + 1) * 2 + (vs_tmp + vd) * 0x80;
+//     int sa = (hs + hd + 1) * 2 + ((vs & 0x3ff) + vd) * 0x80;
+       
+       if(cmd != 0xffff) {
+               // mono
+               scrntype_t col = RGB_COLOR(255, 255, 255);
+               for(int y = 0; y < 512; y++) {
+                       int ptr = sa & 0x1ffff;
+                       sa += 0x80;
+                       scrntype_t *dest = emu->get_screen_buffer(y);
+                       
+                       for(int x = 0; x < 720; x += 8) {
+                               uint8_t pat = vram[ptr];
+                               ptr = (ptr + 1) & 0x1ffff;
+                               
+                               dest[x + 0] = pat & 0x01 ? col : 0;
+                               dest[x + 1] = pat & 0x02 ? col : 0;
+                               dest[x + 2] = pat & 0x04 ? col : 0;
+                               dest[x + 3] = pat & 0x08 ? col : 0;
+                               dest[x + 4] = pat & 0x10 ? col : 0;
+                               dest[x + 5] = pat & 0x20 ? col : 0;
+                               dest[x + 6] = pat & 0x40 ? col : 0;
+                               dest[x + 7] = pat & 0x80 ? col : 0;
+                       }
+               }
+       } else {
+               // color
+               for(int y = 0; y < 512; y++) {
+                       int ptr = sa & 0x1ffff;
+                       sa += 0x80;
+                       scrntype_t *dest = emu->get_screen_buffer(y);
+                       
+                       for(int x = 0; x < 720; x += 8) {
+                               uint8_t p0 = vram[0x00000 | ptr];
+                               uint8_t p1 = vram[0x20000 | ptr];
+                               uint8_t p2 = vram[0x40000 | ptr];
+                               uint8_t p3 = vram[0x60000 | ptr];
+                               ptr = (ptr + 1) & 0x1ffff;
+                               
+                               dest[x + 0] = palette_pc[((p0 & 0x01) << 0) | ((p1 & 0x01) << 1) | ((p2 & 0x01) << 2) | ((p3 & 0x01) << 3)];
+                               dest[x + 1] = palette_pc[((p0 & 0x02) >> 1) | ((p1 & 0x02) << 0) | ((p2 & 0x02) << 1) | ((p3 & 0x02) << 2)];
+                               dest[x + 2] = palette_pc[((p0 & 0x04) >> 2) | ((p1 & 0x04) >> 1) | ((p2 & 0x04) << 0) | ((p3 & 0x04) << 1)];
+                               dest[x + 3] = palette_pc[((p0 & 0x08) >> 3) | ((p1 & 0x08) >> 2) | ((p2 & 0x08) >> 1) | ((p3 & 0x08) << 0)];
+                               dest[x + 4] = palette_pc[((p0 & 0x10) >> 4) | ((p1 & 0x10) >> 3) | ((p2 & 0x10) >> 2) | ((p3 & 0x10) >> 1)];
+                               dest[x + 5] = palette_pc[((p0 & 0x20) >> 5) | ((p1 & 0x20) >> 4) | ((p2 & 0x20) >> 3) | ((p3 & 0x20) >> 2)];
+                               dest[x + 6] = palette_pc[((p0 & 0x40) >> 6) | ((p1 & 0x40) >> 5) | ((p2 & 0x40) >> 4) | ((p3 & 0x40) >> 3)];
+                               dest[x + 7] = palette_pc[((p0 & 0x80) >> 7) | ((p1 & 0x80) >> 6) | ((p2 & 0x80) >> 5) | ((p3 & 0x80) >> 4)];
+                       }
+               }
+       }
+       emu->screen_skip_line(false);
+}
+
+void CRTC::update_palette(int num)
+{
+       int r = (palette[num] >> 0) & 7;
+       int g = (palette[num] >> 3) & 7;
+       int b = (palette[num] >> 6) & 7;
+       palette_pc[num] = RGB_COLOR(r << 5, g << 5, b << 5);
+}
+
+#define STATE_VERSION  1
+
+#include "../../statesub.h"
+
+void CRTC::decl_state()
+{
+       enter_decl_state(STATE_VERSION);
+
+       DECL_STATE_ENTRY_SCRNTYPE_T_1D_ARRAY(palette_pc, 16);
+       DECL_STATE_ENTRY_1D_ARRAY(palette, 16);
+       DECL_STATE_ENTRY_UINT8(sel);
+       DECL_STATE_ENTRY_1D_ARRAY(regs, sizeof(regs));
+       DECL_STATE_ENTRY_UINT16(vs);
+       DECL_STATE_ENTRY_UINT16(cmd);
+       DECL_STATE_ENTRY_1D_ARRAY(vram, sizeof(vram));
+       DECL_STATE_ENTRY_UINT32(shift);
+       DECL_STATE_ENTRY_UINT32(maskl);
+       DECL_STATE_ENTRY_UINT32(maskh);
+       DECL_STATE_ENTRY_UINT32(busl);
+       DECL_STATE_ENTRY_UINT32(bush);
+       DECL_STATE_ENTRY_UINT32(write_plane);
+       DECL_STATE_ENTRY_UINT32(read_plane);
+       
+       leave_decl_state();
+}
+       
+void CRTC::save_state(FILEIO* state_fio)
+{
+       if(state_entry != NULL) {
+               state_entry->save_state(state_fio);
+       }
+//     state_fio->FputUint32(STATE_VERSION);
+//     state_fio->FputInt32(this_device_id);
+       
+//     state_fio->Fwrite(palette_pc, sizeof(palette_pc), 1);
+//     state_fio->Fwrite(palette, sizeof(palette), 1);
+//     state_fio->FputUint8(sel);
+//     state_fio->Fwrite(regs, sizeof(regs), 1);
+//     state_fio->FputUint16(vs);
+//     state_fio->FputUint16(cmd);
+//     state_fio->Fwrite(vram, sizeof(vram), 1);
+//     state_fio->FputUint32(shift);
+//     state_fio->FputUint32(maskl);
+//     state_fio->FputUint32(maskh);
+//     state_fio->FputUint32(busl);
+//     state_fio->FputUint32(bush);
+//     state_fio->FputUint32(write_plane);
+//     state_fio->FputUint32(read_plane);
+}
+
+bool CRTC::load_state(FILEIO* state_fio)
+{
+       bool mb = false;
+       if(state_entry != NULL) {
+               mb = state_entry->load_state(state_fio);
+       }
+       if(!mb) {
+               return false;
+       }
+//     if(state_fio->FgetUint32() != STATE_VERSION) {
+//             return false;
+//     }
+//     if(state_fio->FgetInt32() != this_device_id) {
+//             return false;
+//     }
+//     state_fio->Fread(palette_pc, sizeof(palette_pc), 1);
+//     state_fio->Fread(palette, sizeof(palette), 1);
+//     sel = state_fio->FgetUint8();
+//     state_fio->Fread(regs, sizeof(regs), 1);
+//     vs = state_fio->FgetUint16();
+//     cmd = state_fio->FgetUint16();
+//     state_fio->Fread(vram, sizeof(vram), 1);
+//     shift = state_fio->FgetUint32();
+//     maskl = state_fio->FgetUint32();
+//     maskh = state_fio->FgetUint32();
+//     busl = state_fio->FgetUint32();
+//     bush = state_fio->FgetUint32();
+//     write_plane = state_fio->FgetUint32();
+//     read_plane = state_fio->FgetUint32();
+       return true;
+}
+
+bool CRTC::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       state_fio->StateBuffer(palette_pc, sizeof(palette_pc), 1);
+       state_fio->StateBuffer(palette, sizeof(palette), 1);
+       state_fio->StateUint8(sel);
+       state_fio->StateBuffer(regs, sizeof(regs), 1);
+       state_fio->StateUint16(vs);
+       state_fio->StateUint16(cmd);
+       state_fio->StateBuffer(vram, sizeof(vram), 1);
+       state_fio->StateUint32(shift);
+       state_fio->StateUint32(maskl);
+       state_fio->StateUint32(maskh);
+       state_fio->StateUint32(busl);
+       state_fio->StateUint32(bush);
+       state_fio->StateUint32(write_plane);
+       state_fio->StateUint32(read_plane);
+       return true;
+}