Mercurial > repos > blastem
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 } |