OSDN Git Service

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