2 SHARP MZ-5500 Emulator 'EmuZ-5500'
4 Author : Takeda.Toshiya
14 static const int plane_priority[8][8] = {
15 {0, 1, 2, 3, 0, 1, 2, 3}, {0, 1, 2, 3, 4, 1, 2, 3},
16 {0, 1, 2, 3, 4, 4, 2, 3}, {0, 1, 2, 3, 4, 4, 4, 3},
17 {0, 1, 2, 3, 4, 4, 4, 4}, {0, 1, 2, 3, 4, 4, 4, 4},
18 {0, 1, 2, 3, 4, 4, 4, 4}, {0, 1, 2, 3, 4, 4, 4, 4}
21 void DISPLAY::initialize()
24 for(int i = 0; i < 8; i++) {
25 palette_pc_base[i] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);
28 mode_r = mode_c = mode_p = 0;
31 // init window controller
33 memset(wregs, 0, sizeof(wregs));
34 memset(pri, 0, sizeof(pri));
35 memset(vma, 0, sizeof(vma));
36 memset(vds, 0, sizeof(vds));
37 memset(back, 0, sizeof(back));
38 memset(reverse, 0, sizeof(reverse));
41 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
43 switch(addr & 0x3ff) {
58 int p1 = (data >> 6) & 3;
59 int p2 = (data >> 4) & 3;
60 int p3 = (data >> 2) & 3;
65 pri[ 3] = (p1 >= p2) ? 1 : 2;
67 pri[ 5] = (p1 >= p3) ? 1 : 3;
68 pri[ 6] = (p2 >= p3) ? 2 : 3;
69 pri[ 7] = (p1 >= p2 && p1 >= p3) ? 1 : (p2 >= p1 && p2 >= p3) ? 2 : 3;
71 pri[ 9] = (p1 >= p4) ? 1 : 4;
72 pri[10] = (p2 >= p4) ? 2 : 4;
73 pri[11] = (p1 >= p2 && p1 >= p4) ? 1 : (p2 >= p1 && p2 >= p4) ? 2 : 4;
74 pri[12] = (p3 >= p4) ? 3 : 4;
75 pri[13] = (p1 >= p3 && p1 >= p4) ? 1 : (p3 >= p1 && p3 >= p4) ? 3 : 4;
76 pri[14] = (p2 >= p3 && p2 >= p4) ? 2 : (p3 >= p2 && p3 >= p4) ? 3 : 4;
77 pri[15] = (p1 >= p2 && p1 >= p3 && p1 >= p4) ? 1 : (p2 >= p1 && p2 >= p3 && p2 >= p4) ? 2 : (p3 >= p1 && p3 >= p2 && p3 >= p4) ? 3 : 4;
80 memset(pri, 0, sizeof(pri));
83 } else if(rno == 1 || rno == 2) {
84 vma[1] = wregs[1] | (wregs[2] << 8);
86 vds[1] = wregs[3] & 7;
87 } else if(rno == 4 || rno == 5) {
88 vma[2] = wregs[4] | (wregs[5] << 8);
90 vds[2] = wregs[6] & 7;
91 } else if(rno == 7 || rno == 8) {
92 vma[3] = wregs[7] | (wregs[8] << 8);
94 vds[3] = wregs[9] & 7;
95 } else if(rno == 10 || rno == 11) {
96 vma[4] = wregs[10] | (wregs[11] << 8);
97 } else if(rno == 12) {
98 vds[4] = wregs[12] & 7;
100 rno = (++rno) & 0x0f;
121 reverse[4] = (data & 1) ? 0xff : 0;
124 reverse[1] = (data & 1) ? 0xff : 0;
125 reverse[2] = (data & 2) ? 0xff : 0;
126 reverse[3] = (data & 4) ? 0xff : 0;
140 palette[0] = data & 7;
145 palette[1] = data & 7;
150 palette[2] = data & 7;
155 palette[3] = data & 7;
160 palette[4] = data & 7;
165 palette[5] = data & 7;
170 palette[6] = data & 7;
175 palette[7] = data & 7;
181 uint32_t DISPLAY::read_io8(uint32_t addr)
185 switch(addr & 0x3ff) {
196 rno = (++rno) & 0x0f;
226 void DISPLAY::draw_screen()
229 int ymax = (cs[0] & 1) ? 200 : 400;
231 draw_320dot_screen(ymax);
233 draw_640dot_screen(ymax);
239 for(int y = 0; y < 400; y++) {
240 scrntype_t* dest = emu->get_screen_buffer(y);
241 uint8_t* src = screen[y];
243 for(int x = 0; x < 640; x++) {
244 dest[x] = palette_pc[src[x]];
247 emu->screen_skip_line(false);
250 for(int y = 0; y < 200; y++) {
251 scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
252 scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
253 uint8_t* src = screen[y];
255 for(int x = 0; x < 640; x++) {
256 dest0[x] = palette_pc[src[x]];
258 if(config.scan_line) {
259 memset(dest1, 0, 640 * sizeof(scrntype_t));
261 my_memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
264 emu->screen_skip_line(true);
268 void DISPLAY::draw_640dot_screen(int ymax)
270 int al = (sync[6] | (sync[7] << 8)) & 0x3ff;
271 bool wy1 = false, wy2 = false, wy3 = false, wy4 = false;
273 for(int i = 0, total = 0; i < 4 && total < al; i++) {
274 uint32_t tmp = ra[4 * i];
275 tmp |= ra[4 * i + 1] << 8;
276 tmp |= ra[4 * i + 2] << 16;
277 tmp |= ra[4 * i + 3] << 24;
278 int ptr = (tmp << 1) & 0xfffe;
279 int line = (tmp >> 20) & 0x3ff;
280 bool wide = ((tmp & 0x80000000) != 0);
282 for(int y = total; y < total + line && y < ymax; y++) {
283 uint8_t mapy = mapram[y << 1];
284 if(mapy & 1) wy1 = !wy1;
285 if(mapy & 2) wy2 = !wy2;
286 if(mapy & 4) wy3 = !wy3;
287 if(mapy & 8) wy4 = !wy4;
288 bool wx1 = false, wx2 = false, wx3 = false, wx4 = false;
291 for(int x = 0; x < 640; x+= 16) {
292 uint8_t mapx = mapram[(x >> 4) << 1];
293 if(mapx & 0x10) wx1 = !wx1;
294 if(mapx & 0x20) wx2 = !wx2;
295 if(mapx & 0x40) wx3 = !wx3;
296 if(mapx & 0x80) wx4 = !wx4;
297 int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
299 int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
301 uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
302 uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
303 uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
304 uint8_t col, bcol = back[wn];
312 col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
313 screen[y][x + 0] = screen[y][x + 1] = col ? col : bcol;
314 col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
315 screen[y][x + 2] = screen[y][x + 3] = col ? col : bcol;
316 col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
317 screen[y][x + 4] = screen[y][x + 5] = col ? col : bcol;
318 col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
319 screen[y][x + 6] = screen[y][x + 7] = col ? col : bcol;
320 col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
321 screen[y][x + 8] = screen[y][x + 9] = col ? col : bcol;
322 col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
323 screen[y][x + 10] = screen[y][x + 11] = col ? col : bcol;
324 col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
325 screen[y][x + 12] = screen[y][x + 13] = col ? col : bcol;
326 col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
327 screen[y][x + 14] = screen[y][x + 15] = col ? col : bcol;
330 for(int x = 0; x < 640; x+= 8) {
332 uint8_t mapx = mapram[(x >> 4) << 1];
333 if(mapx & 0x10) wx1 = !wx1;
334 if(mapx & 0x20) wx2 = !wx2;
335 if(mapx & 0x40) wx3 = !wx3;
336 if(mapx & 0x80) wx4 = !wx4;
338 int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
340 int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
342 uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
343 uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
344 uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
345 uint8_t col, bcol = back[wn];
353 col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
354 screen[y][x + 0] = col ? col : bcol;
355 col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
356 screen[y][x + 1] = col ? col : bcol;
357 col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
358 screen[y][x + 2] = col ? col : bcol;
359 col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
360 screen[y][x + 3] = col ? col : bcol;
361 col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
362 screen[y][x + 4] = col ? col : bcol;
363 col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
364 screen[y][x + 5] = col ? col : bcol;
365 col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
366 screen[y][x + 6] = col ? col : bcol;
367 col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
368 screen[y][x + 7] = col ? col : bcol;
376 void DISPLAY::draw_320dot_screen(int ymax)
378 int al = (sync[6] | (sync[7] << 8)) & 0x3ff;
379 bool wy1 = false, wy2 = false, wy3 = false, wy4 = false;
381 for(int i = 0, total = 0; i < 4 && total < al; i++) {
382 uint32_t tmp = ra[4 * i];
383 tmp |= ra[4 * i + 1] << 8;
384 tmp |= ra[4 * i + 2] << 16;
385 tmp |= ra[4 * i + 3] << 24;
386 int ptr = (tmp << 1) & 0xfffe;
387 int line = (tmp >> 20) & 0x3ff;
388 bool wide = ((tmp & 0x80000000) != 0);
390 for(int y = total; y < total + line && y < ymax; y++) {
391 uint8_t mapy = mapram[y << 1];
392 if(mapy & 1) wy1 = !wy1;
393 if(mapy & 2) wy2 = !wy2;
394 if(mapy & 4) wy3 = !wy3;
395 if(mapy & 8) wy4 = !wy4;
396 bool wx1 = false, wx2 = false, wx3 = false, wx4 = false;
399 for(int x = 0; x < 640; x+= 32) {
400 uint8_t mapx = mapram[(x >> 4) << 1];
401 if(mapx & 0x10) wx1 = !wx1;
402 if(mapx & 0x20) wx2 = !wx2;
403 if(mapx & 0x40) wx3 = !wx3;
404 if(mapx & 0x80) wx4 = !wx4;
405 int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
407 int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
409 uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
410 uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
411 uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
412 uint8_t col, bcol = back[wn];
420 col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
421 screen[y][x + 0] = screen[y][x + 1] = screen[y][x + 2] = screen[y][x + 3] = col ? col : bcol;
422 col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
423 screen[y][x + 4] = screen[y][x + 5] = screen[y][x + 6] = screen[y][x + 7] = col ? col : bcol;
424 col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
425 screen[y][x + 8] = screen[y][x + 9] = screen[y][x + 10] = screen[y][x + 11] = col ? col : bcol;
426 col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
427 screen[y][x + 12] = screen[y][x + 13] = screen[y][x + 14] = screen[y][x + 15] = col ? col : bcol;
428 col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
429 screen[y][x + 16] = screen[y][x + 17] = screen[y][x + 18] = screen[y][x + 19] = col ? col : bcol;
430 col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
431 screen[y][x + 20] = screen[y][x + 21] = screen[y][x + 22] = screen[y][x + 23] = col ? col : bcol;
432 col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
433 screen[y][x + 24] = screen[y][x + 25] = screen[y][x + 26] = screen[y][x + 27] = col ? col : bcol;
434 col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
435 screen[y][x + 28] = screen[y][x + 29] = screen[y][x + 30] = screen[y][x + 31] = col ? col : bcol;
438 for(int x = 0; x < 640; x+= 16) {
439 uint8_t mapx = mapram[(x >> 4) << 1];
440 if(mapx & 0x10) wx1 = !wx1;
441 if(mapx & 0x20) wx2 = !wx2;
442 if(mapx & 0x40) wx3 = !wx3;
443 if(mapx & 0x80) wx4 = !wx4;
444 int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
446 int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
448 uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
449 uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
450 uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
451 uint8_t col, bcol = back[wn];
459 col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
460 screen[y][x + 0] = screen[y][x + 1] = col ? col : bcol;
461 col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
462 screen[y][x + 2] = screen[y][x + 3] = col ? col : bcol;
463 col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
464 screen[y][x + 4] = screen[y][x + 5] = col ? col : bcol;
465 col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
466 screen[y][x + 6] = screen[y][x + 7] = col ? col : bcol;
467 col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
468 screen[y][x + 8] = screen[y][x + 9] = col ? col : bcol;
469 col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
470 screen[y][x + 10] = screen[y][x + 11] = col ? col : bcol;
471 col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
472 screen[y][x + 12] = screen[y][x + 13] = col ? col : bcol;
473 col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
474 screen[y][x + 14] = screen[y][x + 15] = col ? col : bcol;
482 void DISPLAY::update_palette()
486 for(int i = 1; i < 8; i++) {
487 palette_pc[i] = palette_pc_base[7];
489 palette_pc[0] = palette_pc_base[0];
490 } else if(mode_c & 4) {
492 for(int i = 0; i < 8; i++) {
493 palette_pc[i] = palette_pc_base[plane_priority[mode_p][palette[i]]];
497 for(int i = 0; i < 8; i++) {
498 palette_pc[i] = palette_pc_base[palette[i]];
503 #define STATE_VERSION 1
505 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
507 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
510 if(!state_fio->StateCheckInt32(this_device_id)) {
513 //state_fio->StateBuffer(palette_pc, sizeof(palette_pc), 1);
514 for(int i = 0; i < (sizeof(palette) / sizeof(scrntype_t)); i++) {
517 r = state_fio->FgetUint8();
518 g = state_fio->FgetUint8();
519 b = state_fio->FgetUint8();
520 palette[i] = RGB_COLOR(r, g, b);
523 r = R_OF_COLOR(palette[i]);
524 g = G_OF_COLOR(palette[i]);
525 b = B_OF_COLOR(palette[i]);
526 state_fio->FputUint8(r);
527 state_fio->FputUint8(g);
528 state_fio->FputUint8(b);
531 state_fio->StateBuffer(palette, sizeof(palette), 1);
532 state_fio->StateBuffer(back, sizeof(back), 1);
533 state_fio->StateBuffer(reverse, sizeof(reverse), 1);
534 state_fio->StateUint8(rno);
535 state_fio->StateBuffer(wregs, sizeof(wregs), 1);
536 //state_fio->StateBuffer(pri, sizeof(pri), 1);
537 for(int i = 0; i < (sizeof(pri) / sizeof(int)); i++) {
538 state_fio->StateInt32(pri[i]);
540 //state_fio->StateBuffer(vma, sizeof(vma), 1);
541 for(int i = 0; i < (sizeof(vma) / sizeof(int)); i++) {
542 state_fio->StateInt32(vma[i]);
544 state_fio->StateBuffer(vds, sizeof(vds), 1);
545 state_fio->StateUint8(mode_r);
546 state_fio->StateUint8(mode_c);
547 state_fio->StateUint8(mode_p);