OSDN Git Service

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