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 }