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 }