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