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;