Mercurial > repos > blastem
comparison vdp.c @ 1894:55d034719345
Fix regression in handling of color index 0 in Mode 4. Support Mode 4 in CRAM viewer window
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 06 Jan 2020 18:36:36 -0800 |
parents | 179a2ac29f27 |
children | 59a83c21d9d2 |
comparison
equal
deleted
inserted
replaced
1893:7b62e6805e6a | 1894:55d034719345 |
---|---|
1736 context->buf_a_off = (context->buf_a_off + 8) & 15; | 1736 context->buf_a_off = (context->buf_a_off + 8) & 15; |
1737 | 1737 |
1738 uint8_t *dst = context->compositebuf + col * 8 + BORDER_LEFT; | 1738 uint8_t *dst = context->compositebuf + col * 8 + BORDER_LEFT; |
1739 uint8_t *debug_dst = context->layer_debug_buf + col * 8 + BORDER_LEFT; | 1739 uint8_t *debug_dst = context->layer_debug_buf + col * 8 + BORDER_LEFT; |
1740 if (context->state == PREPARING) { | 1740 if (context->state == PREPARING) { |
1741 memset(dst, 0, 8); | 1741 memset(dst, 0x10 + (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET, 8); |
1742 memset(debug_dst, DBG_SRC_BG, 8); | 1742 memset(debug_dst, DBG_SRC_BG, 8); |
1743 context->done_composite = dst + 8; | 1743 context->done_composite = dst + 8; |
1744 return; | 1744 return; |
1745 } | 1745 } |
1746 | 1746 |
1763 *(debug_dst++) = DBG_SRC_S; | 1763 *(debug_dst++) = DBG_SRC_S; |
1764 } | 1764 } |
1765 } | 1765 } |
1766 context->done_composite = dst; | 1766 context->done_composite = dst; |
1767 } else { | 1767 } else { |
1768 memset(dst, 0, 8); | 1768 memset(dst, 0x10 + (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET, 8); |
1769 memset(dst, DBG_SRC_BG, 8); | 1769 memset(debug_dst, DBG_SRC_BG, 8); |
1770 context->done_composite = dst + 8; | 1770 context->done_composite = dst + 8; |
1771 } | 1771 } |
1772 } | 1772 } |
1773 | 1773 |
1774 static uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19}; | 1774 static uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19}; |
1820 } else { | 1820 } else { |
1821 line += context->border_top; | 1821 line += context->border_top; |
1822 } | 1822 } |
1823 if (context->enabled_debuggers & (1 << VDP_DEBUG_CRAM)) { | 1823 if (context->enabled_debuggers & (1 << VDP_DEBUG_CRAM)) { |
1824 uint32_t *fb = context->debug_fbs[VDP_DEBUG_CRAM] + context->debug_fb_pitch[VDP_DEBUG_CRAM] * line / sizeof(uint32_t); | 1824 uint32_t *fb = context->debug_fbs[VDP_DEBUG_CRAM] + context->debug_fb_pitch[VDP_DEBUG_CRAM] * line / sizeof(uint32_t); |
1825 for (int i = 0; i < 64; i++) | 1825 if (context->regs[REG_MODE_2] & BIT_MODE_5) { |
1826 { | 1826 for (int i = 0; i < 64; i++) |
1827 for (int x = 0; x < 8; x++) | |
1828 { | 1827 { |
1829 *(fb++) = context->colors[i]; | 1828 for (int x = 0; x < 8; x++) |
1829 { | |
1830 *(fb++) = context->colors[i]; | |
1831 } | |
1832 } | |
1833 } else { | |
1834 for (int i = MODE4_OFFSET; i < MODE4_OFFSET+32; i++) | |
1835 { | |
1836 for (int x = 0; x < 16; x++) | |
1837 { | |
1838 *(fb++) = context->colors[i]; | |
1839 } | |
1830 } | 1840 } |
1831 } | 1841 } |
1832 } | 1842 } |
1833 if ( | 1843 if ( |
1834 context->enabled_debuggers & (1 << VDP_DEBUG_COMPOSITE) | 1844 context->enabled_debuggers & (1 << VDP_DEBUG_COMPOSITE) |
1999 | 2009 |
2000 if (context->enabled_debuggers & (1 << VDP_DEBUG_CRAM)) { | 2010 if (context->enabled_debuggers & (1 << VDP_DEBUG_CRAM)) { |
2001 uint32_t starting_line = 512 - 32*4; | 2011 uint32_t starting_line = 512 - 32*4; |
2002 uint32_t *line = context->debug_fbs[VDP_DEBUG_CRAM] | 2012 uint32_t *line = context->debug_fbs[VDP_DEBUG_CRAM] |
2003 + context->debug_fb_pitch[VDP_DEBUG_CRAM] * starting_line / sizeof(uint32_t); | 2013 + context->debug_fb_pitch[VDP_DEBUG_CRAM] * starting_line / sizeof(uint32_t); |
2004 for (int pal = 0; pal < 4; pal ++) | 2014 if (context->regs[REG_MODE_2] & BIT_MODE_5) { |
2005 { | 2015 for (int pal = 0; pal < 4; pal ++) |
2006 uint32_t *cur; | |
2007 for (int y = 0; y < 31; y++) | |
2008 { | 2016 { |
2017 uint32_t *cur; | |
2018 for (int y = 0; y < 31; y++) | |
2019 { | |
2020 cur = line; | |
2021 for (int offset = 0; offset < 16; offset++) | |
2022 { | |
2023 for (int x = 0; x < 31; x++) | |
2024 { | |
2025 *(cur++) = context->colors[pal * 16 + offset]; | |
2026 } | |
2027 *(cur++) = 0xFF000000; | |
2028 } | |
2029 line += context->debug_fb_pitch[VDP_DEBUG_CRAM] / sizeof(uint32_t); | |
2030 } | |
2009 cur = line; | 2031 cur = line; |
2010 for (int offset = 0; offset < 16; offset++) | 2032 for (int x = 0; x < 512; x++) |
2011 { | 2033 { |
2012 for (int x = 0; x < 31; x++) | 2034 *(cur++) = 0xFF000000; |
2035 } | |
2036 line += context->debug_fb_pitch[VDP_DEBUG_CRAM] / sizeof(uint32_t); | |
2037 } | |
2038 } else { | |
2039 for (int pal = 0; pal < 2; pal ++) | |
2040 { | |
2041 uint32_t *cur; | |
2042 for (int y = 0; y < 31; y++) | |
2043 { | |
2044 cur = line; | |
2045 for (int offset = MODE4_OFFSET; offset < MODE4_OFFSET + 16; offset++) | |
2013 { | 2046 { |
2014 *(cur++) = context->colors[pal * 16 + offset]; | 2047 for (int x = 0; x < 31; x++) |
2048 { | |
2049 *(cur++) = context->colors[pal * 16 + offset]; | |
2050 } | |
2051 *(cur++) = 0xFF000000; | |
2015 } | 2052 } |
2053 line += context->debug_fb_pitch[VDP_DEBUG_CRAM] / sizeof(uint32_t); | |
2054 } | |
2055 cur = line; | |
2056 for (int x = 0; x < 512; x++) | |
2057 { | |
2016 *(cur++) = 0xFF000000; | 2058 *(cur++) = 0xFF000000; |
2017 } | 2059 } |
2018 line += context->debug_fb_pitch[VDP_DEBUG_CRAM] / sizeof(uint32_t); | 2060 line += context->debug_fb_pitch[VDP_DEBUG_CRAM] / sizeof(uint32_t); |
2019 } | 2061 } |
2020 cur = line; | |
2021 for (int x = 0; x < 512; x++) | |
2022 { | |
2023 *(cur++) = 0xFF000000; | |
2024 } | |
2025 line += context->debug_fb_pitch[VDP_DEBUG_CRAM] / sizeof(uint32_t); | |
2026 } | 2062 } |
2027 render_framebuffer_updated(context->debug_fb_indices[VDP_DEBUG_CRAM], 512); | 2063 render_framebuffer_updated(context->debug_fb_indices[VDP_DEBUG_CRAM], 512); |
2028 context->debug_fbs[VDP_DEBUG_CRAM] = render_get_framebuffer(context->debug_fb_indices[VDP_DEBUG_CRAM], &context->debug_fb_pitch[VDP_DEBUG_CRAM]); | 2064 context->debug_fbs[VDP_DEBUG_CRAM] = render_get_framebuffer(context->debug_fb_indices[VDP_DEBUG_CRAM], &context->debug_fb_pitch[VDP_DEBUG_CRAM]); |
2029 } | 2065 } |
2030 if (context->enabled_debuggers & (1 << VDP_DEBUG_COMPOSITE)) { | 2066 if (context->enabled_debuggers & (1 << VDP_DEBUG_COMPOSITE)) { |
2240 if (slot != (BG_START_SLOT + (256+HORIZ_BORDER)/2)) {\ | 2276 if (slot != (BG_START_SLOT + (256+HORIZ_BORDER)/2)) {\ |
2241 if ((*src & 0x3F) | test_layer) {\ | 2277 if ((*src & 0x3F) | test_layer) {\ |
2242 *(dst++) = context->colors[*(src++)];\ | 2278 *(dst++) = context->colors[*(src++)];\ |
2243 } else {\ | 2279 } else {\ |
2244 *(dst++) = context->colors[(*(src++) & 0xC0) | bgindex];\ | 2280 *(dst++) = context->colors[(*(src++) & 0xC0) | bgindex];\ |
2281 }\ | |
2282 }\ | |
2283 } | |
2284 | |
2285 //BG_START_SLOT => dst = 0, src = border | |
2286 //BG_START_SLOT + 13/2=6, dst = 6, src = border + comp + 13 | |
2287 #define OUTPUT_PIXEL_MODE4(slot) if ((slot) >= BG_START_SLOT) {\ | |
2288 uint8_t *src = context->compositebuf + ((slot) - BG_START_SLOT) *2;\ | |
2289 uint32_t *dst = context->output + ((slot) - BG_START_SLOT) *2;\ | |
2290 if ((slot) - BG_START_SLOT < BORDER_LEFT/2) {\ | |
2291 *(dst++) = context->colors[bgindex];\ | |
2292 *(dst++) = context->colors[bgindex];\ | |
2293 } else if ((slot) - BG_START_SLOT < (BORDER_LEFT+256)/2){\ | |
2294 if ((slot) - BG_START_SLOT == BORDER_LEFT/2) {\ | |
2295 *(dst++) = context->colors[bgindex];\ | |
2296 src++;\ | |
2297 } else {\ | |
2298 *(dst++) = context->colors[*(src++)];\ | |
2299 }\ | |
2300 *(dst++) = context->colors[*(src++)];\ | |
2301 } else if ((slot) - BG_START_SLOT <= (HORIZ_BORDER+256)/2) {\ | |
2302 *(dst++) = context->colors[bgindex];\ | |
2303 if ((slot) - BG_START_SLOT < (HORIZ_BORDER+256)/2) {\ | |
2304 *(dst++) = context->colors[bgindex];\ | |
2245 }\ | 2305 }\ |
2246 }\ | 2306 }\ |
2247 } | 2307 } |
2248 | 2308 |
2249 #define COLUMN_RENDER_BLOCK(column, startcyc) \ | 2309 #define COLUMN_RENDER_BLOCK(column, startcyc) \ |
2316 render_map_output(context->vcounter, column, context);\ | 2376 render_map_output(context->vcounter, column, context);\ |
2317 CHECK_LIMIT | 2377 CHECK_LIMIT |
2318 | 2378 |
2319 #define COLUMN_RENDER_BLOCK_MODE4(column, startcyc) \ | 2379 #define COLUMN_RENDER_BLOCK_MODE4(column, startcyc) \ |
2320 case startcyc:\ | 2380 case startcyc:\ |
2321 OUTPUT_PIXEL(startcyc)\ | 2381 OUTPUT_PIXEL_MODE4(startcyc)\ |
2322 read_map_mode4(column, context->vcounter, context);\ | 2382 read_map_mode4(column, context->vcounter, context);\ |
2323 CHECK_LIMIT\ | 2383 CHECK_LIMIT\ |
2324 case ((startcyc+1)&0xFF):\ | 2384 case ((startcyc+1)&0xFF):\ |
2325 OUTPUT_PIXEL((startcyc+1)&0xFF)\ | 2385 OUTPUT_PIXEL_MODE4((startcyc+1)&0xFF)\ |
2326 if (column & 3) {\ | 2386 if (column & 3) {\ |
2327 scan_sprite_table_mode4(context);\ | 2387 scan_sprite_table_mode4(context);\ |
2328 } else {\ | 2388 } else {\ |
2329 external_slot(context);\ | 2389 external_slot(context);\ |
2330 }\ | 2390 }\ |
2331 CHECK_LIMIT\ | 2391 CHECK_LIMIT\ |
2332 case ((startcyc+2)&0xFF):\ | 2392 case ((startcyc+2)&0xFF):\ |
2333 OUTPUT_PIXEL((startcyc+2)&0xFF)\ | 2393 OUTPUT_PIXEL_MODE4((startcyc+2)&0xFF)\ |
2334 fetch_map_mode4(column, context->vcounter, context);\ | 2394 fetch_map_mode4(column, context->vcounter, context);\ |
2335 CHECK_LIMIT\ | 2395 CHECK_LIMIT\ |
2336 case ((startcyc+3)&0xFF):\ | 2396 case ((startcyc+3)&0xFF):\ |
2337 OUTPUT_PIXEL((startcyc+3)&0xFF)\ | 2397 OUTPUT_PIXEL_MODE4((startcyc+3)&0xFF)\ |
2338 render_map_mode4(context->vcounter, column, context);\ | 2398 render_map_mode4(context->vcounter, column, context);\ |
2339 CHECK_LIMIT | 2399 CHECK_LIMIT |
2340 | 2400 |
2341 #define CHECK_LIMIT_HSYNC(slot) \ | 2401 #define CHECK_LIMIT_HSYNC(slot) \ |
2342 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ | 2402 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ |
2449 | 2509 |
2450 #define CALC_SLOT(slot, increment) ((slot+increment) > 147 && (slot+increment) < 233 ? (slot+increment-148+233): (slot+increment)) | 2510 #define CALC_SLOT(slot, increment) ((slot+increment) > 147 && (slot+increment) < 233 ? (slot+increment-148+233): (slot+increment)) |
2451 | 2511 |
2452 #define SPRITE_RENDER_H32_MODE4(slot) \ | 2512 #define SPRITE_RENDER_H32_MODE4(slot) \ |
2453 case slot:\ | 2513 case slot:\ |
2454 OUTPUT_PIXEL_H32(slot)\ | 2514 OUTPUT_PIXEL_MODE4(slot)\ |
2455 read_sprite_x_mode4(context);\ | 2515 read_sprite_x_mode4(context);\ |
2456 MODE4_CHECK_SLOT_LINE(slot)\ | 2516 MODE4_CHECK_SLOT_LINE(slot)\ |
2457 case CALC_SLOT(slot, 1):\ | 2517 case CALC_SLOT(slot, 1):\ |
2458 OUTPUT_PIXEL(CALC_SLOT(slot, 1))\ | 2518 OUTPUT_PIXEL_MODE4(CALC_SLOT(slot, 1))\ |
2459 read_sprite_x_mode4(context);\ | 2519 read_sprite_x_mode4(context);\ |
2460 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot,1))\ | 2520 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot,1))\ |
2461 case CALC_SLOT(slot, 2):\ | 2521 case CALC_SLOT(slot, 2):\ |
2462 OUTPUT_PIXEL(CALC_SLOT(slot, 2))\ | 2522 OUTPUT_PIXEL_MODE4(CALC_SLOT(slot, 2))\ |
2463 fetch_sprite_cells_mode4(context);\ | 2523 fetch_sprite_cells_mode4(context);\ |
2464 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 2))\ | 2524 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 2))\ |
2465 case CALC_SLOT(slot, 3):\ | 2525 case CALC_SLOT(slot, 3):\ |
2466 OUTPUT_PIXEL(CALC_SLOT(slot, 3))\ | 2526 OUTPUT_PIXEL_MODE4(CALC_SLOT(slot, 3))\ |
2467 render_sprite_cells_mode4(context);\ | 2527 render_sprite_cells_mode4(context);\ |
2468 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 3))\ | 2528 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 3))\ |
2469 case CALC_SLOT(slot, 4):\ | 2529 case CALC_SLOT(slot, 4):\ |
2470 OUTPUT_PIXEL(CALC_SLOT(slot, 4))\ | 2530 OUTPUT_PIXEL_MODE4(CALC_SLOT(slot, 4))\ |
2471 fetch_sprite_cells_mode4(context);\ | 2531 fetch_sprite_cells_mode4(context);\ |
2472 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 4))\ | 2532 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 4))\ |
2473 case CALC_SLOT(slot, 5):\ | 2533 case CALC_SLOT(slot, 5):\ |
2474 OUTPUT_PIXEL(CALC_SLOT(slot, 5))\ | 2534 OUTPUT_PIXEL_MODE4(CALC_SLOT(slot, 5))\ |
2475 render_sprite_cells_mode4(context);\ | 2535 render_sprite_cells_mode4(context);\ |
2476 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 5)) | 2536 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 5)) |
2477 | 2537 |
2478 static uint32_t dummy_buffer[LINEBUF_SIZE]; | 2538 static uint32_t dummy_buffer[LINEBUF_SIZE]; |
2479 static void vdp_h40_line(vdp_context * context) | 2539 static void vdp_h40_line(vdp_context * context) |
3220 COLUMN_RENDER_BLOCK_MODE4(28, 117) | 3280 COLUMN_RENDER_BLOCK_MODE4(28, 117) |
3221 COLUMN_RENDER_BLOCK_MODE4(29, 121) | 3281 COLUMN_RENDER_BLOCK_MODE4(29, 121) |
3222 COLUMN_RENDER_BLOCK_MODE4(30, 125) | 3282 COLUMN_RENDER_BLOCK_MODE4(30, 125) |
3223 COLUMN_RENDER_BLOCK_MODE4(31, 129) | 3283 COLUMN_RENDER_BLOCK_MODE4(31, 129) |
3224 case 133: | 3284 case 133: |
3225 OUTPUT_PIXEL(133) | 3285 OUTPUT_PIXEL_MODE4(133) |
3226 external_slot(context); | 3286 external_slot(context); |
3227 CHECK_LIMIT | 3287 CHECK_LIMIT |
3228 case 134: | 3288 case 134: |
3229 OUTPUT_PIXEL(134) | 3289 OUTPUT_PIXEL_MODE4(134) |
3230 external_slot(context); | 3290 external_slot(context); |
3231 CHECK_LIMIT | 3291 CHECK_LIMIT |
3232 case 135: | 3292 case 135: |
3233 OUTPUT_PIXEL(135) | 3293 OUTPUT_PIXEL_MODE4(135) |
3234 external_slot(context); | 3294 external_slot(context); |
3235 CHECK_LIMIT | 3295 CHECK_LIMIT |
3236 case 136: { | 3296 case 136: { |
3237 OUTPUT_PIXEL(136) | 3297 OUTPUT_PIXEL_MODE4(136) |
3238 external_slot(context); | 3298 external_slot(context); |
3239 //set things up for sprite rendering in the next slot | 3299 //set things up for sprite rendering in the next slot |
3240 memset(context->linebuf, 0, LINEBUF_SIZE); | 3300 memset(context->linebuf, 0, LINEBUF_SIZE); |
3241 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; | 3301 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; |
3242 context->sprite_draws = MAX_DRAWS_H32_MODE4; | 3302 context->sprite_draws = MAX_DRAWS_H32_MODE4; |
3302 static void vdp_inactive(vdp_context *context, uint32_t target_cycles, uint8_t is_h40, uint8_t mode_5) | 3362 static void vdp_inactive(vdp_context *context, uint32_t target_cycles, uint8_t is_h40, uint8_t mode_5) |
3303 { | 3363 { |
3304 uint8_t buf_clear_slot, index_reset_slot, bg_end_slot, vint_slot, line_change, jump_start, jump_dest, latch_slot; | 3364 uint8_t buf_clear_slot, index_reset_slot, bg_end_slot, vint_slot, line_change, jump_start, jump_dest, latch_slot; |
3305 uint8_t index_reset_value, max_draws, max_sprites; | 3365 uint8_t index_reset_value, max_draws, max_sprites; |
3306 uint16_t vint_line, active_line; | 3366 uint16_t vint_line, active_line; |
3307 uint32_t bg_color; | |
3308 | 3367 |
3309 if (mode_5) { | 3368 if (mode_5) { |
3310 if (is_h40) { | 3369 if (is_h40) { |
3311 latch_slot = 165; | 3370 latch_slot = 165; |
3312 buf_clear_slot = 163; | 3371 buf_clear_slot = 163; |
3346 index_reset_slot = 253; | 3405 index_reset_slot = 253; |
3347 index_reset_value = 0; | 3406 index_reset_value = 0; |
3348 vint_line = context->inactive_start + 1; | 3407 vint_line = context->inactive_start + 1; |
3349 vint_slot = VINT_SLOT_MODE4; | 3408 vint_slot = VINT_SLOT_MODE4; |
3350 line_change = LINE_CHANGE_MODE4; | 3409 line_change = LINE_CHANGE_MODE4; |
3351 bg_color = render_map_color(0, 0, 0); | |
3352 jump_start = 147; | 3410 jump_start = 147; |
3353 jump_dest = 233; | 3411 jump_dest = 233; |
3354 if (context->regs[REG_MODE_1] & BIT_MODE_4) { | 3412 if (context->regs[REG_MODE_1] & BIT_MODE_4) { |
3355 active_line = 0x1FF; | 3413 active_line = 0x1FF; |
3356 } else { | 3414 } else { |
3429 context->flags2 ^= FLAG2_EVEN_FIELD; | 3487 context->flags2 ^= FLAG2_EVEN_FIELD; |
3430 } | 3488 } |
3431 | 3489 |
3432 if (dst) { | 3490 if (dst) { |
3433 uint8_t bg_index; | 3491 uint8_t bg_index; |
3492 uint32_t bg_color; | |
3434 if (mode_5) { | 3493 if (mode_5) { |
3435 bg_index = context->regs[REG_BG_COLOR] & 0x3F; | 3494 bg_index = context->regs[REG_BG_COLOR] & 0x3F; |
3436 bg_color = context->colors[bg_index]; | 3495 bg_color = context->colors[bg_index]; |
3437 } else if (context->regs[REG_MODE_1] & BIT_MODE_4) { | 3496 } else if (context->regs[REG_MODE_1] & BIT_MODE_4) { |
3438 bg_index = 0x10 + (context->regs[REG_BG_COLOR] & 0xF); | 3497 bg_index = 0x10 + (context->regs[REG_BG_COLOR] & 0xF); |