Mercurial > repos > blastem
comparison vdp.c @ 1077:1a66d5165ea7
Cleanup the separation of render backend and VDP code in preparation for having extra debug windows. Make determination of H40/H32 based on number of lines in each mode.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 22 Aug 2016 09:46:18 -0700 |
parents | fa6fe03f218a |
children | c15896605bf2 |
comparison
equal
deleted
inserted
replaced
1076:fa6fe03f218a | 1077:1a66d5165ea7 |
---|---|
57 context->vdpmem = malloc(VRAM_SIZE); | 57 context->vdpmem = malloc(VRAM_SIZE); |
58 memset(context->vdpmem, 0, VRAM_SIZE); | 58 memset(context->vdpmem, 0, VRAM_SIZE); |
59 /* | 59 /* |
60 */ | 60 */ |
61 if (headless) { | 61 if (headless) { |
62 context->oddbuf = context->framebuf = malloc(FRAMEBUF_ENTRIES * (32 / 8)); | 62 context->output = malloc(LINEBUF_SIZE); |
63 memset(context->framebuf, 0, FRAMEBUF_ENTRIES * (32 / 8)); | 63 context->output_pitch = 0; |
64 context->evenbuf = malloc(FRAMEBUF_ENTRIES * (32 / 8)); | |
65 memset(context->evenbuf, 0, FRAMEBUF_ENTRIES * (32 / 8)); | |
66 } else { | 64 } else { |
67 render_alloc_surfaces(context); | 65 context->output = render_get_framebuffer(FRAMEBUFFER_ODD, &context->output_pitch); |
68 } | 66 } |
69 context->framebuf = context->oddbuf; | |
70 context->linebuf = malloc(LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); | 67 context->linebuf = malloc(LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); |
71 memset(context->linebuf, 0, LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); | 68 memset(context->linebuf, 0, LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); |
72 context->tmp_buf_a = context->linebuf + LINEBUF_SIZE; | 69 context->tmp_buf_a = context->linebuf + LINEBUF_SIZE; |
73 context->tmp_buf_b = context->tmp_buf_a + SCROLL_BUFFER_SIZE; | 70 context->tmp_buf_b = context->tmp_buf_a + SCROLL_BUFFER_SIZE; |
74 context->sprite_draws = MAX_DRAWS; | 71 context->sprite_draws = MAX_DRAWS; |
144 | 141 |
145 void vdp_free(vdp_context *context) | 142 void vdp_free(vdp_context *context) |
146 { | 143 { |
147 free(context->vdpmem); | 144 free(context->vdpmem); |
148 free(context->linebuf); | 145 free(context->linebuf); |
149 if (headless) { | |
150 free(context->oddbuf); | |
151 free(context->evenbuf); | |
152 } else { | |
153 render_free_surfaces(context); | |
154 } | |
155 free(context); | 146 free(context); |
156 } | 147 } |
157 | 148 |
158 int is_refresh(vdp_context * context, uint32_t slot) | 149 int is_refresh(vdp_context * context, uint32_t slot) |
159 { | 150 { |
354 line &= 0xFF; | 345 line &= 0xFF; |
355 uint16_t ymask, ymin; | 346 uint16_t ymask, ymin; |
356 uint8_t height_mult; | 347 uint8_t height_mult; |
357 if (context->double_res) { | 348 if (context->double_res) { |
358 line *= 2; | 349 line *= 2; |
359 if (context->framebuf != context->oddbuf) { | 350 if (context->flags2 & FLAG2_EVEN_FIELD) { |
360 line++; | 351 line++; |
361 } | 352 } |
362 ymask = 0x3FF; | 353 ymask = 0x3FF; |
363 ymin = 256; | 354 ymin = 256; |
364 height_mult = 16; | 355 height_mult = 16; |
425 uint8_t width = ((context->sprite_info_list[context->cur_slot].size >> 2) & 0x3) + 1; | 416 uint8_t width = ((context->sprite_info_list[context->cur_slot].size >> 2) & 0x3) + 1; |
426 //in pixels | 417 //in pixels |
427 uint8_t height = ((context->sprite_info_list[context->cur_slot].size & 0x3) + 1) * 8; | 418 uint8_t height = ((context->sprite_info_list[context->cur_slot].size & 0x3) + 1) * 8; |
428 if (context->double_res) { | 419 if (context->double_res) { |
429 line *= 2; | 420 line *= 2; |
430 if (context->framebuf != context->oddbuf) { | 421 if (context->flags2 & FLAG2_EVEN_FIELD) { |
431 line++; | 422 line++; |
432 } | 423 } |
433 height *= 2; | 424 height *= 2; |
434 } | 425 } |
435 uint16_t att_addr = ((context->regs[REG_SAT] & 0x7F) << 9) + context->sprite_info_list[context->cur_slot].index * 8 + 4; | 426 uint16_t att_addr = ((context->regs[REG_SAT] & 0x7F) << 9) + context->sprite_info_list[context->cur_slot].index * 8 + 4; |
671 void read_map_scroll(uint16_t column, uint16_t vsram_off, uint32_t line, uint16_t address, uint16_t hscroll_val, vdp_context * context) | 662 void read_map_scroll(uint16_t column, uint16_t vsram_off, uint32_t line, uint16_t address, uint16_t hscroll_val, vdp_context * context) |
672 { | 663 { |
673 uint16_t window_line_shift, v_offset_mask, vscroll_shift; | 664 uint16_t window_line_shift, v_offset_mask, vscroll_shift; |
674 if (context->double_res) { | 665 if (context->double_res) { |
675 line *= 2; | 666 line *= 2; |
676 if (context->framebuf != context->oddbuf) { | 667 if (context->flags2 & FLAG2_EVEN_FIELD) { |
677 line++; | 668 line++; |
678 } | 669 } |
679 window_line_shift = 4; | 670 window_line_shift = 4; |
680 v_offset_mask = 0xF; | 671 v_offset_mask = 0xF; |
681 vscroll_shift = 4; | 672 vscroll_shift = 4; |
884 uint8_t *sprite_buf, *plane_a, *plane_b; | 875 uint8_t *sprite_buf, *plane_a, *plane_b; |
885 int plane_a_off, plane_b_off; | 876 int plane_a_off, plane_b_off; |
886 if (col) | 877 if (col) |
887 { | 878 { |
888 col-=2; | 879 col-=2; |
889 dst = context->framebuf; | 880 dst = context->output + col * 8; |
890 dst += line * 320 + col * 8; | |
891 if (context->debug < 2) { | 881 if (context->debug < 2) { |
892 sprite_buf = context->linebuf + col * 8; | 882 sprite_buf = context->linebuf + col * 8; |
893 uint8_t a_src, src; | 883 uint8_t a_src, src; |
894 if (context->flags & FLAG_WINDOW) { | 884 if (context->flags & FLAG_WINDOW) { |
895 plane_a_off = context->buf_a_off; | 885 plane_a_off = context->buf_a_off; |
1040 context->vcounter = 0x1CA; | 1030 context->vcounter = 0x1CA; |
1041 } | 1031 } |
1042 } else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) { | 1032 } else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) { |
1043 context->vcounter = 0x1E5; | 1033 context->vcounter = 0x1E5; |
1044 } | 1034 } |
1045 | 1035 uint32_t inactive_start = (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START); |
1046 if (context->vcounter > (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) { | 1036 if (!headless) { |
1037 if (!context->vcounter && !context->output) { | |
1038 context->output = render_get_framebuffer(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD, &context->output_pitch); | |
1039 context->h40_lines = 0; | |
1040 } else if (context->vcounter == inactive_start) { //TODO: Change this once border emulation is added | |
1041 context->output = NULL; | |
1042 render_framebuffer_updated(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN: FRAMEBUFFER_ODD, context->h40_lines > inactive_start / 2 ? 320 : 256); | |
1043 if (context->double_res) { | |
1044 context->flags2 ^= FLAG2_EVEN_FIELD; | |
1045 } | |
1046 } else if (context->output) { | |
1047 context->output = (uint32_t *)(((char *)context->output) + context->output_pitch); | |
1048 if (context->regs[REG_MODE_4] & BIT_H40) { | |
1049 context->h40_lines++; | |
1050 } | |
1051 } | |
1052 } | |
1053 | |
1054 if (context->vcounter > inactive_start) { | |
1047 context->hint_counter = context->regs[REG_HINT]; | 1055 context->hint_counter = context->regs[REG_HINT]; |
1048 } else if (context->hint_counter) { | 1056 } else if (context->hint_counter) { |
1049 context->hint_counter--; | 1057 context->hint_counter--; |
1050 } else { | 1058 } else { |
1051 context->flags2 |= FLAG2_HINT_PENDING; | 1059 context->flags2 |= FLAG2_HINT_PENDING; |
1457 void check_render_bg(vdp_context * context, int32_t line, uint32_t slot) | 1465 void check_render_bg(vdp_context * context, int32_t line, uint32_t slot) |
1458 { | 1466 { |
1459 int starti = -1; | 1467 int starti = -1; |
1460 if (context->regs[REG_MODE_4] & BIT_H40) { | 1468 if (context->regs[REG_MODE_4] & BIT_H40) { |
1461 if (slot >= 12 && slot < 172) { | 1469 if (slot >= 12 && slot < 172) { |
1462 uint32_t x = (slot-12)*2; | 1470 starti = (slot-12)*2; |
1463 starti = line * 320 + x; | |
1464 } | 1471 } |
1465 } else { | 1472 } else { |
1466 if (slot >= 11 && slot < 139) { | 1473 if (slot >= 11 && slot < 139) { |
1467 uint32_t x = (slot-11)*2; | 1474 starti = (slot-11)*2; |
1468 starti = line * 320 + x; | |
1469 } | 1475 } |
1470 } | 1476 } |
1471 if (starti >= 0) { | 1477 if (starti >= 0) { |
1472 uint32_t color = context->colors[context->regs[REG_BG_COLOR]]; | 1478 uint32_t color = context->colors[context->regs[REG_BG_COLOR]]; |
1473 uint32_t * start = context->framebuf; | 1479 uint32_t * start = context->output + starti; |
1474 start += starti; | |
1475 for (int i = 0; i < 2; i++) { | 1480 for (int i = 0; i < 2; i++) { |
1476 *(start++) = color; | 1481 *(start++) = color; |
1477 } | 1482 } |
1478 } | 1483 } |
1479 } | 1484 } |
1648 }*/ | 1653 }*/ |
1649 context->regs[reg] = value; | 1654 context->regs[reg] = value; |
1650 if (reg == REG_MODE_4) { | 1655 if (reg == REG_MODE_4) { |
1651 context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES); | 1656 context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES); |
1652 if (!context->double_res) { | 1657 if (!context->double_res) { |
1653 context->framebuf = context->oddbuf; | 1658 context->flags &= FLAG2_EVEN_FIELD; |
1654 } | 1659 } |
1655 } | 1660 } |
1656 context->cd &= 0x3C; | 1661 context->cd &= 0x3C; |
1657 } | 1662 } |
1658 } else { | 1663 } else { |
1726 } | 1731 } |
1727 if (context->flags2 & FLAG2_SPRITE_COLLIDE) { | 1732 if (context->flags2 & FLAG2_SPRITE_COLLIDE) { |
1728 value |= 0x20; | 1733 value |= 0x20; |
1729 context->flags2 &= ~FLAG2_SPRITE_COLLIDE; | 1734 context->flags2 &= ~FLAG2_SPRITE_COLLIDE; |
1730 } | 1735 } |
1731 if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && context->framebuf == context->oddbuf) { | 1736 if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && !(context->flags2 & FLAG2_EVEN_FIELD)) { |
1732 value |= 0x10; | 1737 value |= 0x10; |
1733 } | 1738 } |
1734 uint32_t line= context->vcounter; | 1739 uint32_t line= context->vcounter; |
1735 uint32_t slot = context->hslot; | 1740 uint32_t slot = context->hslot; |
1736 uint32_t inactive_start = (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START); | 1741 uint32_t inactive_start = (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START); |
1765 context->flags2 &= ~FLAG2_READ_PENDING; | 1770 context->flags2 &= ~FLAG2_READ_PENDING; |
1766 } | 1771 } |
1767 if (context->cd & 1) { | 1772 if (context->cd & 1) { |
1768 warning("Read from VDP data port while writes are configured, CPU is now frozen. VDP Address: %X, CD: %X\n", context->address, context->cd); | 1773 warning("Read from VDP data port while writes are configured, CPU is now frozen. VDP Address: %X, CD: %X\n", context->address, context->cd); |
1769 } | 1774 } |
1770 uint32_t old_frame = context->frame; | |
1771 while (!(context->flags & FLAG_READ_FETCHED)) { | 1775 while (!(context->flags & FLAG_READ_FETCHED)) { |
1772 vdp_run_context(context, context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20)); | 1776 vdp_run_context(context, context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20)); |
1773 if (context->frame != old_frame) { | |
1774 if (!headless) { | |
1775 //TODO: make pushing frames to renderer automatic so this doesn't need to be here | |
1776 wait_render_frame(context, 0); | |
1777 } | |
1778 old_frame = context->frame; | |
1779 } | |
1780 } | 1777 } |
1781 context->flags &= ~FLAG_READ_FETCHED; | 1778 context->flags &= ~FLAG_READ_FETCHED; |
1782 //Should this happen after the prefetch or after the read? | 1779 //Should this happen after the prefetch or after the read? |
1783 context->address += context->regs[REG_AUTOINC]; | 1780 context->address += context->regs[REG_AUTOINC]; |
1784 return context->prefetch; | 1781 return context->prefetch; |