Mercurial > repos > blastem
comparison vdp.c @ 2040:a61b47d5489e
Fix window bug implementation
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 09 Mar 2021 22:47:51 -0800 |
parents | 441d5d6cea2f |
children | c5d0edf1d7e7 |
comparison
equal
deleted
inserted
replaced
2039:3b8e29ef1145 | 2040:a61b47d5489e |
---|---|
1152 offset = address + line_offset + (((column - 1) * 2) & mask); | 1152 offset = address + line_offset + (((column - 1) * 2) & mask); |
1153 context->col_2 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1]; | 1153 context->col_2 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1]; |
1154 context->v_offset = (line) & v_offset_mask; | 1154 context->v_offset = (line) & v_offset_mask; |
1155 context->flags |= FLAG_WINDOW; | 1155 context->flags |= FLAG_WINDOW; |
1156 return; | 1156 return; |
1157 } | 1157 } else if (column == right_col) { |
1158 context->flags &= ~FLAG_WINDOW; | 1158 context->flags |= FLAG_WINDOW_EDGE; |
1159 context->flags &= ~FLAG_WINDOW; | |
1160 } else { | |
1161 context->flags &= ~(FLAG_WINDOW_EDGE|FLAG_WINDOW); | |
1162 } | |
1159 } | 1163 } |
1160 //TODO: Verify behavior for 0x20 case | 1164 //TODO: Verify behavior for 0x20 case |
1161 uint16_t vscroll = 0xFF | (context->regs[REG_SCROLL] & 0x30) << 4; | 1165 uint16_t vscroll = 0xFF | (context->regs[REG_SCROLL] & 0x30) << 4; |
1162 if (context->double_res) { | 1166 if (context->double_res) { |
1163 vscroll <<= 1; | 1167 vscroll <<= 1; |
1346 } | 1350 } |
1347 *debug_dst = src; | 1351 *debug_dst = src; |
1348 return (sh_pixel){.index = pixel, .intensity = intensity}; | 1352 return (sh_pixel){.index = pixel, .intensity = intensity}; |
1349 } | 1353 } |
1350 | 1354 |
1351 static void render_normal(vdp_context *context, int32_t col, uint8_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off) | 1355 static void render_normal(vdp_context *context, int32_t col, uint8_t *dst, uint8_t *debug_dst, uint8_t *buf_a, int plane_a_off, int plane_a_mask, int plane_b_off) |
1352 { | 1356 { |
1353 uint8_t *sprite_buf = context->linebuf + col * 8; | 1357 uint8_t *sprite_buf = context->linebuf + col * 8; |
1354 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) { | 1358 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) { |
1355 memset(dst, 0, 8); | 1359 memset(dst, 0, 8); |
1356 memset(debug_dst, DBG_SRC_BG, 8); | 1360 memset(debug_dst, DBG_SRC_BG, 8); |
1360 plane_a_off += 8; | 1364 plane_a_off += 8; |
1361 plane_b_off += 8; | 1365 plane_b_off += 8; |
1362 for (int i = 0; i < 8; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) | 1366 for (int i = 0; i < 8; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) |
1363 { | 1367 { |
1364 uint8_t sprite, plane_a, plane_b; | 1368 uint8_t sprite, plane_a, plane_b; |
1365 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK]; | 1369 plane_a = buf_a[plane_a_off & plane_a_mask]; |
1366 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; | 1370 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; |
1367 *(dst++) = composite_normal(context, debug_dst, *sprite_buf, plane_a, plane_b, context->regs[REG_BG_COLOR]) & 0x3F; | 1371 *(dst++) = composite_normal(context, debug_dst, *sprite_buf, plane_a, plane_b, context->regs[REG_BG_COLOR]) & 0x3F; |
1368 debug_dst++; | 1372 debug_dst++; |
1369 } | 1373 } |
1370 } else { | 1374 } else { |
1371 for (int i = 0; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) | 1375 for (int i = 0; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) |
1372 { | 1376 { |
1373 uint8_t sprite, plane_a, plane_b; | 1377 uint8_t sprite, plane_a, plane_b; |
1374 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK]; | 1378 plane_a = buf_a[plane_a_off & plane_a_mask]; |
1375 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; | 1379 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; |
1376 *(dst++) = composite_normal(context, debug_dst, *sprite_buf, plane_a, plane_b, context->regs[REG_BG_COLOR]) & 0x3F; | 1380 *(dst++) = composite_normal(context, debug_dst, *sprite_buf, plane_a, plane_b, context->regs[REG_BG_COLOR]) & 0x3F; |
1377 debug_dst++; | 1381 debug_dst++; |
1378 } | 1382 } |
1379 } | 1383 } |
1380 } | 1384 } |
1381 | 1385 |
1382 static void render_highlight(vdp_context *context, int32_t col, uint8_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off) | 1386 static void render_highlight(vdp_context *context, int32_t col, uint8_t *dst, uint8_t *debug_dst, uint8_t *buf_a, int plane_a_off, int plane_a_mask, int plane_b_off) |
1383 { | 1387 { |
1384 int start = 0; | 1388 int start = 0; |
1385 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) { | 1389 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) { |
1386 memset(dst, SHADOW_OFFSET + (context->regs[REG_BG_COLOR] & 0x3F), 8); | 1390 memset(dst, SHADOW_OFFSET + (context->regs[REG_BG_COLOR] & 0x3F), 8); |
1387 memset(debug_dst, DBG_SRC_BG | DBG_SHADOW, 8); | 1391 memset(debug_dst, DBG_SRC_BG | DBG_SHADOW, 8); |
1391 } | 1395 } |
1392 uint8_t *sprite_buf = context->linebuf + col * 8 + start; | 1396 uint8_t *sprite_buf = context->linebuf + col * 8 + start; |
1393 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) | 1397 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) |
1394 { | 1398 { |
1395 uint8_t sprite, plane_a, plane_b; | 1399 uint8_t sprite, plane_a, plane_b; |
1396 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK]; | 1400 plane_a = buf_a[plane_a_off & plane_a_mask]; |
1397 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; | 1401 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; |
1398 sprite = *sprite_buf; | 1402 sprite = *sprite_buf; |
1399 sh_pixel pixel = composite_highlight(context, debug_dst, sprite, plane_a, plane_b, context->regs[REG_BG_COLOR]); | 1403 sh_pixel pixel = composite_highlight(context, debug_dst, sprite, plane_a, plane_b, context->regs[REG_BG_COLOR]); |
1400 uint8_t final_pixel; | 1404 uint8_t final_pixel; |
1401 if (pixel.intensity == BUF_BIT_PRIORITY << 1) { | 1405 if (pixel.intensity == BUF_BIT_PRIORITY << 1) { |
1408 debug_dst++; | 1412 debug_dst++; |
1409 *(dst++) = final_pixel; | 1413 *(dst++) = final_pixel; |
1410 } | 1414 } |
1411 } | 1415 } |
1412 | 1416 |
1413 static void render_testreg(vdp_context *context, int32_t col, uint8_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off, uint8_t output_disabled, uint8_t test_layer) | 1417 static void render_testreg(vdp_context *context, int32_t col, uint8_t *dst, uint8_t *debug_dst, uint8_t *buf_a, int plane_a_off, int plane_a_mask, int plane_b_off, uint8_t output_disabled, uint8_t test_layer) |
1414 { | 1418 { |
1415 if (output_disabled) { | 1419 if (output_disabled) { |
1416 switch (test_layer) | 1420 switch (test_layer) |
1417 { | 1421 { |
1418 case 0: | 1422 case 0: |
1432 break; | 1436 break; |
1433 } | 1437 } |
1434 case 2: | 1438 case 2: |
1435 for (int i = 0; i < 16; i++) | 1439 for (int i = 0; i < 16; i++) |
1436 { | 1440 { |
1437 *(dst++) = context->tmp_buf_a[(plane_a_off++) & SCROLL_BUFFER_MASK] & 0x3F; | 1441 *(dst++) = buf_a[(plane_a_off++) & plane_a_mask] & 0x3F; |
1438 *(debug_dst++) = DBG_SRC_A; | 1442 *(debug_dst++) = DBG_SRC_A; |
1439 } | 1443 } |
1440 break; | 1444 break; |
1441 case 3: | 1445 case 3: |
1442 for (int i = 0; i < 16; i++) | 1446 for (int i = 0; i < 16; i++) |
1462 if (pixel) { | 1466 if (pixel) { |
1463 src = DBG_SRC_S; | 1467 src = DBG_SRC_S; |
1464 } | 1468 } |
1465 break; | 1469 break; |
1466 case 2: | 1470 case 2: |
1467 pixel &= context->tmp_buf_a[(plane_a_off + i) & SCROLL_BUFFER_MASK]; | 1471 pixel &= buf_a[(plane_a_off + i) & plane_a_mask]; |
1468 if (pixel) { | 1472 if (pixel) { |
1469 src = DBG_SRC_A; | 1473 src = DBG_SRC_A; |
1470 } | 1474 } |
1471 break; | 1475 break; |
1472 case 3: | 1476 case 3: |
1486 start = 8; | 1490 start = 8; |
1487 } | 1491 } |
1488 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) | 1492 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) |
1489 { | 1493 { |
1490 uint8_t sprite, plane_a, plane_b; | 1494 uint8_t sprite, plane_a, plane_b; |
1491 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK]; | 1495 plane_a = buf_a[plane_a_off & plane_a_mask]; |
1492 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; | 1496 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; |
1493 sprite = *sprite_buf; | 1497 sprite = *sprite_buf; |
1494 uint8_t pixel = composite_normal(context, debug_dst, sprite, plane_a, plane_b, 0x3F) & 0x3F; | 1498 uint8_t pixel = composite_normal(context, debug_dst, sprite, plane_a, plane_b, 0x3F) & 0x3F; |
1495 switch (test_layer) | 1499 switch (test_layer) |
1496 { | 1500 { |
1517 *(dst++) = pixel; | 1521 *(dst++) = pixel; |
1518 } | 1522 } |
1519 } | 1523 } |
1520 } | 1524 } |
1521 | 1525 |
1522 static void render_testreg_highlight(vdp_context *context, int32_t col, uint8_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off, uint8_t output_disabled, uint8_t test_layer) | 1526 static void render_testreg_highlight(vdp_context *context, int32_t col, uint8_t *dst, uint8_t *debug_dst, uint8_t *buf_a, int plane_a_off, int plane_a_mask, int plane_b_off, uint8_t output_disabled, uint8_t test_layer) |
1523 { | 1527 { |
1524 int start = 0; | 1528 int start = 0; |
1525 uint8_t *sprite_buf = context->linebuf + col * 8; | 1529 uint8_t *sprite_buf = context->linebuf + col * 8; |
1526 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) { | 1530 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) { |
1527 //TODO: Confirm how test register interacts with column 0 blanking | 1531 //TODO: Confirm how test register interacts with column 0 blanking |
1536 if (pixel) { | 1540 if (pixel) { |
1537 src = DBG_SRC_S | DBG_SHADOW; | 1541 src = DBG_SRC_S | DBG_SHADOW; |
1538 } | 1542 } |
1539 break; | 1543 break; |
1540 case 2: | 1544 case 2: |
1541 pixel &= context->tmp_buf_a[(plane_a_off + i) & SCROLL_BUFFER_MASK]; | 1545 pixel &= buf_a[(plane_a_off + i) & plane_a_mask]; |
1542 if (pixel) { | 1546 if (pixel) { |
1543 src = DBG_SRC_A | DBG_SHADOW; | 1547 src = DBG_SRC_A | DBG_SHADOW; |
1544 } | 1548 } |
1545 break; | 1549 break; |
1546 case 3: | 1550 case 3: |
1560 start = 8; | 1564 start = 8; |
1561 } | 1565 } |
1562 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) | 1566 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) |
1563 { | 1567 { |
1564 uint8_t sprite, plane_a, plane_b; | 1568 uint8_t sprite, plane_a, plane_b; |
1565 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK]; | 1569 plane_a = buf_a[plane_a_off & plane_a_mask]; |
1566 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; | 1570 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK]; |
1567 sprite = *sprite_buf; | 1571 sprite = *sprite_buf; |
1568 sh_pixel pixel = composite_highlight(context, debug_dst, sprite, plane_a, plane_b, 0x3F); | 1572 sh_pixel pixel = composite_highlight(context, debug_dst, sprite, plane_a, plane_b, 0x3F); |
1569 if (output_disabled) { | 1573 if (output_disabled) { |
1570 pixel.index = 0x3F; | 1574 pixel.index = 0x3F; |
1634 dst = context->compositebuf + BORDER_LEFT + col * 8; | 1638 dst = context->compositebuf + BORDER_LEFT + col * 8; |
1635 debug_dst = context->layer_debug_buf + BORDER_LEFT + col * 8; | 1639 debug_dst = context->layer_debug_buf + BORDER_LEFT + col * 8; |
1636 | 1640 |
1637 | 1641 |
1638 uint8_t a_src, src; | 1642 uint8_t a_src, src; |
1643 uint8_t *buf_a; | |
1644 int plane_a_mask; | |
1639 if (context->flags & FLAG_WINDOW) { | 1645 if (context->flags & FLAG_WINDOW) { |
1640 plane_a_off = context->buf_a_off; | 1646 plane_a_off = context->buf_a_off; |
1647 buf_a = context->tmp_buf_a; | |
1641 a_src = DBG_SRC_W; | 1648 a_src = DBG_SRC_W; |
1649 plane_a_mask = SCROLL_BUFFER_MASK; | |
1642 } else { | 1650 } else { |
1643 plane_a_off = context->buf_a_off - context->hscroll_a_fine; | 1651 if (context->flags & FLAG_WINDOW_EDGE) { |
1652 buf_a = context->tmp_buf_a + context->buf_a_off; | |
1653 plane_a_mask = 15; | |
1654 plane_a_off = -context->hscroll_a_fine; | |
1655 } else { | |
1656 plane_a_off = context->buf_a_off - context->hscroll_a_fine; | |
1657 plane_a_mask = SCROLL_BUFFER_MASK; | |
1658 buf_a = context->tmp_buf_a; | |
1659 } | |
1644 a_src = DBG_SRC_A; | 1660 a_src = DBG_SRC_A; |
1645 } | 1661 } |
1662 plane_a_off &= plane_a_mask; | |
1646 plane_b_off = context->buf_b_off - context->hscroll_b_fine; | 1663 plane_b_off = context->buf_b_off - context->hscroll_b_fine; |
1647 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7)); | 1664 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7)); |
1648 | 1665 |
1649 if (context->regs[REG_MODE_4] & BIT_HILIGHT) { | 1666 if (context->regs[REG_MODE_4] & BIT_HILIGHT) { |
1650 if (output_disabled || test_layer) { | 1667 if (output_disabled || test_layer) { |
1651 render_testreg_highlight(context, col, dst, debug_dst, plane_a_off, plane_b_off, output_disabled, test_layer); | 1668 render_testreg_highlight(context, col, dst, debug_dst, buf_a, plane_a_off, plane_a_mask, plane_b_off, output_disabled, test_layer); |
1652 } else { | 1669 } else { |
1653 render_highlight(context, col, dst, debug_dst, plane_a_off, plane_b_off); | 1670 render_highlight(context, col, dst, debug_dst, buf_a, plane_a_off, plane_a_mask, plane_b_off); |
1654 } | 1671 } |
1655 } else { | 1672 } else { |
1656 if (output_disabled || test_layer) { | 1673 if (output_disabled || test_layer) { |
1657 render_testreg(context, col, dst, debug_dst, plane_a_off, plane_b_off, output_disabled, test_layer); | 1674 render_testreg(context, col, dst, debug_dst, buf_a, plane_a_off, plane_a_mask, plane_b_off, output_disabled, test_layer); |
1658 } else { | 1675 } else { |
1659 render_normal(context, col, dst, debug_dst, plane_a_off, plane_b_off); | 1676 render_normal(context, col, dst, debug_dst, buf_a, plane_a_off, plane_a_mask, plane_b_off); |
1660 } | 1677 } |
1661 } | 1678 } |
1662 dst += 16; | 1679 dst += 16; |
1663 } else { | 1680 } else { |
1664 dst = context->compositebuf; | 1681 dst = context->compositebuf; |