OSDN Git Service

[VM][UPD7810] Fix FTBFS.
[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 #include "../../statesub.h"
134
135 void VDP::decl_state()
136 {
137         enter_decl_state(STATE_VERSION);
138
139         DECL_STATE_ENTRY_INT32(tmp_vram_size);    // (int)(vram - base);
140         DECL_STATE_ENTRY_INT32(tmp_pcg_size);     // (int)(pcg - base);
141         DECL_STATE_ENTRY_INT32(tmp_pattern_size); // (int)(pattern - base);
142         DECL_STATE_ENTRY_BOOL(force_pattern);
143         
144         leave_decl_state();
145 }
146
147 void VDP::save_state(FILEIO* state_fio)
148 {
149         tmp_vram_size = (int)(vram - base);
150         tmp_pcg_size = (int)(pcg - base);
151         tmp_pattern_size = (int)(pattern - base);
152
153         if(state_entry != NULL) {
154                 state_entry->save_state(state_fio);
155         }
156 //      state_fio->FputUint32(STATE_VERSION);
157 //      state_fio->FputInt32(this_device_id);
158         
159 //      state_fio->FputInt32((int)(vram - base));
160 //      state_fio->FputInt32((int)(pcg - base));
161 //      state_fio->FputInt32((int)(pattern - base));
162 //      state_fio->FputBool(force_pattern);
163 }
164
165 bool VDP::load_state(FILEIO* state_fio)
166 {
167         bool mb = false;
168         if(state_entry != NULL) {
169                 mb = state_entry->load_state(state_fio);
170         }
171         if(!mb) {
172                 return false;
173         }
174 //      if(state_fio->FgetUint32() != STATE_VERSION) {
175 //              return false;
176 //      }
177 //      if(state_fio->FgetInt32() != this_device_id) {
178 //              return false;
179 //      }
180 //      vram = base + state_fio->FgetInt32();
181 //      pcg = base + state_fio->FgetInt32();
182 //      pattern = base + state_fio->FgetInt32();
183 //      force_pattern = state_fio->FgetBool();
184         vram = base + tmp_vram_size;
185         pcg = base + tmp_pcg_size;
186         pattern = base + tmp_pattern_size;
187         return true;
188 }
189
190 bool VDP::process_state(FILEIO* state_fio, bool loading)
191 {
192         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
193                 return false;
194         }
195         if(!state_fio->StateCheckInt32(this_device_id)) {
196                 return false;
197         }
198         if(loading) {
199                 vram = base + state_fio->FgetInt32_LE();
200                 pcg = base + state_fio->FgetInt32_LE();
201                 pattern = base + state_fio->FgetInt32_LE();
202         } else {
203                 state_fio->FputInt32_LE((int)(vram - base));
204                 state_fio->FputInt32_LE((int)(pcg - base));
205                 state_fio->FputInt32_LE((int)(pattern - base));
206         }
207         state_fio->StateBool(force_pattern);
208         return true;
209 }