Mercurial > repos > blastem
comparison vdp.c @ 623:66cc60215e5c
Fix most of the breakage caused by the vcounter/hcounter changes
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 18 Jun 2014 16:30:19 -0700 |
parents | b76d2a628ab9 |
children | 788545f4064f |
comparison
equal
deleted
inserted
replaced
622:b76d2a628ab9 | 623:66cc60215e5c |
---|---|
44 {127, 0, 127} //Sprites | 44 {127, 0, 127} //Sprites |
45 }; | 45 }; |
46 | 46 |
47 uint8_t color_map_init_done; | 47 uint8_t color_map_init_done; |
48 | 48 |
49 void init_vdp_context(vdp_context * context) | 49 void init_vdp_context(vdp_context * context, uint8_t region_pal) |
50 { | 50 { |
51 memset(context, 0, sizeof(*context)); | 51 memset(context, 0, sizeof(*context)); |
52 context->vdpmem = malloc(VRAM_SIZE); | 52 context->vdpmem = malloc(VRAM_SIZE); |
53 memset(context->vdpmem, 0, VRAM_SIZE); | 53 memset(context->vdpmem, 0, VRAM_SIZE); |
54 /* | 54 /* |
130 r += 72; | 130 r += 72; |
131 } | 131 } |
132 } | 132 } |
133 context->debugcolors[color] = render_map_color(r, g, b); | 133 context->debugcolors[color] = render_map_color(r, g, b); |
134 } | 134 } |
135 } | |
136 if (region_pal) { | |
137 context->flags2 |= FLAG2_REGION_PAL; | |
135 } | 138 } |
136 } | 139 } |
137 | 140 |
138 int is_refresh(vdp_context * context, uint32_t slot) | 141 int is_refresh(vdp_context * context, uint32_t slot) |
139 { | 142 { |
1426 //TODO: Figure out when this actually happens | 1429 //TODO: Figure out when this actually happens |
1427 if (!line && !slot) { | 1430 if (!line && !slot) { |
1428 latch_mode(context); | 1431 latch_mode(context); |
1429 } | 1432 } |
1430 uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40; | 1433 uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40; |
1431 if (is_h40 && slot == 167 || !is_h40 && slot == 134) { | 1434 if (is_h40 && slot == HBLANK_START_H40 || !is_h40 && slot == 134) { |
1432 if (line >= inactive_start) { | 1435 if (line >= inactive_start) { |
1433 context->hint_counter = context->regs[REG_HINT]; | 1436 context->hint_counter = context->regs[REG_HINT]; |
1434 } else if (context->hint_counter) { | 1437 } else if (context->hint_counter) { |
1435 context->hint_counter--; | 1438 context->hint_counter--; |
1436 } else { | 1439 } else { |
1465 } | 1468 } |
1466 uint8_t inc_slot = 1; | 1469 uint8_t inc_slot = 1; |
1467 if (context->regs[REG_MODE_2] & DISPLAY_ENABLE && active_slot) { | 1470 if (context->regs[REG_MODE_2] & DISPLAY_ENABLE && active_slot) { |
1468 //run VDP rendering for a slot or a line | 1471 //run VDP rendering for a slot or a line |
1469 if (is_h40) { | 1472 if (is_h40) { |
1470 if (slot == 167 && line < inactive_start && (target_cycles - context->cycles) >= MCLKS_LINE) { | 1473 if (slot == HBLANK_START_H40 && line < inactive_start && (target_cycles - context->cycles) >= MCLKS_LINE) { |
1471 vdp_h40_line(line, context); | 1474 vdp_h40_line(line, context); |
1472 inccycles = MCLKS_LINE; | 1475 inccycles = MCLKS_LINE; |
1473 context->vcounter++; | 1476 context->vcounter++; |
1474 inc_slot = 0; | 1477 inc_slot = 0; |
1475 } else { | 1478 } else { |
1491 } | 1494 } |
1492 if (inc_slot) { | 1495 if (inc_slot) { |
1493 context->hslot++; | 1496 context->hslot++; |
1494 context->hslot &= 0xFF; | 1497 context->hslot &= 0xFF; |
1495 if (is_h40) { | 1498 if (is_h40) { |
1496 if (context->hslot == 167) { | 1499 if (context->hslot == HBLANK_START_H40) { |
1497 context->vcounter++; | 1500 context->vcounter++; |
1498 } else if (context->hslot == 183) { | 1501 } else if (context->hslot == 183) { |
1499 context->hslot = 229; | 1502 context->hslot = 229; |
1500 } | 1503 } |
1501 } else { | 1504 } else { |
1505 context->hslot = 233; | 1508 context->hslot = 233; |
1506 } | 1509 } |
1507 } | 1510 } |
1508 | 1511 |
1509 } | 1512 } |
1510 if (context->vcounter == 0xEA) { | 1513 context->vcounter &= 0x1FF; |
1511 context->vcounter += 0xFA; | 1514 if (context->flags2 & FLAG2_REGION_PAL) { |
1512 } else { | 1515 if (context->latched_mode & BIT_PAL) { |
1513 context->vcounter &= 0x1FF; | 1516 if (context->vcounter == 0x10B) { |
1517 context->vcounter = 0x1D2; | |
1518 } | |
1519 } else if (context->vcounter == 0x103){ | |
1520 context->vcounter = 0x1CA; | |
1521 } | |
1522 } else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) { | |
1523 context->vcounter = 0x1E5; | |
1514 } | 1524 } |
1515 context->cycles += inccycles; | 1525 context->cycles += inccycles; |
1516 } | 1526 } |
1517 } | 1527 } |
1518 | 1528 |
1755 line <<= 1; | 1765 line <<= 1; |
1756 if (line & 0x100) { | 1766 if (line & 0x100) { |
1757 line |= 1; | 1767 line |= 1; |
1758 } | 1768 } |
1759 } | 1769 } |
1770 printf("hv_counter_read line: %d, horiz: %d, cycles: %d\n", line, linecyc, context->cycles); | |
1760 return (line << 8) | linecyc; | 1771 return (line << 8) | linecyc; |
1761 } | 1772 } |
1762 | 1773 |
1763 uint16_t vdp_test_port_read(vdp_context * context) | 1774 uint16_t vdp_test_port_read(vdp_context * context) |
1764 { | 1775 { |
1780 idx = (idx+1) & (FIFO_SIZE-1); | 1791 idx = (idx+1) & (FIFO_SIZE-1); |
1781 } while(idx != context->fifo_write); | 1792 } while(idx != context->fifo_write); |
1782 } | 1793 } |
1783 } | 1794 } |
1784 | 1795 |
1796 uint32_t vdp_cycles_next_line(vdp_context * context) | |
1797 { | |
1798 if (context->regs[REG_MODE_4] & BIT_H40) { | |
1799 if (context->hslot < HBLANK_START_H40) { | |
1800 return (HBLANK_START_H40 - context->hslot) * MCLKS_SLOT_H40; | |
1801 } else if (context->hslot < 183) { | |
1802 return MCLKS_LINE - (context->hslot - HBLANK_START_H40) * MCLKS_SLOT_H40; | |
1803 } else { | |
1804 return (256-context->hslot + HBLANK_START_H40) * MCLKS_SLOT_H40; | |
1805 } | |
1806 } else { | |
1807 if (context->hslot < HBLANK_START_H32) { | |
1808 return (HBLANK_START_H32 - context->hslot) * MCLKS_SLOT_H32; | |
1809 } else if (context->hslot < 148) { | |
1810 return MCLKS_LINE - (context->hslot - HBLANK_START_H32) * MCLKS_SLOT_H32; | |
1811 } else { | |
1812 return (256-context->hslot + HBLANK_START_H32) * MCLKS_SLOT_H32; | |
1813 } | |
1814 } | |
1815 } | |
1816 | |
1817 uint32_t vdp_cycles_to_line(vdp_context * context, uint32_t target) | |
1818 { | |
1819 uint32_t jump_start, jump_dst; | |
1820 if (context->flags2 & FLAG2_REGION_PAL) { | |
1821 if (context->latched_mode & BIT_PAL) { | |
1822 jump_start = 0x10B; | |
1823 jump_dst = 0x1D2; | |
1824 } else { | |
1825 jump_start = 0x103; | |
1826 jump_dst = 0x1CA; | |
1827 } | |
1828 } else { | |
1829 if (context->latched_mode & BIT_PAL) { | |
1830 jump_start = 0; | |
1831 jump_dst = 0; | |
1832 } else { | |
1833 jump_start = 0xEB; | |
1834 jump_dst = 0x1E5; | |
1835 } | |
1836 } | |
1837 uint32_t lines; | |
1838 if (context->vcounter < target) { | |
1839 if (target < jump_start) { | |
1840 lines = target - context->vcounter; | |
1841 } else { | |
1842 lines = jump_start - context->vcounter + target - jump_dst; | |
1843 } | |
1844 } else { | |
1845 if (context->vcounter < jump_start) { | |
1846 lines = jump_start - context->vcounter + 512 - jump_dst; | |
1847 } else { | |
1848 lines = 512 - context->vcounter; | |
1849 } | |
1850 if (target < jump_start) { | |
1851 lines += target; | |
1852 } else { | |
1853 lines += jump_start + target - jump_dst; | |
1854 } | |
1855 } | |
1856 return MCLKS_LINE * (lines - 1) + vdp_cycles_next_line(context); | |
1857 } | |
1858 | |
1859 uint32_t vdp_cycles_to_frame_end(vdp_context * context) | |
1860 { | |
1861 uint32_t frame_end; | |
1862 if (context->flags2 & FLAG2_REGION_PAL) { | |
1863 if (context->latched_mode & BIT_PAL) { | |
1864 frame_end = PAL_INACTIVE_START + 8; | |
1865 } else { | |
1866 frame_end = NTSC_INACTIVE_START + 8; | |
1867 } | |
1868 } else { | |
1869 if (context->latched_mode & BIT_PAL) { | |
1870 frame_end = 512; | |
1871 } else { | |
1872 frame_end = NTSC_INACTIVE_START + 8; | |
1873 } | |
1874 } | |
1875 return context->cycles + vdp_cycles_to_line(context, frame_end); | |
1876 } | |
1877 | |
1785 uint32_t vdp_next_hint(vdp_context * context) | 1878 uint32_t vdp_next_hint(vdp_context * context) |
1786 { | 1879 { |
1787 if (!(context->regs[REG_MODE_1] & BIT_HINT_EN)) { | 1880 if (!(context->regs[REG_MODE_1] & BIT_HINT_EN)) { |
1788 return 0xFFFFFFFF; | 1881 return 0xFFFFFFFF; |
1789 } | 1882 } |
1790 if (context->flags2 & FLAG2_HINT_PENDING) { | 1883 if (context->flags2 & FLAG2_HINT_PENDING) { |
1791 return context->cycles; | 1884 return context->cycles; |
1792 } | 1885 } |
1793 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; | 1886 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; |
1794 uint32_t line = context->cycles / MCLKS_LINE; | 1887 uint32_t hint_line; |
1795 if (line >= inactive_start) { | 1888 if (context->vcounter >= inactive_start) { |
1796 return 0xFFFFFFFF; | 1889 hint_line = context->regs[REG_HINT]; |
1797 } | 1890 } else { |
1798 uint32_t linecyc = context->cycles % MCLKS_LINE; | 1891 hint_line = context->vcounter + context->hint_counter + 1; |
1799 uint32_t hcycle = context->cycles + context->hint_counter * MCLKS_LINE + MCLKS_LINE - linecyc; | 1892 } |
1800 return hcycle; | 1893 |
1894 return context->cycles + vdp_cycles_to_line(context, hint_line); | |
1801 } | 1895 } |
1802 | 1896 |
1803 uint32_t vdp_next_vint(vdp_context * context) | 1897 uint32_t vdp_next_vint(vdp_context * context) |
1804 { | 1898 { |
1805 if (!(context->regs[REG_MODE_2] & BIT_VINT_EN)) { | 1899 if (!(context->regs[REG_MODE_2] & BIT_VINT_EN)) { |
1806 return 0xFFFFFFFF; | 1900 return 0xFFFFFFFF; |
1807 } | 1901 } |
1808 if (context->flags2 & FLAG2_VINT_PENDING) { | 1902 if (context->flags2 & FLAG2_VINT_PENDING) { |
1809 return context->cycles; | 1903 return context->cycles; |
1810 } | 1904 } |
1905 | |
1906 | |
1907 return vdp_next_vint_z80(context); | |
1908 } | |
1909 | |
1910 uint32_t vdp_next_vint_z80(vdp_context * context) | |
1911 { | |
1811 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; | 1912 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; |
1812 uint32_t vcycle = MCLKS_LINE * inactive_start; | 1913 if (context->vcounter == inactive_start) { |
1914 if (context->regs[REG_MODE_4] & BIT_H40) { | |
1915 if (context->hslot >= HBLANK_START_H40) { | |
1916 if (context->hslot < 183) { | |
1917 return context->cycles + (VINT_SLOT_H40 + 183 - context->hslot + 256 - 229) * MCLKS_SLOT_H40; | |
1918 } else { | |
1919 return context->cycles + (VINT_SLOT_H40 + 256 - context->hslot) * MCLKS_SLOT_H40; | |
1920 } | |
1921 } else if (context->hslot < VINT_SLOT_H40) { | |
1922 return context->cycles + (VINT_SLOT_H40 - context->hslot) * MCLKS_SLOT_H40; | |
1923 } | |
1924 } else { | |
1925 if (context->hslot >= HBLANK_START_H32) { | |
1926 if (context->hslot < 148) { | |
1927 return context->cycles + (VINT_SLOT_H32 + 148 - context->hslot + 256 - 233) * MCLKS_SLOT_H32; | |
1928 } else { | |
1929 return context->cycles + (VINT_SLOT_H32 + 256 - context->hslot) * MCLKS_SLOT_H32; | |
1930 } | |
1931 } else if (context->hslot < VINT_SLOT_H32) { | |
1932 return context->cycles + (VINT_SLOT_H32 - context->hslot) * MCLKS_SLOT_H32; | |
1933 } | |
1934 } | |
1935 } | |
1936 int32_t cycles_to_vint = vdp_cycles_to_line(context, inactive_start); | |
1813 if (context->regs[REG_MODE_4] & BIT_H40) { | 1937 if (context->regs[REG_MODE_4] & BIT_H40) { |
1814 vcycle += VINT_SLOT_H40 * MCLKS_SLOT_H40; | 1938 cycles_to_vint += (VINT_SLOT_H40 + 183 - HBLANK_START_H40 + 256 - 229) * MCLKS_SLOT_H40; |
1815 } else { | 1939 } else { |
1816 vcycle += VINT_SLOT_H32 * MCLKS_SLOT_H32; | 1940 cycles_to_vint += (VINT_SLOT_H32 + 148 - HBLANK_START_H32 + 256 - 233) * MCLKS_SLOT_H32; |
1817 } | 1941 } |
1818 if (vcycle < context->cycles) { | 1942 return context->cycles + cycles_to_vint; |
1819 return 0xFFFFFFFF; | |
1820 } | |
1821 return vcycle; | |
1822 } | |
1823 | |
1824 uint32_t vdp_next_vint_z80(vdp_context * context) | |
1825 { | |
1826 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; | |
1827 uint32_t vcycle = MCLKS_LINE * inactive_start; | |
1828 if (context->regs[REG_MODE_4] & BIT_H40) { | |
1829 vcycle += VINT_SLOT_H40 * MCLKS_SLOT_H40; | |
1830 } else { | |
1831 vcycle += VINT_SLOT_H32 * MCLKS_SLOT_H32; | |
1832 } | |
1833 return vcycle; | |
1834 } | 1943 } |
1835 | 1944 |
1836 void vdp_int_ack(vdp_context * context, uint16_t int_num) | 1945 void vdp_int_ack(vdp_context * context, uint16_t int_num) |
1837 { | 1946 { |
1838 if (int_num == 6) { | 1947 if (int_num == 6) { |