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;