Mercurial > repos > blastem
comparison vdp.c @ 1380:9a5352a2f57a
Implement horizontal border in Mode 4 and make a minor fix to advance_output_line to handle the later vcounter increment in that mode
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 29 May 2017 22:19:33 -0700 |
parents | 71c8b97eb962 |
children | 1eded4f19910 |
comparison
equal
deleted
inserted
replaced
1379:65f1d6558e9e | 1380:9a5352a2f57a |
---|---|
127 } else if (context->state == INACTIVE) { | 127 } else if (context->state == INACTIVE) { |
128 //Undo forced INACTIVE state due to neither Mode 4 nor Mode 5 being active | 128 //Undo forced INACTIVE state due to neither Mode 4 nor Mode 5 being active |
129 if (context->vcounter < context->inactive_start) { | 129 if (context->vcounter < context->inactive_start) { |
130 context->state = ACTIVE; | 130 context->state = ACTIVE; |
131 } | 131 } |
132 /* | |
133 FIXME: uncomment this once mode 4 renderer is updated to handle this | |
134 else if (context->vcounter == 0x1FF) { | 132 else if (context->vcounter == 0x1FF) { |
135 context->state = PREPARING; | 133 context->state = PREPARING; |
136 } | 134 } |
137 */ | |
138 } | 135 } |
139 } | 136 } |
140 } | 137 } |
141 | 138 |
142 static uint8_t color_map_init_done; | 139 static uint8_t color_map_init_done; |
1280 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; | 1277 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; |
1281 for (int i = 0; i < BORDER_LEFT; i++, dst++) | 1278 for (int i = 0; i < BORDER_LEFT; i++, dst++) |
1282 { | 1279 { |
1283 *dst = bg_color; | 1280 *dst = bg_color; |
1284 } | 1281 } |
1282 context->done_output = dst; | |
1285 return; | 1283 return; |
1286 } | 1284 } |
1287 uint32_t color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; | 1285 uint32_t color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; |
1288 for (int i = 0; i < 16; i++) | 1286 for (int i = 0; i < 16; i++) |
1289 { | 1287 { |
1290 *(dst++) = color; | 1288 *(dst++) = color; |
1291 } | 1289 } |
1290 context->done_output = dst; | |
1292 return; | 1291 return; |
1293 } | 1292 } |
1294 line &= 0xFF; | 1293 line &= 0xFF; |
1295 render_map(context->col_2, context->tmp_buf_b, context->buf_b_off+8, context); | 1294 render_map(context->col_2, context->tmp_buf_b, context->buf_b_off+8, context); |
1296 uint8_t *sprite_buf, *plane_a, *plane_b; | 1295 uint8_t *sprite_buf, *plane_a, *plane_b; |
1577 *dst = (pixels >> i & 0xF) | pal_priority; | 1576 *dst = (pixels >> i & 0xF) | pal_priority; |
1578 } | 1577 } |
1579 context->buf_a_off = (context->buf_a_off + 8) & 15; | 1578 context->buf_a_off = (context->buf_a_off + 8) & 15; |
1580 | 1579 |
1581 uint8_t bgcolor = 0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3; | 1580 uint8_t bgcolor = 0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3; |
1582 uint32_t *dst = context->output + col * 8; | 1581 uint32_t *dst = context->output + col * 8 + BORDER_LEFT; |
1582 if (context->state == PREPARING) { | |
1583 for (int i = 0; i < 16; i++) | |
1584 { | |
1585 *(dst++) = context->colors[bgcolor]; | |
1586 } | |
1587 context->done_output = dst; | |
1588 return; | |
1589 } | |
1583 if (context->debug < 2) { | 1590 if (context->debug < 2) { |
1584 if (col || !(context->regs[REG_MODE_1] & BIT_COL0_MASK)) { | 1591 if (col || !(context->regs[REG_MODE_1] & BIT_COL0_MASK)) { |
1585 uint8_t *sprite_src = context->linebuf + col * 8; | 1592 uint8_t *sprite_src = context->linebuf + col * 8; |
1586 if (context->regs[REG_MODE_1] & BIT_SPRITE_8PX) { | 1593 if (context->regs[REG_MODE_1] & BIT_SPRITE_8PX) { |
1587 sprite_src += 8; | 1594 sprite_src += 8; |
1639 } | 1646 } |
1640 *(dst++) = render_map_color(value, value, value); | 1647 *(dst++) = render_map_color(value, value, value); |
1641 } | 1648 } |
1642 } | 1649 } |
1643 } | 1650 } |
1651 context->done_output = dst; | |
1644 } | 1652 } |
1645 | 1653 |
1646 static uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19}; | 1654 static uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19}; |
1647 | 1655 |
1648 static void vdp_advance_line(vdp_context *context) | 1656 static void vdp_advance_line(vdp_context *context) |
1720 context->fb = render_get_framebuffer(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD, &context->output_pitch); | 1728 context->fb = render_get_framebuffer(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD, &context->output_pitch); |
1721 context->h40_lines = 0; | 1729 context->h40_lines = 0; |
1722 context->frame++; | 1730 context->frame++; |
1723 context->output_lines = 0; | 1731 context->output_lines = 0; |
1724 } | 1732 } |
1725 uint32_t output_line; | 1733 uint32_t output_line = context->vcounter; |
1726 if (context->vcounter < context->inactive_start + context->border_bot && context->output_lines > 0) { | 1734 if (!(context->regs[REG_MODE_2] & BIT_MODE_5)) { |
1735 //vcounter increment occurs much later in Mode 4 | |
1736 output_line++; | |
1737 } | |
1738 if (output_line < context->inactive_start + context->border_bot && context->output_lines > 0) { | |
1727 output_line = context->output_lines++;//context->border_top + context->vcounter; | 1739 output_line = context->output_lines++;//context->border_top + context->vcounter; |
1728 } else if (context->vcounter >= 0x200 - context->border_top) { | 1740 } else if (output_line >= 0x200 - context->border_top) { |
1729 output_line = context->output_lines++;//context->vcounter - (0x200 - context->border_top); | 1741 output_line = context->output_lines++;//context->vcounter - (0x200 - context->border_top); |
1730 } else { | 1742 } else { |
1731 output_line = INVALID_LINE; | 1743 output_line = INVALID_LINE; |
1732 } | 1744 } |
1733 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * output_line); | 1745 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * output_line); |
1965 context->cycles += slot_cycles;\ | 1977 context->cycles += slot_cycles;\ |
1966 CHECK_ONLY | 1978 CHECK_ONLY |
1967 | 1979 |
1968 #define MODE4_CHECK_SLOT_LINE(slot) \ | 1980 #define MODE4_CHECK_SLOT_LINE(slot) \ |
1969 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ | 1981 if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } \ |
1982 if ((slot) == BG_START_SLOT + (256+HORIZ_BORDER)/2) {\ | |
1983 advance_output_line(context);\ | |
1984 }\ | |
1970 if ((slot) == 147) {\ | 1985 if ((slot) == 147) {\ |
1971 context->hslot = 233;\ | 1986 context->hslot = 233;\ |
1972 } else {\ | 1987 } else {\ |
1973 context->hslot++;\ | 1988 context->hslot++;\ |
1974 }\ | 1989 }\ |
1975 context->cycles += slot_cycles;\ | 1990 context->cycles += slot_cycles;\ |
1976 if ((slot+1) == LINE_CHANGE_MODE4) {\ | 1991 if ((slot+1) == LINE_CHANGE_MODE4) {\ |
1977 vdp_advance_line(context);\ | 1992 vdp_advance_line(context);\ |
1978 advance_output_line(context);\ | |
1979 if (context->vcounter == 192) {\ | 1993 if (context->vcounter == 192) {\ |
1980 return;\ | 1994 return;\ |
1981 }\ | 1995 }\ |
1982 }\ | 1996 }\ |
1983 CHECK_ONLY | 1997 CHECK_ONLY |
1993 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot,1))\ | 2007 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot,1))\ |
1994 case CALC_SLOT(slot, 2):\ | 2008 case CALC_SLOT(slot, 2):\ |
1995 fetch_sprite_cells_mode4(context);\ | 2009 fetch_sprite_cells_mode4(context);\ |
1996 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 2))\ | 2010 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 2))\ |
1997 case CALC_SLOT(slot, 3):\ | 2011 case CALC_SLOT(slot, 3):\ |
2012 if ((slot + 3) == 140) {\ | |
2013 uint32_t *dst = context->output + BORDER_LEFT + 256 + 8;\ | |
2014 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3];\ | |
2015 for (int i = 0; i < BORDER_RIGHT-8; i++, dst++)\ | |
2016 {\ | |
2017 *dst = bgcolor;\ | |
2018 }\ | |
2019 context->done_output = dst;\ | |
2020 }\ | |
1998 render_sprite_cells_mode4(context);\ | 2021 render_sprite_cells_mode4(context);\ |
1999 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 3))\ | 2022 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 3))\ |
2000 case CALC_SLOT(slot, 4):\ | 2023 case CALC_SLOT(slot, 4):\ |
2001 fetch_sprite_cells_mode4(context);\ | 2024 fetch_sprite_cells_mode4(context);\ |
2002 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 4))\ | 2025 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 4))\ |
2486 scan_sprite_table_mode4(context); | 2509 scan_sprite_table_mode4(context); |
2487 CHECK_LIMIT | 2510 CHECK_LIMIT |
2488 case 255: | 2511 case 255: |
2489 scan_sprite_table_mode4(context); | 2512 scan_sprite_table_mode4(context); |
2490 CHECK_LIMIT | 2513 CHECK_LIMIT |
2491 case 0: | 2514 case 0: { |
2492 scan_sprite_table_mode4(context); | 2515 scan_sprite_table_mode4(context); |
2493 CHECK_LIMIT | 2516 uint32_t *dst = context->output;; |
2517 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3]; | |
2518 for (int i = 0; i < BORDER_LEFT-8; i++, dst++) | |
2519 { | |
2520 *dst = bgcolor; | |
2521 } | |
2522 context->done_output = dst; | |
2523 CHECK_LIMIT | |
2524 } | |
2494 case 1: | 2525 case 1: |
2495 scan_sprite_table_mode4(context); | 2526 scan_sprite_table_mode4(context); |
2496 CHECK_LIMIT | 2527 CHECK_LIMIT |
2497 case 2: | 2528 case 2: |
2498 scan_sprite_table_mode4(context); | 2529 scan_sprite_table_mode4(context); |
2499 CHECK_LIMIT | 2530 CHECK_LIMIT |
2500 case 3: | 2531 case 3: |
2501 scan_sprite_table_mode4(context); | 2532 scan_sprite_table_mode4(context); |
2502 CHECK_LIMIT | 2533 CHECK_LIMIT |
2503 case 4: | 2534 case 4: { |
2504 scan_sprite_table_mode4(context); | 2535 scan_sprite_table_mode4(context); |
2505 context->buf_a_off = 8; | 2536 context->buf_a_off = 8; |
2506 memset(context->tmp_buf_a, 0, 8); | 2537 memset(context->tmp_buf_a, 0, 8); |
2507 CHECK_LIMIT | 2538 uint32_t *dst = context->output + BORDER_LEFT - 8; |
2539 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3]; | |
2540 for (int i = 0; i < 8; i++, dst++) | |
2541 { | |
2542 *dst = bgcolor; | |
2543 } | |
2544 context->done_output = dst; | |
2545 CHECK_LIMIT | |
2546 } | |
2508 COLUMN_RENDER_BLOCK_MODE4(0, 5) | 2547 COLUMN_RENDER_BLOCK_MODE4(0, 5) |
2509 COLUMN_RENDER_BLOCK_MODE4(1, 9) | 2548 COLUMN_RENDER_BLOCK_MODE4(1, 9) |
2510 COLUMN_RENDER_BLOCK_MODE4(2, 13) | 2549 COLUMN_RENDER_BLOCK_MODE4(2, 13) |
2511 COLUMN_RENDER_BLOCK_MODE4(3, 17) | 2550 COLUMN_RENDER_BLOCK_MODE4(3, 17) |
2512 COLUMN_RENDER_BLOCK_MODE4(4, 21) | 2551 COLUMN_RENDER_BLOCK_MODE4(4, 21) |
2544 external_slot(context); | 2583 external_slot(context); |
2545 CHECK_LIMIT | 2584 CHECK_LIMIT |
2546 case 135: | 2585 case 135: |
2547 external_slot(context); | 2586 external_slot(context); |
2548 CHECK_LIMIT | 2587 CHECK_LIMIT |
2549 case 136: | 2588 case 136: { |
2550 external_slot(context); | 2589 external_slot(context); |
2551 //set things up for sprite rendering in the next slot | 2590 //set things up for sprite rendering in the next slot |
2552 memset(context->linebuf, 0, LINEBUF_SIZE); | 2591 memset(context->linebuf, 0, LINEBUF_SIZE); |
2553 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; | 2592 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; |
2554 context->sprite_draws = MAX_DRAWS_H32_MODE4; | 2593 context->sprite_draws = MAX_DRAWS_H32_MODE4; |
2555 CHECK_LIMIT | 2594 uint32_t *dst = context->output + BORDER_LEFT + 256; |
2556 } | 2595 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3]; |
2596 for (int i = 0; i < 8; i++, dst++) | |
2597 { | |
2598 *dst = bgcolor; | |
2599 } | |
2600 context->done_output = dst; | |
2601 CHECK_LIMIT | |
2602 }} | |
2557 default: | 2603 default: |
2558 context->hslot++; | 2604 context->hslot++; |
2559 context->cycles += MCLKS_SLOT_H32; | 2605 context->cycles += MCLKS_SLOT_H32; |
2560 } | 2606 } |
2561 } | 2607 } |
2655 line_change = LINE_CHANGE_MODE4; | 2701 line_change = LINE_CHANGE_MODE4; |
2656 bg_color = render_map_color(0, 0, 0); | 2702 bg_color = render_map_color(0, 0, 0); |
2657 jump_start = 147; | 2703 jump_start = 147; |
2658 jump_dest = 233; | 2704 jump_dest = 233; |
2659 if (context->regs[REG_MODE_1] & BIT_MODE_4) { | 2705 if (context->regs[REG_MODE_1] & BIT_MODE_4) { |
2660 //FIXME: This is actually 0x1FF like in Mode 5 | 2706 active_line = 0x1FF; |
2661 active_line = 0; | |
2662 } else { | 2707 } else { |
2663 //never active unless either mode 4 or mode 5 is turned on | 2708 //never active unless either mode 4 or mode 5 is turned on |
2664 active_line = 0x200; | 2709 active_line = 0x200; |
2665 } | 2710 } |
2666 } | 2711 } |