OSDN Git Service

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