2 SHARP MZ-5500 Emulator 'EmuZ-5500'
4 Author : Takeda.Toshiya
12 static const int plane_priority[8][8] = {
13 {0, 1, 2, 3, 0, 1, 2, 3}, {0, 1, 2, 3, 4, 1, 2, 3},
14 {0, 1, 2, 3, 4, 4, 2, 3}, {0, 1, 2, 3, 4, 4, 4, 3},
15 {0, 1, 2, 3, 4, 4, 4, 4}, {0, 1, 2, 3, 4, 4, 4, 4},
16 {0, 1, 2, 3, 4, 4, 4, 4}, {0, 1, 2, 3, 4, 4, 4, 4}
19 void DISPLAY::initialize()
22 for(int i = 0; i < 8; i++) {
23 palette_pc_base[i] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);
26 mode_r = mode_c = mode_p = 0;
29 // init window controller
31 memset(wregs, 0, sizeof(wregs));
32 memset(pri, 0, sizeof(pri));
33 memset(vma, 0, sizeof(vma));
34 memset(vds, 0, sizeof(vds));
35 memset(back, 0, sizeof(back));
36 memset(reverse, 0, sizeof(reverse));
39 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
41 switch(addr & 0x3ff) {
56 int p1 = (data >> 6) & 3;
57 int p2 = (data >> 4) & 3;
58 int p3 = (data >> 2) & 3;
63 pri[ 3] = (p1 >= p2) ? 1 : 2;
65 pri[ 5] = (p1 >= p3) ? 1 : 3;
66 pri[ 6] = (p2 >= p3) ? 2 : 3;
67 pri[ 7] = (p1 >= p2 && p1 >= p3) ? 1 : (p2 >= p1 && p2 >= p3) ? 2 : 3;
69 pri[ 9] = (p1 >= p4) ? 1 : 4;
70 pri[10] = (p2 >= p4) ? 2 : 4;
71 pri[11] = (p1 >= p2 && p1 >= p4) ? 1 : (p2 >= p1 && p2 >= p4) ? 2 : 4;
72 pri[12] = (p3 >= p4) ? 3 : 4;
73 pri[13] = (p1 >= p3 && p1 >= p4) ? 1 : (p3 >= p1 && p3 >= p4) ? 3 : 4;
74 pri[14] = (p2 >= p3 && p2 >= p4) ? 2 : (p3 >= p2 && p3 >= p4) ? 3 : 4;
75 pri[15] = (p1 >= p2 && p1 >= p3 && p1 >= p4) ? 1 : (p2 >= p1 && p2 >= p3 && p2 >= p4) ? 2 : (p3 >= p1 && p3 >= p2 && p3 >= p4) ? 3 : 4;
78 memset(pri, 0, sizeof(pri));
81 } else if(rno == 1 || rno == 2) {
82 vma[1] = wregs[1] | (wregs[2] << 8);
84 vds[1] = wregs[3] & 7;
85 } else if(rno == 4 || rno == 5) {
86 vma[2] = wregs[4] | (wregs[5] << 8);
88 vds[2] = wregs[6] & 7;
89 } else if(rno == 7 || rno == 8) {
90 vma[3] = wregs[7] | (wregs[8] << 8);
92 vds[3] = wregs[9] & 7;
93 } else if(rno == 10 || rno == 11) {
94 vma[4] = wregs[10] | (wregs[11] << 8);
95 } else if(rno == 12) {
96 vds[4] = wregs[12] & 7;
119 reverse[4] = (data & 1) ? 0xff : 0;
122 reverse[1] = (data & 1) ? 0xff : 0;
123 reverse[2] = (data & 2) ? 0xff : 0;
124 reverse[3] = (data & 4) ? 0xff : 0;
138 palette[0] = data & 7;
143 palette[1] = data & 7;
148 palette[2] = data & 7;
153 palette[3] = data & 7;
158 palette[4] = data & 7;
163 palette[5] = data & 7;
168 palette[6] = data & 7;
173 palette[7] = data & 7;
179 uint32_t DISPLAY::read_io8(uint32_t addr)
183 switch(addr & 0x3ff) {
194 rno = (++rno) & 0x0f;
224 void DISPLAY::draw_screen()
227 int ymax = (cs[0] & 1) ? 200 : 400;
229 draw_320dot_screen(ymax);
231 draw_640dot_screen(ymax);
237 for(int y = 0; y < 400; y++) {
238 scrntype_t* dest = emu->get_screen_buffer(y);
239 uint8_t* src = screen[y];
241 for(int x = 0; x < 640; x++) {
242 dest[x] = palette_pc[src[x]];
245 emu->screen_skip_line(false);
248 for(int y = 0; y < 200; y++) {
249 scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
250 scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
251 uint8_t* src = screen[y];
253 for(int x = 0; x < 640; x++) {
254 dest0[x] = palette_pc[src[x]];
256 if(config.scan_line) {
257 memset(dest1, 0, 640 * sizeof(scrntype_t));
259 my_memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
262 emu->screen_skip_line(true);
266 void DISPLAY::draw_640dot_screen(int ymax)
268 int al = (sync[6] | (sync[7] << 8)) & 0x3ff;
269 bool wy1 = false, wy2 = false, wy3 = false, wy4 = false;
271 for(int i = 0, total = 0; i < 4 && total < al; i++) {
272 uint32_t tmp = ra[4 * i];
273 tmp |= ra[4 * i + 1] << 8;
274 tmp |= ra[4 * i + 2] << 16;
275 tmp |= ra[4 * i + 3] << 24;
276 int ptr = (tmp << 1) & 0xfffe;
277 int line = (tmp >> 20) & 0x3ff;
278 bool wide = ((tmp & 0x80000000) != 0);
280 for(int y = total; y < total + line && y < ymax; y++) {
281 uint8_t mapy = mapram[y << 1];
282 if(mapy & 1) wy1 = !wy1;
283 if(mapy & 2) wy2 = !wy2;
284 if(mapy & 4) wy3 = !wy3;
285 if(mapy & 8) wy4 = !wy4;
286 bool wx1 = false, wx2 = false, wx3 = false, wx4 = false;
289 for(int x = 0; x < 640; x+= 16) {
290 uint8_t mapx = mapram[(x >> 4) << 1];
291 if(mapx & 0x10) wx1 = !wx1;
292 if(mapx & 0x20) wx2 = !wx2;
293 if(mapx & 0x40) wx3 = !wx3;
294 if(mapx & 0x80) wx4 = !wx4;
295 int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
297 int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
299 uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
300 uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
301 uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
302 uint8_t col, bcol = back[wn];
310 col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
311 screen[y][x + 0] = screen[y][x + 1] = col ? col : bcol;
312 col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
313 screen[y][x + 2] = screen[y][x + 3] = col ? col : bcol;
314 col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
315 screen[y][x + 4] = screen[y][x + 5] = col ? col : bcol;
316 col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
317 screen[y][x + 6] = screen[y][x + 7] = col ? col : bcol;
318 col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
319 screen[y][x + 8] = screen[y][x + 9] = col ? col : bcol;
320 col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
321 screen[y][x + 10] = screen[y][x + 11] = col ? col : bcol;
322 col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
323 screen[y][x + 12] = screen[y][x + 13] = col ? col : bcol;
324 col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
325 screen[y][x + 14] = screen[y][x + 15] = col ? col : bcol;
328 for(int x = 0; x < 640; x+= 8) {
330 uint8_t mapx = mapram[(x >> 4) << 1];
331 if(mapx & 0x10) wx1 = !wx1;
332 if(mapx & 0x20) wx2 = !wx2;
333 if(mapx & 0x40) wx3 = !wx3;
334 if(mapx & 0x80) wx4 = !wx4;
336 int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
338 int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
340 uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
341 uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
342 uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
343 uint8_t col, bcol = back[wn];
351 col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
352 screen[y][x + 0] = col ? col : bcol;
353 col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
354 screen[y][x + 1] = col ? col : bcol;
355 col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
356 screen[y][x + 2] = col ? col : bcol;
357 col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
358 screen[y][x + 3] = col ? col : bcol;
359 col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
360 screen[y][x + 4] = col ? col : bcol;
361 col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
362 screen[y][x + 5] = col ? col : bcol;
363 col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
364 screen[y][x + 6] = col ? col : bcol;
365 col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
366 screen[y][x + 7] = col ? col : bcol;
374 void DISPLAY::draw_320dot_screen(int ymax)
376 int al = (sync[6] | (sync[7] << 8)) & 0x3ff;
377 bool wy1 = false, wy2 = false, wy3 = false, wy4 = false;
379 for(int i = 0, total = 0; i < 4 && total < al; i++) {
380 uint32_t tmp = ra[4 * i];
381 tmp |= ra[4 * i + 1] << 8;
382 tmp |= ra[4 * i + 2] << 16;
383 tmp |= ra[4 * i + 3] << 24;
384 int ptr = (tmp << 1) & 0xfffe;
385 int line = (tmp >> 20) & 0x3ff;
386 bool wide = ((tmp & 0x80000000) != 0);
388 for(int y = total; y < total + line && y < ymax; y++) {
389 uint8_t mapy = mapram[y << 1];
390 if(mapy & 1) wy1 = !wy1;
391 if(mapy & 2) wy2 = !wy2;
392 if(mapy & 4) wy3 = !wy3;
393 if(mapy & 8) wy4 = !wy4;
394 bool wx1 = false, wx2 = false, wx3 = false, wx4 = false;
397 for(int x = 0; x < 640; x+= 32) {
398 uint8_t mapx = mapram[(x >> 4) << 1];
399 if(mapx & 0x10) wx1 = !wx1;
400 if(mapx & 0x20) wx2 = !wx2;
401 if(mapx & 0x40) wx3 = !wx3;
402 if(mapx & 0x80) wx4 = !wx4;
403 int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
405 int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
407 uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
408 uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
409 uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
410 uint8_t col, bcol = back[wn];
418 col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
419 screen[y][x + 0] = screen[y][x + 1] = screen[y][x + 2] = screen[y][x + 3] = col ? col : bcol;
420 col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
421 screen[y][x + 4] = screen[y][x + 5] = screen[y][x + 6] = screen[y][x + 7] = col ? col : bcol;
422 col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
423 screen[y][x + 8] = screen[y][x + 9] = screen[y][x + 10] = screen[y][x + 11] = col ? col : bcol;
424 col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
425 screen[y][x + 12] = screen[y][x + 13] = screen[y][x + 14] = screen[y][x + 15] = col ? col : bcol;
426 col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
427 screen[y][x + 16] = screen[y][x + 17] = screen[y][x + 18] = screen[y][x + 19] = col ? col : bcol;
428 col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
429 screen[y][x + 20] = screen[y][x + 21] = screen[y][x + 22] = screen[y][x + 23] = col ? col : bcol;
430 col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
431 screen[y][x + 24] = screen[y][x + 25] = screen[y][x + 26] = screen[y][x + 27] = col ? col : bcol;
432 col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
433 screen[y][x + 28] = screen[y][x + 29] = screen[y][x + 30] = screen[y][x + 31] = col ? col : bcol;
436 for(int x = 0; x < 640; x+= 16) {
437 uint8_t mapx = mapram[(x >> 4) << 1];
438 if(mapx & 0x10) wx1 = !wx1;
439 if(mapx & 0x20) wx2 = !wx2;
440 if(mapx & 0x40) wx3 = !wx3;
441 if(mapx & 0x80) wx4 = !wx4;
442 int wn = pri[(wx1 && wy1 ? 1 : 0) | (wx2 && wy2 ? 2 : 0) | (wx3 && wy3 ? 4 : 0) | (wx4 && wy4 ? 8 : 0)];
444 int vaddr = ((ptr++) + vma[wn] * 2) & 0xffff;
446 uint8_t b = (vds[wn] & 1) ? vram_b[vaddr] : 0;
447 uint8_t r = (vds[wn] & 2) ? vram_r[vaddr] : 0;
448 uint8_t g = (vds[wn] & 4) ? vram_g[vaddr] : 0;
449 uint8_t col, bcol = back[wn];
457 col = ((b & 0x01) ? 1 : 0) | ((r & 0x01) ? 2 : 0) | ((g & 0x01) ? 4 : 0);
458 screen[y][x + 0] = screen[y][x + 1] = col ? col : bcol;
459 col = ((b & 0x02) ? 1 : 0) | ((r & 0x02) ? 2 : 0) | ((g & 0x02) ? 4 : 0);
460 screen[y][x + 2] = screen[y][x + 3] = col ? col : bcol;
461 col = ((b & 0x04) ? 1 : 0) | ((r & 0x04) ? 2 : 0) | ((g & 0x04) ? 4 : 0);
462 screen[y][x + 4] = screen[y][x + 5] = col ? col : bcol;
463 col = ((b & 0x08) ? 1 : 0) | ((r & 0x08) ? 2 : 0) | ((g & 0x08) ? 4 : 0);
464 screen[y][x + 6] = screen[y][x + 7] = col ? col : bcol;
465 col = ((b & 0x10) ? 1 : 0) | ((r & 0x10) ? 2 : 0) | ((g & 0x10) ? 4 : 0);
466 screen[y][x + 8] = screen[y][x + 9] = col ? col : bcol;
467 col = ((b & 0x20) ? 1 : 0) | ((r & 0x20) ? 2 : 0) | ((g & 0x20) ? 4 : 0);
468 screen[y][x + 10] = screen[y][x + 11] = col ? col : bcol;
469 col = ((b & 0x40) ? 1 : 0) | ((r & 0x40) ? 2 : 0) | ((g & 0x40) ? 4 : 0);
470 screen[y][x + 12] = screen[y][x + 13] = col ? col : bcol;
471 col = ((b & 0x80) ? 1 : 0) | ((r & 0x80) ? 2 : 0) | ((g & 0x80) ? 4 : 0);
472 screen[y][x + 14] = screen[y][x + 15] = col ? col : bcol;
480 void DISPLAY::update_palette()
484 for(int i = 1; i < 8; i++) {
485 palette_pc[i] = palette_pc_base[7];
487 palette_pc[0] = palette_pc_base[0];
488 } else if(mode_c & 4) {
490 for(int i = 0; i < 8; i++) {
491 palette_pc[i] = palette_pc_base[plane_priority[mode_p][palette[i]]];
495 for(int i = 0; i < 8; i++) {
496 palette_pc[i] = palette_pc_base[palette[i]];
501 #define STATE_VERSION 1
503 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
505 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
508 if(!state_fio->StateCheckInt32(this_device_id)) {
511 //state_fio->StateBuffer(palette_pc, sizeof(palette_pc), 1);
512 for(int i = 0; i < (sizeof(palette) / sizeof(scrntype_t)); i++) {
515 r = state_fio->FgetUint8();
516 g = state_fio->FgetUint8();
517 b = state_fio->FgetUint8();
518 palette[i] = RGB_COLOR(r, g, b);
521 r = R_OF_COLOR(palette[i]);
522 g = G_OF_COLOR(palette[i]);
523 b = B_OF_COLOR(palette[i]);
524 state_fio->FputUint8(r);
525 state_fio->FputUint8(g);
526 state_fio->FputUint8(b);
529 state_fio->StateBuffer(palette, sizeof(palette), 1);
530 state_fio->StateBuffer(back, sizeof(back), 1);
531 state_fio->StateBuffer(reverse, sizeof(reverse), 1);
532 state_fio->StateUint8(rno);
533 state_fio->StateBuffer(wregs, sizeof(wregs), 1);
534 //state_fio->StateBuffer(pri, sizeof(pri), 1);
535 for(int i = 0; i < (sizeof(pri) / sizeof(int)); i++) {
536 state_fio->StateInt32(pri[i]);
538 //state_fio->StateBuffer(vma, sizeof(vma), 1);
539 for(int i = 0; i < (sizeof(vma) / sizeof(int)); i++) {
540 state_fio->StateInt32(vma[i]);
542 state_fio->StateBuffer(vds, sizeof(vds), 1);
543 state_fio->StateUint8(mode_r);
544 state_fio->StateUint8(mode_c);
545 state_fio->StateUint8(mode_p);