Mercurial > repos > blastem
comparison vdp.c @ 717:22dbdf50d33c
Small correction to VBLANK flag timing. Fixed some inconsistencies in interrupt timing calculation.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 19 May 2015 23:23:53 -0700 |
parents | e29bc2918f69 |
children | eaba6789f316 |
comparison
equal
deleted
inserted
replaced
716:b707a8ddc202 | 717:22dbdf50d33c |
---|---|
31 #define HBLANK_END_H40 0 //should be 5.5 according to Nemesis, but 0 seems to fit better with my test ROM results | 31 #define HBLANK_END_H40 0 //should be 5.5 according to Nemesis, but 0 seems to fit better with my test ROM results |
32 #define HBLANK_START_H32 233 //should be 147 according to Nemesis which is very different from my test ROM result | 32 #define HBLANK_START_H32 233 //should be 147 according to Nemesis which is very different from my test ROM result |
33 #define HBLANK_END_H32 0 //should be 5 according to Nemesis, but 0 seems to fit better with my test ROM results | 33 #define HBLANK_END_H32 0 //should be 5 according to Nemesis, but 0 seems to fit better with my test ROM results |
34 #define LINE_CHANGE_H40 165 | 34 #define LINE_CHANGE_H40 165 |
35 #define LINE_CHANGE_H32 132 | 35 #define LINE_CHANGE_H32 132 |
36 #define VBLANK_START_H40 (LINE_CHANGE_H40+2) | |
37 #define VBLANK_START_H32 (LINE_CHANGE_H32+2) | |
36 #define FIFO_LATENCY 3 | 38 #define FIFO_LATENCY 3 |
37 | 39 |
38 int32_t color_map[1 << 12]; | 40 int32_t color_map[1 << 12]; |
39 uint8_t levels[] = {0, 27, 49, 71, 87, 103, 119, 130, 146, 157, 174, 190, 206, 228, 255}; | 41 uint8_t levels[] = {0, 27, 49, 71, 87, 103, 119, 130, 146, 157, 174, 190, 206, 228, 255}; |
40 | 42 |
560 context->address += context->regs[REG_AUTOINC]; | 562 context->address += context->regs[REG_AUTOINC]; |
561 uint16_t dma_len = ((context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L]) - 1; | 563 uint16_t dma_len = ((context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L]) - 1; |
562 context->regs[REG_DMALEN_H] = dma_len >> 8; | 564 context->regs[REG_DMALEN_H] = dma_len >> 8; |
563 context->regs[REG_DMALEN_L] = dma_len; | 565 context->regs[REG_DMALEN_L] = dma_len; |
564 if (!dma_len) { | 566 if (!dma_len) { |
565 //printf("DMA end at cycle %d\n", context->cycles); | 567 //printf("DMA end at cycle %d, frame: %d, vcounter: %d, hslot: %d\n", context->cycles, context->frame, context->vcounter, context->hslot); |
566 context->flags &= ~FLAG_DMA_RUN; | 568 context->flags &= ~FLAG_DMA_RUN; |
567 context->cd &= 0xF; | 569 context->cd &= 0xF; |
568 } | 570 } |
569 } | 571 } |
570 } | 572 } |
1446 } | 1448 } |
1447 } | 1449 } |
1448 | 1450 |
1449 uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19}; | 1451 uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19}; |
1450 | 1452 |
1453 void vdp_advance_line(vdp_context *context) | |
1454 { | |
1455 context->vcounter++; | |
1456 if (context->vcounter > (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) { | |
1457 context->hint_counter = context->regs[REG_HINT]; | |
1458 } else if (context->hint_counter) { | |
1459 context->hint_counter--; | |
1460 } else { | |
1461 context->flags2 |= FLAG2_HINT_PENDING; | |
1462 context->pending_hint_start = context->cycles; | |
1463 context->hint_counter = context->regs[REG_HINT]; | |
1464 } | |
1465 } | |
1466 | |
1451 void vdp_run_context(vdp_context * context, uint32_t target_cycles) | 1467 void vdp_run_context(vdp_context * context, uint32_t target_cycles) |
1452 { | 1468 { |
1453 while(context->cycles < target_cycles) | 1469 while(context->cycles < target_cycles) |
1454 { | 1470 { |
1455 context->flags &= ~FLAG_UNUSED_SLOT; | 1471 context->flags &= ~FLAG_UNUSED_SLOT; |
1478 } else if (slot == 138) { | 1494 } else if (slot == 138) { |
1479 context->sprite_index = 0x80; | 1495 context->sprite_index = 0x80; |
1480 context->slot_counter = MAX_SPRITES_LINE_H32; | 1496 context->slot_counter = MAX_SPRITES_LINE_H32; |
1481 } | 1497 } |
1482 } | 1498 } |
1483 if (is_h40 && slot == LINE_CHANGE_H40 || !is_h40 && slot == LINE_CHANGE_H32) { | 1499 if(line == inactive_start) { |
1484 if (line > inactive_start) { | |
1485 context->hint_counter = context->regs[REG_HINT]; | |
1486 } else if (context->hint_counter) { | |
1487 context->hint_counter--; | |
1488 } else { | |
1489 context->flags2 |= FLAG2_HINT_PENDING; | |
1490 context->hint_counter = context->regs[REG_HINT]; | |
1491 } | |
1492 } else if(line == inactive_start) { | |
1493 uint32_t intslot = context->regs[REG_MODE_4] & BIT_H40 ? VINT_SLOT_H40 : VINT_SLOT_H32; | 1500 uint32_t intslot = context->regs[REG_MODE_4] & BIT_H40 ? VINT_SLOT_H40 : VINT_SLOT_H32; |
1494 if (slot == intslot) { | 1501 if (slot == intslot) { |
1495 context->flags2 |= FLAG2_VINT_PENDING; | 1502 context->flags2 |= FLAG2_VINT_PENDING; |
1503 context->pending_vint_start = context->cycles; | |
1496 } | 1504 } |
1497 } | 1505 } |
1498 uint32_t inccycles; | 1506 uint32_t inccycles; |
1499 //line 0x1FF is basically active even though it's not displayed | 1507 //line 0x1FF is basically active even though it's not displayed |
1500 uint8_t active_slot = line < inactive_start || line == 0x1FF; | 1508 uint8_t active_slot = line < inactive_start || line == 0x1FF; |
1520 //run VDP rendering for a slot or a line | 1528 //run VDP rendering for a slot or a line |
1521 if (is_h40) { | 1529 if (is_h40) { |
1522 if (slot == LINE_CHANGE_H40 && line < inactive_start && (target_cycles - context->cycles) >= MCLKS_LINE) { | 1530 if (slot == LINE_CHANGE_H40 && line < inactive_start && (target_cycles - context->cycles) >= MCLKS_LINE) { |
1523 vdp_h40_line(line, context); | 1531 vdp_h40_line(line, context); |
1524 inccycles = MCLKS_LINE; | 1532 inccycles = MCLKS_LINE; |
1525 context->vcounter++; | |
1526 inc_slot = 0; | 1533 inc_slot = 0; |
1527 } else { | 1534 } else { |
1528 vdp_h40(line, slot, context); | 1535 vdp_h40(line, slot, context); |
1529 } | 1536 } |
1530 } else { | 1537 } else { |
1539 } | 1546 } |
1540 } | 1547 } |
1541 if (context->flags & FLAG_DMA_RUN && !is_refresh(context, slot)) { | 1548 if (context->flags & FLAG_DMA_RUN && !is_refresh(context, slot)) { |
1542 run_dma_src(context, slot); | 1549 run_dma_src(context, slot); |
1543 } | 1550 } |
1551 context->cycles += inccycles; | |
1544 if (inc_slot) { | 1552 if (inc_slot) { |
1545 context->hslot++; | 1553 context->hslot++; |
1546 context->hslot &= 0xFF; | 1554 context->hslot &= 0xFF; |
1547 if (is_h40) { | 1555 if (is_h40) { |
1548 if (context->hslot == LINE_CHANGE_H40) { | 1556 if (context->hslot == LINE_CHANGE_H40) { |
1549 context->vcounter++; | 1557 vdp_advance_line(context); |
1550 if (context->vcounter == (inactive_start + 8)) { | 1558 if (context->vcounter == (inactive_start + 8)) { |
1551 context->frame++; | 1559 context->frame++; |
1552 } | 1560 } |
1553 } else if (context->hslot == 183) { | 1561 } else if (context->hslot == 183) { |
1554 context->hslot = 229; | 1562 context->hslot = 229; |
1555 } | 1563 } |
1556 } else { | 1564 } else { |
1557 if (context->hslot == LINE_CHANGE_H32) { | 1565 if (context->hslot == LINE_CHANGE_H32) { |
1558 context->vcounter++; | 1566 vdp_advance_line(context); |
1559 if (context->vcounter == (inactive_start + 8)) { | 1567 if (context->vcounter == (inactive_start + 8)) { |
1560 context->frame++; | 1568 context->frame++; |
1561 } | 1569 } |
1562 } else if (context->hslot == 148) { | 1570 } else if (context->hslot == 148) { |
1563 context->hslot = 233; | 1571 context->hslot = 233; |
1564 } | 1572 } |
1565 } | 1573 } |
1566 | 1574 |
1575 } else { | |
1576 vdp_advance_line(context); | |
1567 } | 1577 } |
1568 context->vcounter &= 0x1FF; | 1578 context->vcounter &= 0x1FF; |
1569 if (context->flags2 & FLAG2_REGION_PAL) { | 1579 if (context->flags2 & FLAG2_REGION_PAL) { |
1570 if (context->latched_mode & BIT_PAL) { | 1580 if (context->latched_mode & BIT_PAL) { |
1571 if (context->vcounter == 0x10B) { | 1581 if (context->vcounter == 0x10B) { |
1575 context->vcounter = 0x1CA; | 1585 context->vcounter = 0x1CA; |
1576 } | 1586 } |
1577 } else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) { | 1587 } else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) { |
1578 context->vcounter = 0x1E5; | 1588 context->vcounter = 0x1E5; |
1579 } | 1589 } |
1580 context->cycles += inccycles; | 1590 |
1581 } | 1591 } |
1582 } | 1592 } |
1583 | 1593 |
1584 uint32_t vdp_run_to_vblank(vdp_context * context) | 1594 uint32_t vdp_run_to_vblank(vdp_context * context) |
1585 { | 1595 { |
1629 // | 1639 // |
1630 if((context->regs[REG_DMASRC_H] & 0xC0) != 0x80) { | 1640 if((context->regs[REG_DMASRC_H] & 0xC0) != 0x80) { |
1631 //DMA copy or 68K -> VDP, transfer starts immediately | 1641 //DMA copy or 68K -> VDP, transfer starts immediately |
1632 context->flags |= FLAG_DMA_RUN; | 1642 context->flags |= FLAG_DMA_RUN; |
1633 context->dma_cd = context->cd; | 1643 context->dma_cd = context->cd; |
1634 //printf("DMA start at cycle %d\n", context->cycles); | 1644 //printf("DMA start (length: %X) at cycle %d, frame: %d, vcounter: %d, hslot: %d\n", (context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L], context->cycles, context->frame, context->vcounter, context->hslot); |
1635 if (!(context->regs[REG_DMASRC_H] & 0x80)) { | 1645 if (!(context->regs[REG_DMASRC_H] & 0x80)) { |
1636 //printf("DMA Address: %X, New CD: %X, Source: %X, Length: %X\n", context->address, context->cd, (context->regs[REG_DMASRC_H] << 17) | (context->regs[REG_DMASRC_M] << 9) | (context->regs[REG_DMASRC_L] << 1), context->regs[REG_DMALEN_H] << 8 | context->regs[REG_DMALEN_L]); | 1646 //printf("DMA Address: %X, New CD: %X, Source: %X, Length: %X\n", context->address, context->cd, (context->regs[REG_DMASRC_H] << 17) | (context->regs[REG_DMASRC_M] << 9) | (context->regs[REG_DMASRC_L] << 1), context->regs[REG_DMALEN_H] << 8 | context->regs[REG_DMALEN_L]); |
1637 return 1; | 1647 return 1; |
1638 } else { | 1648 } else { |
1639 //printf("DMA Copy Address: %X, New CD: %X, Source: %X\n", context->address, context->cd, (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]); | 1649 //printf("DMA Copy Address: %X, New CD: %X, Source: %X\n", context->address, context->cd, (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]); |
1652 context->hv_latch = vdp_hv_counter_read(context); | 1662 context->hv_latch = vdp_hv_counter_read(context); |
1653 } | 1663 } |
1654 if (reg == REG_BG_COLOR) { | 1664 if (reg == REG_BG_COLOR) { |
1655 value &= 0x3F; | 1665 value &= 0x3F; |
1656 } | 1666 } |
1667 if (reg == REG_MODE_4 && ((value ^ context->regs[reg]) & BIT_H40)) { | |
1668 printf("Mode changed from H%d to H%d @ %d, frame: %d\n", context->regs[reg] & BIT_H40 ? 40 : 32, value & BIT_H40 ? 40 : 32, context->cycles, context->frame); | |
1669 } | |
1657 context->regs[reg] = value; | 1670 context->regs[reg] = value; |
1658 if (reg == REG_MODE_4) { | 1671 if (reg == REG_MODE_4) { |
1659 context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES); | 1672 context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES); |
1660 if (!context->double_res) { | 1673 if (!context->double_res) { |
1661 context->framebuf = context->oddbuf; | 1674 context->framebuf = context->oddbuf; |
1734 if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && context->framebuf == context->oddbuf) { | 1747 if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && context->framebuf == context->oddbuf) { |
1735 value |= 0x10; | 1748 value |= 0x10; |
1736 } | 1749 } |
1737 uint32_t line= context->vcounter; | 1750 uint32_t line= context->vcounter; |
1738 uint32_t slot = context->hslot; | 1751 uint32_t slot = context->hslot; |
1752 uint32_t inactive_start = (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START); | |
1739 if ( | 1753 if ( |
1740 ( | 1754 ( |
1741 line >= (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START) | 1755 line > inactive_start |
1742 && line < 0x1FF | 1756 && line < 0x1FF |
1743 ) | 1757 ) |
1758 || (line == inactive_start | |
1759 && ( | |
1760 slot >= (context->regs[REG_MODE_4] & BIT_H40 ? VBLANK_START_H40 : VBLANK_START_H32) | |
1761 || slot < (context->regs[REG_MODE_4] & BIT_H40 ? LINE_CHANGE_H40 : LINE_CHANGE_H32) | |
1762 ) | |
1763 ) | |
1764 || (line == 0x1FF | |
1765 && slot < (context->regs[REG_MODE_4] & BIT_H40 ? VBLANK_START_H40 : VBLANK_START_H32)) | |
1766 && slot >= (context->regs[REG_MODE_4] & BIT_H40 ? LINE_CHANGE_H40 : LINE_CHANGE_H32) | |
1744 || !(context->regs[REG_MODE_2] & BIT_DISP_EN) | 1767 || !(context->regs[REG_MODE_2] & BIT_DISP_EN) |
1745 ) { | 1768 ) { |
1746 value |= 0x8; | 1769 value |= 0x8; |
1747 } | 1770 } |
1748 if (context->regs[REG_MODE_4] & BIT_H40) { | 1771 if (context->regs[REG_MODE_4] & BIT_H40) { |
1838 } | 1861 } |
1839 | 1862 |
1840 void vdp_adjust_cycles(vdp_context * context, uint32_t deduction) | 1863 void vdp_adjust_cycles(vdp_context * context, uint32_t deduction) |
1841 { | 1864 { |
1842 context->cycles -= deduction; | 1865 context->cycles -= deduction; |
1866 if (context->pending_vint_start >= deduction) { | |
1867 context->pending_vint_start -= deduction; | |
1868 } else { | |
1869 context->pending_vint_start = 0; | |
1870 } | |
1871 if (context->pending_hint_start >= deduction) { | |
1872 context->pending_hint_start -= deduction; | |
1873 } else { | |
1874 context->pending_hint_start = 0; | |
1875 } | |
1843 if (context->fifo_read >= 0) { | 1876 if (context->fifo_read >= 0) { |
1844 int32_t idx = context->fifo_read; | 1877 int32_t idx = context->fifo_read; |
1845 do { | 1878 do { |
1846 if (context->fifo[idx].cycle >= deduction) { | 1879 if (context->fifo[idx].cycle >= deduction) { |
1847 context->fifo[idx].cycle -= deduction; | 1880 context->fifo[idx].cycle -= deduction; |
1851 idx = (idx+1) & (FIFO_SIZE-1); | 1884 idx = (idx+1) & (FIFO_SIZE-1); |
1852 } while(idx != context->fifo_write); | 1885 } while(idx != context->fifo_write); |
1853 } | 1886 } |
1854 } | 1887 } |
1855 | 1888 |
1889 uint32_t vdp_cycles_hslot_wrap_h40(vdp_context * context) | |
1890 { | |
1891 if (context->hslot < 183) { | |
1892 return MCLKS_LINE - context->hslot * MCLKS_SLOT_H40; | |
1893 } else if (context->hslot < HSYNC_END_H40) { | |
1894 uint32_t before_hsync = context->hslot < HSYNC_SLOT_H40 ? (HSYNC_SLOT_H40 - context->hslot) * MCLKS_SLOT_H40 : 0; | |
1895 uint32_t hsync = 0; | |
1896 for (int i = context->hslot <= HSYNC_SLOT_H40 ? 0 : context->hslot - HSYNC_SLOT_H40; i < sizeof(h40_hsync_cycles)/sizeof(uint32_t); i++) | |
1897 { | |
1898 hsync += h40_hsync_cycles[i]; | |
1899 } | |
1900 uint32_t after_hsync = (256- HSYNC_END_H40) * MCLKS_SLOT_H40; | |
1901 return before_hsync + hsync + after_hsync; | |
1902 } else { | |
1903 return (256-context->hslot) * MCLKS_SLOT_H40; | |
1904 } | |
1905 } | |
1906 | |
1856 uint32_t vdp_cycles_next_line(vdp_context * context) | 1907 uint32_t vdp_cycles_next_line(vdp_context * context) |
1857 { | 1908 { |
1858 if (context->regs[REG_MODE_4] & BIT_H40) { | 1909 if (context->regs[REG_MODE_4] & BIT_H40) { |
1859 if (context->hslot < LINE_CHANGE_H40) { | 1910 if (context->hslot < LINE_CHANGE_H40) { |
1860 return (LINE_CHANGE_H40 - context->hslot) * MCLKS_SLOT_H40; | 1911 return (LINE_CHANGE_H40 - context->hslot) * MCLKS_SLOT_H40; |
1861 } else if (context->hslot < 183) { | 1912 } else { |
1862 return MCLKS_LINE - (context->hslot - LINE_CHANGE_H40) * MCLKS_SLOT_H40; | 1913 return vdp_cycles_hslot_wrap_h40(context) + LINE_CHANGE_H40 * MCLKS_SLOT_H40; |
1863 } else if (context->hslot < HSYNC_END_H40){ | |
1864 uint32_t before_hsync = context->hslot < HSYNC_SLOT_H40 ? (HSYNC_SLOT_H40 - context->hslot) * MCLKS_SLOT_H40 : 0; | |
1865 uint32_t hsync = 0; | |
1866 for (int i = context->hslot <= HSYNC_SLOT_H40 ? 0 : context->hslot - HSYNC_SLOT_H40; i < sizeof(h40_hsync_cycles)/sizeof(uint32_t); i++) | |
1867 { | |
1868 hsync += h40_hsync_cycles[i]; | |
1869 } | |
1870 uint32_t after_hsync = (256- HSYNC_END_H40 + LINE_CHANGE_H40) * MCLKS_SLOT_H40; | |
1871 return before_hsync + hsync + after_hsync; | |
1872 } else { | |
1873 return (256-context->hslot + LINE_CHANGE_H40) * MCLKS_SLOT_H40; | |
1874 } | 1914 } |
1875 } else { | 1915 } else { |
1876 if (context->hslot < LINE_CHANGE_H32) { | 1916 if (context->hslot < LINE_CHANGE_H32) { |
1877 return (LINE_CHANGE_H32 - context->hslot) * MCLKS_SLOT_H32; | 1917 return (LINE_CHANGE_H32 - context->hslot) * MCLKS_SLOT_H32; |
1878 } else if (context->hslot < 148) { | 1918 } else if (context->hslot < 148) { |
1910 } else { | 1950 } else { |
1911 lines = jump_start - context->vcounter + target - jump_dst; | 1951 lines = jump_start - context->vcounter + target - jump_dst; |
1912 } | 1952 } |
1913 } else { | 1953 } else { |
1914 if (context->vcounter < jump_start) { | 1954 if (context->vcounter < jump_start) { |
1915 lines = jump_start - context->vcounter + 512 - jump_dst; | 1955 lines = jump_start - context->vcounter + 512 - jump_dst + 1; |
1916 } else { | 1956 } else { |
1917 lines = 512 - context->vcounter; | 1957 lines = 512 - context->vcounter + 1; |
1918 } | 1958 } |
1919 if (target < jump_start) { | 1959 if (target < jump_start) { |
1920 lines += target; | 1960 lines += target; |
1921 } else { | 1961 } else { |
1922 lines += jump_start + target - jump_dst; | 1962 lines += jump_start + target - jump_dst; |
1953 { | 1993 { |
1954 if (!(context->regs[REG_MODE_1] & BIT_HINT_EN)) { | 1994 if (!(context->regs[REG_MODE_1] & BIT_HINT_EN)) { |
1955 return 0xFFFFFFFF; | 1995 return 0xFFFFFFFF; |
1956 } | 1996 } |
1957 if (context->flags2 & FLAG2_HINT_PENDING) { | 1997 if (context->flags2 & FLAG2_HINT_PENDING) { |
1958 return context->cycles; | 1998 return context->pending_hint_start; |
1959 } | 1999 } |
1960 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; | 2000 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; |
1961 uint32_t hint_line; | 2001 uint32_t hint_line; |
1962 if (context->vcounter + context->hint_counter >= inactive_start) { | 2002 if (context->vcounter + context->hint_counter >= inactive_start) { |
1963 hint_line = context->regs[REG_HINT]; | 2003 hint_line = context->regs[REG_HINT]; |
1972 { | 2012 { |
1973 if (!(context->regs[REG_MODE_2] & BIT_VINT_EN)) { | 2013 if (!(context->regs[REG_MODE_2] & BIT_VINT_EN)) { |
1974 return 0xFFFFFFFF; | 2014 return 0xFFFFFFFF; |
1975 } | 2015 } |
1976 if (context->flags2 & FLAG2_VINT_PENDING) { | 2016 if (context->flags2 & FLAG2_VINT_PENDING) { |
1977 return context->cycles; | 2017 return context->pending_vint_start; |
1978 } | 2018 } |
1979 | 2019 |
1980 | 2020 |
1981 return vdp_next_vint_z80(context); | 2021 return vdp_next_vint_z80(context); |
1982 } | 2022 } |
1985 { | 2025 { |
1986 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; | 2026 uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START; |
1987 if (context->vcounter == inactive_start) { | 2027 if (context->vcounter == inactive_start) { |
1988 if (context->regs[REG_MODE_4] & BIT_H40) { | 2028 if (context->regs[REG_MODE_4] & BIT_H40) { |
1989 if (context->hslot >= LINE_CHANGE_H40) { | 2029 if (context->hslot >= LINE_CHANGE_H40) { |
1990 if (context->hslot < 183) { | 2030 return context->cycles + vdp_cycles_hslot_wrap_h40(context) + VINT_SLOT_H40 * MCLKS_SLOT_H40; |
1991 return context->cycles + (VINT_SLOT_H40 + 183 - context->hslot + 256 - 229) * MCLKS_SLOT_H40; | 2031 } else if (context->hslot <= VINT_SLOT_H40) { |
1992 } else { | |
1993 return context->cycles + (VINT_SLOT_H40 + 256 - context->hslot) * MCLKS_SLOT_H40; | |
1994 } | |
1995 } else if (context->hslot < VINT_SLOT_H40) { | |
1996 return context->cycles + (VINT_SLOT_H40 - context->hslot) * MCLKS_SLOT_H40; | 2032 return context->cycles + (VINT_SLOT_H40 - context->hslot) * MCLKS_SLOT_H40; |
1997 } | 2033 } |
1998 } else { | 2034 } else { |
1999 if (context->hslot >= LINE_CHANGE_H32) { | 2035 if (context->hslot >= LINE_CHANGE_H32) { |
2000 if (context->hslot < 148) { | 2036 if (context->hslot < 148) { |
2001 return context->cycles + (VINT_SLOT_H32 + 148 - context->hslot + 256 - 233) * MCLKS_SLOT_H32; | 2037 return context->cycles + (VINT_SLOT_H32 + 148 - context->hslot + 256 - 233) * MCLKS_SLOT_H32; |
2002 } else { | 2038 } else { |
2003 return context->cycles + (VINT_SLOT_H32 + 256 - context->hslot) * MCLKS_SLOT_H32; | 2039 return context->cycles + (VINT_SLOT_H32 + 256 - context->hslot) * MCLKS_SLOT_H32; |
2004 } | 2040 } |
2005 } else if (context->hslot < VINT_SLOT_H32) { | 2041 } else if (context->hslot <= VINT_SLOT_H32) { |
2006 return context->cycles + (VINT_SLOT_H32 - context->hslot) * MCLKS_SLOT_H32; | 2042 return context->cycles + (VINT_SLOT_H32 - context->hslot) * MCLKS_SLOT_H32; |
2007 } | 2043 } |
2008 } | 2044 } |
2009 } | 2045 } |
2010 int32_t cycles_to_vint = vdp_cycles_to_line(context, inactive_start); | 2046 int32_t cycles_to_vint = vdp_cycles_to_line(context, inactive_start); |
2011 if (context->regs[REG_MODE_4] & BIT_H40) { | 2047 if (context->regs[REG_MODE_4] & BIT_H40) { |
2012 cycles_to_vint += (VINT_SLOT_H40 + 183 - LINE_CHANGE_H40 + 256 - 229) * MCLKS_SLOT_H40; | 2048 cycles_to_vint += MCLKS_LINE - (LINE_CHANGE_H40 - VINT_SLOT_H40) * MCLKS_SLOT_H40; |
2013 } else { | 2049 } else { |
2014 cycles_to_vint += (VINT_SLOT_H32 + 148 - LINE_CHANGE_H32 + 256 - 233) * MCLKS_SLOT_H32; | 2050 cycles_to_vint += (VINT_SLOT_H32 + 148 - LINE_CHANGE_H32 + 256 - 233) * MCLKS_SLOT_H32; |
2015 } | 2051 } |
2016 return context->cycles + cycles_to_vint; | 2052 return context->cycles + cycles_to_vint; |
2017 } | 2053 } |