OSDN Git Service

5a0a84668dcf0bb443f0f57b9df553564f9e783c
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz5500 / display.cpp
1 /*
2         SHARP MZ-5500 Emulator 'EmuZ-5500'
3
4         Author : Takeda.Toshiya
5         Date   : 2008.04.10 -
6
7         [ display ]
8 */
9
10 #include "display.h"
11
12 static const int plane_priority[8][8] = {
13         {0, 1, 2, 3, 0, 1, 2, 3}, {0, 1, 2, 3, 4, 1, 2, 3},
14         {0, 1, 2, 3, 4, 4, 2, 3}, {0, 1, 2, 3, 4, 4, 4, 3},
15         {0, 1, 2, 3, 4, 4, 4, 4}, {0, 1, 2, 3, 4, 4, 4, 4},
16         {0, 1, 2, 3, 4, 4, 4, 4}, {0, 1, 2, 3, 4, 4, 4, 4}
17 };
18
19 void DISPLAY::initialize()
20 {
21         // init pallete
22         for(int i = 0; i < 8; i++) {
23                 palette_pc_base[i] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);
24                 palette[i] = i;
25         }
26         mode_r = mode_c = mode_p = 0;
27         update_palette();
28         
29         // init window controller
30         rno = 0;
31         memset(wregs, 0, sizeof(wregs));
32         memset(pri, 0, sizeof(pri));
33         memset(vma, 0, sizeof(vma));
34         memset(vds, 0, sizeof(vds));
35         memset(back, 0, sizeof(back));
36         memset(reverse, 0, sizeof(reverse));
37 }
38
39 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
40 {
41         switch(addr & 0x3ff) {
42         case 0x110:
43         case 0x114:
44         case 0x118:
45         case 0x11c:
46                 rno = data & 0x0f;
47                 break;
48         case 0x112:
49         case 0x116:
50         case 0x11a:
51         case 0x11e:
52                 wregs[rno] = data;
53                 if(rno == 0) {
54                         // update priority
55                         if(data) {
56                                 int p1 = (data >> 6) & 3;
57                                 int p2 = (data >> 4) & 3;
58                                 int p3 = (data >> 2) & 3;
59                                 int p4 = data & 3;
60                                 pri[ 0] = 0;
61                                 pri[ 1] = 1;
62                                 pri[ 2] = 2;
63                                 pri[ 3] = (p1 >= p2) ? 1 : 2;
64                                 pri[ 4] = 3;
65                                 pri[ 5] = (p1 >= p3) ? 1 : 3;
66                                 pri[ 6] = (p2 >= p3) ? 2 : 3;
67                                 pri[ 7] = (p1 >= p2 && p1 >= p3) ? 1 : (p2 >= p1 && p2 >= p3) ? 2 : 3;
68                                 pri[ 8] = 4;
69                                 pri[ 9] = (p1 >= p4) ? 1 : 4;
70                                 pri[10] = (p2 >= p4) ? 2 : 4;
71                                 pri[11] = (p1 >= p2 && p1 >= p4) ? 1 : (p2 >= p1 && p2 >= p4) ? 2 : 4;
72                                 pri[12] = (p3 >= p4) ? 3 : 4;
73                                 pri[13] = (p1 >= p3 && p1 >= p4) ? 1 : (p3 >= p1 && p3 >= p4) ? 3 : 4;
74                                 pri[14] = (p2 >= p3 && p2 >= p4) ? 2 : (p3 >= p2 && p3 >= p4) ? 3 : 4;
75                                 pri[15] = (p1 >= p2 && p1 >= p3 && p1 >= p4) ? 1 : (p2 >= p1 && p2 >= p3 && p2 >= p4) ? 2 : (p3 >= p1 && p3 >= p2 && p3 >= p4) ? 3 : 4;
76                                 vds[0] = 0;
77                         } else {
78                                 memset(pri, 0, sizeof(pri));
79                                 vds[0] = 7;
80                         }
81                 } else if(rno == 1 || rno == 2) {
82                         vma[1] = wregs[1] | (wregs[2] << 8);
83                 } else if(rno == 3) {
84                         vds[1] = wregs[3] & 7;
85                 } else if(rno == 4 || rno == 5) {
86                         vma[2] = wregs[4] | (wregs[5] << 8);
87                 } else if(rno == 6) {
88                         vds[2] = wregs[6] & 7;
89                 } else if(rno == 7 || rno == 8) {
90                         vma[3] = wregs[7] | (wregs[8] << 8);
91                 } else if(rno == 9) {
92                         vds[3] = wregs[9] & 7;
93                 } else if(rno == 10 || rno == 11) {
94                         vma[4] = wregs[10] | (wregs[11] << 8);
95                 } else if(rno == 12) {
96                         vds[4] = wregs[12] & 7;
97                 }
98                 rno = (++rno) & 0x0f;
99                 break;
100         case 0x120:
101                 mode_c = data & 7;
102                 update_palette();
103                 break;
104         case 0x122:
105                 mode_p = data & 7;
106                 update_palette();
107                 break;
108         case 0x124:
109                 back[1] = data & 7;
110                 break;
111         case 0x126:
112                 back[2] = data & 7;
113                 break;
114         case 0x128:
115                 back[3] = data & 7;
116                 break;
117         case 0x12a:
118                 back[4] = data & 7;
119                 reverse[4] = (data & 1) ? 0xff : 0;
120                 break;
121         case 0x12c:
122                 reverse[1] = (data & 1) ? 0xff : 0;
123                 reverse[2] = (data & 2) ? 0xff : 0;
124                 reverse[3] = (data & 4) ? 0xff : 0;
125                 break;
126         case 0x130:
127         case 0x132:
128         case 0x134:
129         case 0x136:
130         case 0x138:
131         case 0x13a:
132         case 0x13c:
133         case 0x13e:
134                 mode_r = data;
135                 break;
136         case 0x141:
137         case 0x149:
138                 palette[0] = data & 7;
139                 update_palette();
140                 break;
141         case 0x143:
142         case 0x14b:
143                 palette[1] = data & 7;
144                 update_palette();
145                 break;
146         case 0x145:
147         case 0x14d:
148                 palette[2] = data & 7;
149                 update_palette();
150                 break;
151         case 0x147:
152         case 0x14f:
153                 palette[3] = data & 7;
154                 update_palette();
155                 break;
156         case 0x151:
157         case 0x159:
158                 palette[4] = data & 7;
159                 update_palette();
160                 break;
161         case 0x153:
162         case 0x15b:
163                 palette[5] = data & 7;
164                 update_palette();
165                 break;
166         case 0x155:
167         case 0x15d:
168                 palette[6] = data & 7;
169                 update_palette();
170                 break;
171         case 0x157:
172         case 0x15f:
173                 palette[7] = data & 7;
174                 update_palette();
175                 break;
176         }
177 }
178
179 uint32_t DISPLAY::read_io8(uint32_t addr)
180 {
181         uint32_t val = 0xff;
182         
183         switch(addr & 0x3ff) {
184         case 0x110:
185         case 0x114:
186         case 0x118:
187         case 0x11c:
188                 return rno;
189         case 0x112:
190         case 0x116:
191         case 0x11a:
192         case 0x11e:
193                 val = wregs[rno];
194                 rno = (++rno) & 0x0f;
195                 return val;
196         case 0x141:
197         case 0x149:
198                 return palette[0];
199         case 0x143:
200         case 0x14b:
201                 return palette[1];
202         case 0x145:
203         case 0x14d:
204                 return palette[2];
205         case 0x147:
206         case 0x14f:
207                 return palette[3];
208         case 0x151:
209         case 0x159:
210                 return palette[4];
211         case 0x153:
212         case 0x15b:
213                 return palette[5];
214         case 0x155:
215         case 0x15d:
216                 return palette[6];
217         case 0x157:
218         case 0x15f:
219                 return palette[7];
220         }
221         return 0xff;
222 }
223
224 void DISPLAY::draw_screen()
225 {
226         // render screen
227         int ymax = (cs[0] & 1) ? 200 : 400;
228         if(mode_r & 4) {
229                 draw_320dot_screen(ymax);
230         } else {
231                 draw_640dot_screen(ymax);
232         }
233         
234         // copy to pc screen
235         if(ymax == 400) {
236                 // 400 lines
237                 for(int y = 0; y < 400; y++) {
238                         scrntype_t* dest = emu->get_screen_buffer(y);
239                         uint8_t* src = screen[y];
240                         
241                         for(int x = 0; x < 640; x++) {
242                                 dest[x] = palette_pc[src[x]];
243                         }
244                 }
245                 emu->screen_skip_line(false);
246         } else {
247                 // 200 lines
248                 for(int y = 0; y < 200; y++) {
249                         scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
250                         scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
251                         uint8_t* src = screen[y];
252                         
253                         for(int x = 0; x < 640; x++) {
254                                 dest0[x] = palette_pc[src[x]];
255                         }
256                         if(config.scan_line) {
257                                 memset(dest1, 0, 640 * sizeof(scrntype_t));
258                         } else {
259                                 my_memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
260                         }
261                 }
262                 emu->screen_skip_line(true);
263         }
264 }
265
266 void DISPLAY::draw_640dot_screen(int ymax)
267 {
268         int al = (sync[6] | (sync[7] << 8)) & 0x3ff;
269         bool wy1 = false, wy2 = false, wy3 = false, wy4 = false;
270         
271         for(int i = 0, total = 0; i < 4 && total < al; i++) {
272                 uint32_t tmp = ra[4 * i];
273                 tmp |= ra[4 * i + 1] << 8;
274                 tmp |= ra[4 * i + 2] << 16;
275                 tmp |= ra[4 * i + 3] << 24;
276                 int ptr = (tmp << 1) & 0xfffe;
277                 int line = (tmp >> 20) & 0x3ff;
278                 bool wide = ((tmp & 0x80000000) != 0);
279                 
280                 for(int y = total; y < total + line && y < ymax; y++) {
281                         uint8_t mapy = mapram[y << 1];
282                         if(mapy & 1) wy1 = !wy1;
283                         if(mapy & 2) wy2 = !wy2;
284                         if(mapy & 4) wy3 = !wy3;
285                         if(mapy & 8) wy4 = !wy4;
286                         bool wx1 = false, wx2 = false, wx3 = false, wx4 = false;
287                         
288                         if(wide) {
289                                 for(int x = 0; x < 640; x+= 16) {
290                                         uint8_t mapx = mapram[(x >> 4) << 1];
291                                         if(mapx & 0x10) wx1 = !wx1;
292                                         if(mapx & 0x20) wx2 = !wx2;
293                                         if(mapx & 0x40) wx3 = !wx3;
294                                         if(mapx & 0x80) wx4 = !wx4;
295                                         int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
296                                         
297                                         int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
298                                         ptr &= 0xffff;
299                                         uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
300                                         uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
301                                         uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
302                                         uint8_t col, bcol = back[wn];
303                                         if(mode_c & 1) {
304                                                 bcol = 0;
305                                                 b ^= reverse[wn];
306                                                 r ^= reverse[wn];
307                                                 g ^= reverse[wn];
308                                         }
309                                         
310                                         col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
311                                         screen[y][x +  0] = screen[y][x +  1] = col ? col : bcol;
312                                         col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
313                                         screen[y][x +  2] = screen[y][x +  3] = col ? col : bcol;
314                                         col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
315                                         screen[y][x +  4] = screen[y][x +  5] = col ? col : bcol;
316                                         col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
317                                         screen[y][x +  6] = screen[y][x +  7] = col ? col : bcol;
318                                         col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
319                                         screen[y][x +  8] = screen[y][x +  9] = col ? col : bcol;
320                                         col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
321                                         screen[y][x + 10] = screen[y][x + 11] = col ? col : bcol;
322                                         col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
323                                         screen[y][x + 12] = screen[y][x + 13] = col ? col : bcol;
324                                         col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
325                                         screen[y][x + 14] = screen[y][x + 15] = col ? col : bcol;
326                                 }
327                         } else {
328                                 for(int x = 0; x < 640; x+= 8) {
329                                         if(!(x & 8)) {
330                                                 uint8_t mapx = mapram[(x >> 4) << 1];
331                                                 if(mapx & 0x10) wx1 = !wx1;
332                                                 if(mapx & 0x20) wx2 = !wx2;
333                                                 if(mapx & 0x40) wx3 = !wx3;
334                                                 if(mapx & 0x80) wx4 = !wx4;
335                                         }
336                                         int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
337                                         
338                                         int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
339                                         ptr &= 0xffff;
340                                         uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
341                                         uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
342                                         uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
343                                         uint8_t col, bcol = back[wn];
344                                         if(mode_c & 1) {
345                                                 bcol = 0;
346                                                 b ^= reverse[wn];
347                                                 r ^= reverse[wn];
348                                                 g ^= reverse[wn];
349                                         }
350                                         
351                                         col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
352                                         screen[y][x + 0] = col ? col : bcol;
353                                         col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
354                                         screen[y][x + 1] = col ? col : bcol;
355                                         col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
356                                         screen[y][x + 2] = col ? col : bcol;
357                                         col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
358                                         screen[y][x + 3] = col ? col : bcol;
359                                         col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
360                                         screen[y][x + 4] = col ? col : bcol;
361                                         col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
362                                         screen[y][x + 5] = col ? col : bcol;
363                                         col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
364                                         screen[y][x + 6] = col ? col : bcol;
365                                         col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
366                                         screen[y][x + 7] = col ? col : bcol;
367                                 }
368                         }
369                 }
370                 total += line;
371         }
372 }
373
374 void DISPLAY::draw_320dot_screen(int ymax)
375 {
376         int al = (sync[6] | (sync[7] << 8)) & 0x3ff;
377         bool wy1 = false, wy2 = false, wy3 = false, wy4 = false;
378         
379         for(int i = 0, total = 0; i < 4 && total < al; i++) {
380                 uint32_t tmp = ra[4 * i];
381                 tmp |= ra[4 * i + 1] << 8;
382                 tmp |= ra[4 * i + 2] << 16;
383                 tmp |= ra[4 * i + 3] << 24;
384                 int ptr = (tmp << 1) & 0xfffe;
385                 int line = (tmp >> 20) & 0x3ff;
386                 bool wide = ((tmp & 0x80000000) != 0);
387                 
388                 for(int y = total; y < total + line && y < ymax; y++) {
389                         uint8_t mapy = mapram[y << 1];
390                         if(mapy & 1) wy1 = !wy1;
391                         if(mapy & 2) wy2 = !wy2;
392                         if(mapy & 4) wy3 = !wy3;
393                         if(mapy & 8) wy4 = !wy4;
394                         bool wx1 = false, wx2 = false, wx3 = false, wx4 = false;
395                         
396                         if(wide) {
397                                 for(int x = 0; x < 640; x+= 32) {
398                                         uint8_t mapx = mapram[(x >> 4) << 1];
399                                         if(mapx & 0x10) wx1 = !wx1;
400                                         if(mapx & 0x20) wx2 = !wx2;
401                                         if(mapx & 0x40) wx3 = !wx3;
402                                         if(mapx & 0x80) wx4 = !wx4;
403                                         int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
404                                         
405                                         int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
406                                         ptr &= 0xffff;
407                                         uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
408                                         uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
409                                         uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
410                                         uint8_t col, bcol = back[wn];
411                                         if(mode_c & 1) {
412                                                 bcol = 0;
413                                                 b ^= reverse[wn];
414                                                 r ^= reverse[wn];
415                                                 g ^= reverse[wn];
416                                         }
417                                         
418                                         col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
419                                         screen[y][x +  0] = screen[y][x +  1] = screen[y][x +  2] = screen[y][x +  3] = col ? col : bcol;
420                                         col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
421                                         screen[y][x +  4] = screen[y][x +  5] = screen[y][x +  6] = screen[y][x +  7] = col ? col : bcol;
422                                         col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
423                                         screen[y][x +  8] = screen[y][x +  9] = screen[y][x + 10] = screen[y][x + 11] = col ? col : bcol;
424                                         col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
425                                         screen[y][x + 12] = screen[y][x + 13] = screen[y][x + 14] = screen[y][x + 15] = col ? col : bcol;
426                                         col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
427                                         screen[y][x + 16] = screen[y][x + 17] = screen[y][x + 18] = screen[y][x + 19] = col ? col : bcol;
428                                         col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
429                                         screen[y][x + 20] = screen[y][x + 21] = screen[y][x + 22] = screen[y][x + 23] = col ? col : bcol;
430                                         col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
431                                         screen[y][x + 24] = screen[y][x + 25] = screen[y][x + 26] = screen[y][x + 27] = col ? col : bcol;
432                                         col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
433                                         screen[y][x + 28] = screen[y][x + 29] = screen[y][x + 30] = screen[y][x + 31] = col ? col : bcol;
434                                 }
435                         } else {
436                                 for(int x = 0; x < 640; x+= 16) {
437                                         uint8_t mapx = mapram[(x >> 4) << 1];
438                                         if(mapx & 0x10) wx1 = !wx1;
439                                         if(mapx & 0x20) wx2 = !wx2;
440                                         if(mapx & 0x40) wx3 = !wx3;
441                                         if(mapx & 0x80) wx4 = !wx4;
442                                         int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
443                                         
444                                         int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
445                                         ptr &= 0xffff;
446                                         uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
447                                         uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
448                                         uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
449                                         uint8_t col, bcol = back[wn];
450                                         if(mode_c & 1) {
451                                                 bcol = 0;
452                                                 b ^= reverse[wn];
453                                                 r ^= reverse[wn];
454                                                 g ^= reverse[wn];
455                                         }
456                                         
457                                         col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
458                                         screen[y][x +  0] = screen[y][x +  1] = col ? col : bcol;
459                                         col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
460                                         screen[y][x +  2] = screen[y][x +  3] = col ? col : bcol;
461                                         col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
462                                         screen[y][x +  4] = screen[y][x +  5] = col ? col : bcol;
463                                         col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
464                                         screen[y][x +  6] = screen[y][x +  7] = col ? col : bcol;
465                                         col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
466                                         screen[y][x +  8] = screen[y][x +  9] = col ? col : bcol;
467                                         col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
468                                         screen[y][x + 10] = screen[y][x + 11] = col ? col : bcol;
469                                         col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
470                                         screen[y][x + 12] = screen[y][x + 13] = col ? col : bcol;
471                                         col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
472                                         screen[y][x + 14] = screen[y][x + 15] = col ? col : bcol;
473                                 }
474                         }
475                 }
476                 total += line;
477         }
478 }
479
480 void DISPLAY::update_palette()
481 {
482         if(mode_c & 1) {
483                 // mono
484                 for(int i = 1; i < 8; i++) {
485                         palette_pc[i] = palette_pc_base[7];
486                 }
487                 palette_pc[0] = palette_pc_base[0];
488         } else if(mode_c & 4) {
489                 // plane priority
490                 for(int i = 0; i < 8; i++) {
491                         palette_pc[i] = palette_pc_base[plane_priority[mode_p][palette[i]]];
492                 }
493         } else {
494                 // color
495                 for(int i = 0; i < 8; i++) {
496                         palette_pc[i] = palette_pc_base[palette[i]];
497                 }
498         }
499 }
500
501 #define STATE_VERSION   1
502
503 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
504 {
505         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
506                 return false;
507         }
508         if(!state_fio->StateCheckInt32(this_device_id)) {
509                 return false;
510         }
511         //state_fio->StateBuffer(palette_pc, sizeof(palette_pc), 1);
512         for(int i = 0; i < (sizeof(palette) / sizeof(scrntype_t)); i++) {
513                 if(loading) {
514                         uint8_t r, g, b;
515                         r = state_fio->FgetUint8();
516                         g = state_fio->FgetUint8();
517                         b = state_fio->FgetUint8();
518                         palette[i] = RGB_COLOR(r, g, b);
519                 } else {
520                         uint8_t r, g, b;
521                         r = R_OF_COLOR(palette[i]);
522                         g = G_OF_COLOR(palette[i]);
523                         b = B_OF_COLOR(palette[i]);
524                         state_fio->FputUint8(r);
525                         state_fio->FputUint8(g);
526                         state_fio->FputUint8(b);
527                 }
528         }
529         state_fio->StateBuffer(palette, sizeof(palette), 1);
530         state_fio->StateBuffer(back, sizeof(back), 1);
531         state_fio->StateBuffer(reverse, sizeof(reverse), 1);
532         state_fio->StateUint8(rno);
533         state_fio->StateBuffer(wregs, sizeof(wregs), 1);
534         //state_fio->StateBuffer(pri, sizeof(pri), 1);
535         for(int i = 0; i < (sizeof(pri) / sizeof(int)); i++) {
536                 state_fio->StateInt32(pri[i]);
537         }
538         //state_fio->StateBuffer(vma, sizeof(vma), 1);
539         for(int i = 0; i < (sizeof(vma) / sizeof(int)); i++) {
540                 state_fio->StateInt32(vma[i]);
541         }
542         state_fio->StateBuffer(vds, sizeof(vds), 1);
543         state_fio->StateUint8(mode_r);
544         state_fio->StateUint8(mode_c);
545         state_fio->StateUint8(mode_p);
546         return true;
547 }