Mercurial > repos > blastem
comparison vdp.c @ 1160:5f119fe935e7
Update H32 and Mode 4 mappings based on latest tests
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 08 Jan 2017 10:46:32 -0800 |
parents | d5dda22ae6b4 |
children | c2210d586950 |
comparison
equal
deleted
inserted
replaced
1159:8519b54f9413 | 1160:5f119fe935e7 |
---|---|
25 | 25 |
26 #define MCLKS_SLOT_H40 16 | 26 #define MCLKS_SLOT_H40 16 |
27 #define MCLKS_SLOT_H32 20 | 27 #define MCLKS_SLOT_H32 20 |
28 #define VINT_SLOT_H40 255 //21 slots before HSYNC, 16 during, 10 after | 28 #define VINT_SLOT_H40 255 //21 slots before HSYNC, 16 during, 10 after |
29 #define VINT_SLOT_H32 255 //old value was 23, but recent tests suggest the actual value is close to the H40 one | 29 #define VINT_SLOT_H32 255 //old value was 23, but recent tests suggest the actual value is close to the H40 one |
30 #define HSYNC_SLOT_H40 228 | 30 #define VINT_SLOT_MODE4 4 |
31 #define HSYNC_SLOT_H40 230 | |
31 #define HSYNC_END_H40 (HSYNC_SLOT_H40+17) | 32 #define HSYNC_END_H40 (HSYNC_SLOT_H40+17) |
32 #define HSYNC_END_H32 (33 * MCLKS_SLOT_H32) | |
33 #define HBLANK_START_H40 178 //should be 179 according to Nemesis, but 178 seems to fit slightly better with my test ROM results | 33 #define HBLANK_START_H40 178 //should be 179 according to Nemesis, but 178 seems to fit slightly better with my test ROM results |
34 #define HBLANK_END_H40 0 //should be 5.5 according to Nemesis, but 0 seems to fit better with my test ROM results | 34 #define HBLANK_END_H40 0 //should be 5.5 according to Nemesis, but 0 seems to fit better with my test ROM results |
35 #define HBLANK_START_H32 233 //should be 147 according to Nemesis which is very different from my test ROM result | 35 #define HBLANK_START_H32 233 //should be 147 according to Nemesis which is very different from my test ROM result |
36 #define HBLANK_END_H32 0 //should be 5 according to Nemesis, but 0 seems to fit better with my test ROM results | 36 #define HBLANK_END_H32 0 //should be 5 according to Nemesis, but 0 seems to fit better with my test ROM results |
37 #define LINE_CHANGE_H40 165 | 37 #define LINE_CHANGE_H40 165 |
38 #define LINE_CHANGE_H32 132 | 38 #define LINE_CHANGE_H32 132 |
39 #define LINE_CHANGE_MODE4 249 | |
39 #define VBLANK_START_H40 (LINE_CHANGE_H40+2) | 40 #define VBLANK_START_H40 (LINE_CHANGE_H40+2) |
40 #define VBLANK_START_H32 (LINE_CHANGE_H32+2) | 41 #define VBLANK_START_H32 (LINE_CHANGE_H32+2) |
41 #define FIFO_LATENCY 3 | 42 #define FIFO_LATENCY 3 |
42 | 43 |
43 static int32_t color_map[1 << 12]; | 44 static int32_t color_map[1 << 12]; |
1526 context->hslot++;\ | 1527 context->hslot++;\ |
1527 }\ | 1528 }\ |
1528 context->cycles += slot_cycles;\ | 1529 context->cycles += slot_cycles;\ |
1529 CHECK_ONLY | 1530 CHECK_ONLY |
1530 | 1531 |
1532 #define MODE4_CHECK_SLOT_LINE(slot) \ | |
1533 if ((slot) == LINE_CHANGE_MODE4) {\ | |
1534 vdp_advance_line(context);\ | |
1535 if (context->vcounter == 192) {\ | |
1536 return;\ | |
1537 }\ | |
1538 }\ | |
1539 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ | |
1540 if ((slot) == 147) {\ | |
1541 context->hslot = 233;\ | |
1542 } else {\ | |
1543 context->hslot++;\ | |
1544 }\ | |
1545 context->cycles += slot_cycles;\ | |
1546 CHECK_ONLY | |
1547 | |
1548 | |
1531 #define SPRITE_RENDER_H32_MODE4(slot) \ | 1549 #define SPRITE_RENDER_H32_MODE4(slot) \ |
1532 case slot:\ | 1550 case slot:\ |
1533 read_sprite_x_mode4(context);\ | 1551 read_sprite_x_mode4(context);\ |
1534 CHECK_LIMIT\ | 1552 MODE4_CHECK_SLOT_LINE(slot)\ |
1535 case (slot+1):\ | 1553 case (slot+1):\ |
1536 read_sprite_x_mode4(context);\ | 1554 read_sprite_x_mode4(context);\ |
1537 CHECK_LIMIT\ | 1555 MODE4_CHECK_SLOT_LINE(slot+1)\ |
1538 case (slot+2):\ | 1556 case (slot+2):\ |
1539 fetch_sprite_cells_mode4(context);\ | 1557 fetch_sprite_cells_mode4(context);\ |
1540 CHECK_LIMIT\ | 1558 MODE4_CHECK_SLOT_LINE(slot+2)\ |
1541 case (slot+3):\ | 1559 case (slot+3):\ |
1542 render_sprite_cells_mode4(context);\ | 1560 render_sprite_cells_mode4(context);\ |
1543 CHECK_LIMIT\ | 1561 MODE4_CHECK_SLOT_LINE(slot+3)\ |
1544 case (slot+4):\ | 1562 case (slot+4):\ |
1545 fetch_sprite_cells_mode4(context);\ | 1563 fetch_sprite_cells_mode4(context);\ |
1546 CHECK_LIMIT\ | 1564 MODE4_CHECK_SLOT_LINE(slot+4)\ |
1547 case (slot+5):\ | 1565 case (slot+5):\ |
1548 render_sprite_cells_mode4(context);\ | 1566 render_sprite_cells_mode4(context);\ |
1549 CHECK_LIMIT | 1567 MODE4_CHECK_SLOT_LINE(slot+5) |
1550 | 1568 |
1551 static void vdp_h40(vdp_context * context, uint32_t target_cycles) | 1569 static void vdp_h40(vdp_context * context, uint32_t target_cycles) |
1552 { | 1570 { |
1553 uint16_t address; | 1571 uint16_t address; |
1554 uint32_t mask; | 1572 uint32_t mask; |
1723 uint32_t const slot_cycles = MCLKS_SLOT_H32; | 1741 uint32_t const slot_cycles = MCLKS_SLOT_H32; |
1724 switch(context->hslot) | 1742 switch(context->hslot) |
1725 { | 1743 { |
1726 for (;;) | 1744 for (;;) |
1727 { | 1745 { |
1746 case 133: | |
1747 if (context->vcounter == 0x1FF) { | |
1748 external_slot(context); | |
1749 } else { | |
1750 render_sprite_cells(context); | |
1751 } | |
1752 CHECK_LIMIT | |
1753 case 134: | |
1754 if (context->vcounter == 0x1FF) { | |
1755 external_slot(context); | |
1756 } else { | |
1757 render_sprite_cells(context); | |
1758 } | |
1759 CHECK_LIMIT | |
1728 //sprite attribute table scan starts | 1760 //sprite attribute table scan starts |
1729 case 132: | 1761 case 135: //FIXME - Here |
1730 context->sprite_index = 0x80; | 1762 context->sprite_index = 0x80; |
1731 context->slot_counter = MAX_SPRITES_LINE_H32; | 1763 context->slot_counter = MAX_SPRITES_LINE_H32; |
1732 render_sprite_cells( context); | 1764 render_sprite_cells( context); |
1733 scan_sprite_table(context->vcounter, context); | 1765 scan_sprite_table(context->vcounter, context); |
1734 CHECK_LIMIT | 1766 CHECK_LIMIT |
1735 SPRITE_RENDER_H32(133) | |
1736 SPRITE_RENDER_H32(134) | |
1737 SPRITE_RENDER_H32(135) | |
1738 SPRITE_RENDER_H32(136) | 1767 SPRITE_RENDER_H32(136) |
1739 SPRITE_RENDER_H32(137) | 1768 SPRITE_RENDER_H32(137) |
1740 SPRITE_RENDER_H32(138) | 1769 SPRITE_RENDER_H32(138) |
1741 SPRITE_RENDER_H32(139) | 1770 SPRITE_RENDER_H32(139) |
1742 SPRITE_RENDER_H32(140) | 1771 SPRITE_RENDER_H32(140) |
1743 SPRITE_RENDER_H32(141) | 1772 SPRITE_RENDER_H32(141) |
1744 case 142: | 1773 SPRITE_RENDER_H32(142) |
1745 external_slot(context); | |
1746 CHECK_LIMIT | |
1747 SPRITE_RENDER_H32(143) | 1774 SPRITE_RENDER_H32(143) |
1748 SPRITE_RENDER_H32(144) | 1775 SPRITE_RENDER_H32(144) |
1749 SPRITE_RENDER_H32(145) | 1776 case 145: |
1777 external_slot(context); | |
1778 CHECK_LIMIT | |
1750 SPRITE_RENDER_H32(146) | 1779 SPRITE_RENDER_H32(146) |
1751 SPRITE_RENDER_H32(147) | 1780 SPRITE_RENDER_H32(147) |
1752 //HSYNC start | |
1753 SPRITE_RENDER_H32(233) | 1781 SPRITE_RENDER_H32(233) |
1754 SPRITE_RENDER_H32(234) | 1782 SPRITE_RENDER_H32(234) |
1755 SPRITE_RENDER_H32(235) | 1783 SPRITE_RENDER_H32(235) |
1784 //HSYNC start | |
1756 SPRITE_RENDER_H32(236) | 1785 SPRITE_RENDER_H32(236) |
1757 SPRITE_RENDER_H32(237) | 1786 SPRITE_RENDER_H32(237) |
1758 SPRITE_RENDER_H32(238) | 1787 SPRITE_RENDER_H32(238) |
1759 SPRITE_RENDER_H32(239) | 1788 SPRITE_RENDER_H32(239) |
1760 case 240: | 1789 SPRITE_RENDER_H32(240) |
1790 SPRITE_RENDER_H32(241) | |
1791 SPRITE_RENDER_H32(242) | |
1792 case 243: | |
1761 external_slot(context); | 1793 external_slot(context); |
1762 CHECK_LIMIT | 1794 CHECK_LIMIT |
1763 case 241: | 1795 case 244: |
1764 address = (context->regs[REG_HSCROLL] & 0x3F) << 10; | 1796 address = (context->regs[REG_HSCROLL] & 0x3F) << 10; |
1765 mask = 0; | 1797 mask = 0; |
1766 if (context->regs[REG_MODE_3] & 0x2) { | 1798 if (context->regs[REG_MODE_3] & 0x2) { |
1767 mask |= 0xF8; | 1799 mask |= 0xF8; |
1768 } | 1800 } |
1772 address += (context->vcounter & mask) * 4; | 1804 address += (context->vcounter & mask) * 4; |
1773 context->hscroll_a = context->vdpmem[address] << 8 | context->vdpmem[address+1]; | 1805 context->hscroll_a = context->vdpmem[address] << 8 | context->vdpmem[address+1]; |
1774 context->hscroll_b = context->vdpmem[address+2] << 8 | context->vdpmem[address+3]; | 1806 context->hscroll_b = context->vdpmem[address+2] << 8 | context->vdpmem[address+3]; |
1775 //printf("%d: HScroll A: %d, HScroll B: %d\n", context->vcounter, context->hscroll_a, context->hscroll_b); | 1807 //printf("%d: HScroll A: %d, HScroll B: %d\n", context->vcounter, context->hscroll_a, context->hscroll_b); |
1776 CHECK_LIMIT | 1808 CHECK_LIMIT |
1777 SPRITE_RENDER_H32(242) | |
1778 SPRITE_RENDER_H32(243) | |
1779 SPRITE_RENDER_H32(244) | |
1780 SPRITE_RENDER_H32(245) | 1809 SPRITE_RENDER_H32(245) |
1810 SPRITE_RENDER_H32(246) | |
1811 SPRITE_RENDER_H32(247) | |
1812 SPRITE_RENDER_H32(248) | |
1781 //!HSYNC high | 1813 //!HSYNC high |
1782 case 246: | 1814 case 249: |
1783 read_map_scroll_a(0, context->vcounter, context); | 1815 read_map_scroll_a(0, context->vcounter, context); |
1784 CHECK_LIMIT | 1816 CHECK_LIMIT |
1785 SPRITE_RENDER_H32(247) | 1817 SPRITE_RENDER_H32(250) |
1786 case 248: | 1818 case 251: |
1787 render_map_1(context); | 1819 render_map_1(context); |
1788 scan_sprite_table(context->vcounter, context);//Just a guess | 1820 scan_sprite_table(context->vcounter, context);//Just a guess |
1789 CHECK_LIMIT | 1821 CHECK_LIMIT |
1790 case 249: | 1822 case 252: |
1791 render_map_2(context); | 1823 render_map_2(context); |
1792 scan_sprite_table(context->vcounter, context);//Just a guess | 1824 scan_sprite_table(context->vcounter, context);//Just a guess |
1793 CHECK_LIMIT | 1825 CHECK_LIMIT |
1794 case 250: | 1826 case 253: |
1795 read_map_scroll_b(0, context->vcounter, context); | 1827 read_map_scroll_b(0, context->vcounter, context); |
1796 CHECK_LIMIT | 1828 CHECK_LIMIT |
1797 case 251: | 1829 case 254: |
1798 render_sprite_cells(context); | 1830 render_sprite_cells(context); |
1799 scan_sprite_table(context->vcounter, context); | 1831 scan_sprite_table(context->vcounter, context); |
1800 CHECK_LIMIT | 1832 CHECK_LIMIT |
1801 case 252: | 1833 case 255: |
1802 render_map_3(context); | 1834 render_map_3(context); |
1803 scan_sprite_table(context->vcounter, context);//Just a guess | 1835 scan_sprite_table(context->vcounter, context);//Just a guess |
1804 CHECK_LIMIT | 1836 CHECK_LIMIT |
1805 case 253: | 1837 case 0: |
1806 render_map_output(context->vcounter, 0, context); | 1838 render_map_output(context->vcounter, 0, context); |
1807 scan_sprite_table(context->vcounter, context);//Just a guess | 1839 scan_sprite_table(context->vcounter, context);//Just a guess |
1808 //reverse context slot counter so it counts the number of sprite slots | 1840 //reverse context slot counter so it counts the number of sprite slots |
1809 //filled rather than the number of available slots | 1841 //filled rather than the number of available slots |
1810 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; | 1842 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; |
1811 context->cur_slot = MAX_SPRITES_LINE_H32-1; | 1843 context->cur_slot = MAX_SPRITES_LINE_H32-1; |
1812 context->sprite_draws = MAX_DRAWS_H32; | 1844 context->sprite_draws = MAX_DRAWS_H32; |
1813 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); | 1845 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); |
1814 CHECK_LIMIT | 1846 CHECK_LIMIT |
1815 COLUMN_RENDER_BLOCK(2, 254) | 1847 COLUMN_RENDER_BLOCK(2, 1) |
1816 COLUMN_RENDER_BLOCK(4, 6) | 1848 COLUMN_RENDER_BLOCK(4, 9) |
1817 COLUMN_RENDER_BLOCK(6, 14) | 1849 COLUMN_RENDER_BLOCK(6, 17) |
1818 COLUMN_RENDER_BLOCK_REFRESH(8, 22) | 1850 COLUMN_RENDER_BLOCK_REFRESH(8, 25) |
1819 COLUMN_RENDER_BLOCK(10, 30) | 1851 COLUMN_RENDER_BLOCK(10, 33) |
1820 COLUMN_RENDER_BLOCK(12, 38) | 1852 COLUMN_RENDER_BLOCK(12, 41) |
1821 COLUMN_RENDER_BLOCK(14, 46) | 1853 COLUMN_RENDER_BLOCK(14, 49) |
1822 COLUMN_RENDER_BLOCK_REFRESH(16, 54) | 1854 COLUMN_RENDER_BLOCK_REFRESH(16, 57) |
1823 COLUMN_RENDER_BLOCK(18, 62) | 1855 COLUMN_RENDER_BLOCK(18, 65) |
1824 COLUMN_RENDER_BLOCK(20, 70) | 1856 COLUMN_RENDER_BLOCK(20, 73) |
1825 COLUMN_RENDER_BLOCK(22, 78) | 1857 COLUMN_RENDER_BLOCK(22, 81) |
1826 COLUMN_RENDER_BLOCK_REFRESH(24, 86) | 1858 COLUMN_RENDER_BLOCK_REFRESH(24, 89) |
1827 COLUMN_RENDER_BLOCK(26, 94) | 1859 COLUMN_RENDER_BLOCK(26, 97) |
1828 COLUMN_RENDER_BLOCK(28, 102) | 1860 COLUMN_RENDER_BLOCK(28, 105) |
1829 COLUMN_RENDER_BLOCK(30, 110) | 1861 COLUMN_RENDER_BLOCK(30, 113) |
1830 COLUMN_RENDER_BLOCK_REFRESH(32, 118) | 1862 COLUMN_RENDER_BLOCK_REFRESH(32, 121) |
1831 case 126: | 1863 case 129: |
1832 external_slot(context); | 1864 external_slot(context); |
1833 CHECK_LIMIT | 1865 CHECK_LIMIT |
1834 case 127: | 1866 case 130: |
1835 external_slot(context); | 1867 external_slot(context); |
1836 CHECK_LIMIT | 1868 CHECK_LIMIT |
1837 //sprite render to line buffer starts | 1869 //sprite render to line buffer starts |
1838 case 128: | 1870 case 131: |
1839 context->cur_slot = MAX_DRAWS_H32-1; | 1871 context->cur_slot = MAX_DRAWS_H32-1; |
1840 memset(context->linebuf, 0, LINEBUF_SIZE); | 1872 memset(context->linebuf, 0, LINEBUF_SIZE); |
1841 render_sprite_cells(context); | 1873 render_sprite_cells(context); |
1842 CHECK_LIMIT | 1874 CHECK_LIMIT |
1843 case 129: | 1875 case 132: |
1844 render_sprite_cells(context); | |
1845 CHECK_LIMIT | |
1846 case 130: | |
1847 render_sprite_cells(context); | |
1848 CHECK_LIMIT | |
1849 case 131: | |
1850 render_sprite_cells(context); | 1876 render_sprite_cells(context); |
1851 vdp_advance_line(context); | 1877 vdp_advance_line(context); |
1852 if (context->vcounter == (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) { | 1878 if (context->vcounter == (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) { |
1853 context->hslot++; | 1879 context->hslot++; |
1854 context->cycles += slot_cycles; | 1880 context->cycles += slot_cycles; |
1869 uint32_t const slot_cycles = MCLKS_SLOT_H32; | 1895 uint32_t const slot_cycles = MCLKS_SLOT_H32; |
1870 switch(context->hslot) | 1896 switch(context->hslot) |
1871 { | 1897 { |
1872 for (;;) | 1898 for (;;) |
1873 { | 1899 { |
1874 case 132: | 1900 //sprite rendering starts |
1901 SPRITE_RENDER_H32_MODE4(137) | |
1902 SPRITE_RENDER_H32_MODE4(143) | |
1903 case 234: | |
1875 external_slot(context); | 1904 external_slot(context); |
1876 CHECK_LIMIT | 1905 CHECK_LIMIT |
1906 case 235: | |
1907 external_slot(context); | |
1908 CHECK_LIMIT | |
1909 //!HSYNC low | |
1910 case 236: | |
1911 external_slot(context); | |
1912 CHECK_LIMIT | |
1913 case 237: | |
1914 external_slot(context); | |
1915 CHECK_LIMIT | |
1916 case 238: | |
1917 external_slot(context); | |
1918 CHECK_LIMIT | |
1919 SPRITE_RENDER_H32_MODE4(239) | |
1920 SPRITE_RENDER_H32_MODE4(245) | |
1921 case 251: | |
1922 external_slot(context); | |
1923 CHECK_LIMIT | |
1924 case 252: | |
1925 external_slot(context); | |
1926 if (context->regs[REG_MODE_1] & BIT_HSCRL_LOCK && context->vcounter < 16) { | |
1927 context->hscroll_a = 0; | |
1928 } else { | |
1929 context->hscroll_a = context->regs[REG_X_SCROLL]; | |
1930 } | |
1931 CHECK_LIMIT | |
1932 case 253: | |
1933 context->sprite_index = 0; | |
1934 context->slot_counter = MAX_DRAWS_H32_MODE4; | |
1935 scan_sprite_table_mode4(context); | |
1936 CHECK_LIMIT | |
1937 case 254: | |
1938 scan_sprite_table_mode4(context); | |
1939 CHECK_LIMIT | |
1940 case 255: | |
1941 scan_sprite_table_mode4(context); | |
1942 CHECK_LIMIT | |
1943 case 0: | |
1944 scan_sprite_table_mode4(context); | |
1945 CHECK_LIMIT | |
1946 case 1: | |
1947 scan_sprite_table_mode4(context); | |
1948 CHECK_LIMIT | |
1949 case 2: | |
1950 scan_sprite_table_mode4(context); | |
1951 CHECK_LIMIT | |
1952 case 3: | |
1953 scan_sprite_table_mode4(context); | |
1954 CHECK_LIMIT | |
1955 case 4: | |
1956 scan_sprite_table_mode4(context); | |
1957 context->buf_a_off = 8; | |
1958 memset(context->tmp_buf_a, 0, 8); | |
1959 CHECK_LIMIT | |
1960 COLUMN_RENDER_BLOCK_MODE4(0, 5) | |
1961 COLUMN_RENDER_BLOCK_MODE4(1, 9) | |
1962 COLUMN_RENDER_BLOCK_MODE4(2, 13) | |
1963 COLUMN_RENDER_BLOCK_MODE4(3, 17) | |
1964 COLUMN_RENDER_BLOCK_MODE4(4, 21) | |
1965 COLUMN_RENDER_BLOCK_MODE4(5, 25) | |
1966 COLUMN_RENDER_BLOCK_MODE4(6, 29) | |
1967 COLUMN_RENDER_BLOCK_MODE4(7, 33) | |
1968 COLUMN_RENDER_BLOCK_MODE4(8, 37) | |
1969 COLUMN_RENDER_BLOCK_MODE4(9, 41) | |
1970 COLUMN_RENDER_BLOCK_MODE4(10, 45) | |
1971 COLUMN_RENDER_BLOCK_MODE4(11, 49) | |
1972 COLUMN_RENDER_BLOCK_MODE4(12, 53) | |
1973 COLUMN_RENDER_BLOCK_MODE4(13, 57) | |
1974 COLUMN_RENDER_BLOCK_MODE4(14, 61) | |
1975 COLUMN_RENDER_BLOCK_MODE4(15, 65) | |
1976 COLUMN_RENDER_BLOCK_MODE4(16, 69) | |
1977 COLUMN_RENDER_BLOCK_MODE4(17, 73) | |
1978 COLUMN_RENDER_BLOCK_MODE4(18, 77) | |
1979 COLUMN_RENDER_BLOCK_MODE4(19, 81) | |
1980 COLUMN_RENDER_BLOCK_MODE4(20, 85) | |
1981 COLUMN_RENDER_BLOCK_MODE4(21, 89) | |
1982 COLUMN_RENDER_BLOCK_MODE4(22, 93) | |
1983 COLUMN_RENDER_BLOCK_MODE4(23, 97) | |
1984 COLUMN_RENDER_BLOCK_MODE4(24, 101) | |
1985 COLUMN_RENDER_BLOCK_MODE4(25, 105) | |
1986 COLUMN_RENDER_BLOCK_MODE4(26, 109) | |
1987 COLUMN_RENDER_BLOCK_MODE4(27, 113) | |
1988 COLUMN_RENDER_BLOCK_MODE4(28, 117) | |
1989 COLUMN_RENDER_BLOCK_MODE4(29, 121) | |
1990 COLUMN_RENDER_BLOCK_MODE4(30, 125) | |
1991 COLUMN_RENDER_BLOCK_MODE4(31, 129) | |
1877 case 133: | 1992 case 133: |
1993 external_slot(context); | |
1994 CHECK_LIMIT | |
1995 case 134: | |
1996 external_slot(context); | |
1997 CHECK_LIMIT | |
1998 case 135: | |
1999 external_slot(context); | |
2000 CHECK_LIMIT | |
2001 case 136: | |
1878 external_slot(context); | 2002 external_slot(context); |
1879 //set things up for sprite rendering in the next slot | 2003 //set things up for sprite rendering in the next slot |
1880 memset(context->linebuf, 0, LINEBUF_SIZE); | 2004 memset(context->linebuf, 0, LINEBUF_SIZE); |
1881 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; | 2005 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; |
1882 context->sprite_draws = MAX_DRAWS_H32_MODE4; | 2006 context->sprite_draws = MAX_DRAWS_H32_MODE4; |
1883 CHECK_LIMIT | |
1884 //sprite rendering starts | |
1885 SPRITE_RENDER_H32_MODE4(134) | |
1886 SPRITE_RENDER_H32_MODE4(140) | |
1887 case 146: | |
1888 external_slot(context); | |
1889 CHECK_LIMIT | |
1890 case 147: | |
1891 external_slot(context); | |
1892 if (context->flags & FLAG_DMA_RUN) { | |
1893 run_dma_src(context, -1); | |
1894 } | |
1895 context->hslot = 233; | |
1896 context->cycles += slot_cycles; | |
1897 CHECK_ONLY | |
1898 //!HSYNC low | |
1899 case 233: | |
1900 external_slot(context); | |
1901 CHECK_LIMIT | |
1902 case 234: | |
1903 external_slot(context); | |
1904 CHECK_LIMIT | |
1905 case 235: | |
1906 external_slot(context); | |
1907 CHECK_LIMIT | |
1908 SPRITE_RENDER_H32_MODE4(236) | |
1909 SPRITE_RENDER_H32_MODE4(242) | |
1910 case 248: | |
1911 external_slot(context); | |
1912 CHECK_LIMIT | |
1913 case 249: | |
1914 external_slot(context); | |
1915 if (context->regs[REG_MODE_1] & BIT_HSCRL_LOCK && context->vcounter < 16) { | |
1916 context->hscroll_a = 0; | |
1917 } else { | |
1918 context->hscroll_a = context->regs[REG_X_SCROLL]; | |
1919 } | |
1920 CHECK_LIMIT | |
1921 case 250: | |
1922 context->sprite_index = 0; | |
1923 context->slot_counter = MAX_DRAWS_H32_MODE4; | |
1924 scan_sprite_table_mode4(context); | |
1925 CHECK_LIMIT | |
1926 case 251: | |
1927 scan_sprite_table_mode4(context); | |
1928 CHECK_LIMIT | |
1929 case 252: | |
1930 scan_sprite_table_mode4(context); | |
1931 CHECK_LIMIT | |
1932 case 253: | |
1933 scan_sprite_table_mode4(context); | |
1934 CHECK_LIMIT | |
1935 case 254: | |
1936 scan_sprite_table_mode4(context); | |
1937 CHECK_LIMIT | |
1938 case 255: | |
1939 scan_sprite_table_mode4(context); | |
1940 CHECK_LIMIT | |
1941 case 0: | |
1942 scan_sprite_table_mode4(context); | |
1943 CHECK_LIMIT | |
1944 case 1: | |
1945 scan_sprite_table_mode4(context); | |
1946 context->buf_a_off = 8; | |
1947 memset(context->tmp_buf_a, 0, 8); | |
1948 CHECK_LIMIT | |
1949 COLUMN_RENDER_BLOCK_MODE4(0, 2) | |
1950 COLUMN_RENDER_BLOCK_MODE4(1, 6) | |
1951 COLUMN_RENDER_BLOCK_MODE4(2, 10) | |
1952 COLUMN_RENDER_BLOCK_MODE4(3, 14) | |
1953 COLUMN_RENDER_BLOCK_MODE4(4, 18) | |
1954 COLUMN_RENDER_BLOCK_MODE4(5, 22) | |
1955 COLUMN_RENDER_BLOCK_MODE4(6, 26) | |
1956 COLUMN_RENDER_BLOCK_MODE4(7, 30) | |
1957 COLUMN_RENDER_BLOCK_MODE4(8, 34) | |
1958 COLUMN_RENDER_BLOCK_MODE4(9, 38) | |
1959 COLUMN_RENDER_BLOCK_MODE4(10, 42) | |
1960 COLUMN_RENDER_BLOCK_MODE4(11, 46) | |
1961 COLUMN_RENDER_BLOCK_MODE4(12, 50) | |
1962 COLUMN_RENDER_BLOCK_MODE4(13, 54) | |
1963 COLUMN_RENDER_BLOCK_MODE4(14, 58) | |
1964 COLUMN_RENDER_BLOCK_MODE4(15, 62) | |
1965 COLUMN_RENDER_BLOCK_MODE4(16, 66) | |
1966 COLUMN_RENDER_BLOCK_MODE4(17, 70) | |
1967 COLUMN_RENDER_BLOCK_MODE4(18, 74) | |
1968 COLUMN_RENDER_BLOCK_MODE4(19, 78) | |
1969 COLUMN_RENDER_BLOCK_MODE4(20, 82) | |
1970 COLUMN_RENDER_BLOCK_MODE4(21, 86) | |
1971 COLUMN_RENDER_BLOCK_MODE4(22, 90) | |
1972 COLUMN_RENDER_BLOCK_MODE4(23, 94) | |
1973 COLUMN_RENDER_BLOCK_MODE4(24, 98) | |
1974 COLUMN_RENDER_BLOCK_MODE4(25, 102) | |
1975 COLUMN_RENDER_BLOCK_MODE4(26, 106) | |
1976 COLUMN_RENDER_BLOCK_MODE4(27, 110) | |
1977 COLUMN_RENDER_BLOCK_MODE4(28, 114) | |
1978 COLUMN_RENDER_BLOCK_MODE4(29, 118) | |
1979 COLUMN_RENDER_BLOCK_MODE4(30, 122) | |
1980 COLUMN_RENDER_BLOCK_MODE4(31, 126) | |
1981 case 130: | |
1982 external_slot(context); | |
1983 CHECK_LIMIT | |
1984 case 131: | |
1985 external_slot(context); | |
1986 vdp_advance_line(context); | |
1987 if (context->vcounter == MODE4_INACTIVE_START) { | |
1988 context->hslot++; | |
1989 context->cycles += slot_cycles; | |
1990 return; | |
1991 } | |
1992 CHECK_LIMIT | 2007 CHECK_LIMIT |
1993 } | 2008 } |
1994 default: | 2009 default: |
1995 context->hslot++; | 2010 context->hslot++; |
1996 context->cycles += MCLKS_SLOT_H32; | 2011 context->cycles += MCLKS_SLOT_H32; |
2491 } | 2506 } |
2492 | 2507 |
2493 static uint32_t vdp_cycles_next_line(vdp_context * context) | 2508 static uint32_t vdp_cycles_next_line(vdp_context * context) |
2494 { | 2509 { |
2495 if (context->regs[REG_MODE_4] & BIT_H40) { | 2510 if (context->regs[REG_MODE_4] & BIT_H40) { |
2511 //TODO: Handle "illegal" Mode 4/H40 combo | |
2496 if (context->hslot < LINE_CHANGE_H40) { | 2512 if (context->hslot < LINE_CHANGE_H40) { |
2497 return (LINE_CHANGE_H40 - context->hslot) * MCLKS_SLOT_H40; | 2513 return (LINE_CHANGE_H40 - context->hslot) * MCLKS_SLOT_H40; |
2498 } else { | 2514 } else { |
2499 return vdp_cycles_hslot_wrap_h40(context) + LINE_CHANGE_H40 * MCLKS_SLOT_H40; | 2515 return vdp_cycles_hslot_wrap_h40(context) + LINE_CHANGE_H40 * MCLKS_SLOT_H40; |
2500 } | 2516 } |
2501 } else { | 2517 } else { |
2502 if (context->hslot < LINE_CHANGE_H32) { | 2518 if (context->regs[REG_MODE_2] & BIT_MODE_5) { |
2503 return (LINE_CHANGE_H32 - context->hslot) * MCLKS_SLOT_H32; | 2519 if (context->hslot < LINE_CHANGE_H32) { |
2504 } else if (context->hslot < 148) { | 2520 return (LINE_CHANGE_H32 - context->hslot) * MCLKS_SLOT_H32; |
2505 return MCLKS_LINE - (context->hslot - LINE_CHANGE_H32) * MCLKS_SLOT_H32; | 2521 } else if (context->hslot < 148) { |
2506 } else { | 2522 return MCLKS_LINE - (context->hslot - LINE_CHANGE_H32) * MCLKS_SLOT_H32; |
2507 return (256-context->hslot + LINE_CHANGE_H32) * MCLKS_SLOT_H32; | 2523 } else { |
2524 return (256-context->hslot + LINE_CHANGE_H32) * MCLKS_SLOT_H32; | |
2525 } | |
2526 } else { | |
2527 if (context->hslot < 148) { | |
2528 return (148 - context->hslot + LINE_CHANGE_MODE4 - 233) * MCLKS_SLOT_H32; | |
2529 } else if (context->hslot < LINE_CHANGE_MODE4) { | |
2530 return (LINE_CHANGE_MODE4 - context->hslot) * MCLKS_SLOT_H32; | |
2531 } else { | |
2532 return MCLKS_LINE - (context->hslot - LINE_CHANGE_MODE4) * MCLKS_SLOT_H32; | |
2533 } | |
2508 } | 2534 } |
2509 } | 2535 } |
2510 } | 2536 } |
2511 | 2537 |
2512 static uint32_t vdp_cycles_to_line(vdp_context * context, uint32_t target) | 2538 static uint32_t vdp_cycles_to_line(vdp_context * context, uint32_t target) |
2513 { | 2539 { |
2514 uint32_t jump_start, jump_dst; | 2540 uint32_t jump_start, jump_dst; |
2515 if (context->flags2 & FLAG2_REGION_PAL) { | 2541 if (context->regs[REG_MODE_2] & BIT_MODE_5) { |
2516 if (context->latched_mode & BIT_PAL) { | 2542 if (context->flags2 & FLAG2_REGION_PAL) { |
2517 jump_start = 0x10B; | 2543 if (context->latched_mode & BIT_PAL) { |
2518 jump_dst = 0x1D2; | 2544 jump_start = 0x10B; |
2519 } else { | 2545 jump_dst = 0x1D2; |
2520 jump_start = 0x103; | 2546 } else { |
2521 jump_dst = 0x1CA; | 2547 jump_start = 0x103; |
2522 } | 2548 jump_dst = 0x1CA; |
2523 } else { | 2549 } |
2524 if (context->latched_mode & BIT_PAL) { | 2550 } else { |
2525 jump_start = 0; | 2551 if (context->latched_mode & BIT_PAL) { |
2526 jump_dst = 0; | 2552 jump_start = 0; |
2527 } else { | 2553 jump_dst = 0; |
2528 jump_start = 0xEB; | 2554 } else { |
2529 jump_dst = 0x1E5; | 2555 jump_start = 0xEB; |
2530 } | 2556 jump_dst = 0x1E5; |
2557 } | |
2558 } | |
2559 } else { | |
2560 jump_start = 0xDB; | |
2561 jump_dst = 0x1D5; | |
2531 } | 2562 } |
2532 uint32_t lines; | 2563 uint32_t lines; |
2533 if (context->vcounter < target) { | 2564 if (context->vcounter < target) { |
2534 if (target < jump_start) { | 2565 if (target < jump_start) { |
2535 lines = target - context->vcounter; | 2566 lines = target - context->vcounter; |
2617 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; | 2648 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; |
2618 if (!(context->regs[REG_MODE_2] & BIT_MODE_5)) { | 2649 if (!(context->regs[REG_MODE_2] & BIT_MODE_5)) { |
2619 inactive_start = MODE4_INACTIVE_START; | 2650 inactive_start = MODE4_INACTIVE_START; |
2620 } | 2651 } |
2621 if (context->vcounter == inactive_start) { | 2652 if (context->vcounter == inactive_start) { |
2653 if (context->regs[REG_MODE_2] & BIT_MODE_5) { | |
2654 if (context->regs[REG_MODE_4] & BIT_H40) { | |
2655 if (context->hslot >= LINE_CHANGE_H40 && context->hslot <= VINT_SLOT_H40) { | |
2656 uint32_t cycles = context->cycles; | |
2657 if (context->hslot < 182) { | |
2658 cycles += (182 - context->hslot) * MCLKS_SLOT_H40; | |
2659 } | |
2660 | |
2661 if (context->hslot < 229) { | |
2662 cycles += h40_hsync_cycles[0]; | |
2663 } | |
2664 for (int slot = context->hslot <= 229 ? 229 : context->hslot; slot < HSYNC_END_H40; slot++ ) | |
2665 { | |
2666 cycles += h40_hsync_cycles[slot - HSYNC_SLOT_H40]; | |
2667 } | |
2668 cycles += (VINT_SLOT_H40 - (context->hslot > HSYNC_SLOT_H40 ? context->hslot : HSYNC_SLOT_H40)) * MCLKS_SLOT_H40; | |
2669 return cycles; | |
2670 } | |
2671 } else { | |
2672 if (context->hslot >= LINE_CHANGE_H32 && context->hslot <= VINT_SLOT_H32) { | |
2673 if (context->hslot < 233) { | |
2674 return context->cycles + (148 - context->hslot + VINT_SLOT_H40 - 233) * MCLKS_SLOT_H32; | |
2675 } else { | |
2676 return context->cycles + (VINT_SLOT_H32 - context->hslot) * MCLKS_SLOT_H32; | |
2677 } | |
2678 } | |
2679 } | |
2680 } else { | |
2681 if (context->hslot >= LINE_CHANGE_H40) { | |
2682 return context->cycles + (VINT_SLOT_MODE4 + 256 - context->hslot) * MCLKS_SLOT_H32; | |
2683 } | |
2684 if (context->hslot <= VINT_SLOT_MODE4) { | |
2685 return context->cycles + (VINT_SLOT_MODE4 - context->hslot) * MCLKS_SLOT_H32; | |
2686 } | |
2687 } | |
2688 } | |
2689 int32_t cycles_to_vint = vdp_cycles_to_line(context, inactive_start); | |
2690 if (context->regs[REG_MODE_2] & BIT_MODE_5) { | |
2622 if (context->regs[REG_MODE_4] & BIT_H40) { | 2691 if (context->regs[REG_MODE_4] & BIT_H40) { |
2623 if (context->hslot >= LINE_CHANGE_H40 && context->hslot <= VINT_SLOT_H40) { | 2692 cycles_to_vint += MCLKS_LINE - (LINE_CHANGE_H40 + (256 - VINT_SLOT_H40)) * MCLKS_SLOT_H40; |
2624 uint32_t cycles = context->cycles; | 2693 } else { |
2625 if (context->hslot < 182) { | 2694 cycles_to_vint += (VINT_SLOT_H32 - 233 + 148 - LINE_CHANGE_H32) * MCLKS_SLOT_H32; |
2626 cycles += (182 - context->hslot) * MCLKS_SLOT_H40; | 2695 } |
2627 } | 2696 } else { |
2628 | 2697 cycles_to_vint += (256 - LINE_CHANGE_MODE4 + VINT_SLOT_MODE4) * MCLKS_SLOT_H32; |
2629 if (context->hslot < 229) { | |
2630 cycles += h40_hsync_cycles[0]; | |
2631 } | |
2632 for (int slot = context->hslot <= 229 ? 229 : context->hslot; slot < HSYNC_END_H40; slot++ ) | |
2633 { | |
2634 cycles += h40_hsync_cycles[slot - HSYNC_SLOT_H40]; | |
2635 } | |
2636 cycles += (VINT_SLOT_H40 - (context->hslot > HSYNC_SLOT_H40 ? context->hslot : HSYNC_SLOT_H40)) * MCLKS_SLOT_H40; | |
2637 return cycles; | |
2638 } | |
2639 } else { | |
2640 if (context->hslot >= LINE_CHANGE_H32 && context->hslot <= VINT_SLOT_H32) { | |
2641 if (context->hslot < 233) { | |
2642 return context->cycles + (148 - context->hslot + VINT_SLOT_H40 - 233) * MCLKS_SLOT_H32; | |
2643 } else { | |
2644 return context->cycles + (VINT_SLOT_H32 - context->hslot) * MCLKS_SLOT_H32; | |
2645 } | |
2646 } | |
2647 } | |
2648 } | |
2649 int32_t cycles_to_vint = vdp_cycles_to_line(context, inactive_start); | |
2650 if (context->regs[REG_MODE_4] & BIT_H40) { | |
2651 cycles_to_vint += MCLKS_LINE - (LINE_CHANGE_H40 + (256 - VINT_SLOT_H40)) * MCLKS_SLOT_H40; | |
2652 } else { | |
2653 cycles_to_vint += (VINT_SLOT_H32 - 233 + 148 - LINE_CHANGE_H32) * MCLKS_SLOT_H32; | |
2654 } | 2698 } |
2655 return context->cycles + cycles_to_vint; | 2699 return context->cycles + cycles_to_vint; |
2656 } | 2700 } |
2657 | 2701 |
2658 void vdp_int_ack(vdp_context * context) | 2702 void vdp_int_ack(vdp_context * context) |
2659 { | 2703 { |
2660 //Apparently the VDP interrupt controller is not very smart | 2704 //CPU interrupt acknowledge is only used in Mode 5 |
2661 //Instead of paying attention to what interrupt is being acknowledged it just | 2705 if (context->regs[REG_MODE_2] & BIT_MODE_5) { |
2662 //clears the pending flag for whatever interrupt it is currently asserted | 2706 //Apparently the VDP interrupt controller is not very smart |
2663 //which may be different from the interrupt it was asserting when the 68k | 2707 //Instead of paying attention to what interrupt is being acknowledged it just |
2664 //started the interrupt process. The window for this is narrow and depends | 2708 //clears the pending flag for whatever interrupt it is currently asserted |
2665 //on the latency between the int enable register write and the interrupt being | 2709 //which may be different from the interrupt it was asserting when the 68k |
2666 //asserted, but Fatal Rewind depends on this due to some buggy code | 2710 //started the interrupt process. The window for this is narrow and depends |
2667 if ((context->flags2 & FLAG2_VINT_PENDING) && (context->regs[REG_MODE_2] & BIT_VINT_EN)) { | 2711 //on the latency between the int enable register write and the interrupt being |
2668 context->flags2 &= ~FLAG2_VINT_PENDING; | 2712 //asserted, but Fatal Rewind depends on this due to some buggy code |
2669 } else if((context->flags2 & FLAG2_HINT_PENDING) && (context->regs[REG_MODE_1] & BIT_HINT_EN)) { | 2713 if ((context->flags2 & FLAG2_VINT_PENDING) && (context->regs[REG_MODE_2] & BIT_VINT_EN)) { |
2670 context->flags2 &= ~FLAG2_HINT_PENDING; | 2714 context->flags2 &= ~FLAG2_VINT_PENDING; |
2671 } | 2715 } else if((context->flags2 & FLAG2_HINT_PENDING) && (context->regs[REG_MODE_1] & BIT_HINT_EN)) { |
2672 } | 2716 context->flags2 &= ~FLAG2_HINT_PENDING; |
2673 | 2717 } |
2718 } | |
2719 } | |
2720 |