Mercurial > repos > blastem
comparison vdp.c @ 1169:82d8b9324b10
Rework how inactive lines are handled. Fix H40 cycle increment in slot 182
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 15 Jan 2017 22:38:31 -0800 |
parents | fa73a77ddf92 |
children | 9170fc4d9835 |
comparison
equal
deleted
inserted
replaced
1168:fa73a77ddf92 | 1169:82d8b9324b10 |
---|---|
1576 render_sprite_cells( context);\ | 1576 render_sprite_cells( context);\ |
1577 scan_sprite_table(context->vcounter, context);\ | 1577 scan_sprite_table(context->vcounter, context);\ |
1578 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ | 1578 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ |
1579 if (slot == 182) {\ | 1579 if (slot == 182) {\ |
1580 context->hslot = 229;\ | 1580 context->hslot = 229;\ |
1581 context->cycles += h40_hsync_cycles[0];\ | |
1582 } else {\ | 1581 } else {\ |
1583 context->hslot++;\ | 1582 context->hslot++;\ |
1584 if (slot >= HSYNC_SLOT_H40 && slot < HSYNC_END_H40) {\ | 1583 }\ |
1585 context->cycles += h40_hsync_cycles[slot - HSYNC_SLOT_H40];\ | 1584 if (slot >= HSYNC_SLOT_H40 && slot < HSYNC_END_H40) {\ |
1586 } else {\ | 1585 context->cycles += h40_hsync_cycles[slot - HSYNC_SLOT_H40];\ |
1587 context->cycles += slot_cycles;\ | 1586 } else {\ |
1588 }\ | 1587 context->cycles += slot_cycles;\ |
1589 }\ | 1588 }\ |
1590 CHECK_ONLY | 1589 CHECK_ONLY |
1591 | 1590 |
1592 #define SPRITE_RENDER_H32(slot) \ | 1591 #define SPRITE_RENDER_H32(slot) \ |
1593 case slot:\ | 1592 case slot:\ |
1744 case 255: | 1743 case 255: |
1745 render_map_3(context); | 1744 render_map_3(context); |
1746 scan_sprite_table(context->vcounter, context);//Just a guess | 1745 scan_sprite_table(context->vcounter, context);//Just a guess |
1747 CHECK_LIMIT | 1746 CHECK_LIMIT |
1748 case 0: | 1747 case 0: |
1749 if (context->vcounter == context->inactive_start) { | |
1750 context->flags2 |= FLAG2_VINT_PENDING; | |
1751 context->pending_vint_start = context->cycles; | |
1752 } | |
1753 render_map_output(context->vcounter, 0, context); | 1748 render_map_output(context->vcounter, 0, context); |
1754 scan_sprite_table(context->vcounter, context);//Just a guess | 1749 scan_sprite_table(context->vcounter, context);//Just a guess |
1755 //reverse context slot counter so it counts the number of sprite slots | 1750 //reverse context slot counter so it counts the number of sprite slots |
1756 //filled rather than the number of available slots | 1751 //filled rather than the number of available slots |
1757 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; | 1752 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; |
2090 { | 2085 { |
2091 context->latched_mode = context->regs[REG_MODE_2] & BIT_PAL; | 2086 context->latched_mode = context->regs[REG_MODE_2] & BIT_PAL; |
2092 update_video_params(context); | 2087 update_video_params(context); |
2093 } | 2088 } |
2094 | 2089 |
2095 static void check_render_bg(vdp_context * context, int32_t line, uint32_t slot) | 2090 //rough estimate of slot number at which active display starts |
2096 { | 2091 #define BG_START_SLOT 9 |
2097 int starti = -1; | 2092 |
2098 if (context->regs[REG_MODE_4] & BIT_H40) { | 2093 static void vdp_inactive(vdp_context *context, uint32_t target_cycles, uint8_t is_h40, uint8_t mode_5) |
2099 if (slot >= 12 && slot < 172) { | 2094 { |
2100 starti = (slot-12)*2; | 2095 uint8_t buf_clear_slot, index_reset_slot, bg_end_slot, vint_slot, line_change, jump_start, jump_dest; |
2101 } | 2096 uint8_t index_reset_value, max_draws, max_sprites; |
2102 } else { | 2097 uint16_t vint_line, active_line; |
2103 if (slot >= 11 && slot < 139) { | 2098 uint32_t bg_color; |
2104 starti = (slot-11)*2; | 2099 |
2105 } | 2100 if (mode_5) { |
2106 } | 2101 if (is_h40) { |
2107 if (starti >= 0) { | 2102 buf_clear_slot = 161; |
2108 uint32_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) | 2103 index_reset_slot = 165; |
2109 ? context->colors[context->regs[REG_BG_COLOR]] | 2104 bg_end_slot = BG_START_SLOT + 320/2; |
2110 : context->colors[CRAM_SIZE * 3 + 0x10 + (context->regs[REG_BG_COLOR] & 0xF)]; | 2105 max_draws = MAX_DRAWS-1; |
2111 uint32_t * start = context->output + starti; | 2106 max_sprites = MAX_SPRITES_LINE; |
2112 for (int i = 0; i < 2; i++) { | 2107 index_reset_value = 0x80; |
2113 *(start++) = color; | 2108 vint_slot = (VINT_SLOT_H40+1) & 0xFF; |
2114 } | 2109 line_change = LINE_CHANGE_H40; |
2115 } | 2110 jump_start = 182; |
2116 } | 2111 jump_dest = 229; |
2117 | 2112 } else { |
2113 bg_end_slot = BG_START_SLOT + 256/2; | |
2114 max_draws = MAX_DRAWS_H32-1; | |
2115 max_sprites = MAX_SPRITES_LINE_H32; | |
2116 buf_clear_slot = 128; | |
2117 index_reset_slot = 132; | |
2118 index_reset_value = 0x80; | |
2119 vint_slot = (VINT_SLOT_H32+1) & 0xFF; | |
2120 line_change = LINE_CHANGE_H32; | |
2121 jump_start = 147; | |
2122 jump_dest = 233; | |
2123 } | |
2124 vint_line = context->inactive_start; | |
2125 active_line = 0x1FF; | |
2126 } else { | |
2127 bg_end_slot = BG_START_SLOT + 256/2; | |
2128 max_draws = MAX_DRAWS_H32_MODE4; | |
2129 buf_clear_slot = 136; | |
2130 index_reset_slot = 253; | |
2131 index_reset_value = 0; | |
2132 vint_line = context->inactive_start + 1; | |
2133 vint_slot = VINT_SLOT_MODE4; | |
2134 line_change = LINE_CHANGE_H40; | |
2135 bg_color = render_map_color(0, 0, 0); | |
2136 jump_start = 147; | |
2137 jump_dest = 233; | |
2138 active_line = 0; | |
2139 } | |
2140 uint32_t *dst = ( | |
2141 context->vcounter < context->inactive_start + context->border_bot | |
2142 || context->vcounter > 0x200 - context->border_top | |
2143 ) && context->hslot >= BG_START_SLOT && context->hslot < bg_end_slot | |
2144 ? context->output + 2 * (context->hslot - BG_START_SLOT) | |
2145 : NULL; | |
2146 | |
2147 while(context->cycles < target_cycles) | |
2148 { | |
2149 if (context->hslot == BG_START_SLOT && ( | |
2150 context->vcounter < context->inactive_start + context->border_bot | |
2151 || context->vcounter > 0x200 - context->border_top | |
2152 )) { | |
2153 dst = context->output + (context->hslot - BG_START_SLOT) * 2; | |
2154 } else if (context->hslot == bg_end_slot) { | |
2155 dst = NULL; | |
2156 } | |
2157 | |
2158 if (context->hslot == buf_clear_slot) { | |
2159 if (mode_5) { | |
2160 context->cur_slot = max_draws; | |
2161 } else { | |
2162 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; | |
2163 context->sprite_draws = MAX_DRAWS_H32_MODE4; | |
2164 } | |
2165 memset(context->linebuf, 0, LINEBUF_SIZE); | |
2166 } else if (context->hslot == index_reset_slot) { | |
2167 context->sprite_index = index_reset_value; | |
2168 context->slot_counter = max_draws; | |
2169 } else if (context->vcounter == vint_line && context->hslot == vint_slot) { | |
2170 context->flags2 |= FLAG2_VINT_PENDING; | |
2171 context->pending_vint_start = context->cycles; | |
2172 } | |
2173 | |
2174 if (!is_refresh(context, context->hslot)) { | |
2175 external_slot(context); | |
2176 if (context->flags & FLAG_DMA_RUN && !is_refresh(context, context->hslot)) { | |
2177 run_dma_src(context, context->hslot); | |
2178 } | |
2179 } | |
2180 | |
2181 if (dst) { | |
2182 if (mode_5) { | |
2183 bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; | |
2184 } else if (context->regs[REG_MODE_1] & BIT_MODE_4) { | |
2185 bg_color = context->colors[CRAM_SIZE * 3 + 0x10 + (context->regs[REG_BG_COLOR] & 0xF)]; | |
2186 } | |
2187 *(dst++) = bg_color; | |
2188 *(dst++) = bg_color; | |
2189 } | |
2190 if (context->hslot == jump_start) { | |
2191 context->hslot = jump_dest; | |
2192 } else { | |
2193 context->hslot++; | |
2194 } | |
2195 if (is_h40) { | |
2196 if (context->hslot >= HSYNC_SLOT_H40 && context->hslot < HSYNC_END_H40) { | |
2197 context->cycles += h40_hsync_cycles[context->hslot - HSYNC_SLOT_H40]; | |
2198 } else { | |
2199 context->cycles += MCLKS_SLOT_H40; | |
2200 } | |
2201 } else { | |
2202 context->cycles += MCLKS_SLOT_H32; | |
2203 } | |
2204 if (context->hslot == line_change) { | |
2205 vdp_advance_line(context); | |
2206 if (context->vcounter == active_line) { | |
2207 return; | |
2208 } | |
2209 } | |
2210 } | |
2211 } | |
2118 | 2212 |
2119 void vdp_run_context(vdp_context * context, uint32_t target_cycles) | 2213 void vdp_run_context(vdp_context * context, uint32_t target_cycles) |
2120 { | 2214 { |
2121 uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40; | 2215 uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40; |
2122 uint8_t mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5; | 2216 uint8_t mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5; |
2140 } | 2234 } |
2141 } else { | 2235 } else { |
2142 vdp_h32_mode4(context, target_cycles); | 2236 vdp_h32_mode4(context, target_cycles); |
2143 } | 2237 } |
2144 } else { | 2238 } else { |
2145 if (is_h40) { | 2239 vdp_inactive(context, target_cycles, is_h40, mode_5); |
2146 if (context->hslot == 161) { | |
2147 context->cur_slot = MAX_DRAWS-1; | |
2148 memset(context->linebuf, 0, LINEBUF_SIZE); | |
2149 } else if (context->hslot == 165) { | |
2150 context->sprite_index = 0x80; | |
2151 context->slot_counter = MAX_SPRITES_LINE; | |
2152 } | |
2153 } else if (mode_5){ | |
2154 if (context->hslot == 128) { | |
2155 context->cur_slot = MAX_DRAWS_H32-1; | |
2156 memset(context->linebuf, 0, LINEBUF_SIZE); | |
2157 } else if (context->hslot == 132) { | |
2158 context->sprite_index = 0x80; | |
2159 context->slot_counter = MAX_SPRITES_LINE_H32; | |
2160 } | |
2161 } else { | |
2162 if (context->hslot == 253) { | |
2163 context->sprite_index = 0; | |
2164 context->slot_counter = MAX_DRAWS_H32_MODE4; | |
2165 } else if (context->hslot == 136) { | |
2166 memset(context->linebuf, 0, LINEBUF_SIZE); | |
2167 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; | |
2168 context->sprite_draws = MAX_DRAWS_H32_MODE4; | |
2169 } | |
2170 } | |
2171 if(context->vcounter == context->inactive_start) { | |
2172 uint32_t intslot = context->regs[REG_MODE_4] & BIT_H40 ? VINT_SLOT_H40 : VINT_SLOT_H32; | |
2173 if (context->hslot == intslot) { | |
2174 context->flags2 |= FLAG2_VINT_PENDING; | |
2175 context->pending_vint_start = context->cycles; | |
2176 } | |
2177 } | |
2178 uint32_t inccycles; | |
2179 if (is_h40) { | |
2180 if (context->hslot == 182) { | |
2181 inccycles = h40_hsync_cycles[0]; | |
2182 } else if (context->hslot < HSYNC_SLOT_H40 || context->hslot >= HSYNC_END_H40) { | |
2183 inccycles = MCLKS_SLOT_H40; | |
2184 } else { | |
2185 inccycles = h40_hsync_cycles[context->hslot-HSYNC_SLOT_H40]; | |
2186 } | |
2187 } else { | |
2188 inccycles = MCLKS_SLOT_H32; | |
2189 } | |
2190 if (!is_refresh(context, context->hslot)) { | |
2191 external_slot(context); | |
2192 } | |
2193 if (context->vcounter < (context->inactive_start + context->border_bot) || context->vcounter > 0x200 - context->border_top) { | |
2194 check_render_bg(context, context->vcounter, context->hslot); | |
2195 } | |
2196 if (context->flags & FLAG_DMA_RUN && !is_refresh(context, context->hslot)) { | |
2197 run_dma_src(context, context->hslot); | |
2198 } | |
2199 context->cycles += inccycles; | |
2200 context->hslot++; | |
2201 if (is_h40) { | |
2202 if (context->hslot == LINE_CHANGE_H40) { | |
2203 vdp_advance_line(context); | |
2204 } else if (context->hslot == 183) { | |
2205 context->hslot = 229; | |
2206 } | |
2207 } else { | |
2208 if (context->hslot == (mode_5 ? LINE_CHANGE_H32 : LINE_CHANGE_MODE4)) { | |
2209 vdp_advance_line(context); | |
2210 } else if (context->hslot == 148) { | |
2211 context->hslot = 233; | |
2212 } | |
2213 } | |
2214 } | 2240 } |
2215 } | 2241 } |
2216 } | 2242 } |
2217 | 2243 |
2218 uint32_t vdp_run_to_vblank(vdp_context * context) | 2244 uint32_t vdp_run_to_vblank(vdp_context * context) |
2697 return vdp_next_vint_z80(context); | 2723 return vdp_next_vint_z80(context); |
2698 } | 2724 } |
2699 | 2725 |
2700 uint32_t vdp_next_vint_z80(vdp_context * context) | 2726 uint32_t vdp_next_vint_z80(vdp_context * context) |
2701 { | 2727 { |
2702 if (context->vcounter == context->inactive_start) { | 2728 uint16_t vint_line = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->inactive_start : context->inactive_start + 1; |
2729 if (context->vcounter == vint_line) { | |
2703 if (context->regs[REG_MODE_2] & BIT_MODE_5) { | 2730 if (context->regs[REG_MODE_2] & BIT_MODE_5) { |
2704 if (context->regs[REG_MODE_4] & BIT_H40) { | 2731 if (context->regs[REG_MODE_4] & BIT_H40) { |
2705 if (context->hslot >= LINE_CHANGE_H40 && context->hslot <= VINT_SLOT_H40) { | 2732 if (context->hslot >= LINE_CHANGE_H40 && context->hslot <= VINT_SLOT_H40) { |
2706 uint32_t cycles = context->cycles; | 2733 uint32_t cycles = context->cycles; |
2707 if (context->hslot < 182) { | 2734 if (context->hslot < 182) { |
2734 if (context->hslot <= VINT_SLOT_MODE4) { | 2761 if (context->hslot <= VINT_SLOT_MODE4) { |
2735 return context->cycles + (VINT_SLOT_MODE4 - context->hslot) * MCLKS_SLOT_H32; | 2762 return context->cycles + (VINT_SLOT_MODE4 - context->hslot) * MCLKS_SLOT_H32; |
2736 } | 2763 } |
2737 } | 2764 } |
2738 } | 2765 } |
2739 int32_t cycles_to_vint = vdp_cycles_to_line(context, context->inactive_start); | 2766 int32_t cycles_to_vint = vdp_cycles_to_line(context, vint_line); |
2740 if (context->regs[REG_MODE_2] & BIT_MODE_5) { | 2767 if (context->regs[REG_MODE_2] & BIT_MODE_5) { |
2741 if (context->regs[REG_MODE_4] & BIT_H40) { | 2768 if (context->regs[REG_MODE_4] & BIT_H40) { |
2742 cycles_to_vint += MCLKS_LINE - (LINE_CHANGE_H40 + (256 - VINT_SLOT_H40)) * MCLKS_SLOT_H40; | 2769 cycles_to_vint += MCLKS_LINE - (LINE_CHANGE_H40 + (256 - VINT_SLOT_H40)) * MCLKS_SLOT_H40; |
2743 } else { | 2770 } else { |
2744 cycles_to_vint += (VINT_SLOT_H32 - 233 + 148 - LINE_CHANGE_H32) * MCLKS_SLOT_H32; | 2771 cycles_to_vint += (VINT_SLOT_H32 - 233 + 148 - LINE_CHANGE_H32) * MCLKS_SLOT_H32; |