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;