Mercurial > repos > blastem
comparison vdp.c @ 453:b491df8bdbc0
Adjust VBLANK flag and refresh timing to be in line with logic analyzer and visual observations of direct color DMA demos. Remove debug print statements.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 02 Sep 2013 00:20:56 -0700 |
parents | 608815ab4ff2 |
children | e9b6fe443bf2 |
comparison
equal
deleted
inserted
replaced
452:608815ab4ff2 | 453:b491df8bdbc0 |
---|---|
476 } | 476 } |
477 dma_len = ((context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L]) - 1; | 477 dma_len = ((context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L]) - 1; |
478 context->regs[REG_DMALEN_H] = dma_len >> 8; | 478 context->regs[REG_DMALEN_H] = dma_len >> 8; |
479 context->regs[REG_DMALEN_L] = dma_len; | 479 context->regs[REG_DMALEN_L] = dma_len; |
480 if (!dma_len) { | 480 if (!dma_len) { |
481 printf("DMA end at cycle %d\n", context->cycles); | 481 //printf("DMA end at cycle %d\n", context->cycles); |
482 context->flags &= ~FLAG_DMA_RUN; | 482 context->flags &= ~FLAG_DMA_RUN; |
483 } | 483 } |
484 } | 484 } |
485 } else { | 485 } else { |
486 fifo_entry * start = (context->fifo_end - FIFO_SIZE); | 486 fifo_entry * start = (context->fifo_end - FIFO_SIZE); |
487 if (context->fifo_cur != start && start->cycle <= context->cycles) { | 487 if (context->fifo_cur != start && start->cycle <= context->cycles) { |
488 if ((context->regs[REG_MODE_2] & BIT_DMA_ENABLE) && (context->cd & DMA_START) && (context->regs[REG_DMASRC_H] & 0xC0) == 0x80) { | 488 if ((context->regs[REG_MODE_2] & BIT_DMA_ENABLE) && (context->cd & DMA_START) && (context->regs[REG_DMASRC_H] & 0xC0) == 0x80) { |
489 printf("DMA fill started at %d\n", context->cycles); | 489 //printf("DMA fill started at %d\n", context->cycles); |
490 context->flags |= FLAG_DMA_RUN; | 490 context->flags |= FLAG_DMA_RUN; |
491 context->dma_val = start->value; | 491 context->dma_val = start->value; |
492 context->address = start->address; //undo auto-increment | 492 context->address = start->address; //undo auto-increment |
493 context->dma_cd = context->cd; | 493 context->dma_cd = context->cd; |
494 } else { | 494 } else { |
1239 } | 1239 } |
1240 | 1240 |
1241 int is_refresh(vdp_context * context, uint32_t slot) | 1241 int is_refresh(vdp_context * context, uint32_t slot) |
1242 { | 1242 { |
1243 if (context->latched_mode & BIT_H40) { | 1243 if (context->latched_mode & BIT_H40) { |
1244 //TODO: Figure out the exact behavior that reduces DMA slots for direct color DMA demos | 1244 //TODO: Determine behavior for DMA fills and copies |
1245 return (slot == 37 || slot == 69 || slot == 102 || slot == 133 || slot == 165 || slot == 197 || slot >= 210 || (slot < 6 && (context->flags & FLAG_DMA_RUN) && ((context->dma_cd & 0xF) == CRAM_WRITE))); | 1245 return (slot == 37 || slot == 69 || slot == 102 || slot == 133 || slot == 165 || slot == 197 || slot >= 210 |
1246 || ((context->flags & FLAG_DMA_RUN) && ((context->dma_cd & 0xF) != VRAM_WRITE)) && ( | |
1247 //both of the missed reads occurred right next to each other, but there seems | |
1248 //to be some buffering involved, these values produce similar artifacts | |
1249 //to what I see on my Model 2 | |
1250 slot == 34 || slot == 66 || slot == 99 || slot == 130 || slot == 162 || slot == 194)); | |
1246 } else { | 1251 } else { |
1247 //TODO: Figure out which slots are refresh when display is off in 32-cell mode | 1252 //TODO: Figure out which slots are refresh when display is off in 32-cell mode |
1248 //These numbers are guesses based on H40 numbers | 1253 //These numbers are guesses based on H40 numbers |
1249 return (slot == 24 || slot == 56 || slot == 88 || slot == 120 || slot == 152 || (slot < 5 && (context->flags & FLAG_DMA_RUN) && ((context->dma_cd & 0xF) == CRAM_WRITE))); | 1254 return (slot == 24 || slot == 56 || slot == 88 || slot == 120 || slot == 152 |
1255 || ((context->flags & FLAG_DMA_RUN) && ((context->dma_cd & 0xF) != VRAM_WRITE)) && ( | |
1256 slot == 21 || slot == 53 || slot == 85 || slot == 117 || slot == 149)); | |
1250 //The numbers below are the refresh slots during active display | 1257 //The numbers below are the refresh slots during active display |
1251 //return (slot == 66 || slot == 98 || slot == 130 || slot == 162); | 1258 //return (slot == 66 || slot == 98 || slot == 130 || slot == 162); |
1252 } | 1259 } |
1253 } | 1260 } |
1254 | 1261 |
1458 } | 1465 } |
1459 } | 1466 } |
1460 | 1467 |
1461 int vdp_control_port_write(vdp_context * context, uint16_t value) | 1468 int vdp_control_port_write(vdp_context * context, uint16_t value) |
1462 { | 1469 { |
1463 printf("control port write: %X at %d\n", value, context->cycles); | 1470 //printf("control port write: %X at %d\n", value, context->cycles); |
1464 if (context->flags & FLAG_DMA_RUN) { | 1471 if (context->flags & FLAG_DMA_RUN) { |
1465 return -1; | 1472 return -1; |
1466 } | 1473 } |
1467 if (context->flags & FLAG_PENDING) { | 1474 if (context->flags & FLAG_PENDING) { |
1468 context->address = (context->address & 0x3FFF) | (value << 14); | 1475 context->address = (context->address & 0x3FFF) | (value << 14); |
1469 context->cd = (context->cd & 0x3) | ((value >> 2) & 0x3C); | 1476 context->cd = (context->cd & 0x3) | ((value >> 2) & 0x3C); |
1470 context->flags &= ~FLAG_PENDING; | 1477 context->flags &= ~FLAG_PENDING; |
1471 printf("New Address: %X, New CD: %X\n", context->address, context->cd); | 1478 //printf("New Address: %X, New CD: %X\n", context->address, context->cd); |
1472 if (context->cd & 0x20 && (context->regs[REG_MODE_2] & BIT_DMA_ENABLE)) { | 1479 if (context->cd & 0x20 && (context->regs[REG_MODE_2] & BIT_DMA_ENABLE)) { |
1473 // | 1480 // |
1474 if((context->regs[REG_DMASRC_H] & 0xC0) != 0x80) { | 1481 if((context->regs[REG_DMASRC_H] & 0xC0) != 0x80) { |
1475 //DMA copy or 68K -> VDP, transfer starts immediately | 1482 //DMA copy or 68K -> VDP, transfer starts immediately |
1476 context->flags |= FLAG_DMA_RUN; | 1483 context->flags |= FLAG_DMA_RUN; |
1477 context->dma_cd = context->cd; | 1484 context->dma_cd = context->cd; |
1478 printf("DMA start at cycle %d\n", context->cycles); | 1485 //printf("DMA start at cycle %d\n", context->cycles); |
1479 if (!(context->regs[REG_DMASRC_H] & 0x80)) { | 1486 if (!(context->regs[REG_DMASRC_H] & 0x80)) { |
1480 //printf("DMA Address: %X, New CD: %X, Source: %X, Length: %X\n", context->address, context->cd, (context->regs[REG_DMASRC_H] << 17) | (context->regs[REG_DMASRC_M] << 9) | (context->regs[REG_DMASRC_L] << 1), context->regs[REG_DMALEN_H] << 8 | context->regs[REG_DMALEN_L]); | 1487 //printf("DMA Address: %X, New CD: %X, Source: %X, Length: %X\n", context->address, context->cd, (context->regs[REG_DMASRC_H] << 17) | (context->regs[REG_DMASRC_M] << 9) | (context->regs[REG_DMASRC_L] << 1), context->regs[REG_DMALEN_H] << 8 | context->regs[REG_DMALEN_L]); |
1481 return 1; | 1488 return 1; |
1482 } else { | 1489 } else { |
1483 //printf("DMA Copy Address: %X, New CD: %X, Source: %X\n", context->address, context->cd, (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]); | 1490 //printf("DMA Copy Address: %X, New CD: %X, Source: %X\n", context->address, context->cd, (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]); |
1484 } | 1491 } |
1485 } else { | 1492 } else { |
1486 printf("DMA Fill Address: %X, New CD: %X\n", context->address, context->cd); | 1493 //printf("DMA Fill Address: %X, New CD: %X\n", context->address, context->cd); |
1487 } | 1494 } |
1488 } | 1495 } |
1489 } else { | 1496 } else { |
1490 if ((value & 0xC000) == 0x8000) { | 1497 if ((value & 0xC000) == 0x8000) { |
1491 //Register write | 1498 //Register write |
1492 uint8_t reg = (value >> 8) & 0x1F; | 1499 uint8_t reg = (value >> 8) & 0x1F; |
1493 if (reg < VDP_REGS) { | 1500 if (reg < VDP_REGS) { |
1494 printf("register %d set to %X\n", reg, value & 0xFF); | 1501 //printf("register %d set to %X\n", reg, value & 0xFF); |
1495 context->regs[reg] = value; | 1502 context->regs[reg] = value; |
1496 if (reg == REG_MODE_2) { | 1503 if (reg == REG_MODE_2) { |
1497 //printf("Display is now %s\n", (context->regs[REG_MODE_2] & DISPLAY_ENABLE) ? "enabled" : "disabled"); | 1504 //printf("Display is now %s\n", (context->regs[REG_MODE_2] & DISPLAY_ENABLE) ? "enabled" : "disabled"); |
1498 } | 1505 } |
1499 if (reg == REG_MODE_4) { | 1506 if (reg == REG_MODE_4) { |
1512 return 0; | 1519 return 0; |
1513 } | 1520 } |
1514 | 1521 |
1515 int vdp_data_port_write(vdp_context * context, uint16_t value) | 1522 int vdp_data_port_write(vdp_context * context, uint16_t value) |
1516 { | 1523 { |
1517 printf("data port write: %X at %d\n", value, context->cycles); | 1524 //printf("data port write: %X at %d\n", value, context->cycles); |
1518 if (context->flags & FLAG_DMA_RUN) { | 1525 if (context->flags & FLAG_DMA_RUN) { |
1519 return -1; | 1526 return -1; |
1520 } | 1527 } |
1521 if (!(context->cd & 1)) { | 1528 if (!(context->cd & 1)) { |
1522 //ignore writes when cd is configured for read | 1529 //ignore writes when cd is configured for read |
1555 if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && context->framebuf == context->oddbuf) { | 1562 if ((context->regs[REG_MODE_4] & BIT_INTERLACE) && context->framebuf == context->oddbuf) { |
1556 value |= 0x10; | 1563 value |= 0x10; |
1557 } | 1564 } |
1558 uint32_t line= context->cycles / MCLKS_LINE; | 1565 uint32_t line= context->cycles / MCLKS_LINE; |
1559 uint32_t linecyc = context->cycles % MCLKS_LINE; | 1566 uint32_t linecyc = context->cycles % MCLKS_LINE; |
1560 if (line >= (context->latched_mode & BIT_PAL ? PAL_ACTIVE : NTSC_ACTIVE)) { | 1567 if (line >= (context->latched_mode & BIT_PAL ? PAL_ACTIVE : NTSC_ACTIVE) || context->cycles < (context->latched_mode & BIT_H40 ? 16*4 : 16*5)) { |
1561 value |= 0x8; | 1568 value |= 0x8; |
1562 } | 1569 } |
1563 if (linecyc < (context->latched_mode & BIT_H40 ? HBLANK_CLEAR_H40 : HBLANK_CLEAR_H32)) { | 1570 if (linecyc < (context->latched_mode & BIT_H40 ? HBLANK_CLEAR_H40 : HBLANK_CLEAR_H32)) { |
1564 value |= 0x4; | 1571 value |= 0x4; |
1565 } | 1572 } |