comparison vdp.c @ 1652:d0a69348add8

Optimized render_map_output a bit
author Michael Pavone <pavone@retrodev.com>
date Thu, 27 Dec 2018 09:23:51 -0800
parents b500e971da75
children 858d52140375
comparison
equal deleted inserted replaced
1651:9b8fe6729877 1652:d0a69348add8
768 #define BG_START_SLOT 6 768 #define BG_START_SLOT 6
769 769
770 static void update_color_map(vdp_context *context, uint16_t index, uint16_t value) 770 static void update_color_map(vdp_context *context, uint16_t index, uint16_t value)
771 { 771 {
772 context->colors[index] = color_map[value & CRAM_BITS]; 772 context->colors[index] = color_map[value & CRAM_BITS];
773 context->colors[index + CRAM_SIZE] = color_map[(value & CRAM_BITS) | FBUF_SHADOW]; 773 context->colors[index + SHADOW_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_SHADOW];
774 context->colors[index + CRAM_SIZE*2] = color_map[(value & CRAM_BITS) | FBUF_HILIGHT]; 774 context->colors[index + HIGHLIGHT_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_HILIGHT];
775 context->colors[index + CRAM_SIZE*3] = color_map[(value & CRAM_BITS) | FBUF_MODE4]; 775 context->colors[index + MODE4_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_MODE4];
776 } 776 }
777 777
778 void write_cram_internal(vdp_context * context, uint16_t addr, uint16_t value) 778 void write_cram_internal(vdp_context * context, uint16_t addr, uint16_t value)
779 { 779 {
780 context->cram[addr] = value; 780 context->cram[addr] = value;
796 context->vcounter < context->inactive_start + context->border_bot 796 context->vcounter < context->inactive_start + context->border_bot
797 || context->vcounter > 0x200 - context->border_top 797 || context->vcounter > 0x200 - context->border_top
798 )) { 798 )) {
799 uint8_t bg_end_slot = BG_START_SLOT + (context->regs[REG_MODE_4] & BIT_H40) ? LINEBUF_SIZE/2 : (256+HORIZ_BORDER)/2; 799 uint8_t bg_end_slot = BG_START_SLOT + (context->regs[REG_MODE_4] & BIT_H40) ? LINEBUF_SIZE/2 : (256+HORIZ_BORDER)/2;
800 if (context->hslot < bg_end_slot) { 800 if (context->hslot < bg_end_slot) {
801 uint32_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->colors[addr] : context->colors[addr + CRAM_SIZE*3]; 801 uint32_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->colors[addr] : context->colors[addr + MODE4_OFFSET];
802 context->output[(context->hslot - BG_START_SLOT)*2 + 1] = color; 802 context->output[(context->hslot - BG_START_SLOT)*2 + 1] = color;
803 } 803 }
804 } 804 }
805 } 805 }
806 806
1261 uint32_t address = mode4_address_map[((context->col_1 & 0x1FF) * 32) + vscroll * 4]; 1261 uint32_t address = mode4_address_map[((context->col_1 & 0x1FF) * 32) + vscroll * 4];
1262 context->fetch_tmp[0] = context->vdpmem[address]; 1262 context->fetch_tmp[0] = context->vdpmem[address];
1263 context->fetch_tmp[1] = context->vdpmem[address+1]; 1263 context->fetch_tmp[1] = context->vdpmem[address+1];
1264 } 1264 }
1265 1265
1266 static uint8_t composite_normal(vdp_context *context, uint8_t *debug_dst, uint8_t sprite, uint8_t plane_a, uint8_t plane_b, uint8_t bg_index)
1267 {
1268 uint8_t pixel = bg_index;
1269 uint8_t src = DBG_SRC_BG;
1270 if (plane_b & 0xF) {
1271 pixel = plane_b;
1272 src = DBG_SRC_B;
1273 }
1274 if (plane_a & 0xF && (plane_a & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) {
1275 pixel = plane_a;
1276 src = DBG_SRC_A;
1277 }
1278 if (sprite & 0xF && (sprite & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) {
1279 pixel = sprite;
1280 src = DBG_SRC_S;
1281 }
1282 *debug_dst = src;
1283 return pixel;
1284 }
1285 typedef struct {
1286 uint8_t index, intensity;
1287 } sh_pixel;
1288
1289 static sh_pixel composite_highlight(vdp_context *context, uint8_t *debug_dst, uint8_t sprite, uint8_t plane_a, uint8_t plane_b, uint8_t bg_index)
1290 {
1291 uint8_t pixel = bg_index;
1292 uint8_t src = DBG_SRC_BG;
1293 uint8_t intensity = 0;
1294 if (plane_b & 0xF) {
1295 pixel = plane_b;
1296 src = DBG_SRC_B;
1297 }
1298 intensity = plane_b & BUF_BIT_PRIORITY;
1299 if (plane_a & 0xF && (plane_a & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) {
1300 pixel = plane_a;
1301 src = DBG_SRC_A;
1302 }
1303 intensity |= plane_a & BUF_BIT_PRIORITY;
1304 if (sprite & 0xF && (sprite & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) {
1305 if ((sprite & 0x3F) == 0x3E) {
1306 intensity += BUF_BIT_PRIORITY;
1307 } else if ((sprite & 0x3F) == 0x3F) {
1308 intensity = 0;
1309 } else {
1310 pixel = sprite;
1311 src = DBG_SRC_S;
1312 if ((pixel & 0xF) == 0xE) {
1313 intensity = BUF_BIT_PRIORITY;
1314 } else {
1315 intensity |= pixel & BUF_BIT_PRIORITY;
1316 }
1317 }
1318 }
1319 *debug_dst = src;
1320 return (sh_pixel){.index = pixel, .intensity = intensity};
1321 }
1322
1323 static void render_normal(vdp_context *context, int32_t col, uint32_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off)
1324 {
1325 int start = 0;
1326 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) {
1327 uint32_t bgcolor = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
1328 for (int i = 0; i < 8; ++i)
1329 {
1330 *(dst++) = bgcolor;
1331 *(debug_dst++) = DBG_SRC_BG;
1332 }
1333 start = 8;
1334 }
1335 uint8_t *sprite_buf = context->linebuf + col * 8 + start;
1336 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i)
1337 {
1338 uint8_t sprite, plane_a, plane_b;
1339 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK];
1340 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK];
1341 sprite = *sprite_buf;
1342 uint8_t pixel = composite_normal(context, debug_dst, sprite, plane_a, plane_b, context->regs[REG_BG_COLOR]);
1343 debug_dst++;
1344 *(dst++) = context->colors[pixel & 0x3F];
1345 }
1346 }
1347
1348 static void render_highlight(vdp_context *context, int32_t col, uint32_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off)
1349 {
1350 int start = 0;
1351 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) {
1352 uint32_t bgcolor = context->colors[SHADOW_OFFSET + (context->regs[REG_BG_COLOR] & 0x3F)];
1353 for (int i = 0; i < 8; ++i)
1354 {
1355 *(dst++) = bgcolor;
1356 *(debug_dst++) = DBG_SRC_BG | DBG_SHADOW;
1357 }
1358 start = 8;
1359 }
1360 uint8_t *sprite_buf = context->linebuf + col * 8 + start;
1361 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i)
1362 {
1363 uint8_t sprite, plane_a, plane_b;
1364 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK];
1365 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK];
1366 sprite = *sprite_buf;
1367 sh_pixel pixel = composite_highlight(context, debug_dst, sprite, plane_a, plane_b, context->regs[REG_BG_COLOR]);
1368 uint32_t *colors;
1369 if (pixel.intensity == BUF_BIT_PRIORITY << 1) {
1370 colors = context->colors + HIGHLIGHT_OFFSET;
1371 } else if (pixel.intensity) {
1372 colors = context->colors;
1373 } else {
1374 colors = context->colors + SHADOW_OFFSET;
1375 }
1376 debug_dst++;
1377 *(dst++) = colors[pixel.index & 0x3F];
1378 }
1379 }
1380
1381 static void render_testreg(vdp_context *context, int32_t col, uint32_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off, uint8_t output_disabled, uint8_t test_layer)
1382 {
1383 if (output_disabled) {
1384 switch (test_layer)
1385 {
1386 case 0:
1387 for (int i = 0; i < 16; i++)
1388 {
1389 *(dst++) = 0x3F; //TODO: confirm this on hardware
1390 *(debug_dst++) = DBG_SRC_BG;
1391 }
1392 break;
1393 case 1: {
1394 uint8_t *sprite_buf = context->linebuf + col * 8;
1395 for (int i = 0; i < 16; i++)
1396 {
1397 *(dst++) = *(sprite_buf++);
1398 *(debug_dst++) = DBG_SRC_S;
1399 }
1400 break;
1401 }
1402 case 2:
1403 for (int i = 0; i < 16; i++)
1404 {
1405 *(dst++) = context->tmp_buf_a[(plane_a_off++) & SCROLL_BUFFER_MASK];
1406 *(debug_dst++) = DBG_SRC_A;
1407 }
1408 break;
1409 case 3:
1410 for (int i = 0; i < 16; i++)
1411 {
1412 *(dst++) = context->tmp_buf_a[(plane_a_off++) & SCROLL_BUFFER_MASK];
1413 *(debug_dst++) = DBG_SRC_B;
1414 }
1415 break;
1416 }
1417 } else {
1418 int start = 0;
1419 uint8_t *sprite_buf = context->linebuf + col * 8;
1420 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) {
1421 //TODO: Confirm how test register interacts with column 0 blanking
1422 uint8_t pixel = context->regs[REG_BG_COLOR] & 0x3F;
1423 uint8_t src = DBG_SRC_BG;
1424 for (int i = 0; i < 8; ++i)
1425 {
1426 switch (test_layer)
1427 {
1428 case 1:
1429 pixel &= sprite_buf[i];
1430 if (pixel) {
1431 src = DBG_SRC_S;
1432 }
1433 break;
1434 case 2:
1435 pixel &= context->tmp_buf_a[(plane_a_off + i) & SCROLL_BUFFER_MASK];
1436 if (pixel) {
1437 src = DBG_SRC_A;
1438 }
1439 break;
1440 case 3:
1441 pixel &= context->tmp_buf_b[(plane_b_off + i) & SCROLL_BUFFER_MASK];
1442 if (pixel) {
1443 src = DBG_SRC_B;
1444 }
1445 break;
1446 }
1447
1448 *(dst++) = context->colors[pixel & 0x3F];
1449 *(debug_dst++) = src;
1450 }
1451 plane_a_off += 8;
1452 plane_b_off += 8;
1453 sprite_buf += 8;
1454 start = 8;
1455 }
1456 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i)
1457 {
1458 uint8_t sprite, plane_a, plane_b;
1459 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK];
1460 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK];
1461 sprite = *sprite_buf;
1462 uint8_t pixel = composite_normal(context, debug_dst, sprite, plane_a, plane_b, 0x3F);
1463 switch (test_layer)
1464 {
1465 case 1:
1466 pixel &= sprite;
1467 if (pixel) {
1468 *debug_dst = DBG_SRC_S;
1469 }
1470 break;
1471 case 2:
1472 pixel &= plane_a;
1473 if (pixel) {
1474 *debug_dst = DBG_SRC_A;
1475 }
1476 break;
1477 case 3:
1478 pixel &= plane_b;
1479 if (pixel) {
1480 *debug_dst = DBG_SRC_B;
1481 }
1482 break;
1483 }
1484 debug_dst++;
1485 *(dst++) = context->colors[pixel & 0x3F];
1486 }
1487 }
1488 }
1489
1490 static void render_testreg_highlight(vdp_context *context, int32_t col, uint32_t *dst, uint8_t *debug_dst, int plane_a_off, int plane_b_off, uint8_t output_disabled, uint8_t test_layer)
1491 {
1492 if (output_disabled) {
1493 //TODO: confirm how this behaves when shadow/highlight is enabled
1494 switch (test_layer)
1495 {
1496 case 0:
1497 for (int i = 0; i < 16; i++)
1498 {
1499 *(dst++) = 0x3F; //TODO: confirm this on hardware
1500 *(debug_dst++) = DBG_SRC_BG;
1501 }
1502 break;
1503 case 1: {
1504 uint8_t *sprite_buf = context->linebuf + col * 8;
1505 for (int i = 0; i < 16; i++)
1506 {
1507 *(dst++) = *(sprite_buf++);
1508 *(debug_dst++) = DBG_SRC_S;
1509 }
1510 break;
1511 }
1512 case 2:
1513 for (int i = 0; i < 16; i++)
1514 {
1515 *(dst++) = context->tmp_buf_a[(plane_a_off++) & SCROLL_BUFFER_MASK];
1516 *(debug_dst++) = DBG_SRC_A;
1517 }
1518 break;
1519 case 3:
1520 for (int i = 0; i < 16; i++)
1521 {
1522 *(dst++) = context->tmp_buf_a[(plane_a_off++) & SCROLL_BUFFER_MASK];
1523 *(debug_dst++) = DBG_SRC_B;
1524 }
1525 break;
1526 }
1527 } else {
1528 int start = 0;
1529 uint8_t *sprite_buf = context->linebuf + col * 8;
1530 if (!col && (context->regs[REG_MODE_1] & BIT_COL0_MASK)) {
1531 //TODO: Confirm how test register interacts with column 0 blanking
1532 uint8_t pixel = context->regs[REG_BG_COLOR] & 0x3F;
1533 uint8_t src = DBG_SRC_BG | DBG_SHADOW;
1534 for (int i = 0; i < 8; ++i)
1535 {
1536 switch (test_layer)
1537 {
1538 case 1:
1539 pixel &= sprite_buf[i];
1540 if (pixel) {
1541 src = DBG_SRC_S | DBG_SHADOW;
1542 }
1543 break;
1544 case 2:
1545 pixel &= context->tmp_buf_a[(plane_a_off + i) & SCROLL_BUFFER_MASK];
1546 if (pixel) {
1547 src = DBG_SRC_A | DBG_SHADOW;
1548 }
1549 break;
1550 case 3:
1551 pixel &= context->tmp_buf_b[(plane_b_off + i) & SCROLL_BUFFER_MASK];
1552 if (pixel) {
1553 src = DBG_SRC_B | DBG_SHADOW;
1554 }
1555 break;
1556 }
1557
1558 *(dst++) = context->colors[SHADOW_OFFSET + (pixel & 0x3F)];
1559 *(debug_dst++) = src;
1560 }
1561 plane_a_off += 8;
1562 plane_b_off += 8;
1563 sprite_buf += 8;
1564 start = 8;
1565 }
1566 for (int i = start; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i)
1567 {
1568 uint8_t sprite, plane_a, plane_b;
1569 plane_a = context->tmp_buf_a[plane_a_off & SCROLL_BUFFER_MASK];
1570 plane_b = context->tmp_buf_b[plane_b_off & SCROLL_BUFFER_MASK];
1571 sprite = *sprite_buf;
1572 sh_pixel pixel = composite_highlight(context, debug_dst, sprite, plane_a, plane_b, 0x3F);
1573 uint32_t *colors;
1574 if (pixel.intensity == BUF_BIT_PRIORITY << 1) {
1575 colors = context->colors + HIGHLIGHT_OFFSET;
1576 } else if (pixel.intensity) {
1577 colors = context->colors;
1578 } else {
1579 colors = context->colors + SHADOW_OFFSET;
1580 }
1581 switch (test_layer)
1582 {
1583 case 1:
1584 pixel.index &= sprite;
1585 if (pixel.index) {
1586 *debug_dst = DBG_SRC_S;
1587 }
1588 break;
1589 case 2:
1590 pixel.index &= plane_a;
1591 if (pixel.index) {
1592 *debug_dst = DBG_SRC_A;
1593 }
1594 break;
1595 case 3:
1596 pixel.index &= plane_b;
1597 if (pixel.index) {
1598 *debug_dst = DBG_SRC_B;
1599 }
1600 break;
1601 }
1602 debug_dst++;
1603 *(dst++) = colors[pixel.index & 0x3F];
1604 }
1605 }
1606 }
1607
1266 static void render_map_output(uint32_t line, int32_t col, vdp_context * context) 1608 static void render_map_output(uint32_t line, int32_t col, vdp_context * context)
1267 { 1609 {
1268 uint32_t *dst; 1610 uint32_t *dst;
1269 uint8_t *debug_dst; 1611 uint8_t *debug_dst;
1270 uint8_t output_disabled = (context->test_port & TEST_BIT_DISABLE) != 0; 1612 uint8_t output_disabled = (context->test_port & TEST_BIT_DISABLE) != 0;
1291 context->done_output = dst; 1633 context->done_output = dst;
1292 return; 1634 return;
1293 } 1635 }
1294 line &= 0xFF; 1636 line &= 0xFF;
1295 render_map(context->col_2, context->tmp_buf_b, context->buf_b_off+8, context); 1637 render_map(context->col_2, context->tmp_buf_b, context->buf_b_off+8, context);
1296 uint8_t *sprite_buf, *plane_a, *plane_b; 1638 uint8_t *sprite_buf;
1639 uint8_t sprite, plane_a, plane_b;
1297 int plane_a_off, plane_b_off; 1640 int plane_a_off, plane_b_off;
1298 if (col) 1641 if (col)
1299 { 1642 {
1300 col-=2; 1643 col-=2;
1301 dst = context->output + BORDER_LEFT + col * 8; 1644 dst = context->output + BORDER_LEFT + col * 8;
1302 debug_dst = context->layer_debug_buf + BORDER_LEFT + col * 8; 1645 debug_dst = context->layer_debug_buf + BORDER_LEFT + col * 8;
1303 1646
1304 sprite_buf = context->linebuf + col * 8; 1647
1305 uint8_t a_src, src; 1648 uint8_t a_src, src;
1306 if (context->flags & FLAG_WINDOW) { 1649 if (context->flags & FLAG_WINDOW) {
1307 plane_a_off = context->buf_a_off; 1650 plane_a_off = context->buf_a_off;
1308 a_src = DBG_SRC_W; 1651 a_src = DBG_SRC_W;
1309 } else { 1652 } else {
1312 } 1655 }
1313 plane_b_off = context->buf_b_off - (context->hscroll_b & 0xF); 1656 plane_b_off = context->buf_b_off - (context->hscroll_b & 0xF);
1314 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7)); 1657 //printf("A | tmp_buf offset: %d\n", 8 - (context->hscroll_a & 0x7));
1315 1658
1316 if (context->regs[REG_MODE_4] & BIT_HILIGHT) { 1659 if (context->regs[REG_MODE_4] & BIT_HILIGHT) {
1317 for (int i = 0; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) { 1660 if (output_disabled || test_layer) {
1318 plane_a = context->tmp_buf_a + (plane_a_off & SCROLL_BUFFER_MASK); 1661 render_testreg_highlight(context, col, dst, debug_dst, plane_a_off, plane_b_off, output_disabled, test_layer);
1319 plane_b = context->tmp_buf_b + (plane_b_off & SCROLL_BUFFER_MASK); 1662 } else {
1320 uint8_t pixel = context->regs[REG_BG_COLOR]; 1663 render_highlight(context, col, dst, debug_dst, plane_a_off, plane_b_off);
1321 uint32_t *colors = context->colors; 1664 }
1322 src = DBG_SRC_BG; 1665 } else {
1323 uint8_t intensity = 0; 1666 if (output_disabled || test_layer) {
1324 if (col || !(context->regs[REG_MODE_1] & BIT_COL0_MASK) || i >= 8) { 1667 render_testreg(context, col, dst, debug_dst, plane_a_off, plane_b_off, output_disabled, test_layer);
1325 if (*plane_b & 0xF) { 1668 } else {
1326 pixel = *plane_b; 1669 render_normal(context, col, dst, debug_dst, plane_a_off, plane_b_off);
1327 src = DBG_SRC_B;
1328 }
1329 intensity = *plane_b & BUF_BIT_PRIORITY;
1330 if (*plane_a & 0xF && (*plane_a & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) {
1331 pixel = *plane_a;
1332 src = a_src;
1333 }
1334 intensity |= *plane_a & BUF_BIT_PRIORITY;
1335 if (*sprite_buf & 0xF && (*sprite_buf & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) {
1336 if ((*sprite_buf & 0x3F) == 0x3E) {
1337 intensity += BUF_BIT_PRIORITY;
1338 } else if ((*sprite_buf & 0x3F) == 0x3F) {
1339 intensity = 0;
1340 } else {
1341 pixel = *sprite_buf;
1342 src = DBG_SRC_S;
1343 if ((pixel & 0xF) == 0xE) {
1344 intensity = BUF_BIT_PRIORITY;
1345 } else {
1346 intensity |= pixel & BUF_BIT_PRIORITY;
1347 }
1348 }
1349 }
1350 }
1351 if (output_disabled) {
1352 pixel = 0x3F;
1353 }
1354 if (!intensity) {
1355 src |= DBG_SHADOW;
1356 colors += CRAM_SIZE;
1357 } else if (intensity == BUF_BIT_PRIORITY*2) {
1358 src |= DBG_HILIGHT;
1359 colors += CRAM_SIZE*2;
1360 }
1361 //TODO: Verify how test register stuff interacts with shadow/highlight
1362 //TODO: Simulate CRAM corruption from bus fight
1363 switch (test_layer)
1364 {
1365 case 1:
1366 pixel &= *sprite_buf;
1367 if (output_disabled && pixel) {
1368 src = DBG_SRC_S;
1369 }
1370 break;
1371 case 2:
1372 pixel &= *plane_a;
1373 if (output_disabled && pixel) {
1374 src = DBG_SRC_A;
1375 }
1376 break;
1377 case 3:
1378 pixel &= *plane_b;
1379 if (output_disabled && pixel) {
1380 src = DBG_SRC_B;
1381 }
1382 break;
1383 }
1384 *(debug_dst++) = src;
1385 *(dst++) = colors[pixel & 0x3F];
1386 }
1387 } else {
1388 for (int i = 0; i < 16; ++plane_a_off, ++plane_b_off, ++sprite_buf, ++i) {
1389 plane_a = context->tmp_buf_a + (plane_a_off & SCROLL_BUFFER_MASK);
1390 plane_b = context->tmp_buf_b + (plane_b_off & SCROLL_BUFFER_MASK);
1391 uint8_t pixel = context->regs[REG_BG_COLOR];
1392 src = DBG_SRC_BG;
1393 if (output_disabled) {
1394 pixel = 0x3F;
1395 } else {
1396 if (col || !(context->regs[REG_MODE_1] & BIT_COL0_MASK) || i >= 8) {
1397 if (*plane_b & 0xF) {
1398 pixel = *plane_b;
1399 src = DBG_SRC_B;
1400 }
1401 if (*plane_a & 0xF && (*plane_a & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) {
1402 pixel = *plane_a;
1403 src = a_src;
1404 }
1405 if (*sprite_buf & 0xF && (*sprite_buf & BUF_BIT_PRIORITY) >= (pixel & BUF_BIT_PRIORITY)) {
1406 pixel = *sprite_buf;
1407 src = DBG_SRC_S;
1408 }
1409 }
1410 }
1411 //TODO: Simulate CRAM corruption from bus fight
1412 switch (test_layer)
1413 {
1414 case 1:
1415 pixel &= *sprite_buf;
1416 if (output_disabled && pixel) {
1417 src = DBG_SRC_S;
1418 }
1419 break;
1420 case 2:
1421 pixel &= *plane_a;
1422 if (output_disabled && pixel) {
1423 src = DBG_SRC_A;
1424 }
1425 break;
1426 case 3:
1427 pixel &= *plane_b;
1428 if (output_disabled && pixel) {
1429 src = DBG_SRC_B;
1430 }
1431 break;
1432 }
1433 *(dst++) = context->colors[pixel & 0x3F];
1434 *(debug_dst++) = src;
1435 } 1670 }
1436 } 1671 }
1437 } else { 1672 } else {
1438 dst = context->output; 1673 dst = context->output;
1439 debug_dst = context->layer_debug_buf; 1674 debug_dst = context->layer_debug_buf;
1488 *dst = bg_color; 1723 *dst = bg_color;
1489 *debug_dst = DBG_SRC_BG; 1724 *debug_dst = DBG_SRC_BG;
1490 } 1725 }
1491 } 1726 }
1492 } 1727 }
1493 context->done_output = dst; 1728 context->done_output = dst + 16;
1494 context->buf_a_off = (context->buf_a_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; 1729 context->buf_a_off = (context->buf_a_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK;
1495 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK; 1730 context->buf_b_off = (context->buf_b_off + SCROLL_BUFFER_DRAW) & SCROLL_BUFFER_MASK;
1496 } 1731 }
1497 1732
1498 static void render_map_mode4(uint32_t line, int32_t col, vdp_context * context) 1733 static void render_map_mode4(uint32_t line, int32_t col, vdp_context * context)
1533 { 1768 {
1534 *dst = (pixels >> i & 0xF) | pal_priority; 1769 *dst = (pixels >> i & 0xF) | pal_priority;
1535 } 1770 }
1536 context->buf_a_off = (context->buf_a_off + 8) & 15; 1771 context->buf_a_off = (context->buf_a_off + 8) & 15;
1537 1772
1538 uint8_t bgcolor = 0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3; 1773 uint8_t bgcolor = 0x10 | (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET;
1539 uint32_t *dst = context->output + col * 8 + BORDER_LEFT; 1774 uint32_t *dst = context->output + col * 8 + BORDER_LEFT;
1540 uint8_t *debug_dst = context->layer_debug_buf + col * 8 + BORDER_LEFT; 1775 uint8_t *debug_dst = context->layer_debug_buf + col * 8 + BORDER_LEFT;
1541 if (context->state == PREPARING) { 1776 if (context->state == PREPARING) {
1542 for (int i = 0; i < 16; i++) 1777 for (int i = 0; i < 16; i++)
1543 { 1778 {
1555 for (int i = 0; i < 8; i++, sprite_src++) 1790 for (int i = 0; i < 8; i++, sprite_src++)
1556 { 1791 {
1557 uint8_t *bg_src = context->tmp_buf_a + ((8 + i + col * 8 - (context->hscroll_a & 0x7)) & 15); 1792 uint8_t *bg_src = context->tmp_buf_a + ((8 + i + col * 8 - (context->hscroll_a & 0x7)) & 15);
1558 if ((*bg_src & 0x4F) > 0x40 || !*sprite_src) { 1793 if ((*bg_src & 0x4F) > 0x40 || !*sprite_src) {
1559 //background plane has priority and is opaque or sprite layer is transparent 1794 //background plane has priority and is opaque or sprite layer is transparent
1560 *(dst++) = context->colors[(*bg_src & 0x1F) + CRAM_SIZE*3]; 1795 *(dst++) = context->colors[(*bg_src & 0x1F) + MODE4_OFFSET];
1561 *(debug_dst++) = DBG_SRC_A; 1796 *(debug_dst++) = DBG_SRC_A;
1562 } else { 1797 } else {
1563 //sprite layer is opaque and not covered by high priority BG pixels 1798 //sprite layer is opaque and not covered by high priority BG pixels
1564 *(dst++) = context->colors[*sprite_src | 0x10 + CRAM_SIZE*3]; 1799 *(dst++) = context->colors[*sprite_src | 0x10 + MODE4_OFFSET];
1565 *(debug_dst++) = DBG_SRC_S; 1800 *(debug_dst++) = DBG_SRC_S;
1566 } 1801 }
1567 } 1802 }
1568 } else { 1803 } else {
1569 for (int i = 0; i < 8; i++) 1804 for (int i = 0; i < 8; i++)
2178 fetch_sprite_cells_mode4(context);\ 2413 fetch_sprite_cells_mode4(context);\
2179 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 2))\ 2414 MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 2))\
2180 case CALC_SLOT(slot, 3):\ 2415 case CALC_SLOT(slot, 3):\
2181 if ((slot + 3) == 140) {\ 2416 if ((slot + 3) == 140) {\
2182 uint32_t *dst = context->output + BORDER_LEFT + 256 + 8;\ 2417 uint32_t *dst = context->output + BORDER_LEFT + 256 + 8;\
2183 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3];\ 2418 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET];\
2184 for (int i = 0; i < BORDER_RIGHT-8; i++, dst++)\ 2419 for (int i = 0; i < BORDER_RIGHT-8; i++, dst++)\
2185 {\ 2420 {\
2186 *dst = bgcolor;\ 2421 *dst = bgcolor;\
2187 }\ 2422 }\
2188 context->done_output = dst;\ 2423 context->done_output = dst;\
2698 scan_sprite_table_mode4(context); 2933 scan_sprite_table_mode4(context);
2699 CHECK_LIMIT 2934 CHECK_LIMIT
2700 case 0: { 2935 case 0: {
2701 scan_sprite_table_mode4(context); 2936 scan_sprite_table_mode4(context);
2702 uint32_t *dst = context->output;; 2937 uint32_t *dst = context->output;;
2703 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3]; 2938 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET];
2704 for (int i = 0; i < BORDER_LEFT-8; i++, dst++) 2939 for (int i = 0; i < BORDER_LEFT-8; i++, dst++)
2705 { 2940 {
2706 *dst = bgcolor; 2941 *dst = bgcolor;
2707 } 2942 }
2708 context->done_output = dst; 2943 context->done_output = dst;
2720 case 4: { 2955 case 4: {
2721 scan_sprite_table_mode4(context); 2956 scan_sprite_table_mode4(context);
2722 context->buf_a_off = 8; 2957 context->buf_a_off = 8;
2723 memset(context->tmp_buf_a, 0, 8); 2958 memset(context->tmp_buf_a, 0, 8);
2724 uint32_t *dst = context->output + BORDER_LEFT - 8; 2959 uint32_t *dst = context->output + BORDER_LEFT - 8;
2725 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3]; 2960 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET];
2726 for (int i = 0; i < 8; i++, dst++) 2961 for (int i = 0; i < 8; i++, dst++)
2727 { 2962 {
2728 *dst = bgcolor; 2963 *dst = bgcolor;
2729 } 2964 }
2730 context->done_output = dst; 2965 context->done_output = dst;
2776 //set things up for sprite rendering in the next slot 3011 //set things up for sprite rendering in the next slot
2777 memset(context->linebuf, 0, LINEBUF_SIZE); 3012 memset(context->linebuf, 0, LINEBUF_SIZE);
2778 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1; 3013 context->cur_slot = context->sprite_index = MAX_DRAWS_H32_MODE4-1;
2779 context->sprite_draws = MAX_DRAWS_H32_MODE4; 3014 context->sprite_draws = MAX_DRAWS_H32_MODE4;
2780 uint32_t *dst = context->output + BORDER_LEFT + 256; 3015 uint32_t *dst = context->output + BORDER_LEFT + 256;
2781 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + CRAM_SIZE*3]; 3016 uint32_t bgcolor = context->colors[0x10 | (context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET];
2782 for (int i = 0; i < 8; i++, dst++) 3017 for (int i = 0; i < 8; i++, dst++)
2783 { 3018 {
2784 *dst = bgcolor; 3019 *dst = bgcolor;
2785 } 3020 }
2786 context->done_output = dst; 3021 context->done_output = dst;
2991 3226
2992 if (dst) { 3227 if (dst) {
2993 if (mode_5) { 3228 if (mode_5) {
2994 bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; 3229 bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F];
2995 } else if (context->regs[REG_MODE_1] & BIT_MODE_4) { 3230 } else if (context->regs[REG_MODE_1] & BIT_MODE_4) {
2996 bg_color = context->colors[CRAM_SIZE * 3 + 0x10 + (context->regs[REG_BG_COLOR] & 0xF)]; 3231 bg_color = context->colors[MODE4_OFFSET + 0x10 + (context->regs[REG_BG_COLOR] & 0xF)];
2997 } 3232 }
2998 if (dst >= context->done_output) { 3233 if (dst >= context->done_output) {
2999 *(dst++) = bg_color; 3234 *(dst++) = bg_color;
3000 *(debug_dst++) = DBG_SRC_BG; 3235 *(debug_dst++) = DBG_SRC_BG;
3001 } else { 3236 } else {