2 TOSHIBA PASOPIA Emulator 'EmuPIA'
4 Author : Takeda.Toshiya
12 void DISPLAY::initialize()
15 FILEIO* fio = new FILEIO();
16 if(fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {
17 fio->Fread(font, sizeof(font), 1);
24 for(int i = 1; i < 8; i++) {
25 palette_pc[i] = RGB_COLOR(48, 56, 16);
27 palette_pc[0] = RGB_COLOR(160, 168, 160);
29 for(int i = 0; i < 8; i++) {
30 palette_pc[i] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);
39 register_frame_event(this);
42 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
46 d_crtc->write_io8(addr, data);
49 d_crtc->write_io8(addr, data);
54 void DISPLAY::write_signal(int id, uint32_t data, uint32_t mask)
60 void DISPLAY::event_frame()
62 cblink = (cblink + 1) & 0x1f;
65 void DISPLAY::draw_screen()
67 if((regs[8] & 0x30) != 0x30) {
68 uint16_t src = ((regs[12] << 8) | regs[13]) & 0x7ff;
69 if((regs[8] & 0xc0) == 0xc0) {
72 cursor = ((regs[14] << 8) | regs[15]) & 0x7ff;
76 memset(screen, mode & 7, sizeof(screen));
79 case 0x00: // screen 0, wide
80 draw_screen0_wide(src);
82 case 0x20: // screen 0, normal
83 draw_screen0_normal(src);
85 case 0x40: // screen 1, wide
86 draw_screen1_wide(src);
88 case 0x60: // screen 1, normal
89 draw_screen1_normal(src);
91 case 0x80: // screen 2, wide
92 draw_screen2_wide(src);
94 case 0xa0: // screen 2, normal
95 draw_screen2_normal(src);
97 case 0xc0: // screen 1.5, wide
98 draw_screen15_wide(src);
100 case 0xe0: // screen 1.5, normal
101 draw_screen15_normal(src);
105 memset(screen, 0, sizeof(screen));
108 // copy to real screen
109 emu->set_vm_screen_lines(200);
111 uint16_t bcol = palette_pc[mode & 7];
112 emu->set_vm_screen_lines(200);
113 for(int y = 0; y < 200; y++) {
114 scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
115 scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
116 uint8_t* src = screen[y];
118 for(int x = 0; x < 640; x++) {
119 dest0[x] = palette_pc[src[x] & 7];
121 if(config.scan_line) {
122 memset(dest1, 0, 640 * sizeof(scrntype_t));
124 memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
127 emu->screen_skip_line(true);
130 #define IS_ATTRIB(d) (((d) & 0xf8) == 0xf8)
132 void DISPLAY::draw_screen0_normal(uint16_t src)
134 // screen 0, normal char (80chars)
135 uint16_t src_t = src & 0x7ff;
136 uint8_t c_b = mode & 7;
137 int width = regs[1] - 1;
139 for(int y = 0; y < 200; y += 8) {
140 uint8_t c_t = IS_ATTRIB(vram[src_t]) ? (vram[src_t] & 7) : 7;
141 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
143 for(int x = 0; x < width; x++) {
144 uint8_t code = vram[src_t];
145 if(IS_ATTRIB(code)) {
148 uint8_t* font_base = &font[code << 3];
150 for(int l = 0; l < 8; l++) {
151 uint8_t p = font_base[l];
152 uint8_t* d = &screen[y + l][x << 3];
154 d[0] = (p & 0x80) ? c_t : c_b;
155 d[1] = (p & 0x40) ? c_t : c_b;
156 d[2] = (p & 0x20) ? c_t : c_b;
157 d[3] = (p & 0x10) ? c_t : c_b;
158 d[4] = (p & 0x08) ? c_t : c_b;
159 d[5] = (p & 0x04) ? c_t : c_b;
160 d[6] = (p & 0x02) ? c_t : c_b;
161 d[7] = (p & 0x01) ? c_t : c_b;
163 if(src_t == cursor) {
164 int bp = regs[10] & 0x60;
165 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
166 for(int i = (regs[10] & 7); i < 8; i++) {
167 memset(&screen[y + i][x << 3], 7, 8);
171 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
176 void DISPLAY::draw_screen0_wide(uint16_t src)
178 // screen 0, wide char (36chars)
179 uint16_t src_t = src & 0x7ff;
180 uint8_t c_b = mode & 7;
181 int width = regs[1] - 1;
183 for(int y = 0; y < 192; y += 8) {
184 uint8_t c_t = IS_ATTRIB(vram[src_t]) ? (vram[src_t] & 7) : 7;
185 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
187 for(int x = 0; x < width; x++) {
188 uint8_t code = vram[src_t];
189 if(IS_ATTRIB(code)) {
192 uint8_t* font_base = &font[code << 3];
194 for(int l = 0; l < 8; l++) {
195 uint8_t p = font_base[l];
196 uint8_t* d = &screen[y + l][x << 4];
198 d[ 0] = d[ 1] = (p & 0x80) ? c_t : c_b;
199 d[ 2] = d[ 3] = (p & 0x40) ? c_t : c_b;
200 d[ 4] = d[ 5] = (p & 0x20) ? c_t : c_b;
201 d[ 6] = d[ 7] = (p & 0x10) ? c_t : c_b;
202 d[ 8] = d[ 9] = (p & 0x08) ? c_t : c_b;
203 d[10] = d[11] = (p & 0x04) ? c_t : c_b;
204 d[12] = d[13] = (p & 0x02) ? c_t : c_b;
205 d[14] = d[15] = (p & 0x01) ? c_t : c_b;
207 if(src_t == cursor) {
208 int bp = regs[10] & 0x60;
209 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
210 for(int i = (regs[10] & 7); i < 8; i++) {
211 memset(&screen[y + i][x << 4], 7, 16);
215 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
220 void DISPLAY::draw_screen1_normal(uint16_t src)
222 // screen 1, normal char (80chars)
223 uint16_t src_t = src & 0x7ff;
224 uint8_t c_b = mode & 7;
225 int width = regs[1] - 1;
226 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
228 for(int y = 0; y < 200; y += 8) {
229 // character data is set for every other line in scren 1
230 for(int i = 0; i < 8; i += 2) {
231 uint8_t t = vram[src_t + (i * 0x800)];
233 c_t[i] = c_t[i + 1] = t & 7;
236 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
238 for(int x = 0; x < width; x++) {
242 for(int i = 0; i < 8; i += 2) {
243 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
244 is_graph[i] = is_graph[i + 1] = (attr[t] != 0);
245 attr_t[i] = attr_t[i + 1] = attr[t];
246 code[i] = code[i + 1] = vram[t];
249 for(int l = 0; l < 8; l++) {
250 // change line color if vram data is text and is attribute character
251 // note: check only first line
252 uint8_t code_t = code[l];
253 if(!is_graph[l] && IS_ATTRIB(code_t)) {
256 uint8_t* font_base = &font[code_t << 3];
257 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
263 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
268 uint8_t* d = &screen[y + l][x << 3];
270 d[0] = (p & 0x80) ? c_l : c_b;
271 d[1] = (p & 0x40) ? c_l : c_b;
272 d[2] = (p & 0x20) ? c_l : c_b;
273 d[3] = (p & 0x10) ? c_l : c_b;
274 d[4] = (p & 0x08) ? c_r : c_b;
275 d[5] = (p & 0x04) ? c_r : c_b;
276 d[6] = (p & 0x02) ? c_r : c_b;
277 d[7] = (p & 0x01) ? c_r : c_b;
279 if(src_t == cursor) {
280 int bp = regs[10] & 0x60;
281 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
282 for(int i = (regs[10] & 7); i < 8; i++) {
283 memset(&screen[y + i][x << 3], 7, 8);
287 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
292 void DISPLAY::draw_screen1_wide(uint16_t src)
294 // screen 1, wide char (36chars)
295 uint16_t src_t = src & 0x7ff;
296 uint8_t c_b = mode & 7;
297 int width = regs[1] - 1;
298 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
300 for(int y = 0; y < 192; y += 8) {
301 // character data is set for every other line in scren 1
302 for(int i = 0; i < 8; i += 2) {
303 uint8_t t = vram[src_t + (i * 0x800)];
305 c_t[i] = c_t[i + 1] = t & 7;
308 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
310 for(int x = 0; x < width; x++) {
314 for(int i = 0; i < 8; i += 2) {
315 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
316 is_graph[i] = is_graph[i + 1] = (attr[t] != 0);
317 attr_t[i] = attr_t[i + 1] = attr[t];
318 code[i] = code[i + 1] = vram[t];
321 for(int l = 0; l < 8; l++) {
322 // change line color if vram data is text and is attribute character
323 // note: check only first line
324 uint8_t code_t = code[l];
325 if(!is_graph[l] && IS_ATTRIB(code_t)) {
328 uint8_t* font_base = &font[code_t << 3];
329 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
335 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
340 uint8_t* d = &screen[y + l][x << 4];
342 d[ 0] = d[ 1] = (p & 0x80) ? c_l : c_b;
343 d[ 2] = d[ 3] = (p & 0x40) ? c_l : c_b;
344 d[ 4] = d[ 5] = (p & 0x20) ? c_l : c_b;
345 d[ 6] = d[ 7] = (p & 0x10) ? c_l : c_b;
346 d[ 8] = d[ 9] = (p & 0x08) ? c_r : c_b;
347 d[10] = d[11] = (p & 0x04) ? c_r : c_b;
348 d[12] = d[13] = (p & 0x02) ? c_r : c_b;
349 d[14] = d[15] = (p & 0x01) ? c_r : c_b;
351 if(src_t == cursor) {
352 int bp = regs[10] & 0x60;
353 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
354 for(int i = (regs[10] & 7); i < 8; i++) {
355 memset(&screen[y + i][x << 4], 7, 16);
359 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
364 void DISPLAY::draw_screen2_normal(uint16_t src)
366 // screen 2, normal char (80chars)
367 uint16_t src_t = src & 0x7ff;
368 uint8_t c_b = mode & 7;
369 int width = regs[1] - 1;
370 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
372 for(int y = 0; y < 200; y += 8) {
373 // character data is set for every line in scren 2
374 for(int i = 0; i < 8; i++) {
375 uint8_t t = vram[src_t + (i * 0x800)];
380 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
382 for(int x = 0; x < width; x++) {
383 uint16_t src_g = src_t;
386 for(int i = 0; i < 8; i++) {
387 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
388 is_graph[i] = (attr[t] != 0);
392 for(int l = 0; l < 8; l++) {
393 // change line color if vram data is text and is attribute character
394 uint8_t code_t = code[l];
395 if(!is_graph[l] && (0xf8 <= code_t) && (code_t <= 0xff)) {
398 uint8_t c_l = c_t[l], c_r = c_t[l];
400 uint8_t* font_base = &font[code_t << 3];
401 uint8_t p = is_graph[l] ? (attr[src_g] ? vram[src_g] : 0) : font_base[l];
402 src_g = (src_g + 0x800) & 0x3fff;
403 uint8_t c_p = /*is_graph[l] ? 7 : */c_t[l];
404 uint8_t* d = &screen[y + l][x << 3];
406 d[0] = (p & 0x80) ? c_p : c_b;
407 d[1] = (p & 0x40) ? c_p : c_b;
408 d[2] = (p & 0x20) ? c_p : c_b;
409 d[3] = (p & 0x10) ? c_p : c_b;
410 d[4] = (p & 0x08) ? c_p : c_b;
411 d[5] = (p & 0x04) ? c_p : c_b;
412 d[6] = (p & 0x02) ? c_p : c_b;
413 d[7] = (p & 0x01) ? c_p : c_b;
415 if(src_t == cursor) {
416 int bp = regs[10] & 0x60;
417 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
418 for(int i = (regs[10] & 7); i < 8; i++) {
419 memset(&screen[y + i][x << 3], 7, 8);
423 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
428 void DISPLAY::draw_screen2_wide(uint16_t src)
430 // screen 0, wide char (36chars)
431 uint16_t src_t = src & 0x7ff;
432 uint8_t c_b = mode & 7;
433 int width = regs[1] - 1;
434 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
436 for(int y = 0; y < 192; y += 8) {
437 // character data is set for every line in scren 2
438 for(int i = 0; i < 8; i++) {
439 uint8_t t = vram[src_t + (i * 0x800)];
444 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
446 for(int x = 0; x < width; x++) {
447 uint16_t src_g = src_t;
450 for(int i = 0; i < 8; i++) {
451 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
452 is_graph[i] = (attr[t] != 0);
455 for(int l = 0; l < 8; l++) {
456 // change line color if vram data is text and is attribute character
457 uint8_t code_t = code[l];
458 if(!is_graph[l] && IS_ATTRIB(code_t)) {
461 uint8_t c_l = c_t[l], c_r = c_t[l];
463 uint8_t* font_base = &font[code_t << 3];
464 uint8_t p = is_graph[l] ? (attr[src_g] ? vram[src_g] : 0) : font_base[l];
465 src_g = (src_g + 0x800) & 0x3fff;
466 uint8_t c_p = /*is_graph[l] ? 7 : */c_t[l];
467 uint8_t* d = &screen[y + l][x << 4];
469 d[ 0] = d[ 1] = (p & 0x80) ? c_p : c_b;
470 d[ 2] = d[ 3] = (p & 0x40) ? c_p : c_b;
471 d[ 4] = d[ 5] = (p & 0x20) ? c_p : c_b;
472 d[ 6] = d[ 7] = (p & 0x10) ? c_p : c_b;
473 d[ 8] = d[ 9] = (p & 0x08) ? c_p : c_b;
474 d[10] = d[11] = (p & 0x04) ? c_p : c_b;
475 d[12] = d[13] = (p & 0x02) ? c_p : c_b;
476 d[14] = d[15] = (p & 0x01) ? c_p : c_b;
478 if(src_t == cursor) {
479 int bp = regs[10] & 0x60;
480 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
481 for(int i = (regs[10] & 7); i < 8; i++) {
482 memset(&screen[y + i][x << 4], 7, 16);
486 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
491 void DISPLAY::draw_screen15_normal(uint16_t src)
493 // screen 2, normal char (80chars)
494 uint16_t src_t = src & 0x7ff;
495 uint8_t c_b = mode & 7;
496 int width = regs[1] - 1;
497 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
499 for(int y = 0; y < 200; y += 8) {
500 // character data is set for every line in scren 1.5
501 for(int i = 0; i < 8; i++) {
502 uint8_t t = vram[src_t + (i * 0x800)];
507 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
509 for(int x = 0; x < width; x++) {
513 for(int i = 0; i < 8; i++) {
514 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
515 is_graph[i] = (attr[t] != 0);
519 for(int l = 0; l < 8; l++) {
520 // change line color if vram data is text and is attribute character
521 uint8_t code_t = code[l];
522 if(!is_graph[l] && IS_ATTRIB(code_t)) {
525 uint8_t* font_base = &font[code_t << 3];
526 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
532 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
537 uint8_t* d = &screen[y + l][x << 3];
539 d[0] = (p & 0x80) ? c_l : c_b;
540 d[1] = (p & 0x40) ? c_l : c_b;
541 d[2] = (p & 0x20) ? c_l : c_b;
542 d[3] = (p & 0x10) ? c_l : c_b;
543 d[4] = (p & 0x08) ? c_r : c_b;
544 d[5] = (p & 0x04) ? c_r : c_b;
545 d[6] = (p & 0x02) ? c_r : c_b;
546 d[7] = (p & 0x01) ? c_r : c_b;
548 if(src_t == cursor) {
549 int bp = regs[10] & 0x60;
550 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
551 for(int i = (regs[10] & 7); i < 8; i++) {
552 memset(&screen[y + i][x << 3], 7, 8);
556 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
561 void DISPLAY::draw_screen15_wide(uint16_t src)
563 // screen 0, normal char (80chars)
564 uint16_t src_t = src & 0x7ff;
565 uint8_t c_b = mode & 7;
566 int width = regs[1] - 1;
567 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
569 for(int y = 0; y < 192; y += 8) {
570 // character data is set for every line in scren 1.5
571 for(int i = 0; i < 8; i++) {
572 uint8_t t = vram[src_t + (i * 0x800)];
577 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
579 for(int x = 0; x < width; x++) {
583 for(int i = 0; i < 8; i++) {
584 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
585 is_graph[i] = (attr[t] != 0);
590 for(int l = 0; l < 8; l++) {
591 // change line color if vram data is text and is attribute character
592 uint8_t code_t = code[l];
593 if(!is_graph[l] && IS_ATTRIB(code_t)) {
596 uint8_t* font_base = &font[code_t << 3];
597 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
603 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
608 uint8_t* d = &screen[y + l][x << 4];
610 d[ 0] = d[ 1] = (p & 0x80) ? c_l : c_b;
611 d[ 2] = d[ 3] = (p & 0x40) ? c_l : c_b;
612 d[ 4] = d[ 5] = (p & 0x20) ? c_l : c_b;
613 d[ 6] = d[ 7] = (p & 0x10) ? c_l : c_b;
614 d[ 8] = d[ 9] = (p & 0x08) ? c_r : c_b;
615 d[10] = d[11] = (p & 0x04) ? c_r : c_b;
616 d[12] = d[13] = (p & 0x02) ? c_r : c_b;
617 d[14] = d[15] = (p & 0x01) ? c_r : c_b;
619 if(src_t == cursor) {
620 int bp = regs[10] & 0x60;
621 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
622 for(int i = (regs[10] & 7); i < 8; i++) {
623 memset(&screen[y + i][x << 4], 7, 16);
627 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
632 #define STATE_VERSION 1
634 #include "../../statesub.h"
636 void DISPLAY::decl_state()
638 enter_decl_state(STATE_VERSION);
640 DECL_STATE_ENTRY_UINT8(mode);
641 DECL_STATE_ENTRY_UINT16(cursor);
642 DECL_STATE_ENTRY_UINT16(cblink);
647 void DISPLAY::save_state(FILEIO* state_fio)
649 if(state_entry != NULL) {
650 state_entry->save_state(state_fio);
652 // state_fio->FputUint32(STATE_VERSION);
653 // state_fio->FputInt32(this_device_id);
655 // state_fio->FputUint8(mode);
656 // state_fio->FputUint16(cursor);
657 // state_fio->FputUint16(cblink);
660 bool DISPLAY::load_state(FILEIO* state_fio)
663 if(state_entry != NULL) {
664 mb = state_entry->load_state(state_fio);
669 // if(state_fio->FgetUint32() != STATE_VERSION) {
672 // if(state_fio->FgetInt32() != this_device_id) {
675 // mode = state_fio->FgetUint8();
676 // cursor = state_fio->FgetUint16();
677 // cblink = state_fio->FgetUint16();
681 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
683 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
686 if(!state_fio->StateCheckInt32(this_device_id)) {
689 state_fio->StateUint8(mode);
690 state_fio->StateUint16(cursor);
691 state_fio->StateUint16(cblink);