2 SHARP MZ-2500 Emulator 'EmuZ-2500'
4 Author : Takeda.Toshiya
11 #include "interrupt.h"
16 #define EVENT_BLINK 256
18 #define SCRN_640x400 1
19 #define SCRN_640x200 2
20 #define SCRN_320x200 3
22 void CRTC::initialize()
25 monitor_200line = ((config.monitor_type & 2) != 0);
26 scan_line = scan_tmp = (monitor_200line && config.scan_line);
27 monitor_digital = monitor_tmp = ((config.monitor_type & 1) != 0);
29 // thanks Mr.Sato (http://x1center.org/)
31 frames_per_sec = 60.99;
32 lines_per_frame = 262;
35 frames_per_sec = 55.49;
36 lines_per_frame = 448;
39 set_frames_per_sec(frames_per_sec);
40 set_lines_per_frame(lines_per_frame);
42 // set 16/4096 palette
43 for(int i = 0; i < 16; i++) {
44 uint8_t r, g, b, r8, g8, b8;
51 r = ((i & 0x0a) == 0x0a) ? 255 : ((i & 0x0a) == 2) ? 127 : 0;
52 g = ((i & 0x0c) == 0x0c) ? 255 : ((i & 0x0c) == 4) ? 127 : 0;
53 b = ((i & 0x09) == 0x09) ? 255 : ((i & 0x09) == 1) ? 127 : 0;
54 r8 = (i & 2) ? 255 : 0;
55 g8 = (i & 4) ? 255 : 0;
56 b8 = (i & 1) ? 255 : 0;
60 palette16[i] = RGB_COLOR(r8, g8, b8);
62 palette16[i] = RGB_COLOR(r, g, b);
67 palette4096[i] = RGB_COLOR(r, g, b);
69 for(int i = 0; i < 8; i++) {
70 palette16[i + 16] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);
72 for(int i = 0; i < 16; i++) {
73 for(int j = 1; j < 8; j++) {
74 priority16[i][j] = j + 16;
76 priority16[i][0] = i; // transparent black
77 priority16[i][8] = 0 + 16; // non transparent black
83 for(int i = 0; i < 256; i++) {
84 palette256[i] = RGB_COLOR(((i & 0x20) ? 128 : 0) | ((i & 2) ? 64 : 0) | ((i & 0x80) ? 32 : 0),
85 ((i & 0x40) ? 128 : 0) | ((i & 4) ? 64 : 0) | ((i & 0x80) ? 32 : 0),
86 ((i & 0x10) ? 128 : 0) | ((i & 1) ? 64 : 0) | ((i & 0x80) ? 32 : 0));
88 for(int i = 0; i < 8; i++) {
89 palette256[i + 256] = RGB_COLOR(((i & 2) ? 255 : 0), ((i & 4) ? 255 : 0), ((i & 1) ? 255 : 0));
91 for(int i = 0; i < 64; i++) {
92 palette256[i + 256 + 16] = RGB_COLOR(((i & 2) ? 64 : 0) | ((i & 0x10) ? 128 : 0),
93 ((i & 4) ? 64 : 0) | ((i & 0x20) ? 128 : 0),
94 ((i & 1) ? 64 : 0) | ((i & 0x08) ? 128 : 0));
96 for(int i = 0; i < 256; i++) {
97 for(int j = 1; j < 16 + 64; j++) {
98 priority256[i][j] = j + 256;
100 priority256[i][0] = i; // transparent black
101 priority256[i][8] = 0 + 256; // non transparent black
102 priority256[i][16] = i; // transparent black (64 colors)
107 // extract cg optimization matrix
108 for(int p1 = 0; p1 < 256; p1++) {
109 for(int p2 = 0; p2 < 256; p2++) {
110 for(int i = 0; i < 8; i++) {
111 cg_matrix0[p1][p2][i] = (p1 & (1 << i) ? 0x01 : 0) | (p2 & (1 << i) ? 0x02 : 0);
112 cg_matrix1[p1][p2][i] = (p1 & (1 << i) ? 0x04 : 0) | (p2 & (1 << i) ? 0x08 : 0);
113 cg_matrix2[p1][p2][i] = (p1 & (1 << i) ? 0x10 : 0) | (p2 & (1 << i) ? 0x20 : 0);
114 cg_matrix3[p1][p2][i] = (p1 & (1 << i) ? 0x40 : 0) | (p2 & (1 << i) ? 0x80 : 0);
120 memset(textreg, 0, sizeof(textreg));
121 memset(cgreg, 0, sizeof(cgreg));
124 cgreg[0x00] = cgreg[0x01] = cgreg[0x02] = cgreg[0x03] = cgreg[0x06] = 0xff;
125 GDEVS = 0; cgreg[0x08] = 0x00; cgreg[0x09] = 0x00;
126 GDEVE = monitor_200line ? 200 : 400; cgreg[0x0a] = GDEVE & 0xff; cgreg[0x0b] = GDEVE >> 8;
127 GDEHS = 0; cgreg[0x0c] = 0x00;
128 GDEHSC = (int)(CPU_CLOCKS * GDEHS / frames_per_sec / lines_per_frame / chars_per_line + 0.5);
129 GDEHE = 80; cgreg[0x0d] = GDEHE;
130 GDEHEC = (int)(CPU_CLOCKS * (GDEHE + 3) / frames_per_sec / lines_per_frame / chars_per_line + 0.5);
132 for(int i = 0; i < 16; i++) {
135 scrn_size = SCRN_320x200;
140 cg_mask256_init = false;
145 latch[0] = latch[1] = latch[2] = latch[3] = 0;
146 hblank = vblank = false;
147 map_init = trans_init = true;
150 register_vline_event(this);
151 register_event(this, EVENT_BLINK, 500000, true, NULL);
154 void CRTC::write_data8(uint32_t addr, uint32_t data)
157 if(cgreg[0x0e] == 0x03) {
159 uint8_t *vram_b1 = ((cgreg[0x18] & 3) == 1) ? vram_b + 0x4000 : vram_g;
160 uint8_t *vram_r1 = ((cgreg[0x18] & 3) == 1) ? vram_r + 0x4000 : vram_i;
163 if((cgreg[5] & 0xc0) == 0x00) {
168 vram_b1[addr] &= ~cgreg[6];
169 vram_b1[addr] |= (cgreg[4] & 1) ? (data & cgreg[0] & cgreg[6]) : 0;
172 vram_r1[addr] &= ~cgreg[6];
173 vram_r1[addr] |= (cgreg[4] & 2) ? (data & cgreg[1] & cgreg[6]) : 0;
178 vram_b[addr] &= ~cgreg[6];
179 vram_b[addr] |= (cgreg[4] & 1) ? (data & cgreg[0] & cgreg[6]) : 0;
182 vram_r[addr] &= ~cgreg[6];
183 vram_r[addr] |= (cgreg[4] & 2) ? (data & cgreg[1] & cgreg[6]) : 0;
186 } else if((cgreg[5] & 0xc0) == 0x40) {
191 vram_b1[addr] &= ~data;
192 vram_b1[addr] |= (cgreg[4] & 1) ? (data & cgreg[0]) : 0;
195 vram_r1[addr] &= ~data;
196 vram_r1[addr] |= (cgreg[4] & 2) ? (data & cgreg[1]) : 0;
201 vram_b[addr] &= ~data;
202 vram_b[addr] |= (cgreg[4] & 1) ? (data & cgreg[0]) : 0;
205 vram_r[addr] &= ~data;
206 vram_r[addr] |= (cgreg[4] & 2) ? (data & cgreg[1]) : 0;
212 if((cgreg[5] & 0xc0) == 0x00) {
215 vram_b[addr] &= ~cgreg[6];
216 vram_b[addr] |= (cgreg[4] & 1) ? (data & cgreg[0] & cgreg[6]) : 0;
219 vram_r[addr] &= ~cgreg[6];
220 vram_r[addr] |= (cgreg[4] & 2) ? (data & cgreg[1] & cgreg[6]) : 0;
223 vram_g[addr] &= ~cgreg[6];
224 vram_g[addr] |= (cgreg[4] & 4) ? (data & cgreg[2] & cgreg[6]) : 0;
227 vram_i[addr] &= ~cgreg[6];
228 vram_i[addr] |= (cgreg[4] & 8) ? (data & cgreg[3] & cgreg[6]) : 0;
230 } else if((cgreg[5] & 0xc0) == 0x40) {
233 vram_b[addr] &= ~data;
234 vram_b[addr] |= (cgreg[4] & 1) ? (data & cgreg[0]) : 0;
237 vram_r[addr] &= ~data;
238 vram_r[addr] |= (cgreg[4] & 2) ? (data & cgreg[1]) : 0;
241 vram_g[addr] &= ~data;
242 vram_g[addr] |= (cgreg[4] & 4) ? (data & cgreg[2]) : 0;
245 vram_i[addr] &= ~data;
246 vram_i[addr] |= (cgreg[4] & 8) ? (data & cgreg[3]) : 0;
252 uint32_t CRTC::read_data8(uint32_t addr)
255 uint8_t b, r, g, i, pl;
257 if(cgreg[0x0e] == 0x03) {
259 b = latch[0] = (addr & 0x4000) ? vram_g[addr & 0x3fff] : vram_b[addr & 0x3fff];
260 r = latch[1] = (addr & 0x4000) ? vram_i[addr & 0x3fff] : vram_r[addr & 0x3fff];
266 b = latch[0] = vram_b[addr];
267 r = latch[1] = vram_r[addr];
268 g = latch[2] = vram_g[addr];
269 i = latch[3] = vram_i[addr];
273 if(cgreg[7] & 0x10) {
274 uint8_t compare = cgreg[7] & 0x0f;
275 uint8_t val = (compare == (((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5) | ((i & 0x80) >> 4))) ? 0x80 : 0;
276 val |= (compare == (((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4) | ((i & 0x40) >> 3))) ? 0x40 : 0;
277 val |= (compare == (((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3) | ((i & 0x20) >> 2))) ? 0x20 : 0;
278 val |= (compare == (((b & 0x10) >> 4) | ((r & 0x10) >> 3) | ((g & 0x10) >> 2) | ((i & 0x10) >> 1))) ? 0x10 : 0;
279 val |= (compare == (((b & 0x08) >> 3) | ((r & 0x08) >> 2) | ((g & 0x08) >> 1) | ((i & 0x08) >> 0))) ? 0x08 : 0;
280 val |= (compare == (((b & 0x04) >> 2) | ((r & 0x04) >> 1) | ((g & 0x04) >> 0) | ((i & 0x04) << 1))) ? 0x04 : 0;
281 val |= (compare == (((b & 0x02) >> 1) | ((r & 0x02) >> 0) | ((g & 0x02) << 1) | ((i & 0x02) << 2))) ? 0x02 : 0;
282 val |= (compare == (((b & 0x01) >> 0) | ((r & 0x01) << 1) | ((g & 0x01) << 2) | ((i & 0x01) << 3))) ? 0x01 : 0;
289 void CRTC::write_io8(uint32_t addr, uint32_t data)
291 uint8_t haddr = (addr >> 8) & 0xff;
292 uint8_t num, r, g, b, prev;
294 switch(addr & 0xff) {
297 num = (haddr & 0x1f) >> 1;
298 r = palette4096r[num];
299 g = palette4096g[num];
300 b = palette4096b[num];
302 g = (data & 0x0f) << 4;
305 b = (data & 0x0f) << 4;
307 if(palette4096r[num] != r || palette4096g[num] != g || palette4096b[num] != b) {
308 palette4096r[num] = r;
309 palette4096g[num] = g;
310 palette4096b[num] = b;
311 palette4096[num] = RGB_COLOR(r, g, b);
314 // never change palette 0
315 //palette4096[0] = 0;
323 prev = cgreg[cgreg_num & 0x1f];
324 cgreg[cgreg_num & 0x1f] = data;
326 switch(cgreg_num & 0x1f) {
329 if((data & 0xc0) == 0x80) {
331 switch(cgreg[0x0e]) {
332 case 0x03: case 0x14: case 0x15: case 0x17: case 0x1d:
333 // clear 0x0000 - 0x4000
337 case 0x94: case 0x95: case 0x97: case 0x9d:
338 // clear 0x4000 - 0x7fff
343 // clear 0x0000 - 0x7fff
347 if(cgreg[5] & 0x01) {
348 memset(vram_b + st, 0, sz);
350 if(cgreg[5] & 0x02) {
351 memset(vram_r + st, 0, sz);
353 if(cgreg[5] & 0x04) {
354 memset(vram_g + st, 0, sz);
356 if(cgreg[5] & 0x08) {
357 memset(vram_i + st, 0, sz);
366 GDEVS = (cgreg[0x08] | ((cgreg[0x09] & 1) << 8));
371 GDEVE = (cgreg[0x0a] | ((cgreg[0x0b] & 1) << 8));
374 GDEHS = cgreg[0x0c] & 0x7f;
375 GDEHSC = (int)(CPU_CLOCKS * GDEHS / frames_per_sec / lines_per_frame / chars_per_line + 0.5);
378 GDEHE = cgreg[0x0d] & 0x7f;
379 GDEHEC = (int)(CPU_CLOCKS * (GDEHE + 3) / frames_per_sec / lines_per_frame / chars_per_line + 0.5);
384 case 0x15: case 0x14: case 0x1d: case 0x95: case 0x94: case 0x9d:
385 map_init |= (scrn_size != SCRN_320x200);
386 scrn_size = SCRN_320x200;
388 case 0x17: case 0x97:
389 map_init |= (scrn_size != SCRN_640x200);
390 scrn_size = SCRN_640x200;
392 case 0x03: case 0x93:
393 map_init |= (scrn_size != SCRN_640x400);
394 scrn_size = SCRN_640x400;
400 map_init |= ((prev & 0x07) != (uint8_t)(data & 0x07));
402 case 0x10: case 0x12: case 0x14: case 0x16:
403 map_init |= (prev != (uint8_t)(data & 0xff));
405 case 0x11: case 0x13: case 0x15:
406 map_init |= ((prev & 0x7f) != (uint8_t)(data & 0x7f));
409 map_init |= ((prev & 0x01) != (uint8_t)(data & 0x01));
413 cg_mask256_init |= (prev != (uint8_t)(data & 0xff));
417 if(cgreg_num & 0x80) {
418 cgreg_num = (cgreg_num & 0xfc) | ((cgreg_num + 1) & 0x03);
427 if(textreg_num < 0x10) {
428 if(textreg_num == 0) {
429 trans_init |= ((textreg[0] & 2) != (uint8_t)(data & 2));
430 } else if(textreg_num == 0x0a) {
431 // update 256 colors palette
432 if((textreg[0x0a] & 0x3f) != (uint8_t)(data & 0x3f)) {
433 for(int i = 0; i < 256; i++) {
434 uint8_t b0 = (data & 0x03) >> 0;
435 uint8_t r0 = (data & 0x0c) >> 2;
436 uint8_t g0 = (data & 0x30) >> 4;
437 uint16_t b = ((i & 0x10) ? 128 : 0) | ((i & 1) ? 64 : 0) | ((b0 == 0 && (i & 0x80)) || (b0 == 1 && (i & 8)) || (b0 == 2) ? 32 : 0);
438 uint16_t r = ((i & 0x20) ? 128 : 0) | ((i & 2) ? 64 : 0) | ((r0 == 0 && (i & 0x80)) || (r0 == 1 && (i & 8)) || (r0 == 2) ? 32 : 0);
439 uint16_t g = ((i & 0x40) ? 128 : 0) | ((i & 4) ? 64 : 0) | ((g0 == 0 && (i & 0x80)) || (g0 == 1 && (i & 8)) || (g0 == 2) ? 32 : 0);
440 palette256[i] = RGB_COLOR(r, g, b);
445 textreg[textreg_num] = data;
447 // kugyokuden 400line patch
448 if(get_cpu_pc(0) == 0xc27e && !monitor_200line) {
449 if(textreg[3] == 0x26 && textreg[5] == 0xee) {
454 } else if(0x80 <= textreg_num && textreg_num < 0x90) {
455 int c = textreg_num & 0x0f;
458 prev = palette_reg[c];
459 palette_reg[c] = data;
461 if((prev & 0x0f) != (uint8_t)(data & 0x0f)) {
464 if((prev & 0x10) != (uint8_t)(data & 0x10)) {
466 for(int i = 1; i < 8; i++) {
467 priority16[c][i] = p ? c : (i + 16);
469 priority16[c][0] = c; // transparent black
470 priority16[c][8] = p ? c : (0 + 16); // non transparent black
473 if((prev & 0x1f) != (uint8_t)(data & 0x1f)) {
474 // update priority (256 colors)
476 int col16 = (data & 0x0f) << 4;
478 for(int i = 0; i < 16; i++) {
479 for(int j = 1; j < 16 + 64; j++) {
480 priority256[c16 | i][j] = p ? (col16 | i) : (j + 256);
482 priority256[c16 | i][0] = col16 | i; // transparent black
483 priority256[c16 | i][8] = p ? (col16 | i) : (0 + 256); // non transparent black
484 priority256[c16 | i][16] = col16 | i; // transparent black (64 colors)
493 cg_mask = (data & 7) | ((data & 1) ? 8 : 0);
494 if(prev != cg_mask) {
495 cg_mask256_init = true;
501 font_size = ((data & 1) != 0);
506 uint32_t CRTC::read_io8(uint32_t addr)
508 switch(addr & 0xff) {
511 if(cgreg[7] & 0x10) {
512 uint8_t b = latch[0];
513 uint8_t r = latch[1];
514 uint8_t g = latch[2];
515 uint8_t i = latch[3];
516 uint8_t compare = cgreg[7] & 0x0f;
518 uint8_t val = (compare == (((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5) | ((i & 0x80) >> 4))) ? 0x80 : 0;
519 val |= (compare == (((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4) | ((i & 0x40) >> 3))) ? 0x40 : 0;
520 val |= (compare == (((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3) | ((i & 0x20) >> 2))) ? 0x20 : 0;
521 val |= (compare == (((b & 0x10) >> 4) | ((r & 0x10) >> 3) | ((g & 0x10) >> 2) | ((i & 0x10) >> 1))) ? 0x10 : 0;
522 val |= (compare == (((b & 0x08) >> 3) | ((r & 0x08) >> 2) | ((g & 0x08) >> 1) | ((i & 0x08) >> 0))) ? 0x08 : 0;
523 val |= (compare == (((b & 0x04) >> 2) | ((r & 0x04) >> 1) | ((g & 0x04) >> 0) | ((i & 0x04) << 1))) ? 0x04 : 0;
524 val |= (compare == (((b & 0x02) >> 1) | ((r & 0x02) >> 0) | ((g & 0x02) << 1) | ((i & 0x02) << 2))) ? 0x02 : 0;
525 val |= (compare == (((b & 0x01) >> 0) | ((r & 0x01) << 1) | ((g & 0x01) << 2) | ((i & 0x01) << 3))) ? 0x01 : 0;
532 if(cgreg[7] & 0x10) {
533 return (vblank ? 0 : 0x80) | clear_flag;
543 case 0xf4: case 0xf5: case 0xf6: case 0xf7:
545 return (vblank ? 0 : 1) | (hblank ? 0 : 2);
550 void CRTC::write_signal(int id, uint32_t data, uint32_t mask)
552 if(id == SIG_CRTC_COLUMN_SIZE) {
553 column_size = ((data & mask) != 0); // from z80pio port a
554 } else if(id == SIG_CRTC_PALLETE) {
555 pal_select = ((data & mask) == 0); // from ym2203 port a
556 } else if(id == SIG_CRTC_MASK) {
557 screen_mask = ((data & mask) != 0); // from i8255 port c
561 void CRTC::event_callback(int event_id, int err)
563 if(event_id & EVENT_BLINK) {
570 void CRTC::event_vline(int v, int clock)
572 bool next = !(GDEVS <= v && v < GDEVE); // vblank = true
574 d_pio->write_signal(SIG_I8255_PORT_B, next ? 0 : 1, 1);
575 d_int->write_signal(SIG_INTERRUPT_CRTC, next ? 1 : 0, 1);
576 d_mem->write_signal(SIG_MEMORY_VBLANK, next ? 1 : 0, 1);
579 // complete clear screen
580 if(v == (monitor_200line ? 200 : 400)) {
583 // register hsync events
586 } else if(GDEHS < chars_per_line) {
587 register_event_by_clock(this, GDEHS, GDEHSC, false, NULL);
591 } else if(GDEHE < chars_per_line) {
592 register_event_by_clock(this, GDEHE, GDEHEC, false, NULL);
596 void CRTC::set_hsync(int h)
598 bool next = !(GDEHS <= h && h < GDEHE); // hblank = true
600 d_mem->write_signal(SIG_MEMORY_HBLANK, next ? 1 : 0, 1);
605 void CRTC::update_config()
607 //monitor_200line = ((config.monitor_type & 2) != 0);
608 scan_tmp = (monitor_200line && config.scan_line);
609 monitor_tmp = ((config.monitor_type & 1) != 0);
612 // ----------------------------------------------------------------------------
614 // ----------------------------------------------------------------------------
616 void CRTC::draw_screen()
619 scan_line = scan_tmp;
621 if(monitor_digital != monitor_tmp) {
622 monitor_digital = monitor_tmp;
623 // set 16 colors palette
624 for(int i = 0; i < 16; i++) {
625 uint8_t r, g, b, r8, g8, b8;
626 if((i & 0x0f) == 0x08) {
632 r = ((i & 0x0a) == 0x0a) ? 255 : ((i & 0x0a) == 0x02) ? 127 : 0;
633 g = ((i & 0x0c) == 0x0c) ? 255 : ((i & 0x0c) == 0x04) ? 127 : 0;
634 b = ((i & 0x09) == 0x09) ? 255 : ((i & 0x09) == 0x01) ? 127 : 0;
635 r8 = (i & 0x02) ? 255 : 0;
636 g8 = (i & 0x04) ? 255 : 0;
637 b8 = (i & 0x01) ? 255 : 0;
640 if(monitor_digital) {
641 palette16[i] = RGB_COLOR(r8, g8, b8);
643 palette16[i] = RGB_COLOR(r, g, b);
649 // update 16/4096 palette
650 uint8_t back16 = ((textreg[0x0b] & 4) >> 2) | ((textreg[0x0b] & 0x20) >> 4) | ((textreg[0x0c] & 1) << 2) | ((textreg[0x0b] & 1) << 3);
651 if(back16 != prev16) {
656 scrntype_t palette16tmp[16 + 8], palette4096tmp[16 + 8];
657 for(int i = 0; i < 16 + 8; i++) {
658 palette16tmp[i] = palette16[(i & 16) ? i : (palette_reg[i] & 0x0f) ? (palette_reg[i] & cg_mask) : (back16 & cg_mask)];
659 uint8_t col = (i == 16) ? 0 : (i & 16) ? (i & 0x0f) + 8 : i;
660 palette4096tmp[i] = palette4096[(palette_reg[col] & 0x0f) ? (palette_reg[col] & cg_mask) : (back16 & cg_mask)];
662 for(int i = 0; i < 16; i++) {
663 for(int j = 0; j < 9; j++) {
664 palette16pri[i][j] = palette16tmp[priority16[i][j]];
665 palette4096pri[i][j] = palette4096tmp[priority16[i][j]];
668 memcpy(palette16txt, &palette16tmp[16], sizeof(scrntype_t) * 8);
669 // palette16txt[0] = (back16 == 0 && (palette_reg[0] & 0x0f)== 2) ? 0 : palette16[palette_reg[back16] & 0x0f]; // tower of doruaga
670 palette16txt[0] = palette16[palette_reg[back16] & 0x0f];
672 memcpy(palette4096txt, &palette4096tmp[16], sizeof(scrntype_t) * 8);
673 palette4096txt[0] = palette4096[palette_reg[back16] & 0x0f];
674 palette4096txt[8] = 0;
678 // update 256 palette
679 scrntype_t back256 = RGB_COLOR((textreg[0x0b] & 0x38) << 2, ((textreg[0x0b] & 0xc0) >> 1) | ((textreg[0x0c] & 1) << 7), (textreg[0x0b] & 7) << 5);
680 if(back256 != prev256) {
685 palette256[0] = back256;
686 for(int i = 0; i < 256; i++) {
687 for(int j = 0; j < 16 + 64; j++) {
688 palette256pri[i][j] = palette256[priority256[i][j]];
691 memcpy(palette256txt, &palette256[256], sizeof(scrntype_t) * (16 + 64));
692 palette256txt[0] = back256;
693 palette256txt[8] = 0;
698 memset(cg, 0, sizeof(cg));
702 memset(text, 0, sizeof(text));
706 int vs = (GDEVS <= GDEVE) ? GDEVS * (scrn_size == SCRN_640x400 ? 1 : 2) : 0;
707 int ve = (GDEVS <= GDEVE) ? GDEVE * (scrn_size == SCRN_640x400 ? 1 : 2) : 400;
708 int hs = (GDEHS <= GDEHE && GDEHS < 80) ? (GDEHS << 3) : 0;
709 int he = (GDEHS <= GDEHE && GDEHE < 80) ? (GDEHE << 3) : 640;
711 emu->set_vm_screen_lines(ve);
714 emu->set_vm_screen_lines(ve);
718 for(int y = 0; y < 400; y++) {
719 scrntype_t *dest = emu->get_screen_buffer(y);
720 memset(dest, 0, sizeof(scrntype_t) * 640);
722 } else if(cgreg[0x0e] == 0x1d || cgreg[0x0e] == 0x9d) {
724 for(int y = 0; y < vs && y < 400; y++) {
725 scrntype_t *dest = emu->get_screen_buffer(y);
726 uint8_t *src_text = &text[640 * y];
727 for(int x = 0; x < 640; x++) {
728 dest[x] = palette256txt[src_text[x]];
731 for(int y = vs; y < ve && y < 400; y++) {
732 scrntype_t *dest = emu->get_screen_buffer(y);
733 uint8_t *src_cg = &cg[640 * y], *src_text = &text[640 * y];
734 for(int x = 0; x < hs && x < 640; x++) {
735 dest[x] = palette256txt[src_text[x]];
737 for(int x = hs; x < he && x < 640; x++) {
738 dest[x] = palette256pri[src_cg[x]][src_text[x]];
740 for(int x = he; x < 640; x++) {
741 dest[x] = palette256txt[src_text[x]];
744 for(int y = ve; y < 400; y++) {
745 scrntype_t *dest = emu->get_screen_buffer(y);
746 uint8_t *src_text = &text[640 * y];
747 for(int x = 0; x < 640; x++) {
748 dest[x] = palette256txt[src_text[x]];
751 } else if(!pal_select) {
753 for(int y = 0; y < vs && y < 400; y++) {
754 scrntype_t *dest = emu->get_screen_buffer(y);
755 uint8_t *src_cg = &cg[640 * y], *src_text = &text[640 * y];
756 for(int x = 0; x < 640; x++) {
757 dest[x] = palette16txt[src_text[x]];
760 for(int y = vs; y < ve && y < 400; y++) {
761 scrntype_t *dest = emu->get_screen_buffer(y);
762 uint8_t *src_cg = &cg[640 * y], *src_text = &text[640 * y];
763 for(int x = 0; x < hs && x < 640; x++) {
764 dest[x] = palette16txt[src_text[x]];
766 for(int x = hs; x < he && x < 640; x++) {
767 dest[x] = palette16pri[src_cg[x]][src_text[x]];
769 for(int x = he; x < 640; x++) {
770 dest[x] = palette16txt[src_text[x]];
773 for(int y = ve; y < 400; y++) {
774 scrntype_t *dest = emu->get_screen_buffer(y);
775 uint8_t *src_cg = &cg[640 * y], *src_text = &text[640 * y];
776 for(int x = 0; x < 640; x++) {
777 dest[x] = palette16txt[src_text[x]];
782 for(int y = 0; y < vs && y < 400; y++) {
783 scrntype_t *dest = emu->get_screen_buffer(y);
784 uint8_t *src_cg = &cg[640 * y], *src_text = &text[640 * y];
785 for(int x = 0; x < 640; x++) {
786 dest[x] = palette4096txt[src_text[x]];
789 for(int y = vs; y < ve && y < 400; y++) {
790 scrntype_t *dest = emu->get_screen_buffer(y);
791 uint8_t *src_cg = &cg[640 * y], *src_text = &text[640 * y];
792 for(int x = 0; x < hs && x < 640; x++) {
793 dest[x] = palette4096txt[src_text[x]];
795 for(int x = hs; x < he && x < 640; x++) {
796 dest[x] = palette4096pri[src_cg[x]][src_text[x]];
798 for(int x = he; x < 640; x++) {
799 dest[x] = palette4096txt[src_text[x]];
802 for(int y = ve; y < 400; y++) {
803 scrntype_t *dest = emu->get_screen_buffer(y);
804 uint8_t *src_cg = &cg[640 * y], *src_text = &text[640 * y];
805 for(int x = 0; x < 640; x++) {
806 dest[x] = palette4096txt[src_text[x]];
810 emu->screen_skip_line(monitor_200line);
813 // ----------------------------------------------------------------------------
815 // ----------------------------------------------------------------------------
817 void CRTC::draw_text()
819 // extract text optimization matrix
821 trans_color = (textreg[0] & 2) ? 8 : 0;
822 for(int pat = 0; pat < 256; pat++) {
823 for(int col = 0; col < 8; col++) {
824 int fore_color = col ? col : 8;
825 text_matrix[pat][col][0] = text_matrixw[pat][col][ 0] = text_matrixw[pat][col][ 1] = (pat & 0x80) ? fore_color : trans_color;
826 text_matrix[pat][col][1] = text_matrixw[pat][col][ 2] = text_matrixw[pat][col][ 3] = (pat & 0x40) ? fore_color : trans_color;
827 text_matrix[pat][col][2] = text_matrixw[pat][col][ 4] = text_matrixw[pat][col][ 5] = (pat & 0x20) ? fore_color : trans_color;
828 text_matrix[pat][col][3] = text_matrixw[pat][col][ 6] = text_matrixw[pat][col][ 7] = (pat & 0x10) ? fore_color : trans_color;
829 text_matrix[pat][col][4] = text_matrixw[pat][col][ 8] = text_matrixw[pat][col][ 9] = (pat & 0x08) ? fore_color : trans_color;
830 text_matrix[pat][col][5] = text_matrixw[pat][col][10] = text_matrixw[pat][col][11] = (pat & 0x04) ? fore_color : trans_color;
831 text_matrix[pat][col][6] = text_matrixw[pat][col][12] = text_matrixw[pat][col][13] = (pat & 0x02) ? fore_color : trans_color;
832 text_matrix[pat][col][7] = text_matrixw[pat][col][14] = text_matrixw[pat][col][15] = (pat & 0x01) ? fore_color : trans_color;
840 draw_80column_screen();
842 draw_40column_screen();
847 if(monitor_200line) {
849 SL = (textreg[3] - 38) << 1;
850 EL = (textreg[5] - 38) << 1;
853 SC = (textreg[7] & 0x7f) - 11;
854 EC = (textreg[8] & 0x7f) - 11;
857 SC = (textreg[7] & 0x7f) - 10;
858 EC = (textreg[8] & 0x7f) - 10;
862 SL = (textreg[3] - 17) << 1;
863 EL = (textreg[5] - 17) << 1;
866 SC = (textreg[7] & 0x7f) - 9;
867 EC = (textreg[8] & 0x7f) - 9;
870 SC = (textreg[7] & 0x7f) - 8;
871 EC = (textreg[8] & 0x7f) - 8;
874 SL = (SL < 0) ? 0 : (SL > 400) ? 400 : SL;
875 EL = (EL < 0) ? 0 : (EL > 400) ? 400 : EL;
876 SC = (SC < 0) ? 0 : (SC > 80) ? 80 : SC;
877 EC = (EC < 0) ? 0 : (EC > 80) ? 80 : EC;
880 for(int y = 0; y < SL; y++) {
881 memset(text + 640 * y, trans_color, 640);
883 for(int y = EL; y < 400; y++) {
884 memset(text + 640 * y, trans_color, 640);
887 for(int y = EL; y < SL; y++) {
888 memset(text + 640 * y, trans_color, 640);
892 for(int y = 0; y < 400; y++) {
893 memset(text + 640 * y, trans_color, SC << 3);
894 memset(text + 640 * y + (EC << 3), trans_color, (80 - EC) << 3);
897 for(int y = 0; y < 400; y++) {
898 memset(text + 640 * y + (EC << 3), trans_color, (SC - EC) << 3);
903 void CRTC::draw_80column_screen()
905 uint16_t src = textreg[1] | ((textreg[2] & 0x07) << 8);
906 uint8_t line = (textreg[0] & 0x10) ? 2 : 0;
907 uint8_t height = (textreg[0] & 0x10) ? 20 : 16;
908 uint8_t vd = (textreg[9] & 0x0f) << 1;
911 for(int y = line; y < 416; y += height) {
912 int dest = (y - vd) * 640;
913 for(int x = 0; x < 80; x++) {
914 draw_80column_font((src++) & 0x7ff, dest, y - vd);
920 void CRTC::draw_40column_screen()
922 uint16_t src1 = textreg[1] | ((textreg[2] & 0x07) << 8);
923 uint16_t src2 = src1 + 0x400;
924 uint8_t line = (textreg[0] & 0x10) ? 2 : 0;
925 uint8_t height = (textreg[0] & 0x10) ? 20 : 16;
926 uint8_t vd = (textreg[9] & 0x0f) << 1;
928 switch(textreg[0] & 0x0c) {
930 // 40x20(25), 64colors
931 for(int y = line; y < 416; y += height) {
932 int dest1 = (y - vd) * 640;
933 int dest2 = (y - vd) * 640 + 640 * 480;
934 for(int x = 0; x < 40; x++) {
935 draw_40column_font((src1++) & 0x7ff, dest1, y - vd);
936 draw_40column_font((src2++) & 0x7ff, dest2, y - vd);
941 for(int y = 0; y < 400; y++) {
942 uint32_t src1 = 640 * y;
943 uint32_t src2 = 640 * y + 640 * 480;
944 uint32_t dest = 640 * y;
946 for(int x = 0; x < 640; x++) {
947 if((text[src1] & 8) && (text[src2] & 8)) {
948 col = 8; // non transparent black
950 col = (((text[src1] & 7) << 3) | (text[src2] & 7)) + 16;
959 // 40x20(25), No.1 Screen
960 for(int y = line; y < 416; y += height) {
961 int dest = (y - vd) * 640;
962 for(int x = 0; x < 40; x++) {
963 draw_40column_font((src1++) & 0x7ff, dest, y - vd);
969 // 40x20(25), No.2 Screen
970 for(int y = line; y < 416; y += height) {
971 int dest = (y - vd) * 640;
972 for(int x = 0; x < 40; x++) {
973 draw_40column_font((src2++) & 0x7ff, dest, y - vd);
979 // 40x20(25), No.1 + No.2 Screens (No.1 > No.2)
980 for(int y = line; y < 416; y += height) {
981 int dest = (y - vd) * 640;
982 for(int x = 0; x < 40; x++) {
983 draw_40column_font((src1++) & 0x7ff, dest, y - vd);
987 for(int y = line; y < 416; y += height) {
988 int dest = (y - vd) * 640 + 640 * 480;
989 for(int x = 0; x < 40; x++) {
990 draw_40column_font((src2++) & 0x7ff, dest, y - vd);
994 for(int y = line; y < 400; y++) {
995 int dest = (y - vd) * 640;
996 uint8_t* tsrc1 = &text[dest];
997 uint8_t* tsrc2 = &text[dest + 640 * 480];
998 uint8_t* tdest = &text[dest];
999 for(int x = 0; x < 640; x++) {
1000 tdest[x] = (tsrc1[x] & 7) ? tsrc1[x] : (tsrc2[x] & 7) ? tsrc2[x] : ((tsrc1[x] & 8) | (tsrc2[x] & 8));
1007 void CRTC::draw_80column_font(uint16_t src, int dest, int y)
1009 // draw char (80 column)
1015 uint8_t sel, col, pat1, pat2, pat3;
1016 uint8_t t1 = tvram1[src], t2 = tvram2[src], attr = attrib[src];
1019 sel = (t2 & 0xc0) | (attr & 0x38);
1021 case 0x00: case 0x40:
1030 case 0x10: case 0x50: case 0x90: case 0xd0:
1033 case 0x20: case 0x60: case 0xa0: case 0xe0:
1036 case 0x30: case 0x70: case 0xb0: case 0xf0:
1046 // PCG1 + PCG2 + PCG3 8colors
1049 code = font_size ? t1 << 3 : (t1 & 0xfe) << 3;
1052 for(int i = 0; i < 8; i++) {
1053 // check end line of screen
1057 if((attr & 0x80) && blink) {
1059 uint8_t val = (attr & 0x40) ? 7 : trans_color;
1061 memset(text + dest, val, 8);
1064 // check end line of screen
1068 if(dest >= 0 && !scan_line) {
1069 memset(text + dest, val, 8);
1074 pat1 = ~pattern1[code + i];
1075 pat2 = ~pattern2[code + i];
1076 pat3 = ~pattern3[code + i];
1078 pat1 = pattern1[code + i];
1079 pat2 = pattern2[code + i];
1080 pat3 = pattern3[code + i];
1083 uint8_t* tdest = &text[dest];
1084 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[0] = col ? col : trans_color;
1085 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[1] = col ? col : trans_color;
1086 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[2] = col ? col : trans_color;
1087 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[3] = col ? col : trans_color;
1088 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[4] = col ? col : trans_color;
1089 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[5] = col ? col : trans_color;
1090 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[6] = col ? col : trans_color;
1091 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[7] = col ? col : trans_color;
1094 // check end line of screen
1098 if(dest >= 0 && !scan_line) {
1100 memcpy(text + dest, text + dest - 640, 8);
1102 uint8_t* tdest = &text[dest];
1103 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[0] = col ? col : trans_color;
1104 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[1] = col ? col : trans_color;
1105 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[2] = col ? col : trans_color;
1106 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[3] = col ? col : trans_color;
1107 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[4] = col ? col : trans_color;
1108 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[5] = col ? col : trans_color;
1109 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[6] = col ? col : trans_color;
1110 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[7] = col ? col : trans_color;
1117 for(int i = 0; i < 16; i++) {
1118 // check end line of screen
1123 if((attr & 0x80) && blink) {
1125 memset(text + dest, 7, 8);
1127 memset(text + dest, trans_color, 8);
1131 pat1 = ~pattern1[code + i];
1132 pat2 = ~pattern2[code + i];
1133 pat3 = ~pattern3[code + i];
1135 pat1 = pattern1[code + i];
1136 pat2 = pattern2[code + i];
1137 pat3 = pattern3[code + i];
1139 uint8_t* tdest = &text[dest];
1140 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[0] = col ? col : trans_color;
1141 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[1] = col ? col : trans_color;
1142 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[2] = col ? col : trans_color;
1143 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[3] = col ? col : trans_color;
1144 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[4] = col ? col : trans_color;
1145 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[5] = col ? col : trans_color;
1146 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[6] = col ? col : trans_color;
1147 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[7] = col ? col : trans_color;
1158 if(sel == 0x80 || sel == 0xc0) {
1159 code = ((t2 & 0x3f) << 11) | (t1 << 3);
1164 if(sel == 0x80 || sel == 0xc0) {
1165 code = ((t2 & 0x3f) << 11) | ((t1 & 0xfe) << 3);
1167 code = (t1 & 0xfe) << 3;
1174 uint32_t dest1 = dest;
1175 uint32_t dest2 = (dest >= 640 * 399) ? dest - 640 * 399 : dest + 640;
1176 for(int i = 0; i < 8; i++) {
1177 // check end line of screen
1183 pat1 = ((attr & 0x80) && blink) ? 0xff : ~pattern1[code + i];
1185 pat1 = ((attr & 0x80) && blink) ? 0x00 : pattern1[code + i];
1188 memcpy(&text[dest], text_matrix[pat1][col], 8);
1191 // check end line of screen
1195 if(dest >= 0 && !scan_line) {
1196 memcpy(&text[dest], text_matrix[pat1][col], 8);
1201 for(int i = 0; i < 16; i++) {
1202 // check end line of screen
1209 pat1 = ((attr & 0x80) && blink) ? 0xff : ~pattern1[code + i];
1211 pat1 = ((attr & 0x80) && blink) ? 0x00 : pattern1[code + i];
1213 memcpy(&text[dest], text_matrix[pat1][col], 8);
1221 void CRTC::draw_40column_font(uint16_t src, int dest, int y)
1223 // draw char (40 column)
1229 uint8_t sel, col, pat1, pat2, pat3;
1230 uint8_t t1 = tvram1[src], t2 = tvram2[src], attr = attrib[src];
1233 sel = (t2 & 0xc0) | (attr & 0x38);
1235 case 0x00: case 0x40:
1244 case 0x10: case 0x50: case 0x90: case 0xd0:
1247 case 0x20: case 0x60: case 0xa0: case 0xe0:
1250 case 0x30: case 0x70: case 0xb0: case 0xf0:
1260 // PCG1 + PCG2 + PCG3 8colors
1263 code = font_size ? t1 << 3 : (t1 & 0xfe) << 3;
1266 for(int i = 0; i < 8; i++) {
1267 // check end line of screen
1271 if((attr & 0x80) && blink) {
1273 uint8_t val = (attr & 0x40) ? 7 : trans_color;
1275 memset(text + dest, val, 16);
1278 // check end line of screen
1282 if(dest >= 0 && !scan_line) {
1283 memset(text + dest, val, 16);
1288 pat1 = ~pattern1[code + i];
1289 pat2 = ~pattern2[code + i];
1290 pat3 = ~pattern3[code + i];
1292 pat1 = pattern1[code + i];
1293 pat2 = pattern2[code + i];
1294 pat3 = pattern3[code + i];
1297 uint8_t* tdest = &text[dest];
1298 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[ 0] = tdest[ 1] = col ? col : trans_color;
1299 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[ 2] = tdest[ 3] = col ? col : trans_color;
1300 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[ 4] = tdest[ 5] = col ? col : trans_color;
1301 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[ 6] = tdest[ 7] = col ? col : trans_color;
1302 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[ 8] = tdest[ 9] = col ? col : trans_color;
1303 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[10] = tdest[11] = col ? col : trans_color;
1304 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[12] = tdest[13] = col ? col : trans_color;
1305 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[14] = tdest[15] = col ? col : trans_color;
1308 // check end line of screen
1312 if(dest >= 0 && !scan_line) {
1314 memcpy(text + dest, text + dest - 640, 16);
1316 uint8_t* tdest = &text[dest];
1317 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[ 0] = tdest[ 1] = col ? col : trans_color;
1318 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[ 2] = tdest[ 3] = col ? col : trans_color;
1319 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[ 4] = tdest[ 5] = col ? col : trans_color;
1320 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[ 6] = tdest[ 7] = col ? col : trans_color;
1321 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[ 8] = tdest[ 9] = col ? col : trans_color;
1322 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[10] = tdest[11] = col ? col : trans_color;
1323 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[12] = tdest[13] = col ? col : trans_color;
1324 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[14] = tdest[15] = col ? col : trans_color;
1331 for(int i = 0; i < 16; i++) {
1332 // check end line of screen
1337 if((attr & 0x80) && blink) {
1339 memset(text + dest, 7, 16);
1341 memset(text + dest, trans_color, 16);
1345 pat1 = ~pattern1[code + i];
1346 pat2 = ~pattern2[code + i];
1347 pat3 = ~pattern3[code + i];
1349 pat1 = pattern1[code + i];
1350 pat2 = pattern2[code + i];
1351 pat3 = pattern3[code + i];
1353 uint8_t* tdest = &text[dest];
1354 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[ 0] = tdest[ 1] = col ? col : trans_color;
1355 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[ 2] = tdest[ 3] = col ? col : trans_color;
1356 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[ 4] = tdest[ 5] = col ? col : trans_color;
1357 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[ 6] = tdest[ 7] = col ? col : trans_color;
1358 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[ 8] = tdest[ 9] = col ? col : trans_color;
1359 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[10] = tdest[11] = col ? col : trans_color;
1360 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[12] = tdest[13] = col ? col : trans_color;
1361 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[14] = tdest[15] = col ? col : trans_color;
1372 if(sel == 0x80 || sel == 0xc0) {
1373 code = ((t2 & 0x3f) << 11) | (t1 << 3);
1378 if(sel == 0x80 || sel == 0xc0) {
1379 code = ((t2 & 0x3f) << 11) | ((t1 & 0xfe) << 3);
1381 code = (t1 & 0xfe) << 3;
1388 for(int i = 0; i < 8; i++) {
1389 // check end line of screen
1395 pat1 = ((attr & 0x80) && blink) ? 0xff : ~pattern1[code + i];
1397 pat1 = ((attr & 0x80) && blink) ? 0x00 : pattern1[code + i];
1400 memcpy(&text[dest], text_matrixw[pat1][col], 16);
1403 // check end line of screen
1407 if(dest >= 0 && !scan_line) {
1408 memcpy(&text[dest], text_matrixw[pat1][col], 16);
1413 for(int i = 0; i < 16; i++) {
1414 // check end line of screen
1421 pat1 = ((attr & 0x80) && blink) ? 0xff : ~pattern1[code + i];
1423 pat1 = ((attr & 0x80) && blink) ? 0x00 : pattern1[code + i];
1425 memcpy(&text[dest], text_matrixw[pat1][col], 16);
1433 // ----------------------------------------------------------------------------
1435 // ----------------------------------------------------------------------------
1437 void CRTC::draw_cg()
1440 switch(cgreg[0x0e]) {
1442 draw_640x400x4screen();
1445 draw_320x200x16screen(0);
1446 draw_320x200x16screen(1);
1449 draw_320x200x16screen(1);
1450 draw_320x200x16screen(0);
1453 draw_640x200x16screen(0);
1456 draw_320x200x256screen(0);
1459 draw_640x400x16screen();
1462 draw_320x200x16screen(2);
1463 draw_320x200x16screen(3);
1466 draw_320x200x16screen(3);
1467 draw_320x200x16screen(2);
1470 draw_640x200x16screen(1);
1473 draw_320x200x256screen(1);
1478 if(!scan_line && !(cgreg[0x0e] == 0x03 || cgreg[0x0e] == 0x93)) {
1479 for(int y = 0; y < 400; y += 2) {
1480 memcpy(cg + (y + 1) * 640, cg + y * 640, 640);
1485 void CRTC::draw_320x200x16screen(uint8_t pl)
1487 uint8_t B, R, G, I, col;
1491 create_addr_map(40, 200);
1493 for(int y = 0; y < 200; y++) {
1494 for(int x = 0; x < 40; x++) {
1495 uint16_t src = (map_addr[y][x] + (0x2000 * pl)) & 0x7fff;
1496 uint32_t dest2 = dest + map_hdsc[y][x];
1499 if(pl == 0 || pl == 2) {
1500 B = (cgreg[0x18] & 0x01) ? vram_b[src] : 0;
1501 R = (cgreg[0x18] & 0x02) ? vram_r[src] : 0;
1502 G = (cgreg[0x18] & 0x04) ? vram_g[src] : 0;
1503 I = (cgreg[0x18] & 0x08) ? vram_i[src] : 0;
1505 B = (cgreg[0x18] & 0x10) ? vram_b[src] : 0;
1506 R = (cgreg[0x18] & 0x20) ? vram_r[src] : 0;
1507 G = (cgreg[0x18] & 0x40) ? vram_g[src] : 0;
1508 I = (cgreg[0x18] & 0x80) ? vram_i[src] : 0;
1511 col = cg_matrix0[B][R][0] | cg_matrix1[G][I][0]; if(col) cg[dest2 ] = cg[dest2 + 1] = col;
1512 col = cg_matrix0[B][R][1] | cg_matrix1[G][I][1]; if(col) cg[dest2 + 2] = cg[dest2 + 3] = col;
1513 col = cg_matrix0[B][R][2] | cg_matrix1[G][I][2]; if(col) cg[dest2 + 4] = cg[dest2 + 5] = col;
1514 col = cg_matrix0[B][R][3] | cg_matrix1[G][I][3]; if(col) cg[dest2 + 6] = cg[dest2 + 7] = col;
1515 col = cg_matrix0[B][R][4] | cg_matrix1[G][I][4]; if(col) cg[dest2 + 8] = cg[dest2 + 9] = col;
1516 col = cg_matrix0[B][R][5] | cg_matrix1[G][I][5]; if(col) cg[dest2 + 10] = cg[dest2 + 11] = col;
1517 col = cg_matrix0[B][R][6] | cg_matrix1[G][I][6]; if(col) cg[dest2 + 12] = cg[dest2 + 13] = col;
1518 col = cg_matrix0[B][R][7] | cg_matrix1[G][I][7]; if(col) cg[dest2 + 14] = cg[dest2 + 15] = col;
1524 void CRTC::draw_320x200x256screen(uint8_t pl)
1526 uint8_t B0, B1, R0, R1, G0, G1, I0, I1;
1530 create_addr_map(40, 200);
1532 if(cg_mask256_init) {
1533 cg_mask256 = cgreg[0x18];
1534 if(!(cg_mask & 1)) {
1535 cg_mask256 &= ~(0x11 | 0x88);
1537 if(!(cg_mask & 2)) {
1538 cg_mask256 &= ~0x22;
1540 if(!(cg_mask & 4)) {
1541 cg_mask256 &= ~0x44;
1543 cg_mask256_init = false;
1545 for(int y = 0; y < 200; y++) {
1546 for(int x = 0; x < 40; x++) {
1547 uint16_t src1 = (map_addr[y][x] + (0x4000 * pl)) & 0x7fff;
1548 uint16_t src2 = (src1 + 0x2000) & 0x7fff;
1549 uint32_t dest2 = dest + map_hdsc[y][x];
1552 B1 = (cg_mask256 & 0x01) ? vram_b[src1] : 0;
1553 B0 = (cg_mask256 & 0x10) ? vram_b[src2] : 0;
1554 R1 = (cg_mask256 & 0x02) ? vram_r[src1] : 0;
1555 R0 = (cg_mask256 & 0x20) ? vram_r[src2] : 0;
1556 G1 = (cg_mask256 & 0x04) ? vram_g[src1] : 0;
1557 G0 = (cg_mask256 & 0x40) ? vram_g[src2] : 0;
1558 I1 = (cg_mask256 & 0x08) ? vram_i[src1] : 0;
1559 I0 = (cg_mask256 & 0x80) ? vram_i[src2] : 0;
1561 cg[dest2 ] = cg[dest2 + 1] = cg_matrix0[B0][R0][0] | cg_matrix1[G0][I0][0] | cg_matrix2[B1][R1][0] | cg_matrix3[G1][I1][0];
1562 cg[dest2 + 2] = cg[dest2 + 3] = cg_matrix0[B0][R0][1] | cg_matrix1[G0][I0][1] | cg_matrix2[B1][R1][1] | cg_matrix3[G1][I1][1];
1563 cg[dest2 + 4] = cg[dest2 + 5] = cg_matrix0[B0][R0][2] | cg_matrix1[G0][I0][2] | cg_matrix2[B1][R1][2] | cg_matrix3[G1][I1][2];
1564 cg[dest2 + 6] = cg[dest2 + 7] = cg_matrix0[B0][R0][3] | cg_matrix1[G0][I0][3] | cg_matrix2[B1][R1][3] | cg_matrix3[G1][I1][3];
1565 cg[dest2 + 8] = cg[dest2 + 9] = cg_matrix0[B0][R0][4] | cg_matrix1[G0][I0][4] | cg_matrix2[B1][R1][4] | cg_matrix3[G1][I1][4];
1566 cg[dest2 + 10] = cg[dest2 + 11] = cg_matrix0[B0][R0][5] | cg_matrix1[G0][I0][5] | cg_matrix2[B1][R1][5] | cg_matrix3[G1][I1][5];
1567 cg[dest2 + 12] = cg[dest2 + 13] = cg_matrix0[B0][R0][6] | cg_matrix1[G0][I0][6] | cg_matrix2[B1][R1][6] | cg_matrix3[G1][I1][6];
1568 cg[dest2 + 14] = cg[dest2 + 15] = cg_matrix0[B0][R0][7] | cg_matrix1[G0][I0][7] | cg_matrix2[B1][R1][7] | cg_matrix3[G1][I1][7];
1574 void CRTC::draw_640x200x16screen(uint8_t pl)
1580 create_addr_map(80, 200);
1582 for(int y = 0; y < 200; y++) {
1583 for(int x = 0; x < 80; x++) {
1584 uint16_t src = (map_addr[y][x] + (0x4000 * pl)) & 0x7fff;
1585 uint32_t dest2 = dest + map_hdsc[y][x];
1588 B = (cgreg[0x18] & 0x01) ? vram_b[src] : 0;
1589 R = (cgreg[0x18] & 0x02) ? vram_r[src] : 0;
1590 G = (cgreg[0x18] & 0x04) ? vram_g[src] : 0;
1591 I = (cgreg[0x18] & 0x08) ? vram_i[src] : 0;
1593 cg[dest2 ] = cg_matrix0[B][R][0] | cg_matrix1[G][I][0];
1594 cg[dest2 + 1] = cg_matrix0[B][R][1] | cg_matrix1[G][I][1];
1595 cg[dest2 + 2] = cg_matrix0[B][R][2] | cg_matrix1[G][I][2];
1596 cg[dest2 + 3] = cg_matrix0[B][R][3] | cg_matrix1[G][I][3];
1597 cg[dest2 + 4] = cg_matrix0[B][R][4] | cg_matrix1[G][I][4];
1598 cg[dest2 + 5] = cg_matrix0[B][R][5] | cg_matrix1[G][I][5];
1599 cg[dest2 + 6] = cg_matrix0[B][R][6] | cg_matrix1[G][I][6];
1600 cg[dest2 + 7] = cg_matrix0[B][R][7] | cg_matrix1[G][I][7];
1606 void CRTC::draw_640x400x4screen()
1611 uint8_t *vram_b1 = ((cgreg[0x18] & 3) == 1) ? vram_b + 0x4000 : vram_g;
1612 uint8_t *vram_r1 = ((cgreg[0x18] & 3) == 1) ? vram_r + 0x4000 : vram_i;
1615 create_addr_map(80, 400);
1617 for(int y = 0; y < 400; y++) {
1618 for(int x = 0; x < 80; x++) {
1619 uint16_t src = map_addr[y][x];
1620 uint32_t dest2 = dest + map_hdsc[y][x];
1623 B = (cgreg[0x18] & 0x01) ? ((src & 0x4000) ? vram_b1[src & 0x3fff] : vram_b[src]) : 0;
1624 R = (cgreg[0x18] & 0x02) ? ((src & 0x4000) ? vram_r1[src & 0x3fff] : vram_r[src]) : 0;
1626 cg[dest2 ] = cg_matrix0[B][R][0];
1627 cg[dest2 + 1] = cg_matrix0[B][R][1];
1628 cg[dest2 + 2] = cg_matrix0[B][R][2];
1629 cg[dest2 + 3] = cg_matrix0[B][R][3];
1630 cg[dest2 + 4] = cg_matrix0[B][R][4];
1631 cg[dest2 + 5] = cg_matrix0[B][R][5];
1632 cg[dest2 + 6] = cg_matrix0[B][R][6];
1633 cg[dest2 + 7] = cg_matrix0[B][R][7];
1638 void CRTC::draw_640x400x16screen()
1644 create_addr_map(80, 400);
1646 for(int y = 0; y < 400; y++) {
1647 for(int x = 0; x < 80; x++) {
1648 uint16_t src = map_addr[y][x];
1649 uint32_t dest2 = dest + map_hdsc[y][x];
1657 cg[dest2 ] = cg_matrix0[B][R][0] | cg_matrix1[G][I][0];
1658 cg[dest2 + 1] = cg_matrix0[B][R][1] | cg_matrix1[G][I][1];
1659 cg[dest2 + 2] = cg_matrix0[B][R][2] | cg_matrix1[G][I][2];
1660 cg[dest2 + 3] = cg_matrix0[B][R][3] | cg_matrix1[G][I][3];
1661 cg[dest2 + 4] = cg_matrix0[B][R][4] | cg_matrix1[G][I][4];
1662 cg[dest2 + 5] = cg_matrix0[B][R][5] | cg_matrix1[G][I][5];
1663 cg[dest2 + 6] = cg_matrix0[B][R][6] | cg_matrix1[G][I][6];
1664 cg[dest2 + 7] = cg_matrix0[B][R][7] | cg_matrix1[G][I][7];
1669 void CRTC::create_addr_map(int xmax, int ymax)
1671 uint8_t HDSC = cgreg[0x0f] & 0x07;
1672 uint16_t SAD0 = cgreg[0x10] | ((cgreg[0x11] & 0x7f) << 8);
1673 uint16_t SAD1 = cgreg[0x12] | ((cgreg[0x13] & 0x7f) << 8);
1674 uint16_t SAD2 = cgreg[0x14] | ((cgreg[0x15] & 0x7f) << 8);
1675 uint16_t SLN1 = cgreg[0x16] | ((cgreg[0x17] & 0x01) << 8);
1677 for(int y = 0; y < SLN1 && y < ymax; y++) {
1678 for(int x = 0; x < xmax; x++) {
1679 map_hdsc[y][x] = HDSC;
1680 map_addr[y][x] = SAD0;
1681 SAD0 = (SAD0 == SAD1) ? 0 : ((SAD0 + 1) & 0x7fff);
1684 for(int y = SLN1; y < ymax; y++) {
1685 for(int x = 0; x < xmax; x++) {
1687 map_addr[y][x] = (SAD2++) & 0x7fff;
1693 #define STATE_VERSION 1
1695 #include "../../statesub.h"
1697 void CRTC::decl_state()
1699 enter_decl_state(STATE_VERSION);
1701 DECL_STATE_ENTRY_BOOL(scan_line);
1702 DECL_STATE_ENTRY_BOOL(scan_tmp);
1703 DECL_STATE_ENTRY_BOOL(monitor_200line);
1704 DECL_STATE_ENTRY_BOOL(monitor_digital);
1705 DECL_STATE_ENTRY_BOOL(monitor_tmp);
1706 DECL_STATE_ENTRY_UINT8(textreg_num);
1707 DECL_STATE_ENTRY_1D_ARRAY(textreg, sizeof(textreg));
1708 DECL_STATE_ENTRY_UINT8(cgreg_num);
1709 DECL_STATE_ENTRY_1D_ARRAY(cgreg, sizeof(cgreg));
1710 DECL_STATE_ENTRY_UINT8(scrn_size);
1711 DECL_STATE_ENTRY_UINT8(cg_mask);
1712 DECL_STATE_ENTRY_UINT8(cg_mask256);
1713 DECL_STATE_ENTRY_BOOL(cg_mask256_init);
1714 DECL_STATE_ENTRY_BOOL(font_size);
1715 DECL_STATE_ENTRY_BOOL(column_size);
1716 DECL_STATE_ENTRY_1D_ARRAY(latch, sizeof(latch));
1717 DECL_STATE_ENTRY_UINT16(GDEVS);
1718 DECL_STATE_ENTRY_UINT16(GDEVE);
1719 DECL_STATE_ENTRY_UINT8(GDEHS);
1720 DECL_STATE_ENTRY_UINT8(GDEHE);
1721 DECL_STATE_ENTRY_INT32(GDEHSC);
1722 DECL_STATE_ENTRY_INT32(GDEHEC);
1723 DECL_STATE_ENTRY_BOOL(hblank);
1724 DECL_STATE_ENTRY_BOOL(vblank);
1725 DECL_STATE_ENTRY_BOOL(blink);
1726 DECL_STATE_ENTRY_UINT8(clear_flag);
1727 DECL_STATE_ENTRY_1D_ARRAY(palette_reg, sizeof(palette_reg));
1728 DECL_STATE_ENTRY_BOOL(pal_select);
1729 DECL_STATE_ENTRY_BOOL(screen_mask);
1730 DECL_STATE_ENTRY_2D_ARRAY(priority16, 16, 9);
1732 DECL_STATE_ENTRY_SCRNTYPE_T_1D_ARRAY(palette16, sizeof(palette16) / sizeof(scrntype_t));
1733 DECL_STATE_ENTRY_SCRNTYPE_T_1D_ARRAY(palette4096, sizeof(palette4096) / sizeof(scrntype_t));
1734 DECL_STATE_ENTRY_1D_ARRAY(palette4096r, sizeof(palette4096r));
1735 DECL_STATE_ENTRY_1D_ARRAY(palette4096g, sizeof(palette4096g));
1736 DECL_STATE_ENTRY_1D_ARRAY(palette4096b, sizeof(palette4096b));
1737 DECL_STATE_ENTRY_SCRNTYPE_T_1D_ARRAY(palette16txt, sizeof(palette16txt) / sizeof(scrntype_t));
1738 DECL_STATE_ENTRY_SCRNTYPE_T_1D_ARRAY(palette4096txt, sizeof(palette4096txt) / sizeof(scrntype_t));
1739 DECL_STATE_ENTRY_SCRNTYPE_T_2D_ARRAY(palette16pri, 16, 9);
1740 DECL_STATE_ENTRY_SCRNTYPE_T_2D_ARRAY(palette4096pri, 16, 9);
1741 DECL_STATE_ENTRY_UINT8(prev16);
1742 DECL_STATE_ENTRY_BOOL(update16);
1743 DECL_STATE_ENTRY_2D_ARRAY(priority256, 256, 16+64);
1744 DECL_STATE_ENTRY_SCRNTYPE_T_1D_ARRAY(palette256, sizeof(palette256) / sizeof(scrntype_t));
1745 DECL_STATE_ENTRY_SCRNTYPE_T_1D_ARRAY(palette256txt, sizeof(palette256txt) / sizeof(scrntype_t));
1746 DECL_STATE_ENTRY_SCRNTYPE_T_2D_ARRAY(palette256pri, 256, 16+64);
1747 DECL_STATE_ENTRY_SCRNTYPE_T(prev256);
1748 DECL_STATE_ENTRY_BOOL(update256);
1749 DECL_STATE_ENTRY_2D_ARRAY(map_addr, 400, 80);
1750 DECL_STATE_ENTRY_2D_ARRAY(map_hdsc, 400, 80);
1751 DECL_STATE_ENTRY_3D_ARRAY(text_matrix, 256, 8, 8);
1752 DECL_STATE_ENTRY_3D_ARRAY(text_matrixw, 256, 8, 8);
1753 DECL_STATE_ENTRY_UINT8(trans_color);
1754 DECL_STATE_ENTRY_BOOL(map_init);
1755 DECL_STATE_ENTRY_BOOL(trans_init);
1759 void CRTC::save_state(FILEIO* state_fio)
1761 if(state_entry != NULL) {
1762 state_entry->save_state(state_fio);
1764 // state_fio->FputUint32(STATE_VERSION);
1765 // state_fio->FputInt32(this_device_id);
1767 // state_fio->FputBool(scan_line);
1768 // state_fio->FputBool(scan_tmp);
1769 // state_fio->FputBool(monitor_200line);
1770 // state_fio->FputBool(monitor_digital);
1771 // state_fio->FputBool(monitor_tmp);
1772 // state_fio->FputUint8(textreg_num);
1773 // state_fio->Fwrite(textreg, sizeof(textreg), 1);
1774 // state_fio->FputUint8(cgreg_num);
1775 // state_fio->Fwrite(cgreg, sizeof(cgreg), 1);
1776 // state_fio->FputUint8(scrn_size);
1777 // state_fio->FputUint8(cg_mask);
1778 // state_fio->FputUint8(cg_mask256);
1779 // state_fio->FputBool(cg_mask256_init);
1780 // state_fio->FputBool(font_size);
1781 // state_fio->FputBool(column_size);
1782 // state_fio->Fwrite(latch, sizeof(latch), 1);
1783 // state_fio->FputUint16(GDEVS);
1784 // state_fio->FputUint16(GDEVE);
1785 // state_fio->FputUint8(GDEHS);
1786 // state_fio->FputUint8(GDEHE);
1787 // state_fio->FputInt32(GDEHSC);
1788 // state_fio->FputInt32(GDEHEC);
1789 // state_fio->FputBool(hblank);
1790 // state_fio->FputBool(vblank);
1791 // state_fio->FputBool(blink);
1792 // state_fio->FputUint8(clear_flag);
1793 // state_fio->Fwrite(palette_reg, sizeof(palette_reg), 1);
1794 // state_fio->FputBool(pal_select);
1795 // state_fio->FputBool(screen_mask);
1796 // state_fio->Fwrite(priority16, sizeof(priority16), 1);
1797 // state_fio->Fwrite(palette16, sizeof(palette16), 1);
1798 // state_fio->Fwrite(palette4096, sizeof(palette4096), 1);
1799 // state_fio->Fwrite(palette4096r, sizeof(palette4096r), 1);
1800 // state_fio->Fwrite(palette4096g, sizeof(palette4096g), 1);
1801 // state_fio->Fwrite(palette4096b, sizeof(palette4096b), 1);
1802 // state_fio->Fwrite(palette16txt, sizeof(palette16txt), 1);
1803 // state_fio->Fwrite(palette4096txt, sizeof(palette4096txt), 1);
1804 // state_fio->Fwrite(palette16pri, sizeof(palette16pri), 1);
1805 // state_fio->Fwrite(palette4096pri, sizeof(palette4096pri), 1);
1806 // state_fio->FputUint8(prev16);
1807 // state_fio->FputBool(update16);
1808 // state_fio->Fwrite(priority256, sizeof(priority256), 1);
1809 // state_fio->Fwrite(palette256, sizeof(palette256), 1);
1810 // state_fio->Fwrite(palette256txt, sizeof(palette256txt), 1);
1811 // state_fio->Fwrite(palette256pri, sizeof(palette256pri), 1);
1812 // state_fio->FputUint32((uint32_t)prev256);
1813 // state_fio->FputBool(update256);
1814 // state_fio->Fwrite(map_addr, sizeof(map_addr), 1);
1815 // state_fio->Fwrite(map_hdsc, sizeof(map_hdsc), 1);
1816 // state_fio->Fwrite(text_matrix, sizeof(text_matrix), 1);
1817 // state_fio->Fwrite(text_matrixw, sizeof(text_matrixw), 1);
1818 // state_fio->FputUint8(trans_color);
1819 // state_fio->FputBool(map_init);
1820 // state_fio->FputBool(trans_init);
1823 bool CRTC::load_state(FILEIO* state_fio)
1826 if(state_entry != NULL) {
1827 mb = state_entry->load_state(state_fio);
1832 // if(state_fio->FgetUint32() != STATE_VERSION) {
1835 // if(state_fio->FgetInt32() != this_device_id) {
1838 // scan_line = state_fio->FgetBool();
1839 // scan_tmp = state_fio->FgetBool();
1840 // monitor_200line = state_fio->FgetBool();
1841 // monitor_digital = state_fio->FgetBool();
1842 // monitor_tmp = state_fio->FgetBool();
1843 // textreg_num = state_fio->FgetUint8();
1844 // state_fio->Fread(textreg, sizeof(textreg), 1);
1845 // cgreg_num = state_fio->FgetUint8();
1846 // state_fio->Fread(cgreg, sizeof(cgreg), 1);
1847 // scrn_size = state_fio->FgetUint8();
1848 // cg_mask = state_fio->FgetUint8();
1849 // cg_mask256 = state_fio->FgetUint8();
1850 // cg_mask256_init = state_fio->FgetBool();
1851 // font_size = state_fio->FgetBool();
1852 // column_size = state_fio->FgetBool();
1853 // state_fio->Fread(latch, sizeof(latch), 1);
1854 // GDEVS = state_fio->FgetUint16();
1855 // GDEVE = state_fio->FgetUint16();
1856 // GDEHS = state_fio->FgetUint8();
1857 // GDEHE = state_fio->FgetUint8();
1858 // GDEHSC = state_fio->FgetInt32();
1859 // GDEHEC = state_fio->FgetInt32();
1860 // hblank = state_fio->FgetBool();
1861 // vblank = state_fio->FgetBool();
1862 // blink = state_fio->FgetBool();
1863 // clear_flag = state_fio->FgetUint8();
1864 // state_fio->Fread(palette_reg, sizeof(palette_reg), 1);
1865 // pal_select = state_fio->FgetBool();
1866 // screen_mask = state_fio->FgetBool();
1867 // state_fio->Fread(priority16, sizeof(priority16), 1);
1868 // state_fio->Fread(palette16, sizeof(palette16), 1);
1869 // state_fio->Fread(palette4096, sizeof(palette4096), 1);
1870 // state_fio->Fread(palette4096r, sizeof(palette4096r), 1);
1871 // state_fio->Fread(palette4096g, sizeof(palette4096g), 1);
1872 // state_fio->Fread(palette4096b, sizeof(palette4096b), 1);
1873 // state_fio->Fread(palette16txt, sizeof(palette16txt), 1);
1874 // state_fio->Fread(palette4096txt, sizeof(palette4096txt), 1);
1875 // state_fio->Fread(palette16pri, sizeof(palette16pri), 1);
1876 // state_fio->Fread(palette4096pri, sizeof(palette4096pri), 1);
1877 // prev16 = state_fio->FgetUint8();
1878 // update16 = state_fio->FgetBool();
1879 // state_fio->Fread(priority256, sizeof(priority256), 1);
1880 // state_fio->Fread(palette256, sizeof(palette256), 1);
1881 // state_fio->Fread(palette256txt, sizeof(palette256txt), 1);
1882 // state_fio->Fread(palette256pri, sizeof(palette256pri), 1);
1883 // prev256 = (scrntype_t)state_fio->FgetUint32();
1884 // update256 = state_fio->FgetBool();
1885 // state_fio->Fread(map_addr, sizeof(map_addr), 1);
1886 // state_fio->Fread(map_hdsc, sizeof(map_hdsc), 1);
1887 // state_fio->Fread(text_matrix, sizeof(text_matrix), 1);
1888 // state_fio->Fread(text_matrixw, sizeof(text_matrixw), 1);
1889 // trans_color = state_fio->FgetUint8();
1890 // map_init = state_fio->FgetBool();
1891 // trans_init = state_fio->FgetBool();