OSDN Git Service

[VM][STATE] Apply New framework to some VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pv1000 / vdp.cpp
1 /*
2         CASIO PV-1000 Emulator 'ePV-1000'
3
4         Author : Takeda.Toshiya
5         Date   : 2006.11.16 -
6
7         [ video processor ]
8 */
9
10 #include "vdp.h"
11
12 static const scrntype_t palette_pc[8] = {
13         RGB_COLOR(  0,  0,  0), RGB_COLOR(255,  0,  0), RGB_COLOR(  0,255,  0), RGB_COLOR(255,255,  0),
14         RGB_COLOR(  0,  0,255), RGB_COLOR(255,  0,255), RGB_COLOR(  0,255,255), RGB_COLOR(255,255,255)
15 };
16 static const uint8_t plane[4] = {0, 1, 2, 4};
17
18 void VDP::initialize()
19 {
20         // register event to interrupt
21         register_vline_event(this);
22 }
23
24 void VDP::reset()
25 {
26         force_pattern = false;
27 }
28
29 void VDP::write_io8(uint32_t addr, uint32_t data)
30 {
31         switch(addr & 0xff) {
32         case 0xfe:
33                 vram = base + (data << 8);
34                 pcg = base + (data << 8) + 0x400;
35                 break;
36         case 0xff:
37                 pattern = base + ((data & 0x20) << 8);
38                 force_pattern = ((data & 0x10) != 0);
39                 break;
40         }
41 }
42
43 void VDP::event_callback(int event_id, int err)
44 {
45         d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
46 }
47
48 void VDP::event_vline(int v, int clock)
49 {
50         if(v < LINES_PER_HBLANK) {
51                 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
52                 register_event_by_clock(this, 0, 800, false, NULL);
53         } else {
54                 // hsync interrupt (not pending ???)
55                 d_cpu->set_intr_line(true, false, 0);
56         }
57 }
58
59 void VDP::draw_screen()
60 {
61         memset(bg, 0, sizeof(bg));
62         
63         for(int y = 0; y < 24; y++) {
64                 int y8 = y << 3, y32 = y << 5;
65                 
66                 for(int x = 2; x < 30; x++) {
67                         int x8 = x << 3;
68                         uint8_t code = vram[y32 + x];
69                         
70                         if(code < 0xe0 || force_pattern) {
71                                 draw_pattern(x8, y8, code << 5);
72                         } else {
73                                 draw_pcg(x8, y8, (code & 0x1f) << 5);
74                         }
75                 }
76         }
77         for(int y = 0; y < 192; y++) {
78                 scrntype_t* dest = emu->get_screen_buffer(y);
79                 for(int x = 0; x < 256; x++) {
80                         dest[x] = palette_pc[bg[y][x] & 7];
81                 }
82         }
83 }
84
85 void VDP::draw_pattern(int x8, int y8, uint16_t top)
86 {
87         // draw pattern on rom
88         for(int p = 1; p < 4; p++) {
89                 uint8_t col = plane[p];
90                 uint16_t p8 = top + (p << 3);
91                 
92                 for(int l = 0; l < 8; l++) {
93                         uint8_t* dest = &bg[y8 + l][x8];
94                         uint8_t pat = pattern[p8 + l];
95                         
96                         if(pat & 0x80) dest[0] |= col;
97                         if(pat & 0x40) dest[1] |= col;
98                         if(pat & 0x20) dest[2] |= col;
99                         if(pat & 0x10) dest[3] |= col;
100                         if(pat & 0x08) dest[4] |= col;
101                         if(pat & 0x04) dest[5] |= col;
102                         if(pat & 0x02) dest[6] |= col;
103                         if(pat & 0x01) dest[7] |= col;
104                 }
105         }
106 }
107
108 void VDP::draw_pcg(int x8, int y8, uint16_t top)
109 {
110         // draw pattern on ram
111         for(int p = 1; p < 4; p++) {
112                 uint8_t col = plane[p];
113                 uint16_t p8 = top + (p << 3);
114                 
115                 for(int l = 0; l < 8; l++) {
116                         uint8_t* dest = &bg[y8 + l][x8];
117                         uint8_t pat = pcg[p8 + l];
118                         
119                         if(pat & 0x80) dest[0] |= col;
120                         if(pat & 0x40) dest[1] |= col;
121                         if(pat & 0x20) dest[2] |= col;
122                         if(pat & 0x10) dest[3] |= col;
123                         if(pat & 0x08) dest[4] |= col;
124                         if(pat & 0x04) dest[5] |= col;
125                         if(pat & 0x02) dest[6] |= col;
126                         if(pat & 0x01) dest[7] |= col;
127                 }
128         }
129 }
130
131 #define STATE_VERSION   1
132
133 bool VDP::process_state(FILEIO* state_fio, bool loading)
134 {
135         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
136                 return false;
137         }
138         if(!state_fio->StateCheckInt32(this_device_id)) {
139                 return false;
140         }
141         if(loading) {
142                 vram = base + state_fio->FgetInt32_LE();
143                 pcg = base + state_fio->FgetInt32_LE();
144                 pattern = base + state_fio->FgetInt32_LE();
145         } else {
146                 state_fio->FputInt32_LE((int)(vram - base));
147                 state_fio->FputInt32_LE((int)(pcg - base));
148                 state_fio->FputInt32_LE((int)(pattern - base));
149         }
150         state_fio->StateBool(force_pattern);
151         return true;
152 }