comparison vdp.c @ 1631:c4ba3177b72d

WIP new VDP plane debug view and support for detached VDP debug views generally
author Michael Pavone <pavone@retrodev.com>
date Sun, 04 Nov 2018 22:51:50 -0800
parents 079e5b9d59ce
children cc699c4966b1
comparison
equal deleted inserted replaced
1630:5aa0c3c43b97 1631:c4ba3177b72d
1718 context->pending_hint_start = context->cycles; 1718 context->pending_hint_start = context->cycles;
1719 context->hint_counter = context->regs[REG_HINT]; 1719 context->hint_counter = context->regs[REG_HINT];
1720 } 1720 }
1721 } 1721 }
1722 1722
1723 static void vdp_update_per_frame_debug(vdp_context *context)
1724 {
1725 if (context->enabled_debuggers & (1 << VDP_DEBUG_PLANE)) {
1726 uint32_t pitch;
1727 uint32_t *fb = render_get_framebuffer(context->debug_fb_indices[VDP_DEBUG_PLANE], &pitch);
1728 uint16_t hscroll_mask;
1729 uint16_t v_mul;
1730 uint16_t vscroll_mask = 0x1F | (context->regs[REG_SCROLL] & 0x30) << 1;
1731 switch(context->regs[REG_SCROLL] & 0x3)
1732 {
1733 case 0:
1734 hscroll_mask = 0x1F;
1735 v_mul = 64;
1736 break;
1737 case 0x1:
1738 hscroll_mask = 0x3F;
1739 v_mul = 128;
1740 break;
1741 case 0x2:
1742 //TODO: Verify this behavior
1743 hscroll_mask = 0x1F;
1744 v_mul = 0;
1745 break;
1746 case 0x3:
1747 hscroll_mask = 0x7F;
1748 v_mul = 256;
1749 break;
1750 }
1751 uint16_t table_address;
1752 switch(context->debug_modes[VDP_DEBUG_PLANE] % 3)
1753 {
1754 case 0:
1755 table_address = context->regs[REG_SCROLL_A] << 10 & 0xE000;
1756 break;
1757 case 1:
1758 table_address = context->regs[REG_SCROLL_B] << 13 & 0xE000;
1759 break;
1760 case 2:
1761 table_address = context->regs[REG_WINDOW] << 10;
1762 if (context->regs[REG_MODE_4] & BIT_H40) {
1763 table_address &= 0xF000;
1764 v_mul = 128;
1765 hscroll_mask = 0x3F;
1766 } else {
1767 table_address &= 0xF800;
1768 v_mul = 64;
1769 hscroll_mask = 0x1F;
1770 }
1771 vscroll_mask = 0x1F;
1772 break;
1773 }
1774 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR & 0x3F]];
1775 for (uint16_t row = 0; row < 128; row++)
1776 {
1777 uint16_t row_address = table_address + (row & vscroll_mask) * v_mul;
1778 for (uint16_t col = 0; col < 128; col++)
1779 {
1780 uint16_t address = row_address + (col & hscroll_mask) * 2;
1781 //pccv hnnn nnnn nnnn
1782 //
1783 uint16_t entry = context->vdpmem[address] << 8 | context->vdpmem[address + 1];
1784 uint8_t pal = entry >> 9 & 0x30;
1785
1786 uint32_t *dst = fb + (row * pitch * 8 / sizeof(uint32_t)) + col * 8;
1787 address = (entry & 0x7FF) * 32;
1788 int y_diff = 4;
1789 if (entry & 0x1000) {
1790 y_diff = -4;
1791 address += 7 * 4;
1792 }
1793 int x_diff = 1;
1794 if (entry & 0x800) {
1795 x_diff = -1;
1796 address += 3;
1797 }
1798 for (int y = 0; y < 8; y++)
1799 {
1800 uint16_t trow_address = address;
1801 uint32_t *row_dst = dst;
1802 for (int x = 0; x < 4; x++)
1803 {
1804 uint8_t byte = context->vdpmem[trow_address];
1805 trow_address += x_diff;
1806 uint8_t left, right;
1807 if (x_diff > 0) {
1808 left = byte >> 4;
1809 right = byte & 0xF;
1810 } else {
1811 left = byte & 0xF;
1812 right = byte >> 4;
1813 }
1814 *(row_dst++) = left ? context->colors[left|pal] : bg_color;
1815 *(row_dst++) = right ? context->colors[right|pal] : bg_color;
1816 }
1817 address += y_diff;
1818 dst += pitch / sizeof(uint32_t);
1819 }
1820 }
1821 }
1822 render_framebuffer_updated(context->debug_fb_indices[VDP_DEBUG_PLANE], 1024);
1823 }
1824 }
1825
1723 void vdp_force_update_framebuffer(vdp_context *context) 1826 void vdp_force_update_framebuffer(vdp_context *context)
1724 { 1827 {
1725 uint16_t lines_max = (context->flags2 & FLAG2_REGION_PAL) 1828 uint16_t lines_max = (context->flags2 & FLAG2_REGION_PAL)
1726 ? 240 + BORDER_TOP_V30_PAL + BORDER_BOT_V30_PAL 1829 ? 240 + BORDER_TOP_V30_PAL + BORDER_BOT_V30_PAL
1727 : 224 + BORDER_TOP_V28 + BORDER_BOT_V28; 1830 : 224 + BORDER_TOP_V28 + BORDER_BOT_V28;
1732 0, 1835 0,
1733 to_fill * context->output_pitch 1836 to_fill * context->output_pitch
1734 ); 1837 );
1735 render_framebuffer_updated(context->cur_buffer, context->h40_lines > context->output_lines / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER)); 1838 render_framebuffer_updated(context->cur_buffer, context->h40_lines > context->output_lines / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER));
1736 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch); 1839 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch);
1840 vdp_update_per_frame_debug(context);
1737 } 1841 }
1738 1842
1739 static void advance_output_line(vdp_context *context) 1843 static void advance_output_line(vdp_context *context)
1740 { 1844 {
1741 if (headless) { 1845 if (headless) {
1750 1854
1751 if (context->output_lines == lines_max) { 1855 if (context->output_lines == lines_max) {
1752 render_framebuffer_updated(context->cur_buffer, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER)); 1856 render_framebuffer_updated(context->cur_buffer, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER));
1753 context->cur_buffer = context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD; 1857 context->cur_buffer = context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD;
1754 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch); 1858 context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch);
1859 vdp_update_per_frame_debug(context);
1755 context->h40_lines = 0; 1860 context->h40_lines = 0;
1756 context->frame++; 1861 context->frame++;
1757 context->output_lines = 0; 1862 context->output_lines = 0;
1758 } 1863 }
1759 uint32_t output_line = context->vcounter; 1864 uint32_t output_line = context->vcounter;
3738 context->cycles = load_int32(buf); 3843 context->cycles = load_int32(buf);
3739 context->pending_vint_start = load_int32(buf); 3844 context->pending_vint_start = load_int32(buf);
3740 context->pending_hint_start = load_int32(buf); 3845 context->pending_hint_start = load_int32(buf);
3741 update_video_params(context); 3846 update_video_params(context);
3742 } 3847 }
3848
3849 void vdp_toggle_debug_view(vdp_context *context, uint8_t debug_type)
3850 {
3851 if (context->enabled_debuggers & 1 << debug_type) {
3852 //TODO: implement me
3853 } else {
3854 char *caption;
3855 switch(debug_type)
3856 {
3857 case VDP_DEBUG_PLANE:
3858 caption = "BlastEm - VDP Plane Debugger";
3859 break;
3860 default:
3861 return;
3862 }
3863 context->debug_fb_indices[debug_type] = render_create_window(caption, 1024, 1024);
3864 if (context->debug_fb_indices[debug_type]) {
3865 context->enabled_debuggers |= 1 << debug_type;
3866 }
3867 }
3868 }
3869
3870 void vdp_inc_debug_mode(vdp_context *context)
3871 {
3872 uint8_t active = render_get_active_framebuffer();
3873 if (active < FRAMEBUFFER_USER_START) {
3874 context->debug++;
3875 if (context->debug == 7) {
3876 context->debug = 0;
3877 }
3878 return;
3879 }
3880 for (int i = 0; i < VDP_NUM_DEBUG_TYPES; i++)
3881 {
3882 if (context->enabled_debuggers & (1 << i) && context->debug_fb_indices[i] == active) {
3883 context->debug_modes[i]++;
3884 return;
3885 }
3886 }
3887 }