Mercurial > repos > blastem
comparison vdp.c @ 1171:43fa92976ff2
Fix some timing inconsistencies in H40 mode. Added some ifdefed timing debug code.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 16 Jan 2017 09:31:33 -0800 |
parents | 9170fc4d9835 |
children | 14eb8ff4fb03 |
comparison
equal
deleted
inserted
replaced
1170:9170fc4d9835 | 1171:43fa92976ff2 |
---|---|
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 133 |
39 #define LINE_CHANGE_MODE4 249 | 39 #define LINE_CHANGE_MODE4 249 |
40 #define VBLANK_START_H40 (LINE_CHANGE_H40+2) | 40 #define VBLANK_START_H40 (LINE_CHANGE_H40+2) |
41 #define VBLANK_START_H32 (LINE_CHANGE_H32+2) | 41 #define VBLANK_START_H32 (LINE_CHANGE_H32+2) |
42 #define FIFO_LATENCY 3 | 42 #define FIFO_LATENCY 3 |
43 | 43 |
1435 | 1435 |
1436 static uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19}; | 1436 static uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19}; |
1437 | 1437 |
1438 static void vdp_advance_line(vdp_context *context) | 1438 static void vdp_advance_line(vdp_context *context) |
1439 { | 1439 { |
1440 #ifdef TIMING_DEBUG | |
1441 static uint32_t last_line = 0xFFFFFFFF; | |
1442 if (last_line != 0xFFFFFFFF) { | |
1443 uint32_t diff = context->cycles - last_line; | |
1444 if (diff != MCLKS_LINE) { | |
1445 printf("Line %d took %d cycles\n", context->vcounter, diff); | |
1446 } | |
1447 } | |
1448 last_line = context->cycles; | |
1449 #endif | |
1440 context->vcounter++; | 1450 context->vcounter++; |
1441 | 1451 |
1442 uint8_t is_mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5; | 1452 uint8_t is_mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5; |
1443 if (is_mode_5) { | 1453 if (is_mode_5) { |
1444 if (context->flags2 & FLAG2_REGION_PAL) { | 1454 if (context->flags2 & FLAG2_REGION_PAL) { |
1568 fetch_map_mode4(column, context->vcounter, context);\ | 1578 fetch_map_mode4(column, context->vcounter, context);\ |
1569 CHECK_LIMIT\ | 1579 CHECK_LIMIT\ |
1570 case ((startcyc+3)&0xFF):\ | 1580 case ((startcyc+3)&0xFF):\ |
1571 render_map_mode4(context->vcounter, column, context);\ | 1581 render_map_mode4(context->vcounter, column, context);\ |
1572 CHECK_LIMIT | 1582 CHECK_LIMIT |
1583 | |
1584 #define CHECK_LIMIT_HSYNC(slot) \ | |
1585 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ | |
1586 if (slot >= HSYNC_SLOT_H40 && slot < HSYNC_END_H40) {\ | |
1587 context->cycles += h40_hsync_cycles[slot - HSYNC_SLOT_H40];\ | |
1588 } else {\ | |
1589 context->cycles += slot_cycles;\ | |
1590 }\ | |
1591 if (slot == 182) {\ | |
1592 context->hslot = 229;\ | |
1593 } else {\ | |
1594 context->hslot++;\ | |
1595 }\ | |
1596 CHECK_ONLY | |
1573 | 1597 |
1574 #define SPRITE_RENDER_H40(slot) \ | 1598 #define SPRITE_RENDER_H40(slot) \ |
1575 case slot:\ | 1599 case slot:\ |
1576 render_sprite_cells( context);\ | 1600 render_sprite_cells( context);\ |
1577 scan_sprite_table(context->vcounter, context);\ | 1601 scan_sprite_table(context->vcounter, context);\ |
1578 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ | 1602 CHECK_LIMIT_HSYNC(slot) |
1579 if (slot == 182) {\ | |
1580 context->hslot = 229;\ | |
1581 } else {\ | |
1582 context->hslot++;\ | |
1583 }\ | |
1584 if (slot >= HSYNC_SLOT_H40 && slot < HSYNC_END_H40) {\ | |
1585 context->cycles += h40_hsync_cycles[slot - HSYNC_SLOT_H40];\ | |
1586 } else {\ | |
1587 context->cycles += slot_cycles;\ | |
1588 }\ | |
1589 CHECK_ONLY | |
1590 | 1603 |
1591 #define SPRITE_RENDER_H32(slot) \ | 1604 #define SPRITE_RENDER_H32(slot) \ |
1592 case slot:\ | 1605 case slot:\ |
1593 render_sprite_cells( context);\ | 1606 render_sprite_cells( context);\ |
1594 scan_sprite_table(context->vcounter, context);\ | 1607 scan_sprite_table(context->vcounter, context);\ |
1688 //!HSYNC asserted | 1701 //!HSYNC asserted |
1689 SPRITE_RENDER_H40(230) | 1702 SPRITE_RENDER_H40(230) |
1690 SPRITE_RENDER_H40(231) | 1703 SPRITE_RENDER_H40(231) |
1691 case 232: | 1704 case 232: |
1692 external_slot(context); | 1705 external_slot(context); |
1693 CHECK_LIMIT | 1706 CHECK_LIMIT_HSYNC(232) |
1694 SPRITE_RENDER_H40(233) | 1707 SPRITE_RENDER_H40(233) |
1695 SPRITE_RENDER_H40(234) | 1708 SPRITE_RENDER_H40(234) |
1696 SPRITE_RENDER_H40(235) | 1709 SPRITE_RENDER_H40(235) |
1697 SPRITE_RENDER_H40(236) | 1710 SPRITE_RENDER_H40(236) |
1698 SPRITE_RENDER_H40(237) | 1711 SPRITE_RENDER_H40(237) |
1786 memset(context->linebuf, 0, LINEBUF_SIZE); | 1799 memset(context->linebuf, 0, LINEBUF_SIZE); |
1787 render_sprite_cells(context); | 1800 render_sprite_cells(context); |
1788 CHECK_LIMIT | 1801 CHECK_LIMIT |
1789 case 164: | 1802 case 164: |
1790 render_sprite_cells(context); | 1803 render_sprite_cells(context); |
1804 if (context->flags & FLAG_DMA_RUN) { | |
1805 run_dma_src(context, -1); | |
1806 } | |
1807 context->hslot++; | |
1808 context->cycles += slot_cycles; | |
1791 vdp_advance_line(context); | 1809 vdp_advance_line(context); |
1792 if (context->vcounter == context->inactive_start) { | 1810 if (context->vcounter == context->inactive_start) { |
1793 context->hslot++; | |
1794 context->cycles += slot_cycles; | |
1795 return; | 1811 return; |
1796 } | 1812 } |
1797 CHECK_LIMIT | 1813 CHECK_ONLY |
1798 } | 1814 } |
1799 default: | 1815 default: |
1800 context->hslot++; | 1816 context->hslot++; |
1801 context->cycles += slot_cycles; | 1817 context->cycles += slot_cycles; |
1802 return; | 1818 return; |
2185 bg_color = context->colors[CRAM_SIZE * 3 + 0x10 + (context->regs[REG_BG_COLOR] & 0xF)]; | 2201 bg_color = context->colors[CRAM_SIZE * 3 + 0x10 + (context->regs[REG_BG_COLOR] & 0xF)]; |
2186 } | 2202 } |
2187 *(dst++) = bg_color; | 2203 *(dst++) = bg_color; |
2188 *(dst++) = bg_color; | 2204 *(dst++) = bg_color; |
2189 } | 2205 } |
2190 if (context->hslot == jump_start) { | |
2191 context->hslot = jump_dest; | |
2192 } else { | |
2193 context->hslot++; | |
2194 } | |
2195 if (is_h40) { | 2206 if (is_h40) { |
2196 if (context->hslot >= HSYNC_SLOT_H40 && context->hslot < HSYNC_END_H40) { | 2207 if (context->hslot >= HSYNC_SLOT_H40 && context->hslot < HSYNC_END_H40) { |
2197 context->cycles += h40_hsync_cycles[context->hslot - HSYNC_SLOT_H40]; | 2208 context->cycles += h40_hsync_cycles[context->hslot - HSYNC_SLOT_H40]; |
2198 } else { | 2209 } else { |
2199 context->cycles += MCLKS_SLOT_H40; | 2210 context->cycles += MCLKS_SLOT_H40; |
2200 } | 2211 } |
2201 } else { | 2212 } else { |
2202 context->cycles += MCLKS_SLOT_H32; | 2213 context->cycles += MCLKS_SLOT_H32; |
2214 } | |
2215 if (context->hslot == jump_start) { | |
2216 context->hslot = jump_dest; | |
2217 } else { | |
2218 context->hslot++; | |
2203 } | 2219 } |
2204 if (context->hslot == line_change) { | 2220 if (context->hslot == line_change) { |
2205 vdp_advance_line(context); | 2221 vdp_advance_line(context); |
2206 if (context->vcounter == active_line) { | 2222 if (context->vcounter == active_line) { |
2207 return; | 2223 return; |
2708 } | 2724 } |
2709 | 2725 |
2710 return context->cycles + vdp_cycles_to_line(context, hint_line); | 2726 return context->cycles + vdp_cycles_to_line(context, hint_line); |
2711 } | 2727 } |
2712 | 2728 |
2713 uint32_t vdp_next_vint(vdp_context * context) | 2729 static uint32_t vdp_next_vint_real(vdp_context * context) |
2714 { | 2730 { |
2715 if (!(context->regs[REG_MODE_2] & BIT_VINT_EN)) { | 2731 if (!(context->regs[REG_MODE_2] & BIT_VINT_EN)) { |
2716 return 0xFFFFFFFF; | 2732 return 0xFFFFFFFF; |
2717 } | 2733 } |
2718 if (context->flags2 & FLAG2_VINT_PENDING) { | 2734 if (context->flags2 & FLAG2_VINT_PENDING) { |
2719 return context->pending_vint_start; | 2735 return context->pending_vint_start; |
2720 } | 2736 } |
2721 | 2737 |
2722 | 2738 |
2723 return vdp_next_vint_z80(context); | 2739 return vdp_next_vint_z80(context); |
2740 } | |
2741 | |
2742 uint32_t vdp_next_vint(vdp_context *context) | |
2743 { | |
2744 uint32_t ret = vdp_next_vint_real(context); | |
2745 #ifdef TIMING_DEBUG | |
2746 static uint32_t last = 0xFFFFFFFF; | |
2747 if (last != ret) { | |
2748 printf("vdp_next_vint is %d at frame %d, line %d, hslot %d\n", ret, context->frame, context->vcounter, context->hslot); | |
2749 } | |
2750 last = ret; | |
2751 #endif | |
2752 return ret; | |
2724 } | 2753 } |
2725 | 2754 |
2726 uint32_t vdp_next_vint_z80(vdp_context * context) | 2755 uint32_t vdp_next_vint_z80(vdp_context * context) |
2727 { | 2756 { |
2728 uint16_t vint_line = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->inactive_start : context->inactive_start + 1; | 2757 uint16_t vint_line = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->inactive_start : context->inactive_start + 1; |