comparison vdp.c @ 1325:58bfbed6cdb5

Fairly major rework of how active/passive is handled along with how the V30 mode bit is handled. Allows the vertical border extension trick in Overdrive 2 to work right
author Michael Pavone <pavone@retrodev.com>
date Fri, 21 Apr 2017 01:22:52 -0700
parents b1423d432c0e
children 9bba5ff5beb8
comparison
equal deleted inserted replaced
1324:2fc444b69351 1325:58bfbed6cdb5
53 #define BORDER_BOT_V28_PAL 32 53 #define BORDER_BOT_V28_PAL 32
54 #define BORDER_BOT_V30_PAL 24 54 #define BORDER_BOT_V30_PAL 24
55 55
56 #define INVALID_LINE 0x200 56 #define INVALID_LINE 0x200
57 57
58 enum {
59 INACTIVE = 0,
60 PREPARING, //used for line 0x1FF
61 ACTIVE
62 };
63
58 static int32_t color_map[1 << 12]; 64 static int32_t color_map[1 << 12];
59 static uint16_t mode4_address_map[0x4000]; 65 static uint16_t mode4_address_map[0x4000];
60 static uint32_t planar_to_chunky[256]; 66 static uint32_t planar_to_chunky[256];
61 static uint8_t levels[] = {0, 27, 49, 71, 87, 103, 119, 130, 146, 157, 174, 190, 206, 228, 255}; 67 static uint8_t levels[] = {0, 27, 49, 71, 87, 103, 119, 130, 146, 157, 174, 190, 206, 228, 255};
62 68
69 }; 75 };
70 76
71 static void update_video_params(vdp_context *context) 77 static void update_video_params(vdp_context *context)
72 { 78 {
73 if (context->regs[REG_MODE_2] & BIT_MODE_5) { 79 if (context->regs[REG_MODE_2] & BIT_MODE_5) {
74 if (context->latched_mode & BIT_PAL) { 80 if (context->regs[REG_MODE_2] & BIT_PAL) {
75 if (context->flags2 & FLAG2_REGION_PAL) { 81 if (context->flags2 & FLAG2_REGION_PAL) {
76 context->inactive_start = PAL_INACTIVE_START; 82 context->inactive_start = PAL_INACTIVE_START;
77 context->border_top = BORDER_TOP_V30_PAL; 83 context->border_top = BORDER_TOP_V30_PAL;
78 context->border_bot = BORDER_BOT_V30_PAL; 84 context->border_bot = BORDER_BOT_V30_PAL;
79 } else { 85 } else {
80 context->inactive_start = 0x200; 86 //the behavior here is rather weird and needs more investigation
81 context->border_top = context->border_bot = 0; 87 context->inactive_start = 0xF0;
88 context->border_top = 1;
89 context->border_bot = 3;
82 } 90 }
83 } else { 91 } else {
84 context->inactive_start = NTSC_INACTIVE_START; 92 context->inactive_start = NTSC_INACTIVE_START;
85 if (context->flags2 & FLAG2_REGION_PAL) { 93 if (context->flags2 & FLAG2_REGION_PAL) {
86 context->border_top = BORDER_TOP_V28_PAL; 94 context->border_top = BORDER_TOP_V28_PAL;
88 } else { 96 } else {
89 context->border_top = BORDER_TOP_V28; 97 context->border_top = BORDER_TOP_V28;
90 context->border_bot = BORDER_TOP_V28; 98 context->border_bot = BORDER_TOP_V28;
91 } 99 }
92 } 100 }
101 if (context->state == INACTIVE) {
102 //Undo forced INACTIVE state due to neither Mode 4 nor Mode 5 being active
103 if (context->vcounter < context->inactive_start) {
104 context->state = ACTIVE;
105 } else if (context->vcounter == 0x1FF) {
106 context->state = PREPARING;
107 }
108 }
93 } else { 109 } else {
94 context->inactive_start = MODE4_INACTIVE_START; 110 context->inactive_start = MODE4_INACTIVE_START;
95 if (context->flags2 & FLAG2_REGION_PAL) { 111 if (context->flags2 & FLAG2_REGION_PAL) {
96 context->border_top = BORDER_TOP_V24_PAL; 112 context->border_top = BORDER_TOP_V24_PAL;
97 context->border_bot = BORDER_BOT_V24_PAL; 113 context->border_bot = BORDER_BOT_V24_PAL;
98 } else { 114 } else {
99 context->border_top = BORDER_TOP_V24; 115 context->border_top = BORDER_TOP_V24;
100 context->border_bot = BORDER_BOT_V24; 116 context->border_bot = BORDER_BOT_V24;
117 }
118 if (!(context->regs[REG_MODE_1] & BIT_MODE_4)){
119 context->state = INACTIVE;
120 } else if (context->state == INACTIVE) {
121 //Undo forced INACTIVE state due to neither Mode 4 nor Mode 5 being active
122 if (context->vcounter < context->inactive_start) {
123 context->state = ACTIVE;
124 }
125 /*
126 FIXME: uncomment this once mode 4 renderer is updated to handle this
127 else if (context->vcounter == 0x1FF) {
128 context->state = PREPARING;
129 }
130 */
101 } 131 }
102 } 132 }
103 } 133 }
104 134
105 static uint8_t color_map_init_done; 135 static uint8_t color_map_init_done;
505 (context->flags2 & FLAG2_HINT_PENDING) ? "true" : "false", vdp_control_port_read(context)); 535 (context->flags2 & FLAG2_HINT_PENDING) ? "true" : "false", vdp_control_port_read(context));
506 536
507 //TODO: Window Group, DMA Group 537 //TODO: Window Group, DMA Group
508 } 538 }
509 539
540 static uint8_t is_active(vdp_context *context)
541 {
542 return context->state != INACTIVE && (context->regs[REG_MODE_2] & BIT_DISP_EN) != 0;
543 }
544
510 static void scan_sprite_table(uint32_t line, vdp_context * context) 545 static void scan_sprite_table(uint32_t line, vdp_context * context)
511 { 546 {
512 if (context->sprite_index && context->slot_counter) { 547 if (context->sprite_index && context->slot_counter) {
513 line += 1; 548 line += 1;
514 line &= 0xFF; 549 line &= 0xFF;
1199 } 1234 }
1200 1235
1201 static void render_map_output(uint32_t line, int32_t col, vdp_context * context) 1236 static void render_map_output(uint32_t line, int32_t col, vdp_context * context)
1202 { 1237 {
1203 uint32_t *dst; 1238 uint32_t *dst;
1204 if (line == 0x1FF) { 1239 if (context->state == PREPARING) {
1205 if (!col) { 1240 if (!col) {
1206 return; 1241 return;
1207 } 1242 }
1208 col -= 2; 1243 col -= 2;
1209 if (col) { 1244 if (col) {
1221 { 1256 {
1222 *(dst++) = color; 1257 *(dst++) = color;
1223 } 1258 }
1224 return; 1259 return;
1225 } 1260 }
1226 if (line >= 240) { 1261 line &= 0xFF;
1227 return;
1228 }
1229 render_map(context->col_2, context->tmp_buf_b, context->buf_b_off+8, context); 1262 render_map(context->col_2, context->tmp_buf_b, context->buf_b_off+8, context);
1230 uint8_t *sprite_buf, *plane_a, *plane_b; 1263 uint8_t *sprite_buf, *plane_a, *plane_b;
1231 int plane_a_off, plane_b_off; 1264 int plane_a_off, plane_b_off;
1232 if (col) 1265 if (col)
1233 { 1266 {
1303 //TODO: Simulate CRAM corruption from bus fight 1336 //TODO: Simulate CRAM corruption from bus fight
1304 switch (test_layer) 1337 switch (test_layer)
1305 { 1338 {
1306 case 1: 1339 case 1:
1307 pixel &= *sprite_buf; 1340 pixel &= *sprite_buf;
1341 if (output_disabled && pixel) {
1342 src = DBG_SRC_S;
1343 }
1308 break; 1344 break;
1309 case 2: 1345 case 2:
1310 pixel &= *plane_a; 1346 pixel &= *plane_a;
1347 if (output_disabled && pixel) {
1348 src = DBG_SRC_A;
1349 }
1311 break; 1350 break;
1312 case 3: 1351 case 3:
1313 pixel &= *plane_b; 1352 pixel &= *plane_b;
1353 if (output_disabled && pixel) {
1354 src = DBG_SRC_B;
1355 }
1314 break; 1356 break;
1315 } 1357 }
1316 1358
1317 uint32_t outpixel; 1359 uint32_t outpixel;
1318 if (context->debug) { 1360 if (context->debug) {
1347 //TODO: Simulate CRAM corruption from bus fight 1389 //TODO: Simulate CRAM corruption from bus fight
1348 switch (test_layer) 1390 switch (test_layer)
1349 { 1391 {
1350 case 1: 1392 case 1:
1351 pixel &= *sprite_buf; 1393 pixel &= *sprite_buf;
1394 if (output_disabled && pixel) {
1395 src = DBG_SRC_S;
1396 }
1352 break; 1397 break;
1353 case 2: 1398 case 2:
1354 pixel &= *plane_a; 1399 pixel &= *plane_a;
1400 if (output_disabled && pixel) {
1401 src = DBG_SRC_A;
1402 }
1355 break; 1403 break;
1356 case 3: 1404 case 3:
1357 pixel &= *plane_b; 1405 pixel &= *plane_b;
1406 if (output_disabled && pixel) {
1407 src = DBG_SRC_B;
1408 }
1358 break; 1409 break;
1359 } 1410 }
1360 uint32_t outpixel; 1411 uint32_t outpixel;
1361 if (context->debug) { 1412 if (context->debug) {
1362 outpixel = context->debugcolors[src]; 1413 outpixel = context->debugcolors[src];
1537 context->vcounter++; 1588 context->vcounter++;
1538 1589
1539 uint8_t is_mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5; 1590 uint8_t is_mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5;
1540 if (is_mode_5) { 1591 if (is_mode_5) {
1541 if (context->flags2 & FLAG2_REGION_PAL) { 1592 if (context->flags2 & FLAG2_REGION_PAL) {
1542 if (context->latched_mode & BIT_PAL) { 1593 if (context->regs[REG_MODE_2] & BIT_PAL) {
1543 if (context->vcounter == 0x10B) { 1594 if (context->vcounter == 0x10B) {
1544 context->vcounter = 0x1D2; 1595 context->vcounter = 0x1D2;
1545 } 1596 }
1546 } else if (context->vcounter == 0x103){ 1597 } else if (context->vcounter == 0x103){
1547 context->vcounter = 0x1CA; 1598 context->vcounter = 0x1CA;
1548 } 1599 }
1549 } else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) { 1600 } else {
1550 context->vcounter = 0x1E5; 1601 if (context->regs[REG_MODE_2] & BIT_PAL) {
1551 } 1602 if (context->vcounter == 0x100) {
1552 if (context->vcounter == 0x200 - context->border_top) { 1603 context->vcounter = 0x1FA;
1553 latch_mode(context); 1604 }
1605 } else if (context->vcounter == 0xEB) {
1606 context->vcounter = 0x1E5;
1607 }
1554 } 1608 }
1555 } else if (context->vcounter == 0xDB) { 1609 } else if (context->vcounter == 0xDB) {
1556 context->vcounter = 0x1D5; 1610 context->vcounter = 0x1D5;
1557 } 1611 }
1558 context->vcounter &= 0x1FF; 1612 context->vcounter &= 0x1FF;
1559 1613 if (context->state == PREPARING) {
1560 if (context->vcounter > context->inactive_start) { 1614 context->state = ACTIVE;
1615 }
1616
1617 if (context->state != ACTIVE) {
1561 context->hint_counter = context->regs[REG_HINT]; 1618 context->hint_counter = context->regs[REG_HINT];
1562 } else if (context->hint_counter) { 1619 } else if (context->hint_counter) {
1563 context->hint_counter--; 1620 context->hint_counter--;
1564 } else { 1621 } else {
1565 context->flags2 |= FLAG2_HINT_PENDING; 1622 context->flags2 |= FLAG2_HINT_PENDING;
1574 if (context->vcounter == context->inactive_start) { 1631 if (context->vcounter == context->inactive_start) {
1575 context->frame++; 1632 context->frame++;
1576 } 1633 }
1577 context->vcounter &= 0x1FF; 1634 context->vcounter &= 0x1FF;
1578 } else { 1635 } else {
1579 if (context->vcounter == (context->inactive_start & 0x1FF)) { 1636 uint16_t lines_max = (context->flags2 & FLAG2_REGION_PAL)
1637 ? 240 + BORDER_TOP_V30_PAL + BORDER_BOT_V30_PAL
1638 : 224 + BORDER_TOP_V28 + BORDER_BOT_V28;
1639
1640 if (context->output_lines == lines_max) {
1580 render_framebuffer_updated(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN: FRAMEBUFFER_ODD, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER)); 1641 render_framebuffer_updated(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN: FRAMEBUFFER_ODD, context->h40_lines > (context->inactive_start + context->border_top) / 2 ? LINEBUF_SIZE : (256+HORIZ_BORDER));
1581 if (context->double_res) { 1642 if (context->double_res) {
1582 context->flags2 ^= FLAG2_EVEN_FIELD; 1643 context->flags2 ^= FLAG2_EVEN_FIELD;
1583 } 1644 }
1584 context->fb = render_get_framebuffer(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD, &context->output_pitch); 1645 context->fb = render_get_framebuffer(context->flags2 & FLAG2_EVEN_FIELD ? FRAMEBUFFER_EVEN : FRAMEBUFFER_ODD, &context->output_pitch);
1585 context->h40_lines = 0; 1646 context->h40_lines = 0;
1586 context->frame++; 1647 context->frame++;
1648 context->output_lines = 0;
1587 } 1649 }
1588 uint32_t output_line; 1650 uint32_t output_line;
1589 if (context->vcounter < context->inactive_start + context->border_bot) { 1651 if (context->vcounter < context->inactive_start + context->border_bot && context->output_lines > 0) {
1590 output_line = context->border_top + context->vcounter; 1652 output_line = context->output_lines++;//context->border_top + context->vcounter;
1591 } else if (context->vcounter > 0x200 - context->border_top) { 1653 } else if (context->vcounter >= 0x200 - context->border_top) {
1592 output_line = context->vcounter - (0x200 - context->border_top); 1654 output_line = context->output_lines++;//context->vcounter - (0x200 - context->border_top);
1593 } else { 1655 } else {
1594 output_line = INVALID_LINE; 1656 output_line = INVALID_LINE;
1595 } 1657 }
1596 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * output_line); 1658 context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * output_line);
1597 #ifdef DEBUG_FB_FILL 1659 #ifdef DEBUG_FB_FILL
1598 for (int i = 0; i < LINEBUF_SIZE; i++) 1660 for (int i = 0; i < LINEBUF_SIZE; i++)
1599 { 1661 {
1600 context->output[i] = 0xFFFF00FF; 1662 context->output[i] = 0xFFFF00FF;
1768 switch(context->hslot) 1830 switch(context->hslot)
1769 { 1831 {
1770 for (;;) 1832 for (;;)
1771 { 1833 {
1772 case 165: 1834 case 165:
1773 if (context->vcounter == 0x1FF) { 1835 if (context->state == PREPARING) {
1774 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; 1836 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
1775 uint32_t *dst; 1837 uint32_t *dst;
1776 if (headless) { 1838 if (headless) {
1777 dst = context->output; 1839 dst = context->output;
1778 } else { 1840 } else {
1785 } else { 1847 } else {
1786 render_sprite_cells(context); 1848 render_sprite_cells(context);
1787 } 1849 }
1788 CHECK_LIMIT 1850 CHECK_LIMIT
1789 case 166: 1851 case 166:
1790 if (context->vcounter == 0x1FF) { 1852 if (context->state == PREPARING) {
1791 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; 1853 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
1792 uint32_t *dst; 1854 uint32_t *dst;
1793 if (headless) { 1855 if (headless) {
1794 dst = context->output; 1856 dst = context->output;
1795 } else { 1857 } else {
1803 render_sprite_cells(context); 1865 render_sprite_cells(context);
1804 } 1866 }
1805 CHECK_LIMIT 1867 CHECK_LIMIT
1806 //sprite attribute table scan starts 1868 //sprite attribute table scan starts
1807 case 167: 1869 case 167:
1808 if (context->vcounter == 0x1FF) { 1870 if (context->state == PREPARING) {
1809 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; 1871 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
1810 uint32_t *dst; 1872 uint32_t *dst;
1811 if (headless) { 1873 if (headless) {
1812 dst = context->output; 1874 dst = context->output;
1813 } else { 1875 } else {
1975 switch(context->hslot) 2037 switch(context->hslot)
1976 { 2038 {
1977 for (;;) 2039 for (;;)
1978 { 2040 {
1979 case 133: 2041 case 133:
1980 if (context->vcounter == 0x1FF) { 2042 if (context->state == PREPARING) {
1981 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; 2043 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
1982 uint32_t *dst; 2044 uint32_t *dst;
1983 if (headless) { 2045 if (headless) {
1984 dst = context->output; 2046 dst = context->output;
1985 } else { 2047 } else {
1992 } else { 2054 } else {
1993 render_sprite_cells(context); 2055 render_sprite_cells(context);
1994 } 2056 }
1995 CHECK_LIMIT 2057 CHECK_LIMIT
1996 case 134: 2058 case 134:
1997 if (context->vcounter == 0x1FF) { 2059 if (context->state == PREPARING) {
1998 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; 2060 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
1999 uint32_t *dst; 2061 uint32_t *dst;
2000 if (headless) { 2062 if (headless) {
2001 dst = context->output; 2063 dst = context->output;
2002 } else { 2064 } else {
2010 render_sprite_cells(context); 2072 render_sprite_cells(context);
2011 } 2073 }
2012 CHECK_LIMIT 2074 CHECK_LIMIT
2013 //sprite attribute table scan starts 2075 //sprite attribute table scan starts
2014 case 135: //FIXME - Here 2076 case 135: //FIXME - Here
2015 if (context->vcounter == 0x1FF) { 2077 if (context->state == PREPARING) {
2016 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; 2078 uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
2017 uint32_t *dst; 2079 uint32_t *dst;
2018 if (headless) { 2080 if (headless) {
2019 dst = context->output; 2081 dst = context->output;
2020 } else { 2082 } else {
2286 context->hslot++; 2348 context->hslot++;
2287 context->cycles += MCLKS_SLOT_H32; 2349 context->cycles += MCLKS_SLOT_H32;
2288 } 2350 }
2289 } 2351 }
2290 2352
2291 void latch_mode(vdp_context * context)
2292 {
2293 context->latched_mode = context->regs[REG_MODE_2] & BIT_PAL;
2294 update_video_params(context);
2295 }
2296
2297 static void vdp_inactive(vdp_context *context, uint32_t target_cycles, uint8_t is_h40, uint8_t mode_5) 2353 static void vdp_inactive(vdp_context *context, uint32_t target_cycles, uint8_t is_h40, uint8_t mode_5)
2298 { 2354 {
2299 uint8_t buf_clear_slot, index_reset_slot, bg_end_slot, vint_slot, line_change, jump_start, jump_dest; 2355 uint8_t buf_clear_slot, index_reset_slot, bg_end_slot, vint_slot, line_change, jump_start, jump_dest;
2300 uint8_t index_reset_value, max_draws, max_sprites; 2356 uint8_t index_reset_value, max_draws, max_sprites;
2301 uint16_t vint_line, active_line; 2357 uint16_t vint_line, active_line;
2338 vint_slot = VINT_SLOT_MODE4; 2394 vint_slot = VINT_SLOT_MODE4;
2339 line_change = LINE_CHANGE_MODE4; 2395 line_change = LINE_CHANGE_MODE4;
2340 bg_color = render_map_color(0, 0, 0); 2396 bg_color = render_map_color(0, 0, 0);
2341 jump_start = 147; 2397 jump_start = 147;
2342 jump_dest = 233; 2398 jump_dest = 233;
2343 active_line = 0; 2399 if (context->regs[REG_MODE_1] & BIT_MODE_4) {
2400 //FIXME: This is actually 0x1FF like in Mode 5
2401 active_line = 0;
2402 } else {
2403 //never active unless either mode 4 or mode 5 is turned on
2404 active_line = 0x200;
2405 }
2344 } 2406 }
2345 uint32_t *dst = ( 2407 uint32_t *dst = (
2346 context->vcounter < context->inactive_start + context->border_bot 2408 context->vcounter < context->inactive_start + context->border_bot
2347 || context->vcounter > 0x200 - context->border_top 2409 || context->vcounter > 0x200 - context->border_top
2348 ) && context->hslot >= BG_START_SLOT && context->hslot < bg_end_slot 2410 ) && context->hslot >= BG_START_SLOT && context->hslot < bg_end_slot
2412 context->hslot++; 2474 context->hslot++;
2413 } 2475 }
2414 if (context->hslot == line_change) { 2476 if (context->hslot == line_change) {
2415 vdp_advance_line(context); 2477 vdp_advance_line(context);
2416 if (context->vcounter == active_line) { 2478 if (context->vcounter == active_line) {
2479 context->state = PREPARING;
2417 return; 2480 return;
2418 } 2481 }
2419 } 2482 }
2420 } 2483 }
2421 } 2484 }
2424 { 2487 {
2425 uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40; 2488 uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40;
2426 uint8_t mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5; 2489 uint8_t mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5;
2427 while(context->cycles < target_cycles) 2490 while(context->cycles < target_cycles)
2428 { 2491 {
2429 uint8_t active_slot; 2492 if (context->state == ACTIVE && context->vcounter == context->inactive_start) {
2430 if (mode_5) { 2493 context->state = INACTIVE;
2431 //line 0x1FF is basically active even though it's not displayed
2432 active_slot = (context->vcounter < context->inactive_start || context->vcounter == 0x1FF) && (context->regs[REG_MODE_2] & DISPLAY_ENABLE);
2433 } else {
2434 //display is effectively disabled if neither mode 5 nor mode 4 are selected
2435 active_slot = context->vcounter < context->inactive_start && (context->regs[REG_MODE_2] & DISPLAY_ENABLE) && (context->regs[REG_MODE_1] & BIT_MODE_4);
2436 } 2494 }
2437 2495
2438 if (active_slot) { 2496 if (is_active(context)) {
2439 if (mode_5) { 2497 if (mode_5) {
2440 if (is_h40) { 2498 if (is_h40) {
2441 vdp_h40(context, target_cycles); 2499 vdp_h40(context, target_cycles);
2442 } else { 2500 } else {
2443 vdp_h32(context, target_cycles); 2501 vdp_h32(context, target_cycles);
2723 context->flags2 &= ~FLAG2_SPRITE_COLLIDE; 2781 context->flags2 &= ~FLAG2_SPRITE_COLLIDE;
2724 } 2782 }
2725 if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && !(context->flags2 & FLAG2_EVEN_FIELD)) { 2783 if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && !(context->flags2 & FLAG2_EVEN_FIELD)) {
2726 value |= 0x10; 2784 value |= 0x10;
2727 } 2785 }
2728 uint32_t line= context->vcounter;
2729 uint32_t slot = context->hslot; 2786 uint32_t slot = context->hslot;
2730 if ((line >= context->inactive_start && line < 0x1FF) || !(context->regs[REG_MODE_2] & BIT_DISP_EN)) { 2787 if (!is_active(context)) {
2731 value |= 0x8; 2788 value |= 0x8;
2732 } 2789 }
2733 if (context->regs[REG_MODE_4] & BIT_H40) { 2790 if (context->regs[REG_MODE_4] & BIT_H40) {
2734 if (slot < HBLANK_END_H40 || slot > HBLANK_START_H40) { 2791 if (slot < HBLANK_END_H40 || slot > HBLANK_START_H40) {
2735 value |= 0x4; 2792 value |= 0x4;
2854 } 2911 }
2855 } 2912 }
2856 } 2913 }
2857 } 2914 }
2858 2915
2859 static uint32_t vdp_cycles_to_line(vdp_context * context, uint32_t target) 2916 static void get_jump_params(vdp_context *context, uint32_t *jump_start, uint32_t *jump_dst)
2860 { 2917 {
2861 uint32_t jump_start, jump_dst;
2862 if (context->regs[REG_MODE_2] & BIT_MODE_5) { 2918 if (context->regs[REG_MODE_2] & BIT_MODE_5) {
2863 if (context->flags2 & FLAG2_REGION_PAL) { 2919 if (context->flags2 & FLAG2_REGION_PAL) {
2864 if (context->latched_mode & BIT_PAL) { 2920 if (context->regs[REG_MODE_2] & BIT_PAL) {
2865 jump_start = 0x10B; 2921 *jump_start = 0x10B;
2866 jump_dst = 0x1D2; 2922 *jump_dst = 0x1D2;
2867 } else { 2923 } else {
2868 jump_start = 0x103; 2924 *jump_start = 0x103;
2869 jump_dst = 0x1CA; 2925 *jump_dst = 0x1CA;
2870 } 2926 }
2871 } else { 2927 } else {
2872 if (context->latched_mode & BIT_PAL) { 2928 if (context->regs[REG_MODE_2] & BIT_PAL) {
2873 jump_start = 0; 2929 *jump_start = 0x100;
2874 jump_dst = 0; 2930 *jump_dst = 0x1FA;
2875 } else { 2931 } else {
2876 jump_start = 0xEB; 2932 *jump_start = 0xEB;
2877 jump_dst = 0x1E5; 2933 *jump_dst = 0x1E5;
2878 } 2934 }
2879 } 2935 }
2880 } else { 2936 } else {
2881 jump_start = 0xDB; 2937 *jump_start = 0xDB;
2882 jump_dst = 0x1D5; 2938 *jump_dst = 0x1D5;
2883 } 2939 }
2940 }
2941
2942 static uint32_t vdp_cycles_to_line(vdp_context * context, uint32_t target)
2943 {
2944 uint32_t jump_start, jump_dst;
2945 get_jump_params(context, &jump_start, &jump_dst);
2884 uint32_t lines; 2946 uint32_t lines;
2885 if (context->vcounter < target) { 2947 if (context->vcounter < target) {
2886 if (target < jump_start) { 2948 if (target < jump_start || context->vcounter > jump_start) {
2887 lines = target - context->vcounter; 2949 lines = target - context->vcounter;
2888 } else { 2950 } else {
2889 lines = jump_start - context->vcounter + target - jump_dst; 2951 lines = jump_start - context->vcounter + target - jump_dst;
2890 } 2952 }
2891 } else { 2953 } else {
2915 } 2977 }
2916 if (context->flags2 & FLAG2_HINT_PENDING) { 2978 if (context->flags2 & FLAG2_HINT_PENDING) {
2917 return context->pending_hint_start; 2979 return context->pending_hint_start;
2918 } 2980 }
2919 uint32_t hint_line; 2981 uint32_t hint_line;
2920 if (context->vcounter + context->hint_counter >= context->inactive_start) { 2982 if (context->state != ACTIVE) {
2921 if (context->regs[REG_HINT] > context->inactive_start) { 2983 hint_line = context->regs[REG_HINT];
2984 if (hint_line > context->inactive_start) {
2922 return 0xFFFFFFFF; 2985 return 0xFFFFFFFF;
2923 } 2986 }
2924 hint_line = context->regs[REG_HINT];
2925 } else { 2987 } else {
2926 hint_line = context->vcounter + context->hint_counter + 1; 2988 hint_line = context->vcounter + context->hint_counter + 1;
2927 } 2989 if (context->vcounter < context->inactive_start) {
2928 2990 if (hint_line > context->inactive_start) {
2991 hint_line = context->regs[REG_HINT];
2992 if (hint_line > context->inactive_start) {
2993 return 0xFFFFFFFF;
2994 }
2995 }
2996 } else {
2997 uint32_t jump_start, jump_dst;
2998 get_jump_params(context, &jump_start, &jump_dst);
2999 if (hint_line >= jump_start && context->vcounter < jump_dst) {
3000 hint_line = (hint_line + jump_dst - jump_start) & 0x1FF;
3001 }
3002 if (hint_line < context->vcounter && hint_line > context->inactive_start) {
3003 return 0xFFFFFFFF;
3004 }
3005 }
3006 }
2929 return context->cycles + vdp_cycles_to_line(context, hint_line); 3007 return context->cycles + vdp_cycles_to_line(context, hint_line);
2930 } 3008 }
2931 3009
2932 static uint32_t vdp_next_vint_real(vdp_context * context) 3010 static uint32_t vdp_next_vint_real(vdp_context * context)
2933 { 3011 {