2 SHARP MZ-2800 Emulator 'EmuZ-2800'
4 Author : Takeda.Toshiya
15 #define EVENT_BLINK 256
17 #define SCRN_640x400 1
18 #define SCRN_640x200 2
20 void CRTC::initialize()
22 // set 16/4096 palette
23 for(int i = 0; i < 16; i++) {
24 uint8_t r = ((i & 0x0f) == 8) ? 152 : ((i & 0x0a) == 0x0a) ? 255 : ((i & 0x0a) == 2) ? 127 : 0;
25 uint8_t g = ((i & 0x0f) == 8) ? 152 : ((i & 0x0c) == 0x0c) ? 255 : ((i & 0x0c) == 4) ? 127 : 0;
26 uint8_t b = ((i & 0x0f) == 8) ? 152 : ((i & 0x09) == 0x09) ? 255 : ((i & 0x09) == 1) ? 127 : 0;
27 palette16[i] = RGB_COLOR(r, g, b);
31 palette4096[i] = RGB_COLOR(r, g, b);
33 for(int i = 0; i < 8; i++) {
34 palette16[i + 16] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);
36 for(int i = 0; i < 16; i++) {
37 for(int j = 1; j < 8; j++) {
38 priority16[i][j] = j + 16;
40 priority16[i][0] = i; // transparent black
41 priority16[i][8] = 0 + 16; // non transparent black
47 for(int i = 0; i < 65536; i++) {
48 // BBBB RRRR GGGG IGRB
49 uint8_t b = ((i & 0xf000) >> 8) | ((i & 1) << 3) | ((i & 8) >> 1);
50 uint8_t r = ((i & 0x0f00) >> 4) | ((i & 2) << 2) | ((i & 8) >> 1);
51 uint8_t g = ((i & 0x00f0) >> 0) | ((i & 4) << 1) | ((i & 8) >> 1);
52 palette65536[i] = RGB_COLOR(r, g, b);
55 // extract cg optimize matrix
56 for(int p1 = 0; p1 < 256; p1++) {
57 for(int p2 = 0; p2 < 256; p2++) {
58 for(int i = 0; i < 8; i++) {
59 cg_matrix0[p1][p2][i] = (p1 & (0x80 >> i) ? 0x01 : 0) | (p2 & (0x80 >> i) ? 0x02 : 0);
60 cg_matrix1[p1][p2][i] = (p1 & (0x80 >> i) ? 0x04 : 0) | (p2 & (0x80 >> i) ? 0x08 : 0);
61 cg_matrix2[p1][p2][i] = (p1 & (0x80 >> i) ? 0x10 : 0) | (p2 & (0x80 >> i) ? 0x20 : 0);
62 cg_matrix3[p1][p2][i] = (p1 & (0x80 >> i) ? 0x40 : 0) | (p2 & (0x80 >> i) ? 0x80 : 0);
68 memset(textreg, 0, sizeof(textreg));
69 memset(rmwreg, 0, sizeof(rmwreg));
70 memset(cgreg, 0, sizeof(cgreg));
71 memset(latch, 0, sizeof(latch));
73 rmwreg_num[0] = rmwreg_num[1] = cgreg_num = 0x80;
74 GDEVS = 0; cgreg[0] = 0x00; cgreg[1] = 0x00;
75 GDEVE = 400; cgreg[2] = 0x90; cgreg[3] = 0x01;
76 GDEHS = 0; cgreg[4] = 0x00;
77 GDEHSC = (int)(CPU_CLOCKS * GDEHS / FRAMES_PER_SEC / LINES_PER_FRAME / CHARS_PER_LINE + 0.5);
78 GDEHE = 80; cgreg[5] = 0x50;
79 GDEHEC = (int)(CPU_CLOCKS * GDEHE / FRAMES_PER_SEC / LINES_PER_FRAME / CHARS_PER_LINE + 0.5);
81 for(int i = 0; i < 16; i++) {
84 scrn_size = SCRN_640x400;
92 blank = hblank = vblank = false;
93 map_init = trans_init = true;
96 register_vline_event(this);
97 register_event(this, EVENT_BLINK, 500000, true, NULL);
100 void CRTC::write_data8(uint32_t addr, uint32_t data)
105 if((rmwreg[lh][5] & 0xc0) == 0x00) {
107 if(rmwreg[lh][5] & 1) {
108 vram_b[addr] &= ~rmwreg[lh][6];
109 vram_b[addr] |= (rmwreg[lh][4] & 1) ? (data & rmwreg[lh][0] & rmwreg[lh][6]) : 0;
111 if(rmwreg[lh][5] & 2) {
112 vram_r[addr] &= ~rmwreg[lh][6];
113 vram_r[addr] |= (rmwreg[lh][4] & 2) ? (data & rmwreg[lh][1] & rmwreg[lh][6]) : 0;
115 if(rmwreg[lh][5] & 4) {
116 vram_g[addr] &= ~rmwreg[lh][6];
117 vram_g[addr] |= (rmwreg[lh][4] & 4) ? (data & rmwreg[lh][2] & rmwreg[lh][6]) : 0;
119 if(rmwreg[lh][5] & 8) {
120 vram_i[addr] &= ~rmwreg[lh][6];
121 vram_i[addr] |= (rmwreg[lh][4] & 8) ? (data & rmwreg[lh][3] & rmwreg[lh][6]) : 0;
123 } else if((rmwreg[lh][5] & 0xc0) == 0x40) {
125 if(rmwreg[lh][5] & 1) {
126 vram_b[addr] &= ~data;
127 vram_b[addr] |= (rmwreg[lh][4] & 1) ? (data & rmwreg[lh][0]) : 0;
129 if(rmwreg[lh][5] & 2) {
130 vram_r[addr] &= ~data;
131 vram_r[addr] |= (rmwreg[lh][4] & 2) ? (data & rmwreg[lh][1]) : 0;
133 if(rmwreg[lh][5] & 4) {
134 vram_g[addr] &= ~data;
135 vram_g[addr] |= (rmwreg[lh][4] & 4) ? (data & rmwreg[lh][2]) : 0;
137 if(rmwreg[lh][5] & 8) {
138 vram_i[addr] &= ~data;
139 vram_i[addr] |= (rmwreg[lh][4] & 8) ? (data & rmwreg[lh][3]) : 0;
144 uint32_t CRTC::read_data8(uint32_t addr)
149 uint8_t b = latch[lh][0] = vram_b[addr];
150 uint8_t r = latch[lh][1] = vram_r[addr];
151 uint8_t g = latch[lh][2] = vram_g[addr];
152 uint8_t i = latch[lh][3] = vram_i[addr];
153 uint8_t pl = rmwreg[lh][7] & 3;
155 if(rmwreg[lh][7] & 0x10) {
156 uint8_t compare = rmwreg[lh][7] & 0x0f;
157 uint8_t val = (compare == (((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5) | ((i & 0x80) >> 4))) ? 0x80 : 0;
158 val |= (compare == (((b & 0x40) >> 6) | ((r & 0x40) >> 5) | ((g & 0x40) >> 4) | ((i & 0x40) >> 3))) ? 0x40 : 0;
159 val |= (compare == (((b & 0x20) >> 5) | ((r & 0x20) >> 4) | ((g & 0x20) >> 3) | ((i & 0x20) >> 2))) ? 0x20 : 0;
160 val |= (compare == (((b & 0x10) >> 4) | ((r & 0x10) >> 3) | ((g & 0x10) >> 2) | ((i & 0x10) >> 1))) ? 0x10 : 0;
161 val |= (compare == (((b & 0x08) >> 3) | ((r & 0x08) >> 2) | ((g & 0x08) >> 1) | ((i & 0x08) ))) ? 0x08 : 0;
162 val |= (compare == (((b & 0x04) >> 2) | ((r & 0x04) >> 1) | ((g & 0x04) ) | ((i & 0x04) << 1))) ? 0x04 : 0;
163 val |= (compare == (((b & 0x02) >> 1) | ((r & 0x02) ) | ((g & 0x02) << 1) | ((i & 0x02) << 2))) ? 0x02 : 0;
164 val |= (compare == (((b & 0x01) ) | ((r & 0x01) << 1) | ((g & 0x01) << 2) | ((i & 0x01) << 3))) ? 0x01 : 0;
167 return latch[lh][pl];
171 void CRTC::write_io8(uint32_t addr, uint32_t data)
173 uint8_t num, r, g, b, prev;
176 switch(addr & 0x7fff) {
177 case 0x00ae: case 0x01ae: case 0x02ae: case 0x03ae: case 0x04ae: case 0x05ae: case 0x06ae: case 0x07ae:
178 case 0x08ae: case 0x09ae: case 0x0aae: case 0x0bae: case 0x0cae: case 0x0dae: case 0x0eae: case 0x0fae:
179 case 0x10ae: case 0x11ae: case 0x12ae: case 0x13ae: case 0x14ae: case 0x15ae: case 0x16ae: case 0x17ae:
180 case 0x18ae: case 0x19ae: case 0x1aae: case 0x1bae: case 0x1cae: case 0x1dae: case 0x1eae: case 0x1fae:
182 num = (addr & 0x1f00) >> 9;
183 r = palette4096r[num];
184 g = palette4096g[num];
185 b = palette4096b[num];
187 g = (data & 0x0f) << 4;
190 b = (data & 0x0f) << 4;
192 if(palette4096r[num] != r || palette4096g[num] != g || palette4096b[num] != b) {
193 palette4096r[num] = r;
194 palette4096g[num] = g;
195 palette4096b[num] = b;
196 palette4096[num] = RGB_COLOR(r, g, b);
199 // never change palette 0
200 //palette4096[0] = 0;
208 if(textreg_num < 0x10) {
209 if(textreg_num == 0) {
210 trans_init |= ((textreg[0] & 2) != (uint8_t)(data & 2));
212 textreg[textreg_num] = data;
213 } else if(0x80 <= textreg_num && textreg_num < 0x90) {
214 int c = textreg_num & 0x0f;
216 prev = palette_reg[c];
217 palette_reg[c] = data;
219 if((prev & 0x0f) != (uint8_t)(data & 0x0f)) {
222 if((prev & 0x10) != (uint8_t)(data & 0x10)) {
224 int col = data & 0x0f;
225 int col16 = col << 4;
229 for(int i = 1; i < 8; i++) {
230 priority16[c][i] = p ? c : (i + 16);
232 priority16[c][0] = c; // transparent black
233 priority16[c][8] = p ? c : (0 + 16); // non transparent black
241 cg_mask = (data & 7) | ((data & 1) ? 8 : 0);
242 update16 |= (prev != cg_mask);
246 font_size = ((data & 1) != 0);
251 rmwreg_num[lh] = data;
256 rmwreg[lh][rmwreg_num[lh] & 0x1f] = data;
258 if((rmwreg_num[lh] & 0x1f) == 5 && (data & 0xc0) == 0x80) {
260 switch(rmwreg[lh][0x0e]) {
261 case 0x03: case 0x14: case 0x15: case 0x17: case 0x1d:
262 // clear 0x0000 - 0x4000
266 case 0x94: case 0x95: case 0x97: case 0x9d:
267 // clear 0x4000 - 0x7fff
272 // clear 0x0000 - 0x7fff
276 if(rmwreg[lh][5] & 1) {
277 memset(vram_b + st, 0, sz);
279 if(rmwreg[lh][5] & 2) {
280 memset(vram_r + st, 0, sz);
282 if(rmwreg[lh][5] & 4) {
283 memset(vram_g + st, 0, sz);
285 if(rmwreg[lh][5] & 8) {
286 memset(vram_i + st, 0, sz);
291 if(rmwreg_num[lh] & 0x80) {
292 rmwreg_num[lh] = (rmwreg_num[lh] & 0xfc) | ((rmwreg_num[lh] + 1) & 3);
301 prev = cgreg[cgreg_num & 0x1f];;
302 cgreg[cgreg_num & 0x1f] = data;
304 switch(cgreg_num & 0x1f) {
309 GDEVS = (cgreg[0] | ((cgreg[1] & 1) << 8)); //* ((scrn_size == SCRN_640x400) ? 1 : 2);
314 GDEVE = (cgreg[2] | ((cgreg[3] & 1) << 8)); //* ((scrn_size == SCRN_640x400) ? 1 : 2);
317 GDEHS = cgreg[4] & 0x7f;
318 GDEHSC = (int)(CPU_CLOCKS * GDEHS / FRAMES_PER_SEC / LINES_PER_FRAME / CHARS_PER_LINE + 0.5);
321 GDEHE = cgreg[5] & 0x7f;
322 GDEHEC = (int)(CPU_CLOCKS * GDEHE / FRAMES_PER_SEC / LINES_PER_FRAME / CHARS_PER_LINE + 0.5);
327 case 0x17: case 0x1f:
328 map_init |= (scrn_size != SCRN_640x200);
329 scrn_size = SCRN_640x200;
331 case 0x13: case 0x1b:
332 map_init |= (scrn_size != SCRN_640x400);
333 scrn_size = SCRN_640x400;
339 map_init |= ((prev & 0x07) != (uint8_t)(data & 0x07));
341 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c:
342 map_init |= (prev != (uint8_t)(data & 0xff));
345 map_init |= ((prev & 0x01) != (uint8_t)(data & 0x01));
349 if(cgreg_num & 0x80) {
350 cgreg_num = (cgreg_num & 0xfc) | ((cgreg_num + 1) & 3);
356 void CRTC::write_signal(int id, uint32_t data, uint32_t mask)
358 if(id == SIG_CRTC_COLUMN_SIZE) {
359 column_size = ((data & mask) != 0); // from z80pio port a
360 } else if(id == SIG_CRTC_PALLETE) {
361 pal_select = ((data & mask) == 0); // from ym2203 port a
362 } else if(id == SIG_CRTC_MASK) {
363 screen_mask = ((data & mask) != 0); // from i8255 port c
367 void CRTC::event_callback(int event_id, int err)
376 void CRTC::event_vline(int v, int clock)
379 bool next = !(GDEVS <= v && v < GDEVE);
382 // d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR1, next ? 2 : 0, 2);
383 // d_pio->write_signal(SIG_I8255_PORT_B, next ? 2 : 0, 2);
389 d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR1, 0, 2);
390 d_pio->write_signal(SIG_I8255_PORT_B, 0, 2);
391 } else if(v == 400) {
392 d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR1, 2, 2);
393 d_pio->write_signal(SIG_I8255_PORT_B, 2, 2);
397 // complete clear screen
402 // register hsync events
405 } else if(GDEHS < CHARS_PER_LINE) {
406 register_event_by_clock(this, GDEHS, GDEHSC, false, NULL);
410 } else if(GDEHE < CHARS_PER_LINE) {
411 register_event_by_clock(this, GDEHE, GDEHEC, false, NULL);
415 void CRTC::set_hsync(int h)
417 hblank = !(GDEHS <= h && h < GDEHE);
418 bool next = (hblank || vblank);
420 d_pio->write_signal(SIG_I8255_PORT_B, next ? 1 : 0, 1);
425 // ----------------------------------------------------------------------------
427 // ----------------------------------------------------------------------------
429 void CRTC::draw_screen()
431 // update 16/4096 palette
432 uint8_t back16 = ((textreg[0x0b] & 4) >> 2) | ((textreg[0x0b] & 0x20) >> 4) | ((textreg[0x0c] & 1) << 2) | ((textreg[0x0b] & 1) << 3);
433 if(back16 != prev16) {
438 scrntype_t palette16tmp[16 + 8], palette4096tmp[16 + 8];
439 for(int i = 0; i < 16 + 8; i++) {
440 palette16tmp[i] = palette16[(i & 16) ? i : (palette_reg[i] & 0x0f) ? (palette_reg[i] & cg_mask) : (back16 & cg_mask)];
441 uint8_t col = (i == 16) ? 0 : (i & 16) ? (i & 0x0f) + 8 : i;
442 palette4096tmp[i] = palette4096[(palette_reg[col] & 0x0f) ? (palette_reg[col] & cg_mask) : (back16 & cg_mask)];
444 for(int i = 0; i < 16; i++) {
445 for(int j = 0; j < 9; j++) {
446 palette16pri[i][j] = palette16tmp[priority16[i][j]];
447 palette4096pri[i][j] = palette4096tmp[priority16[i][j]];
450 memcpy(palette16txt, &palette16tmp[16], sizeof(scrntype_t) * 8);
451 palette16txt[0] = palette16[palette_reg[back16] & 0x0f];
453 memcpy(palette4096txt, &palette4096tmp[16], sizeof(scrntype_t) * 8);
454 palette4096txt[0] = palette4096[palette_reg[back16] & 0x0f];
455 palette4096txt[8] = 0;
460 memset(cg, 0, sizeof(cg));
464 memset(text, 0, sizeof(text));
468 int vs = (GDEVS <= GDEVE) ? GDEVS * (scrn_size == SCRN_640x400 ? 1 : 2) : 0;
469 int ve = (GDEVS <= GDEVE) ? GDEVE * (scrn_size == SCRN_640x400 ? 1 : 2) : 400;
470 int hs = (GDEHS <= GDEHE && GDEHS < 80) ? (GDEHS << 3) : 0;
471 int he = (GDEHS <= GDEHE && GDEHE < 80) ? (GDEHE << 3) : 640;
476 for(int y = 0; y < 400; y++) {
477 scrntype_t *dest = emu->get_screen_buffer(y);
478 memset(dest, 0, sizeof(scrntype_t) * 640);
480 } else if(cgreg[6] == 0x1b || cgreg[6] == 0x1f) {
482 for(int y = 0; y < vs && y < 400; y++) {
483 scrntype_t *dest = emu->get_screen_buffer(y);
484 uint8_t *src_text = &text[640 * y];
485 for(int x = 0; x < 640; x++) {
486 dest[x] = palette16txt[src_text[x]];
489 for(int y = vs; y < ve && y < 400; y++) {
490 scrntype_t *dest = emu->get_screen_buffer(y);
491 uint16_t *src_cg = &cg[640 * y];
492 uint8_t *src_text = &text[640 * y];
493 for(int x = 0; x < hs && x < 640; x++) {
494 dest[x] = palette16txt[src_text[x]];
496 for(int x = hs; x < he && x < 640; x++) {
497 dest[x] = src_text[x] ? palette16txt[src_text[x]] : palette65536[src_cg[x]];
499 for(int x = he; x < 640; x++) {
500 dest[x] = palette16txt[src_text[x]];
503 for(int y = ve; y < 400; y++) {
504 scrntype_t *dest = emu->get_screen_buffer(y);
505 uint8_t *src_text = &text[640 * y];
506 for(int x = 0; x < 640; x++) {
507 dest[x] = palette16txt[src_text[x]];
510 } else if(!pal_select) {
512 for(int y = 0; y < vs && y < 400; y++) {
513 scrntype_t *dest = emu->get_screen_buffer(y);
514 uint8_t *src_text = &text[640 * y];
515 for(int x = 0; x < 640; x++) {
516 dest[x] = palette16txt[src_text[x]];
519 for(int y = vs; y < ve && y < 400; y++) {
520 scrntype_t *dest = emu->get_screen_buffer(y);
521 uint16_t *src_cg = &cg[640 * y];
522 uint8_t *src_text = &text[640 * y];
523 for(int x = 0; x < hs && x < 640; x++) {
524 dest[x] = palette16txt[src_text[x]];
526 for(int x = hs; x < he && x < 640; x++) {
527 dest[x] = palette16pri[src_cg[x]][src_text[x]];
529 for(int x = he; x < 640; x++) {
530 dest[x] = palette16txt[src_text[x]];
533 for(int y = ve; y < 400; y++) {
534 scrntype_t *dest = emu->get_screen_buffer(y);
535 uint8_t *src_text = &text[640 * y];
536 for(int x = 0; x < 640; x++) {
537 dest[x] = palette16txt[src_text[x]];
542 for(int y = 0; y < vs && y < 400; y++) {
543 scrntype_t *dest = emu->get_screen_buffer(y);
544 uint8_t *src_text = &text[640 * y];
545 for(int x = 0; x < 640; x++) {
546 dest[x] = palette4096txt[src_text[x]];
549 for(int y = vs; y < ve && y < 400; y++) {
550 scrntype_t *dest = emu->get_screen_buffer(y);
551 uint16_t *src_cg = &cg[640 * y];
552 uint8_t *src_text = &text[640 * y];
553 for(int x = 0; x < hs && x < 640; x++) {
554 dest[x] = palette4096txt[src_text[x]];
556 for(int x = hs; x < he && x < 640; x++) {
557 dest[x] = palette4096pri[src_cg[x]][src_text[x]];
559 for(int x = he; x < 640; x++) {
560 dest[x] = palette4096txt[src_text[x]];
563 for(int y = ve; y < 400; y++) {
564 scrntype_t *dest = emu->get_screen_buffer(y);
565 uint8_t *src_text = &text[640 * y];
566 for(int x = 0; x < 640; x++) {
567 dest[x] = palette4096txt[src_text[x]];
571 emu->screen_skip_line(false);
574 // ----------------------------------------------------------------------------
576 // ----------------------------------------------------------------------------
578 void CRTC::draw_text()
580 // extract text optimize matrix
582 trans_color = (textreg[0] & 2) ? 8 : 0;
583 for(int pat = 0; pat < 256; pat++) {
584 for(int col = 0; col < 8; col++) {
585 int fore_color = col ? col : 8;
586 text_matrix[pat][col][0] = text_matrixw[pat][col][ 0] = text_matrixw[pat][col][ 1] = (pat & 0x80) ? fore_color : trans_color;
587 text_matrix[pat][col][1] = text_matrixw[pat][col][ 2] = text_matrixw[pat][col][ 3] = (pat & 0x40) ? fore_color : trans_color;
588 text_matrix[pat][col][2] = text_matrixw[pat][col][ 4] = text_matrixw[pat][col][ 5] = (pat & 0x20) ? fore_color : trans_color;
589 text_matrix[pat][col][3] = text_matrixw[pat][col][ 6] = text_matrixw[pat][col][ 7] = (pat & 0x10) ? fore_color : trans_color;
590 text_matrix[pat][col][4] = text_matrixw[pat][col][ 8] = text_matrixw[pat][col][ 9] = (pat & 0x08) ? fore_color : trans_color;
591 text_matrix[pat][col][5] = text_matrixw[pat][col][10] = text_matrixw[pat][col][11] = (pat & 0x04) ? fore_color : trans_color;
592 text_matrix[pat][col][6] = text_matrixw[pat][col][12] = text_matrixw[pat][col][13] = (pat & 0x02) ? fore_color : trans_color;
593 text_matrix[pat][col][7] = text_matrixw[pat][col][14] = text_matrixw[pat][col][15] = (pat & 0x01) ? fore_color : trans_color;
601 draw_80column_screen();
603 draw_40column_screen();
607 int SL = (textreg[3] - 17) << 1, SC;
608 int EL = (textreg[5] - 17) << 1, EC;
611 SC = (textreg[7] & 0x7f) - 9;
612 EC = (textreg[8] & 0x7f) - 9;
615 SC = (textreg[7] & 0x7f) - 8;
616 EC = (textreg[8] & 0x7f) - 8;
618 SL = (SL < 0) ? 0 : (SL > 400) ? 400 : SL;
619 EL = (EL < 0) ? 0 : (EL > 400) ? 400 : EL;
620 SC = (SC < 0) ? 0 : (SC > 80) ? 80 : SC;
621 EC = (EC < 0) ? 0 : (EC > 80) ? 80 : EC;
624 for(int y = 0; y < SL; y++) {
625 memset(text + 640 * y, trans_color, 640);
627 for(int y = EL; y < 400; y++) {
628 memset(text + 640 * y, trans_color, 640);
631 for(int y = EL; y < SL; y++) {
632 memset(text + 640 * y, trans_color, 640);
636 for(int y = 0; y < 400; y++) {
637 memset(text + 640 * y, trans_color, SC << 3);
638 memset(text + 640 * y + (EC << 3), trans_color, (80 - EC) << 3);
641 for(int y = 0; y < 400; y++) {
642 memset(text + 640 * y + (EC << 3), trans_color, (SC - EC) << 3);
647 void CRTC::draw_80column_screen()
649 uint16_t src = (textreg[1] << 2) | ((textreg[2] & 7) << 10);
650 uint8_t line = (textreg[0] & 0x10) ? 2 : 0;
651 uint8_t height = (textreg[0] & 0x10) ? 20 : 16;
652 uint8_t vd = (textreg[9] & 0x0f) << 1;
655 for(int y = line; y < 416; y += height) {
656 int dest = (y - vd) * 640;
657 for(int x = 0; x < 80; x++) {
658 draw_80column_font(src & 0x1fff, dest, y - vd);
665 void CRTC::draw_40column_screen()
667 uint16_t src1 = (textreg[1] << 2) | ((textreg[2] & 7) << 10);
668 uint16_t src2 = src1 + 0x1000;
669 uint8_t line = (textreg[0] & 0x10) ? 2 : 0;
670 uint8_t height = (textreg[0] & 0x10) ? 20 : 16;
671 uint8_t vd = (textreg[9] & 0x0f) << 1;
673 switch(textreg[0] & 0x0c) {
675 // 40x20(25), 64colors
676 for(int y = line; y < 416; y += height) {
677 int dest1 = (y - vd) * 640;
678 int dest2 = (y - vd) * 640 + 640 * 480;
679 for(int x = 0; x < 40; x++) {
680 draw_40column_font(src1 & 0x1fff, dest1, y - vd);
681 draw_40column_font(src2 & 0x1fff, dest2, y - vd);
688 for(int y = 0; y < 400; y++) {
689 uint32_t src1 = 640 * y;
690 uint32_t src2 = 640 * y + 640 * 480;
691 uint32_t dest = 640 * y;
693 for(int x = 0; x < 640; x++) {
694 //if((text[src1] & 8) | (text[src2] & 8))
695 if((text[src1] & 8) && (text[src2] & 8)) {
696 // non transparent black
699 col = (((text[src1] & 7) << 3) | (text[src2] & 7)) + 16;
708 // 40x20(25), No.1 Screen
709 for(int y = line; y < 416; y += height) {
710 int dest = (y - vd) * 640;
711 for(int x = 0; x < 40; x++) {
712 draw_40column_font(src1 & 0x1fff, dest, y - vd);
719 // 40x20(25), No.2 Screen
720 for(int y = line; y < 416; y += height) {
721 int dest = (y - vd) * 640;
722 for(int x = 0; x < 40; x++) {
723 draw_40column_font(src2 & 0x1fff, dest, y - vd);
730 // 40x20(25), No.1 + No.2 Screens (No.1 > No.2)
731 for(int y = line; y < 416; y += height) {
732 int dest = (y - vd) * 640;
733 for(int x = 0; x < 40; x++) {
734 draw_40column_font(src1 & 0x1fff, dest, y - vd);
739 for(int y = line; y < 416; y += height) {
740 int dest = (y - vd) * 640 + 640 * 480;
741 for(int x = 0; x < 40; x++) {
742 draw_40column_font(src2 & 0x1fff, dest, y - vd);
747 for(int y = line; y < 400; y++) {
748 int dest = (y - vd) * 640;
749 uint8_t* tsrc1 = &text[dest];
750 uint8_t* tsrc2 = &text[dest + 640 * 480];
751 uint8_t* tdest = &text[dest];
752 for(int x = 0; x < 640; x++) {
753 tdest[x] = (tsrc1[x] & 7) ? tsrc1[x] : (tsrc2[x] & 7) ? tsrc2[x] : ((tsrc1[x] & 8) | (tsrc2[x] & 8));
760 void CRTC::draw_80column_font(uint16_t src, int dest, int y)
762 // draw char (80 column)
768 uint8_t sel, col, pat1, pat2, pat3;
769 uint8_t t1 = tvram[src], t2 = tvram[src + 1], attr = tvram[src + 2];
772 sel = (t2 & 0xc0) | (attr & 0x38);
774 case 0x00: case 0x40:
783 case 0x10: case 0x50: case 0x90: case 0xd0:
786 case 0x20: case 0x60: case 0xa0: case 0xe0:
789 case 0x30: case 0x70: case 0xb0: case 0xf0:
799 // PCG1 + PCG2 + PCG3 8colors
802 code = font_size ? t1 << 3 : (t1 & 0xfe) << 3;
806 for(int i = 0; i < 8; i++) {
807 // check end line of screen
811 if((attr & 0x80) && blink) {
813 uint8_t val = (attr & 0x40) ? 7 : trans_color;
815 memset(text + dest, val, 8);
818 // check end line of screen
823 memset(text + dest, val, 8);
828 pat1 = ~pattern1[(code + i) << 1];
829 pat2 = ~pattern2[(code + i) << 1];
830 pat3 = ~pattern3[(code + i) << 1];
832 pat1 = pattern1[(code + i) << 1];
833 pat2 = pattern2[(code + i) << 1];
834 pat3 = pattern3[(code + i) << 1];
837 uint8_t* tdest = &text[dest];
838 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[0] = col ? col : trans_color;
839 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[1] = col ? col : trans_color;
840 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[2] = col ? col : trans_color;
841 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[3] = col ? col : trans_color;
842 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[4] = col ? col : trans_color;
843 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[5] = col ? col : trans_color;
844 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[6] = col ? col : trans_color;
845 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[7] = col ? col : trans_color;
848 // check end line of screen
854 memcpy(text + dest, text + dest - 640, 8);
856 uint8_t* tdest = &text[dest];
857 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[0] = col ? col : trans_color;
858 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[1] = col ? col : trans_color;
859 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[2] = col ? col : trans_color;
860 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[3] = col ? col : trans_color;
861 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[4] = col ? col : trans_color;
862 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[5] = col ? col : trans_color;
863 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[6] = col ? col : trans_color;
864 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[7] = col ? col : trans_color;
871 for(int i = 0; i < 16; i++) {
872 // check end line of screen
877 if((attr & 0x80) && blink) {
879 memset(text + dest, 7, 8);
881 memset(text + dest, trans_color, 8);
885 pat1 = ~pattern1[(code + i) << 1];
886 pat2 = ~pattern2[(code + i) << 1];
887 pat3 = ~pattern3[(code + i) << 1];
889 pat1 = pattern1[(code + i) << 1];
890 pat2 = pattern2[(code + i) << 1];
891 pat3 = pattern3[(code + i) << 1];
893 uint8_t* tdest = &text[dest];
894 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[0] = col ? col : trans_color;
895 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[1] = col ? col : trans_color;
896 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[2] = col ? col : trans_color;
897 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[3] = col ? col : trans_color;
898 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[4] = col ? col : trans_color;
899 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[5] = col ? col : trans_color;
900 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[6] = col ? col : trans_color;
901 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[7] = col ? col : trans_color;
912 if(sel == 0x80 || sel == 0xc0) {
913 code = ((t2 & 0x3f) << 11) | (t1 << 3);
918 if(sel == 0x80 || sel == 0xc0) {
919 code = ((t2 & 0x3f) << 11) | ((t1 & 0xfe) << 3);
921 code = (t1 & 0xfe) << 3;
928 uint32_t dest1 = dest;
929 uint32_t dest2 = (dest >= 640 * 399) ? dest - 640 * 399 : dest + 640;
930 for(int i = 0; i < 8; i++) {
931 // check end line of screen
937 pat1 = ((attr & 0x80) && blink) ? 0xff : ~pattern1[(code + i) << 1];
939 pat1 = ((attr & 0x80) && blink) ? 0x00 : pattern1[(code + i) << 1];
942 memcpy(&text[dest], text_matrix[pat1][col], 8);
945 // check end line of screen
950 memcpy(&text[dest], text_matrix[pat1][col], 8);
955 for(int i = 0; i < 16; i++) {
956 // check end line of screen
963 pat1 = ((attr & 0x80) && blink) ? 0xff : ~pattern1[(code + i) << 1];
965 pat1 = ((attr & 0x80) && blink) ? 0x00 : pattern1[(code + i) << 1];
967 memcpy(&text[dest], text_matrix[pat1][col], 8);
975 void CRTC::draw_40column_font(uint16_t src, int dest, int y)
977 // draw char (40 column)
983 uint8_t sel, col, pat1, pat2, pat3;
984 uint8_t t1 = tvram[src], t2 = tvram[src + 1], attr = tvram[src + 2];
987 sel = (t2 & 0xc0) | (attr & 0x38);
989 case 0x00: case 0x40:
998 case 0x10: case 0x50: case 0x90: case 0xd0:
1001 case 0x20: case 0x60: case 0xa0: case 0xe0:
1004 case 0x30: case 0x70: case 0xb0: case 0xf0:
1014 // PCG1 + PCG2 + PCG3 8colors
1017 code = font_size ? t1 << 3 : (t1 & 0xfe) << 3;
1020 for(int i = 0; i < 8; i++) {
1021 // check end line of screen
1025 if((attr & 0x80) && blink) {
1027 uint8_t val = (attr & 0x40) ? 7 : trans_color;
1029 memset(text + dest, val, 16);
1032 // check end line of screen
1037 memset(text + dest, val, 16);
1042 pat1 = ~pattern1[(code + i) << 1];
1043 pat2 = ~pattern2[(code + i) << 1];
1044 pat3 = ~pattern3[(code + i) << 1];
1046 pat1 = pattern1[(code + i) << 1];
1047 pat2 = pattern2[(code + i) << 1];
1048 pat3 = pattern3[(code + i) << 1];
1051 uint8_t* tdest = &text[dest];
1052 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[ 0] = tdest[ 1] = col ? col : trans_color;
1053 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[ 2] = tdest[ 3] = col ? col : trans_color;
1054 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[ 4] = tdest[ 5] = col ? col : trans_color;
1055 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[ 6] = tdest[ 7] = col ? col : trans_color;
1056 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[ 8] = tdest[ 9] = col ? col : trans_color;
1057 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[10] = tdest[11] = col ? col : trans_color;
1058 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[12] = tdest[13] = col ? col : trans_color;
1059 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[14] = tdest[15] = col ? col : trans_color;
1062 // check end line of screen
1068 memcpy(text + dest, text + dest - 640, 16);
1070 uint8_t* tdest = &text[dest];
1071 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[ 0] = tdest[ 1] = col ? col : trans_color;
1072 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[ 2] = tdest[ 3] = col ? col : trans_color;
1073 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[ 4] = tdest[ 5] = col ? col : trans_color;
1074 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[ 6] = tdest[ 7] = col ? col : trans_color;
1075 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[ 8] = tdest[ 9] = col ? col : trans_color;
1076 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[10] = tdest[11] = col ? col : trans_color;
1077 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[12] = tdest[13] = col ? col : trans_color;
1078 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[14] = tdest[15] = col ? col : trans_color;
1085 for(int i = 0; i < 16; i++) {
1086 // check end line of screen
1091 if((attr & 0x80) && blink) {
1093 memset(text + dest, 7, 16);
1095 memset(text + dest, trans_color, 16);
1099 pat1 = ~pattern1[(code + i) << 1];
1100 pat2 = ~pattern2[(code + i) << 1];
1101 pat3 = ~pattern3[(code + i) << 1];
1103 pat1 = pattern1[(code + i) << 1];
1104 pat2 = pattern2[(code + i) << 1];
1105 pat3 = pattern3[(code + i) << 1];
1107 uint8_t* tdest = &text[dest];
1108 col = ((pat1 & 0x80) >> 7) | ((pat2 & 0x80) >> 6) | ((pat3 & 0x80) >> 5); tdest[ 0] = tdest[ 1] = col ? col : trans_color;
1109 col = ((pat1 & 0x40) >> 6) | ((pat2 & 0x40) >> 5) | ((pat3 & 0x40) >> 4); tdest[ 2] = tdest[ 3] = col ? col : trans_color;
1110 col = ((pat1 & 0x20) >> 5) | ((pat2 & 0x20) >> 4) | ((pat3 & 0x20) >> 3); tdest[ 4] = tdest[ 5] = col ? col : trans_color;
1111 col = ((pat1 & 0x10) >> 4) | ((pat2 & 0x10) >> 3) | ((pat3 & 0x10) >> 2); tdest[ 6] = tdest[ 7] = col ? col : trans_color;
1112 col = ((pat1 & 0x08) >> 3) | ((pat2 & 0x08) >> 2) | ((pat3 & 0x08) >> 1); tdest[ 8] = tdest[ 9] = col ? col : trans_color;
1113 col = ((pat1 & 0x04) >> 2) | ((pat2 & 0x04) >> 1) | ((pat3 & 0x04) ); tdest[10] = tdest[11] = col ? col : trans_color;
1114 col = ((pat1 & 0x02) >> 1) | ((pat2 & 0x02) ) | ((pat3 & 0x02) << 1); tdest[12] = tdest[13] = col ? col : trans_color;
1115 col = ((pat1 & 0x01) ) | ((pat2 & 0x01) << 1) | ((pat3 & 0x01) << 2); tdest[14] = tdest[15] = col ? col : trans_color;
1126 if(sel == 0x80 || sel == 0xc0) {
1127 code = ((t2 & 0x3f) << 11) | (t1 << 3);
1132 if(sel == 0x80 || sel == 0xc0) {
1133 code = ((t2 & 0x3f) << 11) | ((t1 & 0xfe) << 3);
1135 code = (t1 & 0xfe) << 3;
1142 for(int i = 0; i < 8; i++) {
1143 // check end line of screen
1149 pat1 = ((attr & 0x80) && blink) ? 0xff : ~pattern1[(code + i) << 1];
1151 pat1 = ((attr & 0x80) && blink) ? 0x00 : pattern1[(code + i) << 1];
1154 memcpy(&text[dest], text_matrixw[pat1][col], 16);
1157 // check end line of screen
1162 memcpy(&text[dest], text_matrixw[pat1][col], 16);
1167 for(int i = 0; i < 16; i++) {
1168 // check end line of screen
1175 pat1 = ((attr & 0x80) && blink) ? 0xff : ~pattern1[(code + i) << 1];
1177 pat1 = ((attr & 0x80) && blink) ? 0x00 : pattern1[(code + i) << 1];
1179 memcpy(&text[dest], text_matrixw[pat1][col], 16);
1187 // ----------------------------------------------------------------------------
1189 // ----------------------------------------------------------------------------
1191 void CRTC::draw_cg()
1194 int is_400l, is_16col, ymax, ofs;
1198 case 0x13: is_400l = 1; is_16col = 1; ymax = 400; ofs = 1; break; // 640x400x16
1199 case 0x17: is_400l = 0; is_16col = 1; ymax = 200; ofs = 1; break; // 640x200x16
1200 case 0x1b: is_400l = 1; is_16col = 0; ymax = 400; ofs = 4; break; // 640x400x65536
1201 case 0x1f: is_400l = 0; is_16col = 0; ymax = 200; ofs = 4; break; // 640x200x65536
1207 // update vram addr map for the hardware scroll
1208 uint8_t HDSC = cgreg[0x07] & 7;
1209 uint32_t SAD0 = (cgreg[0x08] << 1) | (cgreg[0x09] << 9);
1210 uint32_t SAD1 = (cgreg[0x0a] << 1) | (cgreg[0x0b] << 9);
1211 uint16_t SLN1 = cgreg[0x0c] | ((cgreg[0x0d] & 1) << 8);
1213 for(int y = 0; y < SLN1 && y < ymax; y++) {
1214 for(int x = 0; x < 80; x++) {
1215 map_hdsc[y][x] = HDSC;
1216 map_addr[y][x] = SAD0 & 0x1ffff;
1220 for(int y = SLN1; y < ymax; y++) {
1221 for(int x = 0; x < 80; x++) {
1223 map_addr[y][x] = SAD1 & 0x1ffff;
1230 // 16/4096 color mode
1231 for(int y = 0; y < ymax; y++) {
1232 for(int x = 0; x < 80; x++) {
1233 uint32_t src = map_addr[y][x];
1234 uint32_t dest2 = dest + map_hdsc[y][x];
1237 uint8_t B = (cgreg[0x10] & 1) ? vram_b[src] : 0;
1238 uint8_t R = (cgreg[0x10] & 2) ? vram_r[src] : 0;
1239 uint8_t G = (cgreg[0x10] & 4) ? vram_g[src] : 0;
1240 uint8_t I = (cgreg[0x10] & 8) ? vram_i[src] : 0;
1242 cg[dest2 ] = cg_matrix0[B][R][0] | cg_matrix1[G][I][0];
1243 cg[dest2 + 1] = cg_matrix0[B][R][1] | cg_matrix1[G][I][1];
1244 cg[dest2 + 2] = cg_matrix0[B][R][2] | cg_matrix1[G][I][2];
1245 cg[dest2 + 3] = cg_matrix0[B][R][3] | cg_matrix1[G][I][3];
1246 cg[dest2 + 4] = cg_matrix0[B][R][4] | cg_matrix1[G][I][4];
1247 cg[dest2 + 5] = cg_matrix0[B][R][5] | cg_matrix1[G][I][5];
1248 cg[dest2 + 6] = cg_matrix0[B][R][6] | cg_matrix1[G][I][6];
1249 cg[dest2 + 7] = cg_matrix0[B][R][7] | cg_matrix1[G][I][7];
1257 uint8_t B0 = 0, R0 = 0, G0 = 0, I0 = 0;
1258 uint8_t B1 = 0, R1 = 0, G1 = 0, I1 = 0;
1259 uint8_t B2 = 0, R2 = 0, G2 = 0, I2 = 0;
1260 uint8_t B3 = 0, R3 = 0, G3 = 0, I3 = 0;
1261 uint8_t plane_mask = cgreg[0x10] & cg_mask;
1263 for(int y = 0; y < ymax; y++) {
1264 for(int x = 0; x < 80; x++) {
1265 uint32_t src0 = map_addr[y][x];
1266 uint32_t src1 = (src0 + 1) & 0x1ffff;
1267 uint32_t src2 = (src0 + 2) & 0x1ffff;
1268 uint32_t src3 = (src0 + 3) & 0x1ffff;
1269 uint32_t dest2 = dest + map_hdsc[y][x];
1272 if(plane_mask & 1) {
1278 if(plane_mask & 2) {
1284 if(plane_mask & 4) {
1290 if(plane_mask & 8) {
1296 cg[dest2 ] = ((B0 & 0xf0) << 8) | ((R0 & 0xf0) << 4) | ((G0 & 0xf0) ) | ((I0 & 0xf0) >> 4);
1297 cg[dest2 + 1] = ((B0 & 0x0f) << 12) | ((R0 & 0x0f) << 8) | ((G0 & 0x0f) << 4) | ((I0 & 0x0f) );
1298 cg[dest2 + 2] = ((B1 & 0xf0) << 8) | ((R1 & 0xf0) << 4) | ((G1 & 0xf0) ) | ((I1 & 0xf0) >> 4);
1299 cg[dest2 + 3] = ((B1 & 0x0f) << 12) | ((R1 & 0x0f) << 8) | ((G1 & 0x0f) << 4) | ((I1 & 0x0f) );
1300 cg[dest2 + 4] = ((B2 & 0xf0) << 8) | ((R2 & 0xf0) << 4) | ((G2 & 0xf0) ) | ((I2 & 0xf0) >> 4);
1301 cg[dest2 + 5] = ((B2 & 0x0f) << 12) | ((R2 & 0x0f) << 8) | ((G2 & 0x0f) << 4) | ((I2 & 0x0f) );
1302 cg[dest2 + 6] = ((B3 & 0xf0) << 8) | ((R3 & 0xf0) << 4) | ((G3 & 0xf0) ) | ((I3 & 0xf0) >> 4);
1303 cg[dest2 + 7] = ((B3 & 0x0f) << 12) | ((R3 & 0x0f) << 8) | ((G3 & 0x0f) << 4) | ((I3 & 0x0f) );
1312 for(int y = 0; y < 400; y += 2) {
1313 memcpy(cg + (y + 1) * 640, cg + y * 640, 1280);
1318 #define STATE_VERSION 1
1320 bool CRTC::process_state(FILEIO* state_fio, bool loading)
1322 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1325 if(!state_fio->StateCheckInt32(this_device_id)) {
1328 state_fio->StateUint8(textreg_num);
1329 state_fio->StateBuffer(textreg, sizeof(textreg), 1);
1330 state_fio->StateBuffer(rmwreg_num, sizeof(rmwreg_num), 1);
1331 state_fio->StateBuffer(rmwreg, sizeof(rmwreg), 1);
1332 state_fio->StateUint8(cgreg_num);
1333 state_fio->StateBuffer(cgreg, sizeof(cgreg), 1);
1334 state_fio->StateUint8(scrn_size);
1335 state_fio->StateUint8(cg_mask);
1336 state_fio->StateBool(font_size);
1337 state_fio->StateBool(column_size);
1338 state_fio->StateBuffer(latch, sizeof(latch), 1);
1339 state_fio->StateUint16(GDEVS);
1340 state_fio->StateUint16(GDEVE);
1341 state_fio->StateUint8(GDEHS);
1342 state_fio->StateUint8(GDEHE);
1343 state_fio->StateInt32(GDEHSC);
1344 state_fio->StateInt32(GDEHEC);
1345 state_fio->StateBool(blank);
1346 state_fio->StateBool(hblank);
1347 state_fio->StateBool(vblank);
1348 state_fio->StateBool(blink);
1349 state_fio->StateUint8(clear_flag);
1350 state_fio->StateBuffer(palette_reg, sizeof(palette_reg), 1);
1351 state_fio->StateBool(pal_select);
1352 state_fio->StateBool(screen_mask);
1353 state_fio->StateBuffer(priority16, sizeof(priority16), 1);
1354 //state_fio->StateBuffer(palette16, sizeof(palette16), 1);
1355 for(int i = 0; i < (sizeof(palette16) / sizeof(scrntype_t)); i++) {
1358 r = state_fio->FgetUint8();
1359 g = state_fio->FgetUint8();
1360 b = state_fio->FgetUint8();
1361 palette16[i] = RGB_COLOR(r, g, b);
1364 r = R_OF_COLOR(palette16[i]);
1365 g = G_OF_COLOR(palette16[i]);
1366 b = B_OF_COLOR(palette16[i]);
1367 state_fio->FputUint8(r);
1368 state_fio->FputUint8(g);
1369 state_fio->FputUint8(b);
1372 //state_fio->StateBuffer(palette4096, sizeof(palette4096), 1);
1373 for(int i = 0; i < (sizeof(palette4096) / sizeof(scrntype_t)); i++) {
1376 r = state_fio->FgetUint8();
1377 g = state_fio->FgetUint8();
1378 b = state_fio->FgetUint8();
1379 palette4096[i] = RGB_COLOR(r, g, b);
1382 r = R_OF_COLOR(palette4096[i]);
1383 g = G_OF_COLOR(palette4096[i]);
1384 b = B_OF_COLOR(palette4096[i]);
1385 state_fio->FputUint8(r);
1386 state_fio->FputUint8(g);
1387 state_fio->FputUint8(b);
1390 state_fio->StateBuffer(palette4096r, sizeof(palette4096r), 1);
1391 state_fio->StateBuffer(palette4096g, sizeof(palette4096g), 1);
1392 state_fio->StateBuffer(palette4096b, sizeof(palette4096b), 1);
1393 //state_fio->StateBuffer(palette16txt, sizeof(palette16txt), 1);
1394 for(int i = 0; i < (sizeof(palette16txt) / sizeof(scrntype_t)); i++) {
1397 r = state_fio->FgetUint8();
1398 g = state_fio->FgetUint8();
1399 b = state_fio->FgetUint8();
1400 palette16txt[i] = RGB_COLOR(r, g, b);
1403 r = R_OF_COLOR(palette16txt[i]);
1404 g = G_OF_COLOR(palette16txt[i]);
1405 b = B_OF_COLOR(palette16txt[i]);
1406 state_fio->FputUint8(r);
1407 state_fio->FputUint8(g);
1408 state_fio->FputUint8(b);
1411 //state_fio->StateBuffer(palette4096txt, sizeof(palette4096txt), 1);
1412 for(int i = 0; i < (sizeof(palette4096txt) / sizeof(scrntype_t)); i++) {
1415 r = state_fio->FgetUint8();
1416 g = state_fio->FgetUint8();
1417 b = state_fio->FgetUint8();
1418 palette4096txt[i] = RGB_COLOR(r, g, b);
1421 r = R_OF_COLOR(palette4096txt[i]);
1422 g = G_OF_COLOR(palette4096txt[i]);
1423 b = B_OF_COLOR(palette4096txt[i]);
1424 state_fio->FputUint8(r);
1425 state_fio->FputUint8(g);
1426 state_fio->FputUint8(b);
1429 //state_fio->StateBuffer(palette16pri, sizeof(palette16pri), 1);
1430 for(int i = 0; i < 16; i++) {
1431 for(int j = 0; j < 9; j++) {
1434 r = state_fio->FgetUint8();
1435 g = state_fio->FgetUint8();
1436 b = state_fio->FgetUint8();
1437 palette16pri[i][j] = RGB_COLOR(r, g, b);
1440 r = R_OF_COLOR(palette16pri[i][j]);
1441 g = G_OF_COLOR(palette16pri[i][j]);
1442 b = B_OF_COLOR(palette16pri[i][j]);
1443 state_fio->FputUint8(r);
1444 state_fio->FputUint8(g);
1445 state_fio->FputUint8(b);
1449 //state_fio->StateBuffer(palette4096pri, sizeof(palette4096pri), 1);
1450 for(int i = 0; i < 16; i++) {
1451 for(int j = 0; j < 9; j++) {
1454 r = state_fio->FgetUint8();
1455 g = state_fio->FgetUint8();
1456 b = state_fio->FgetUint8();
1457 palette4096pri[i][j] = RGB_COLOR(r, g, b);
1460 r = R_OF_COLOR(palette4096pri[i][j]);
1461 g = G_OF_COLOR(palette4096pri[i][j]);
1462 b = B_OF_COLOR(palette4096pri[i][j]);
1463 state_fio->FputUint8(r);
1464 state_fio->FputUint8(g);
1465 state_fio->FputUint8(b);
1469 state_fio->StateUint8(prev16);
1470 state_fio->StateBool(update16);
1471 //state_fio->StateBuffer(map_addr, sizeof(map_addr), 1);
1472 for(int i = 0; i < 400; i++) {
1473 for(int j = 0; j < 80; j++) {
1474 state_fio->StateUint32(map_addr[i][j]);
1477 state_fio->StateBuffer(map_hdsc, sizeof(map_hdsc), 1);
1478 state_fio->StateBuffer(text_matrix, sizeof(text_matrix), 1);
1479 state_fio->StateBuffer(text_matrixw, sizeof(text_matrixw), 1);
1480 state_fio->StateUint8(trans_color);
1481 state_fio->StateBool(map_init);
1482 state_fio->StateBool(trans_init);