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 bcol = palette_pc[mode & 7];
110 for(int y = 0; y < 200; y++) {
111 scrntype* dest0 = emu->get_screen_buffer(y * 2 + 0);
112 scrntype* dest1 = emu->get_screen_buffer(y * 2 + 1);
113 uint8* src = screen[y];
115 if((dest0 == NULL) || (dest1 == NULL)) continue;
116 for(int x = 0; x < 640; x++) {
117 dest0[x] = palette_pc[src[x] & 7];
119 if(config.scan_line) {
120 memset(dest1, 0, 640 * sizeof(scrntype));
122 memcpy(dest1, dest0, 640 * sizeof(scrntype));
125 emu->screen_skip_line(true);
128 #define IS_ATTRIB(d) (((d) & 0xf8) == 0xf8)
130 void DISPLAY::draw_screen0_normal(uint16_t src)
132 // screen 0, normal char (80chars)
133 uint16_t src_t = src & 0x7ff;
134 uint8_t c_b = mode & 7;
135 int width = regs[1] - 1;
137 for(int y = 0; y < 200; y += 8) {
138 uint8_t c_t = IS_ATTRIB(vram[src_t]) ? (vram[src_t] & 7) : 7;
139 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
141 for(int x = 0; x < width; x++) {
142 uint8_t code = vram[src_t];
143 if(IS_ATTRIB(code)) {
146 uint8_t* font_base = &font[code << 3];
148 for(int l = 0; l < 8; l++) {
149 uint8_t p = font_base[l];
150 uint8_t* d = &screen[y + l][x << 3];
152 d[0] = (p & 0x80) ? c_t : c_b;
153 d[1] = (p & 0x40) ? c_t : c_b;
154 d[2] = (p & 0x20) ? c_t : c_b;
155 d[3] = (p & 0x10) ? c_t : c_b;
156 d[4] = (p & 0x08) ? c_t : c_b;
157 d[5] = (p & 0x04) ? c_t : c_b;
158 d[6] = (p & 0x02) ? c_t : c_b;
159 d[7] = (p & 0x01) ? c_t : c_b;
161 if(src_t == cursor) {
162 int bp = regs[10] & 0x60;
163 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
164 for(int i = (regs[10] & 7); i < 8; i++) {
165 memset(&screen[y + i][x << 3], 7, 8);
169 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
174 void DISPLAY::draw_screen0_wide(uint16_t src)
176 // screen 0, wide char (36chars)
177 uint16_t src_t = src & 0x7ff;
178 uint8_t c_b = mode & 7;
179 int width = regs[1] - 1;
181 for(int y = 0; y < 192; y += 8) {
182 uint8_t c_t = IS_ATTRIB(vram[src_t]) ? (vram[src_t] & 7) : 7;
183 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
185 for(int x = 0; x < width; x++) {
186 uint8_t code = vram[src_t];
187 if(IS_ATTRIB(code)) {
190 uint8_t* font_base = &font[code << 3];
192 for(int l = 0; l < 8; l++) {
193 uint8_t p = font_base[l];
194 uint8_t* d = &screen[y + l][x << 4];
196 d[ 0] = d[ 1] = (p & 0x80) ? c_t : c_b;
197 d[ 2] = d[ 3] = (p & 0x40) ? c_t : c_b;
198 d[ 4] = d[ 5] = (p & 0x20) ? c_t : c_b;
199 d[ 6] = d[ 7] = (p & 0x10) ? c_t : c_b;
200 d[ 8] = d[ 9] = (p & 0x08) ? c_t : c_b;
201 d[10] = d[11] = (p & 0x04) ? c_t : c_b;
202 d[12] = d[13] = (p & 0x02) ? c_t : c_b;
203 d[14] = d[15] = (p & 0x01) ? c_t : c_b;
205 if(src_t == cursor) {
206 int bp = regs[10] & 0x60;
207 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
208 for(int i = (regs[10] & 7); i < 8; i++) {
209 memset(&screen[y + i][x << 4], 7, 16);
213 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
218 void DISPLAY::draw_screen1_normal(uint16_t src)
220 // screen 1, normal char (80chars)
221 uint16_t src_t = src & 0x7ff;
222 uint8_t c_b = mode & 7;
223 int width = regs[1] - 1;
224 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
226 for(int y = 0; y < 200; y += 8) {
227 // character data is set for every other line in scren 1
228 for(int i = 0; i < 8; i += 2) {
229 uint8_t t = vram[src_t + (i * 0x800)];
231 c_t[i] = c_t[i + 1] = t & 7;
234 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
236 for(int x = 0; x < width; x++) {
240 for(int i = 0; i < 8; i += 2) {
241 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
242 is_graph[i] = is_graph[i + 1] = (attr[t] != 0);
243 attr_t[i] = attr_t[i + 1] = attr[t];
244 code[i] = code[i + 1] = vram[t];
247 for(int l = 0; l < 8; l++) {
248 // change line color if vram data is text and is attribute character
249 // note: check only first line
250 uint8_t code_t = code[l];
251 if(!is_graph[l] && IS_ATTRIB(code_t)) {
254 uint8_t* font_base = &font[code_t << 3];
255 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
261 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
266 uint8_t* d = &screen[y + l][x << 3];
268 d[0] = (p & 0x80) ? c_l : c_b;
269 d[1] = (p & 0x40) ? c_l : c_b;
270 d[2] = (p & 0x20) ? c_l : c_b;
271 d[3] = (p & 0x10) ? c_l : c_b;
272 d[4] = (p & 0x08) ? c_r : c_b;
273 d[5] = (p & 0x04) ? c_r : c_b;
274 d[6] = (p & 0x02) ? c_r : c_b;
275 d[7] = (p & 0x01) ? c_r : c_b;
277 if(src_t == cursor) {
278 int bp = regs[10] & 0x60;
279 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
280 for(int i = (regs[10] & 7); i < 8; i++) {
281 memset(&screen[y + i][x << 3], 7, 8);
285 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
290 void DISPLAY::draw_screen1_wide(uint16_t src)
292 // screen 1, wide char (36chars)
293 uint16_t src_t = src & 0x7ff;
294 uint8_t c_b = mode & 7;
295 int width = regs[1] - 1;
296 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
298 for(int y = 0; y < 192; y += 8) {
299 // character data is set for every other line in scren 1
300 for(int i = 0; i < 8; i += 2) {
301 uint8_t t = vram[src_t + (i * 0x800)];
303 c_t[i] = c_t[i + 1] = t & 7;
306 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
308 for(int x = 0; x < width; x++) {
312 for(int i = 0; i < 8; i += 2) {
313 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
314 is_graph[i] = is_graph[i + 1] = (attr[t] != 0);
315 attr_t[i] = attr_t[i + 1] = attr[t];
316 code[i] = code[i + 1] = vram[t];
319 for(int l = 0; l < 8; l++) {
320 // change line color if vram data is text and is attribute character
321 // note: check only first line
322 uint8_t code_t = code[l];
323 if(!is_graph[l] && IS_ATTRIB(code_t)) {
326 uint8_t* font_base = &font[code_t << 3];
327 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
333 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
338 uint8_t* d = &screen[y + l][x << 4];
340 d[ 0] = d[ 1] = (p & 0x80) ? c_l : c_b;
341 d[ 2] = d[ 3] = (p & 0x40) ? c_l : c_b;
342 d[ 4] = d[ 5] = (p & 0x20) ? c_l : c_b;
343 d[ 6] = d[ 7] = (p & 0x10) ? c_l : c_b;
344 d[ 8] = d[ 9] = (p & 0x08) ? c_r : c_b;
345 d[10] = d[11] = (p & 0x04) ? c_r : c_b;
346 d[12] = d[13] = (p & 0x02) ? c_r : c_b;
347 d[14] = d[15] = (p & 0x01) ? c_r : c_b;
349 if(src_t == cursor) {
350 int bp = regs[10] & 0x60;
351 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
352 for(int i = (regs[10] & 7); i < 8; i++) {
353 memset(&screen[y + i][x << 4], 7, 16);
357 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
362 void DISPLAY::draw_screen2_normal(uint16_t src)
364 // screen 2, normal char (80chars)
365 uint16_t src_t = src & 0x7ff;
366 uint8_t c_b = mode & 7;
367 int width = regs[1] - 1;
368 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
370 for(int y = 0; y < 200; y += 8) {
371 // character data is set for every line in scren 2
372 for(int i = 0; i < 8; i++) {
373 uint8_t t = vram[src_t + (i * 0x800)];
378 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
380 for(int x = 0; x < width; x++) {
381 uint16_t src_g = src_t;
384 for(int i = 0; i < 8; i++) {
385 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
386 is_graph[i] = (attr[t] != 0);
390 for(int l = 0; l < 8; l++) {
391 // change line color if vram data is text and is attribute character
392 uint8_t code_t = code[l];
393 if(!is_graph[l] && (0xf8 <= code_t) && (code_t <= 0xff)) {
396 uint8_t c_l = c_t[l], c_r = c_t[l];
398 uint8_t* font_base = &font[code_t << 3];
399 uint8_t p = is_graph[l] ? (attr[src_g] ? vram[src_g] : 0) : font_base[l];
400 src_g = (src_g + 0x800) & 0x3fff;
401 uint8_t c_p = is_graph[l] ? 7 : c_t[l];
402 uint8_t* d = &screen[y + l][x << 3];
404 d[0] = (p & 0x80) ? c_p : c_b;
405 d[1] = (p & 0x40) ? c_p : c_b;
406 d[2] = (p & 0x20) ? c_p : c_b;
407 d[3] = (p & 0x10) ? c_p : c_b;
408 d[4] = (p & 0x08) ? c_p : c_b;
409 d[5] = (p & 0x04) ? c_p : c_b;
410 d[6] = (p & 0x02) ? c_p : c_b;
411 d[7] = (p & 0x01) ? c_p : c_b;
413 if(src_t == cursor) {
414 int bp = regs[10] & 0x60;
415 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
416 for(int i = (regs[10] & 7); i < 8; i++) {
417 memset(&screen[y + i][x << 3], 7, 8);
421 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
426 void DISPLAY::draw_screen2_wide(uint16_t src)
428 // screen 0, wide char (36chars)
429 uint16_t src_t = src & 0x7ff;
430 uint8_t c_b = mode & 7;
431 int width = regs[1] - 1;
432 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
434 for(int y = 0; y < 192; y += 8) {
435 // character data is set for every line in scren 2
436 for(int i = 0; i < 8; i++) {
437 uint8_t t = vram[src_t + (i * 0x800)];
442 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
444 for(int x = 0; x < width; x++) {
445 uint16_t src_g = src_t;
448 for(int i = 0; i < 8; i++) {
449 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
450 is_graph[i] = (attr[t] != 0);
453 for(int l = 0; l < 8; l++) {
454 // change line color if vram data is text and is attribute character
455 uint8_t code_t = code[l];
456 if(!is_graph[l] && IS_ATTRIB(code_t)) {
459 uint8_t c_l = c_t[l], c_r = c_t[l];
461 uint8_t* font_base = &font[code_t << 3];
462 uint8_t p = is_graph[l] ? (attr[src_g] ? vram[src_g] : 0) : font_base[l];
463 src_g = (src_g + 0x800) & 0x3fff;
464 uint8_t c_p = is_graph[l] ? 7 : c_t[l];
465 uint8_t* d = &screen[y + l][x << 4];
467 d[ 0] = d[ 1] = (p & 0x80) ? c_p : c_b;
468 d[ 2] = d[ 3] = (p & 0x40) ? c_p : c_b;
469 d[ 4] = d[ 5] = (p & 0x20) ? c_p : c_b;
470 d[ 6] = d[ 7] = (p & 0x10) ? c_p : c_b;
471 d[ 8] = d[ 9] = (p & 0x08) ? c_p : c_b;
472 d[10] = d[11] = (p & 0x04) ? c_p : c_b;
473 d[12] = d[13] = (p & 0x02) ? c_p : c_b;
474 d[14] = d[15] = (p & 0x01) ? c_p : c_b;
476 if(src_t == cursor) {
477 int bp = regs[10] & 0x60;
478 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
479 for(int i = (regs[10] & 7); i < 8; i++) {
480 memset(&screen[y + i][x << 4], 7, 16);
484 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
489 void DISPLAY::draw_screen15_normal(uint16_t src)
491 // screen 2, normal char (80chars)
492 uint16_t src_t = src & 0x7ff;
493 uint8_t c_b = mode & 7;
494 int width = regs[1] - 1;
495 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
497 for(int y = 0; y < 200; y += 8) {
498 // character data is set for every line in scren 1.5
499 for(int i = 0; i < 8; i++) {
500 uint8_t t = vram[src_t + (i * 0x800)];
505 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
507 for(int x = 0; x < width; x++) {
511 for(int i = 0; i < 8; i++) {
512 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
513 is_graph[i] = (attr[t] != 0);
517 for(int l = 0; l < 8; l++) {
518 // change line color if vram data is text and is attribute character
519 uint8_t code_t = code[l];
520 if(!is_graph[l] && IS_ATTRIB(code_t)) {
523 uint8_t* font_base = &font[code_t << 3];
524 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
530 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
535 uint8_t* d = &screen[y + l][x << 3];
537 d[0] = (p & 0x80) ? c_l : c_b;
538 d[1] = (p & 0x40) ? c_l : c_b;
539 d[2] = (p & 0x20) ? c_l : c_b;
540 d[3] = (p & 0x10) ? c_l : c_b;
541 d[4] = (p & 0x08) ? c_r : c_b;
542 d[5] = (p & 0x04) ? c_r : c_b;
543 d[6] = (p & 0x02) ? c_r : c_b;
544 d[7] = (p & 0x01) ? c_r : c_b;
546 if(src_t == cursor) {
547 int bp = regs[10] & 0x60;
548 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
549 for(int i = (regs[10] & 7); i < 8; i++) {
550 memset(&screen[y + i][x << 3], 7, 8);
554 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
559 void DISPLAY::draw_screen15_wide(uint16_t src)
561 // screen 0, normal char (80chars)
562 uint16_t src_t = src & 0x7ff;
563 uint8_t c_b = mode & 7;
564 int width = regs[1] - 1;
565 uint8_t c_t[8] = {7, 7, 7, 7, 7, 7, 7, 7};
567 for(int y = 0; y < 192; y += 8) {
568 // character data is set for every line in scren 1.5
569 for(int i = 0; i < 8; i++) {
570 uint8_t t = vram[src_t + (i * 0x800)];
575 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
577 for(int x = 0; x < width; x++) {
581 for(int i = 0; i < 8; i++) {
582 uint16_t t = (src_t + (i * 0x800)) & 0x3fff;
583 is_graph[i] = (attr[t] != 0);
588 for(int l = 0; l < 8; l++) {
589 // change line color if vram data is text and is attribute character
590 uint8_t code_t = code[l];
591 if(!is_graph[l] && IS_ATTRIB(code_t)) {
594 uint8_t* font_base = &font[code_t << 3];
595 uint8_t c_l = c_t[l], c_r = c_t[l], p = font_base[l];
601 p = (p & 0xf0 ? 0xf0 : 0) | (p & 0x0f ? 0x0f : 0);
606 uint8_t* d = &screen[y + l][x << 4];
608 d[ 0] = d[ 1] = (p & 0x80) ? c_l : c_b;
609 d[ 2] = d[ 3] = (p & 0x40) ? c_l : c_b;
610 d[ 4] = d[ 5] = (p & 0x20) ? c_l : c_b;
611 d[ 6] = d[ 7] = (p & 0x10) ? c_l : c_b;
612 d[ 8] = d[ 9] = (p & 0x08) ? c_r : c_b;
613 d[10] = d[11] = (p & 0x04) ? c_r : c_b;
614 d[12] = d[13] = (p & 0x02) ? c_r : c_b;
615 d[14] = d[15] = (p & 0x01) ? c_r : c_b;
617 if(src_t == cursor) {
618 int bp = regs[10] & 0x60;
619 if((bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
620 for(int i = (regs[10] & 7); i < 8; i++) {
621 memset(&screen[y + i][x << 4], 7, 16);
625 src_t = (src_t & 0x3800) | ((src_t + 1) & 0x7ff);
630 #define STATE_VERSION 1
632 void DISPLAY::save_state(FILEIO* state_fio)
634 state_fio->FputUint32(STATE_VERSION);
635 state_fio->FputInt32(this_device_id);
637 state_fio->FputUint8(mode);
638 state_fio->FputUint16(cursor);
639 state_fio->FputUint16(cblink);
642 bool DISPLAY::load_state(FILEIO* state_fio)
644 if(state_fio->FgetUint32() != STATE_VERSION) {
647 if(state_fio->FgetInt32() != this_device_id) {
650 mode = state_fio->FgetUint8();
651 cursor = state_fio->FgetUint16();
652 cblink = state_fio->FgetUint16();