OSDN Git Service

3203148bdf5f05f9fc5d9285e866d0d50966591d
[csp-qt/common_source_project-fm7.git] / source / src / vm / qc10 / display.cpp
1 /*
2         EPSON QC-10 Emulator 'eQC-10'
3
4         Author : Takeda.Toshiya
5         Date   : 2008.02.16 -
6
7         [ display ]
8 */
9
10 #include <math.h>
11 #include "display.h"
12 #include "../upd7220.h"
13
14 void DISPLAY::initialize()
15 {
16 #ifdef _COLOR_MONITOR
17         memset(vram_r, 0, sizeof(vram_r));
18         memset(vram_g, 0, sizeof(vram_g));
19         memset(vram_b, 0, sizeof(vram_b));
20 #else
21         memset(vram, 0, sizeof(vram));
22         
23         // load rom image
24         FILEIO* fio = new FILEIO();
25         if(fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {
26                 fio->Fread(font, sizeof(font), 1);
27                 fio->Fclose();
28         }
29         delete fio;
30 #endif
31         
32         // create pc palette
33 #ifdef _COLOR_MONITOR
34         for(int i = 0; i < 8; i++) {
35                 palette_pc[i] = RGB_COLOR(i & 1 ? 255 : 0, i & 2 ? 255 : 0, (i & 4) ? 255 : 0);
36         }
37 #else
38         for(int i = 1; i < 8; i++) {
39                 palette_pc[i + 0] = RGB_COLOR(0, 160, 0);
40                 palette_pc[i + 8] = RGB_COLOR(0, 255, 0);
41         }
42         palette_pc[0] = palette_pc[8] = 0;
43 #endif
44         
45         // cursor blinking
46         register_frame_event(this);
47         blink = 0;
48 }
49
50 void DISPLAY::reset()
51 {
52 #ifdef _COLOR_MONITOR
53         d_gdc->set_vram_ptr(vram_b, VRAM_SIZE);
54 #endif
55         bank = 1;
56 }
57
58 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
59 {
60         switch(addr & 0xff) {
61         case 0x2d:
62 #ifdef _COLOR_MONITOR
63                 if(data & 1) {
64                         d_gdc->set_vram_ptr(vram_b, VRAM_SIZE);
65                 } else if(data & 2) {
66                         d_gdc->set_vram_ptr(vram_g, VRAM_SIZE);
67                 } else {
68                         d_gdc->set_vram_ptr(vram_r, VRAM_SIZE);
69                 }
70 #endif
71                 bank = data;
72                 break;
73         }
74 }
75
76 uint32_t DISPLAY::read_io8(uint32_t addr)
77 {
78         switch(addr & 0xff) {
79         case 0x2c:
80 #ifdef _COLOR_MONITOR
81                 return 0xfd;
82 #else
83                 return 0xfe;
84 #endif
85         case 0x2d:
86                 return bank;
87         }
88         return 0xff;
89 }
90
91 void DISPLAY::event_frame()
92 {
93         blink++;
94 }
95
96 void DISPLAY::draw_screen()
97 {
98         uint8_t cg = sync[0] & 0x22;
99         int al = (sync[6] | (sync[7] << 8)) & 0x3ff;
100         
101         for(int i = 0, total = 0; i < 4 && total < al; i++) {
102                 uint32_t tmp = ra[4 * i];
103                 tmp |= ra[4 * i + 1] << 8;
104                 tmp |= ra[4 * i + 2] << 16;
105                 tmp |= ra[4 * i + 3] << 24;
106                 
107                 int ptr = tmp & ((cg == 0x20) ? 0x1fff : 0x3ffff);
108                 ptr <<= 1;
109                 int line = (tmp >> 20) & 0x3ff;
110                 bool gfx = (cg == 2) ? true : (cg == 0x20) ? false : ((tmp & 0x40000000) != 0);
111                 bool wide = ((tmp & 0x80000000) != 0);
112                 int caddr = ((cs[0] & 0x80) && ((cs[1] & 0x20) || !(blink & 0x10))) ? (*ead << 1) : -1;
113                 
114 #ifdef _COLOR_MONITOR
115 //              if(gfx) {
116                         for(int y = total; y < total + line && y < 400; y++) {
117                                 if(wide) {
118                                         for(int x = 0; x < 640; x+= 16) {
119                                                 uint8_t r = vram_r[ptr];
120                                                 uint8_t g = vram_g[ptr];
121                                                 uint8_t b = vram_b[ptr++];
122                                                 ptr &= VRAM_SIZE - 1;
123                                                 
124                                                 screen[y][x +  0] = screen[y][x +  1] = ((r & 0x01) ? 1 : 0) | ((g & 0x01) ? 2 : 0) | ((b & 0x01) ? 4 : 0);
125                                                 screen[y][x +  2] = screen[y][x +  3] = ((r & 0x02) ? 1 : 0) | ((g & 0x02) ? 2 : 0) | ((b & 0x02) ? 4 : 0);
126                                                 screen[y][x +  4] = screen[y][x +  5] = ((r & 0x04) ? 1 : 0) | ((g & 0x04) ? 2 : 0) | ((b & 0x04) ? 4 : 0);
127                                                 screen[y][x +  6] = screen[y][x +  7] = ((r & 0x08) ? 1 : 0) | ((g & 0x08) ? 2 : 0) | ((b & 0x08) ? 4 : 0);
128                                                 screen[y][x +  8] = screen[y][x +  9] = ((r & 0x10) ? 1 : 0) | ((g & 0x10) ? 2 : 0) | ((b & 0x10) ? 4 : 0);
129                                                 screen[y][x + 10] = screen[y][x + 11] = ((r & 0x20) ? 1 : 0) | ((g & 0x20) ? 2 : 0) | ((b & 0x20) ? 4 : 0);
130                                                 screen[y][x + 12] = screen[y][x + 13] = ((r & 0x40) ? 1 : 0) | ((g & 0x40) ? 2 : 0) | ((b & 0x40) ? 4 : 0);
131                                                 screen[y][x + 14] = screen[y][x + 15] = ((r & 0x80) ? 1 : 0) | ((g & 0x80) ? 2 : 0) | ((b & 0x80) ? 4 : 0);
132                                         }
133                                 } else {
134                                         for(int x = 0; x < 640; x+= 8) {
135                                                 uint8_t r = vram_r[ptr];
136                                                 uint8_t g = vram_g[ptr];
137                                                 uint8_t b = vram_b[ptr++];
138                                                 ptr &= VRAM_SIZE - 1;
139                                                 
140                                                 screen[y][x + 0] = ((r & 0x01) ? 1 : 0) | ((g & 0x01) ? 2 : 0) | ((b & 0x01) ? 4 : 0);
141                                                 screen[y][x + 1] = ((r & 0x02) ? 1 : 0) | ((g & 0x02) ? 2 : 0) | ((b & 0x02) ? 4 : 0);
142                                                 screen[y][x + 2] = ((r & 0x04) ? 1 : 0) | ((g & 0x04) ? 2 : 0) | ((b & 0x04) ? 4 : 0);
143                                                 screen[y][x + 3] = ((r & 0x08) ? 1 : 0) | ((g & 0x08) ? 2 : 0) | ((b & 0x08) ? 4 : 0);
144                                                 screen[y][x + 4] = ((r & 0x10) ? 1 : 0) | ((g & 0x10) ? 2 : 0) | ((b & 0x10) ? 4 : 0);
145                                                 screen[y][x + 5] = ((r & 0x20) ? 1 : 0) | ((g & 0x20) ? 2 : 0) | ((b & 0x20) ? 4 : 0);
146                                                 screen[y][x + 6] = ((r & 0x40) ? 1 : 0) | ((g & 0x40) ? 2 : 0) | ((b & 0x40) ? 4 : 0);
147                                                 screen[y][x + 7] = ((r & 0x80) ? 1 : 0) | ((g & 0x80) ? 2 : 0) | ((b & 0x80) ? 4 : 0);
148                                         }
149                                 }
150                         }
151 //              }
152 #else
153                 if(gfx) {
154                         for(int y = total; y < total + line && y < 400; y++) {
155                                 if(wide) {
156                                         for(int x = 0; x < 640; x+= 16) {
157                                                 uint8_t pat = vram[ptr++];
158                                                 ptr &= VRAM_SIZE - 1;
159                                                 
160                                                 screen[y][x +  0] = screen[y][x +  1] = (pat & 0x01) ? 1 : 0;
161                                                 screen[y][x +  2] = screen[y][x +  3] = (pat & 0x02) ? 1 : 0;
162                                                 screen[y][x +  4] = screen[y][x +  5] = (pat & 0x04) ? 1 : 0;
163                                                 screen[y][x +  6] = screen[y][x +  7] = (pat & 0x08) ? 1 : 0;
164                                                 screen[y][x +  8] = screen[y][x +  9] = (pat & 0x10) ? 1 : 0;
165                                                 screen[y][x + 10] = screen[y][x + 11] = (pat & 0x20) ? 1 : 0;
166                                                 screen[y][x + 12] = screen[y][x + 13] = (pat & 0x40) ? 1 : 0;
167                                                 screen[y][x + 14] = screen[y][x + 15] = (pat & 0x80) ? 1 : 0;
168                                         }
169                                 } else {
170                                         for(int x = 0; x < 640; x+= 8) {
171                                                 uint8_t pat = vram[ptr++];
172                                                 ptr &= VRAM_SIZE - 1;
173                                                 
174                                                 screen[y][x + 0] = (pat & 0x01) ? 1 : 0;
175                                                 screen[y][x + 1] = (pat & 0x02) ? 1 : 0;
176                                                 screen[y][x + 2] = (pat & 0x04) ? 1 : 0;
177                                                 screen[y][x + 3] = (pat & 0x08) ? 1 : 0;
178                                                 screen[y][x + 4] = (pat & 0x10) ? 1 : 0;
179                                                 screen[y][x + 5] = (pat & 0x20) ? 1 : 0;
180                                                 screen[y][x + 6] = (pat & 0x40) ? 1 : 0;
181                                                 screen[y][x + 7] = (pat & 0x80) ? 1 : 0;
182                                         }
183                                 }
184                         }
185                 } else {
186                         for(int y = total; y < total + line;) {
187                                 if(wide) {
188                                         for(int x = 0; x < 640; x += 16) {
189                                                 bool cursor = (ptr == caddr);
190                                                 uint8_t code = vram[ptr++];
191                                                 uint8_t attrib = vram[ptr++];
192                                                 ptr &= VRAM_SIZE - 1;
193                                                 uint8_t* pattern = &font[code * 16];
194                                                 
195                                                 for(int l = y % 16; l < 16 && (y + l) < 400; l++) {
196                                                         uint8_t pat = pattern[l];
197                                                         // attribute
198                                                         if((attrib & 0x40) || ((attrib & 0x80) && (blink & 0x10))) {
199                                                                 pat = 0;
200                                                         }
201                                                         if(attrib & 8) {
202                                                                 pat = ~pat;
203                                                         }
204                                                         uint8_t col = (attrib & 4) ? 9 : 1;
205                                                         
206                                                         screen[y + l][x +  0] = screen[y + l][x +  1] = (pat & 0x01) ? col : 0;
207                                                         screen[y + l][x +  2] = screen[y + l][x +  3] = (pat & 0x02) ? col : 0;
208                                                         screen[y + l][x +  4] = screen[y + l][x +  5] = (pat & 0x04) ? col : 0;
209                                                         screen[y + l][x +  6] = screen[y + l][x +  7] = (pat & 0x08) ? col : 0;
210                                                         screen[y + l][x +  8] = screen[y + l][x +  9] = (pat & 0x10) ? col : 0;
211                                                         screen[y + l][x + 10] = screen[y + l][x + 11] = (pat & 0x20) ? col : 0;
212                                                         screen[y + l][x + 12] = screen[y + l][x + 13] = (pat & 0x40) ? col : 0;
213                                                         screen[y + l][x + 14] = screen[y + l][x + 15] = (pat & 0x80) ? col : 0;
214                                                 }
215                                                 if(cursor) {
216                                                         int top = cs[1] & 0x1f, bottom = cs[2] >> 3;
217                                                         for(int l = top; l < bottom && l < 16; l++) {
218                                                                 memset(&screen[y + l][x], 1, 16);
219                                                         }
220                                                 }
221                                         }
222                                 } else {
223                                         for(int x = 0; x < 640; x += 8) {
224                                                 bool cursor = (ptr == caddr);
225                                                 uint8_t code = vram[ptr++];
226                                                 ptr &= VRAM_SIZE - 1;
227                                                 uint8_t attrib = vram[ptr++];
228                                                 ptr &= VRAM_SIZE - 1;
229                                                 uint8_t* pattern = &font[code * 16];
230                                                 
231                                                 for(int l = y % 16; l < 16 && (y + l) < 400; l++) {
232                                                         uint8_t pat = pattern[l];
233                                                         // attribute
234                                                         if((attrib & 0x40) || ((attrib & 0x80) && (blink & 0x10))) {
235                                                                 pat = 0;
236                                                         }
237                                                         if(attrib & 8) {
238                                                                 pat = ~pat;
239                                                         }
240                                                         uint8_t col = (attrib & 4) ? 9 : 1;
241                                                         
242                                                         screen[y + l][x + 0] = (pat & 0x01) ? col : 0;
243                                                         screen[y + l][x + 1] = (pat & 0x02) ? col : 0;
244                                                         screen[y + l][x + 2] = (pat & 0x04) ? col : 0;
245                                                         screen[y + l][x + 3] = (pat & 0x08) ? col : 0;
246                                                         screen[y + l][x + 4] = (pat & 0x10) ? col : 0;
247                                                         screen[y + l][x + 5] = (pat & 0x20) ? col : 0;
248                                                         screen[y + l][x + 6] = (pat & 0x40) ? col : 0;
249                                                         screen[y + l][x + 7] = (pat & 0x80) ? col : 0;
250                                                 }
251                                                 if(cursor) {
252                                                         int top = cs[1] & 0x1f, bottom = cs[2] >> 3;
253                                                         for(int l = top; l < bottom && l < 16; l++) {
254                                                                 memset(&screen[y + l][x], 1, 8);
255                                                         }
256                                                 }
257                                         }
258                                 }
259                                 y += 16 - (y % 16);
260                         }
261                 }
262 #endif
263                 total += line;
264         }
265         
266         // copy to pc screen
267         if(*zoom) {
268                 for(int y = 0, dy = 0; y < 400 && dy < 400; y++) {
269                         uint8_t* src = screen[y];
270                         
271                         for(int x = 0, dx = 0; x < 640 && dx < 640; x++) {
272                                 scrntype_t col = palette_pc[src[x] & 0xf];
273                                 for(int zx = 0; zx < *zoom + 1; zx++) {
274                                         if(dx >= 640) {
275                                                 break;
276                                         }
277                                         tmp[dx++] = col;
278                                 }
279                         }
280                         // copy line
281                         for(int zy = 1; zy < *zoom + 1; zy++) {
282                                 if(dy >= 400) {
283                                         break;
284                                 }
285                                 scrntype_t *dest = emu->get_screen_buffer(dy++);
286                                 memcpy(dest, tmp, sizeof(scrntype_t) * 640);
287                         }
288                 }
289         } else {
290                 for(int y = 0; y < 400; y++) {
291                         scrntype_t* dest = emu->get_screen_buffer(y);
292                         uint8_t* src = screen[y];
293                         
294                         for(int x = 0; x < 640; x++) {
295 #ifdef _COLOR_MONITOR
296                                 dest[x] = palette_pc[src[x] & 7];
297 #else
298                                 dest[x] = palette_pc[src[x] & 0x0f];
299 #endif
300                         }
301                 }
302         }
303 #ifdef _COLOR_MONITOR
304         emu->screen_skip_line(false);
305 #endif
306 }
307
308 #define STATE_VERSION   1
309
310 #include "../../statesub.h"
311
312 void DISPLAY::decl_state()
313 {
314         enter_decl_state(STATE_VERSION);
315
316 #ifdef _COLOR_MONITOR
317         DECL_STATE_ENTRY_1D_ARRAY(vram_r, sizeof(vram_r));
318         DECL_STATE_ENTRY_1D_ARRAY(vram_g, sizeof(vram_g));
319         DECL_STATE_ENTRY_1D_ARRAY(vram_b, sizeof(vram_b));
320 #else
321         DECL_STATE_ENTRY_1D_ARRAY(vram, sizeof(vram));
322 #endif
323         DECL_STATE_ENTRY_UINT8(bank);
324         DECL_STATE_ENTRY_INT32(blink);
325         
326         leave_decl_state();
327 }
328
329 void DISPLAY::save_state(FILEIO* state_fio)
330 {
331         if(state_entry != NULL) {
332                 state_entry->save_state(state_fio);
333         }
334 //      state_fio->FputUint32(STATE_VERSION);
335 //      state_fio->FputInt32(this_device_id);
336         
337 //#ifdef _COLOR_MONITOR
338 //      state_fio->Fwrite(vram_r, sizeof(vram_r), 1);
339 //      state_fio->Fwrite(vram_g, sizeof(vram_g), 1);
340 //      state_fio->Fwrite(vram_b, sizeof(vram_b), 1);
341 //#else
342 //      state_fio->Fwrite(vram, sizeof(vram), 1);
343 //#endif
344 //      state_fio->FputUint8(bank);
345 //      state_fio->FputInt32(blink);
346 }
347
348 bool DISPLAY::load_state(FILEIO* state_fio)
349 {
350         bool mb = false;
351         if(state_entry != NULL) {
352                 mb = state_entry->load_state(state_fio);
353         }
354         if(!mb) {
355                 return false;
356         }
357 //      if(state_fio->FgetUint32() != STATE_VERSION) {
358 //              return false;
359 //      }
360 //      if(state_fio->FgetInt32() != this_device_id) {
361 //              return false;
362 //      }
363 //#ifdef _COLOR_MONITOR
364 //      state_fio->Fread(vram_r, sizeof(vram_r), 1);
365 //      state_fio->Fread(vram_g, sizeof(vram_g), 1);
366 //      state_fio->Fread(vram_b, sizeof(vram_b), 1);
367 //#else
368 //      state_fio->Fread(vram, sizeof(vram), 1);
369 //#endif
370 //      bank = state_fio->FgetUint8();
371 //      blink = state_fio->FgetInt32();
372         return true;
373 }
374
375 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
376 {
377         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
378                 return false;
379         }
380         if(!state_fio->StateCheckInt32(this_device_id)) {
381                 return false;
382         }
383 #ifdef _COLOR_MONITOR
384         state_fio->StateBuffer(vram_r, sizeof(vram_r), 1);
385         state_fio->StateBuffer(vram_g, sizeof(vram_g), 1);
386         state_fio->StateBuffer(vram_b, sizeof(vram_b), 1);
387 #else
388         state_fio->StateBuffer(vram, sizeof(vram), 1);
389 #endif
390         state_fio->StateUint8(bank);
391         state_fio->StateInt32(blink);
392         return true;
393 }