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) {