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 uint16_t bcol = palette_pc[mode & 7];
110 for(int y = 0; y < 200; y++) {
111 scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
112 scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
113 uint8_t* src = screen[y];
115 for(int x = 0; x < 640; x++) {
116 dest0[x] = palette_pc[src[x] & 7];
118 if(config.scan_line) {
119 memset(dest1, 0, 640 * sizeof(scrntype_t));
121 memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
124 emu->screen_skip_line(true);
127 #define IS_ATTRIB(d) (((d) & 0xf8) == 0xf8)
129 void DISPLAY::draw_screen0_normal(uint16_t src)
131 // screen 0, normal char (80chars)
132 uint16_t src_t = src & 0x7ff;
133 uint8_t c_b = mode & 7;
134 int width = regs[1] - 1;
136 for(int y = 0; y < 200; y += 8) {
137 uint8_t c_t = IS_ATTRIB(vram[src_t]) ? (vram[src_t] & 7) : 7;
138 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
140 for(int x = 0; x < width; x++) {
141 uint8_t code = vram[src_t];
142 if(IS_ATTRIB(code)) {
145 uint8_t* font_base = &font[code << 3];
147 for(int l = 0; l < 8; l++) {
148 uint8_t p = font_base[l];
149 uint8_t* d = &screen[y + l][x << 3];
151 d[0] = (p & 0x80) ? c_t : c_b;
152 d[1] = (p & 0x40) ? c_t : c_b;
153 d[2] = (p & 0x20) ? c_t : c_b;
154 d[3] = (p & 0x10) ? c_t : c_b;
155 d[4] = (p & 0x08) ? c_t : c_b;
156 d[5] = (p & 0x04) ? c_t : c_b;
157 d[6] = (p & 0x02) ? c_t : c_b;
158 d[7] = (p & 0x01) ? c_t : c_b;
160 if(src_t == cursor) {
161 int bp = regs[10] & 0x60;
162 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
163 for(int i = (regs[10] & 7); i < 8; i++) {
164 memset(&screen[y + i][x << 3], 7, 8);
168 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
173 void DISPLAY::draw_screen0_wide(uint16_t src)
175 // screen 0, wide char (36chars)
176 uint16_t src_t = src & 0x7ff;
177 uint8_t c_b = mode & 7;
178 int width = regs[1] - 1;
180 for(int y = 0; y < 192; y += 8) {
181 uint8_t c_t = IS_ATTRIB(vram[src_t]) ? (vram[src_t] & 7) : 7;
182 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
184 for(int x = 0; x < width; x++) {
185 uint8_t code = vram[src_t];
186 if(IS_ATTRIB(code)) {
189 uint8_t* font_base = &font[code << 3];
191 for(int l = 0; l < 8; l++) {
192 uint8_t p = font_base[l];
193 uint8_t* d = &screen[y + l][x << 4];
195 d[ 0] = d[ 1] = (p & 0x80) ? c_t : c_b;
196 d[ 2] = d[ 3] = (p & 0x40) ? c_t : c_b;
197 d[ 4] = d[ 5] = (p & 0x20) ? c_t : c_b;
198 d[ 6] = d[ 7] = (p & 0x10) ? c_t : c_b;
199 d[ 8] = d[ 9] = (p & 0x08) ? c_t : c_b;
200 d[10] = d[11] = (p & 0x04) ? c_t : c_b;
201 d[12] = d[13] = (p & 0x02) ? c_t : c_b;
202 d[14] = d[15] = (p & 0x01) ? c_t : c_b;
204 if(src_t == cursor) {
205 int bp = regs[10] & 0x60;
206 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
207 for(int i = (regs[10] & 7); i < 8; i++) {
208 memset(&screen[y + i][x << 4], 7, 16);
212 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
217 void DISPLAY::draw_screen1_normal(uint16_t src)
219 // screen 1, normal char (80chars)
220 uint16_t src_t = src & 0x7ff;
221 uint8_t c_b = mode & 7;
222 int width = regs[1] - 1;
223 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
225 for(int y = 0; y < 200; y += 8) {
226 // character data is set for every other line in scren 1
227 for(int i = 0; i < 8; i += 2) {
228 uint8_t t = vram[src_t + (i * 0x800)];
230 c_t[i] = c_t[i + 1] = t & 7;
233 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
235 for(int x = 0; x < width; x++) {
239 for(int i = 0; i < 8; i += 2) {
240 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
241 is_graph[i] = is_graph[i + 1] = (attr[t] != 0);
242 attr_t[i] = attr_t[i + 1] = attr[t];
243 code[i] = code[i + 1] = vram[t];
246 for(int l = 0; l < 8; l++) {
247 // change line color if vram data is text and is attribute character
248 // note: check only first line
249 uint8_t code_t = code[l];
250 if(!is_graph[l] && IS_ATTRIB(code_t)) {
253 uint8_t* font_base = &font[code_t << 3];
254 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
260 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
265 uint8_t* d = &screen[y + l][x << 3];
267 d[0] = (p & 0x80) ? c_l : c_b;
268 d[1] = (p & 0x40) ? c_l : c_b;
269 d[2] = (p & 0x20) ? c_l : c_b;
270 d[3] = (p & 0x10) ? c_l : c_b;
271 d[4] = (p & 0x08) ? c_r : c_b;
272 d[5] = (p & 0x04) ? c_r : c_b;
273 d[6] = (p & 0x02) ? c_r : c_b;
274 d[7] = (p & 0x01) ? c_r : c_b;
276 if(src_t == cursor) {
277 int bp = regs[10] & 0x60;
278 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
279 for(int i = (regs[10] & 7); i < 8; i++) {
280 memset(&screen[y + i][x << 3], 7, 8);
284 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
289 void DISPLAY::draw_screen1_wide(uint16_t src)
291 // screen 1, wide char (36chars)
292 uint16_t src_t = src & 0x7ff;
293 uint8_t c_b = mode & 7;
294 int width = regs[1] - 1;
295 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
297 for(int y = 0; y < 192; y += 8) {
298 // character data is set for every other line in scren 1
299 for(int i = 0; i < 8; i += 2) {
300 uint8_t t = vram[src_t + (i * 0x800)];
302 c_t[i] = c_t[i + 1] = t & 7;
305 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
307 for(int x = 0; x < width; x++) {
311 for(int i = 0; i < 8; i += 2) {
312 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
313 is_graph[i] = is_graph[i + 1] = (attr[t] != 0);
314 attr_t[i] = attr_t[i + 1] = attr[t];
315 code[i] = code[i + 1] = vram[t];
318 for(int l = 0; l < 8; l++) {
319 // change line color if vram data is text and is attribute character
320 // note: check only first line
321 uint8_t code_t = code[l];
322 if(!is_graph[l] && IS_ATTRIB(code_t)) {
325 uint8_t* font_base = &font[code_t << 3];
326 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
332 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
337 uint8_t* d = &screen[y + l][x << 4];
339 d[ 0] = d[ 1] = (p & 0x80) ? c_l : c_b;
340 d[ 2] = d[ 3] = (p & 0x40) ? c_l : c_b;
341 d[ 4] = d[ 5] = (p & 0x20) ? c_l : c_b;
342 d[ 6] = d[ 7] = (p & 0x10) ? c_l : c_b;
343 d[ 8] = d[ 9] = (p & 0x08) ? c_r : c_b;
344 d[10] = d[11] = (p & 0x04) ? c_r : c_b;
345 d[12] = d[13] = (p & 0x02) ? c_r : c_b;
346 d[14] = d[15] = (p & 0x01) ? c_r : c_b;
348 if(src_t == cursor) {
349 int bp = regs[10] & 0x60;
350 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
351 for(int i = (regs[10] & 7); i < 8; i++) {
352 memset(&screen[y + i][x << 4], 7, 16);
356 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
361 void DISPLAY::draw_screen2_normal(uint16_t src)
363 // screen 2, normal char (80chars)
364 uint16_t src_t = src & 0x7ff;
365 uint8_t c_b = mode & 7;
366 int width = regs[1] - 1;
367 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
369 for(int y = 0; y < 200; y += 8) {
370 // character data is set for every line in scren 2
371 for(int i = 0; i < 8; i++) {
372 uint8_t t = vram[src_t + (i * 0x800)];
377 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
379 for(int x = 0; x < width; x++) {
380 uint16_t src_g = src_t;
383 for(int i = 0; i < 8; i++) {
384 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
385 is_graph[i] = (attr[t] != 0);
389 for(int l = 0; l < 8; l++) {
390 // change line color if vram data is text and is attribute character
391 uint8_t code_t = code[l];
392 if(!is_graph[l] && (0xf8 <= code_t) && (code_t <= 0xff)) {
395 uint8_t c_l = c_t[l], c_r = c_t[l];
397 uint8_t* font_base = &font[code_t << 3];
398 uint8_t p = is_graph[l] ? (attr[src_g] ? vram[src_g] : 0) : font_base[l];
399 src_g = (src_g + 0x800) & 0x3fff;
400 uint8_t c_p = is_graph[l] ? 7 : c_t[l];
401 uint8_t* d = &screen[y + l][x << 3];
403 d[0] = (p & 0x80) ? c_p : c_b;
404 d[1] = (p & 0x40) ? c_p : c_b;
405 d[2] = (p & 0x20) ? c_p : c_b;
406 d[3] = (p & 0x10) ? c_p : c_b;
407 d[4] = (p & 0x08) ? c_p : c_b;
408 d[5] = (p & 0x04) ? c_p : c_b;
409 d[6] = (p & 0x02) ? c_p : c_b;
410 d[7] = (p & 0x01) ? c_p : c_b;
412 if(src_t == cursor) {
413 int bp = regs[10] & 0x60;
414 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
415 for(int i = (regs[10] & 7); i < 8; i++) {
416 memset(&screen[y + i][x << 3], 7, 8);
420 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
425 void DISPLAY::draw_screen2_wide(uint16_t src)
427 // screen 0, wide char (36chars)
428 uint16_t src_t = src & 0x7ff;
429 uint8_t c_b = mode & 7;
430 int width = regs[1] - 1;
431 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
433 for(int y = 0; y < 192; y += 8) {
434 // character data is set for every line in scren 2
435 for(int i = 0; i < 8; i++) {
436 uint8_t t = vram[src_t + (i * 0x800)];
441 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
443 for(int x = 0; x < width; x++) {
444 uint16_t src_g = src_t;
447 for(int i = 0; i < 8; i++) {
448 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
449 is_graph[i] = (attr[t] != 0);
452 for(int l = 0; l < 8; l++) {
453 // change line color if vram data is text and is attribute character
454 uint8_t code_t = code[l];
455 if(!is_graph[l] && IS_ATTRIB(code_t)) {
458 uint8_t c_l = c_t[l], c_r = c_t[l];
460 uint8_t* font_base = &font[code_t << 3];
461 uint8_t p = is_graph[l] ? (attr[src_g] ? vram[src_g] : 0) : font_base[l];
462 src_g = (src_g + 0x800) & 0x3fff;
463 uint8_t c_p = is_graph[l] ? 7 : c_t[l];
464 uint8_t* d = &screen[y + l][x << 4];
466 d[ 0] = d[ 1] = (p & 0x80) ? c_p : c_b;
467 d[ 2] = d[ 3] = (p & 0x40) ? c_p : c_b;
468 d[ 4] = d[ 5] = (p & 0x20) ? c_p : c_b;
469 d[ 6] = d[ 7] = (p & 0x10) ? c_p : c_b;
470 d[ 8] = d[ 9] = (p & 0x08) ? c_p : c_b;
471 d[10] = d[11] = (p & 0x04) ? c_p : c_b;
472 d[12] = d[13] = (p & 0x02) ? c_p : c_b;
473 d[14] = d[15] = (p & 0x01) ? c_p : c_b;
475 if(src_t == cursor) {
476 int bp = regs[10] & 0x60;
477 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
478 for(int i = (regs[10] & 7); i < 8; i++) {
479 memset(&screen[y + i][x << 4], 7, 16);
483 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
488 void DISPLAY::draw_screen15_normal(uint16_t src)
490 // screen 2, normal char (80chars)
491 uint16_t src_t = src & 0x7ff;
492 uint8_t c_b = mode & 7;
493 int width = regs[1] - 1;
494 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
496 for(int y = 0; y < 200; y += 8) {
497 // character data is set for every line in scren 1.5
498 for(int i = 0; i < 8; i++) {
499 uint8_t t = vram[src_t + (i * 0x800)];
504 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
506 for(int x = 0; x < width; x++) {
510 for(int i = 0; i < 8; i++) {
511 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
512 is_graph[i] = (attr[t] != 0);
516 for(int l = 0; l < 8; l++) {
517 // change line color if vram data is text and is attribute character
518 uint8_t code_t = code[l];
519 if(!is_graph[l] && IS_ATTRIB(code_t)) {
522 uint8_t* font_base = &font[code_t << 3];
523 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
529 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
534 uint8_t* d = &screen[y + l][x << 3];
536 d[0] = (p & 0x80) ? c_l : c_b;
537 d[1] = (p & 0x40) ? c_l : c_b;
538 d[2] = (p & 0x20) ? c_l : c_b;
539 d[3] = (p & 0x10) ? c_l : c_b;
540 d[4] = (p & 0x08) ? c_r : c_b;
541 d[5] = (p & 0x04) ? c_r : c_b;
542 d[6] = (p & 0x02) ? c_r : c_b;
543 d[7] = (p & 0x01) ? c_r : c_b;
545 if(src_t == cursor) {
546 int bp = regs[10] & 0x60;
547 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
548 for(int i = (regs[10] & 7); i < 8; i++) {
549 memset(&screen[y + i][x << 3], 7, 8);
553 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
558 void DISPLAY::draw_screen15_wide(uint16_t src)
560 // screen 0, normal char (80chars)
561 uint16_t src_t = src & 0x7ff;
562 uint8_t c_b = mode & 7;
563 int width = regs[1] - 1;
564 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
566 for(int y = 0; y < 192; y += 8) {
567 // character data is set for every line in scren 1.5
568 for(int i = 0; i < 8; i++) {
569 uint8_t t = vram[src_t + (i * 0x800)];
574 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
576 for(int x = 0; x < width; x++) {
580 for(int i = 0; i < 8; i++) {
581 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
582 is_graph[i] = (attr[t] != 0);
587 for(int l = 0; l < 8; l++) {
588 // change line color if vram data is text and is attribute character
589 uint8_t code_t = code[l];
590 if(!is_graph[l] && IS_ATTRIB(code_t)) {
593 uint8_t* font_base = &font[code_t << 3];
594 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
600 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
605 uint8_t* d = &screen[y + l][x << 4];
607 d[ 0] = d[ 1] = (p & 0x80) ? c_l : c_b;
608 d[ 2] = d[ 3] = (p & 0x40) ? c_l : c_b;
609 d[ 4] = d[ 5] = (p & 0x20) ? c_l : c_b;
610 d[ 6] = d[ 7] = (p & 0x10) ? c_l : c_b;
611 d[ 8] = d[ 9] = (p & 0x08) ? c_r : c_b;
612 d[10] = d[11] = (p & 0x04) ? c_r : c_b;
613 d[12] = d[13] = (p & 0x02) ? c_r : c_b;
614 d[14] = d[15] = (p & 0x01) ? c_r : c_b;
616 if(src_t == cursor) {
617 int bp = regs[10] & 0x60;
618 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
619 for(int i = (regs[10] & 7); i < 8; i++) {
620 memset(&screen[y + i][x << 4], 7, 16);
624 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
629 #define STATE_VERSION 1
631 void DISPLAY::save_state(FILEIO* state_fio)
633 state_fio->FputUint32(STATE_VERSION);
634 state_fio->FputInt32(this_device_id);
636 state_fio->FputUint8(mode);
637 state_fio->FputUint16(cursor);
638 state_fio->FputUint16(cblink);
641 bool DISPLAY::load_state(FILEIO* state_fio)
643 if(state_fio->FgetUint32() != STATE_VERSION) {
646 if(state_fio->FgetInt32() != this_device_id) {
649 mode = state_fio->FgetUint8();
650 cursor = state_fio->FgetUint16();
651 cblink = state_fio->FgetUint16();