summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pavone <pavone@retrodev.com>2013-09-17 00:11:45 -0700
committerMike Pavone <pavone@retrodev.com>2013-09-17 00:11:45 -0700
commit74af15299f37e5c95f4498cfb2f9456c9d4d61bc (patch)
tree61752bd0da3c1d32f50f266548b6be4bd9d237fa
parenta020d55258a5ebf5db027072c4ef28194aa6564b (diff)
Fix DMA fill so that it does not cause observable changes to the FIFO. Get DMA copy mostly correct from an observable ffect perspective. DMA copy probably does not reflect internal implementation still given that evidence seems to suggest no FIFO usage at all.
-rw-r--r--vdp.c61
-rw-r--r--vdp.h2
2 files changed, 30 insertions, 33 deletions
diff --git a/vdp.c b/vdp.c
index 5de80e5..b75f063 100644
--- a/vdp.c
+++ b/vdp.c
@@ -410,8 +410,7 @@ void external_slot(vdp_context * context)
case VRAM_WRITE:
if (start->partial) {
//printf("VRAM Write: %X to %X at %d (line %d, slot %d)\n", start->value, start->address ^ 1, context->cycles, context->cycles/MCLKS_LINE, (context->cycles%MCLKS_LINE)/16);
- context->last_fifo_val = start->value;
- context->vdpmem[start->address ^ 1] = start->value;
+ context->vdpmem[start->address ^ 1] = start->partial == 2 ? start->value >> 8 : start->value;
} else {
//printf("VRAM Write High: %X to %X at %d (line %d, slot %d)\n", start->value >> 8, start->address, context->cycles, context->cycles/MCLKS_LINE, (context->cycles%MCLKS_LINE)/16);
context->vdpmem[start->address] = start->value >> 8;
@@ -423,14 +422,12 @@ void external_slot(vdp_context * context)
case CRAM_WRITE: {
//printf("CRAM Write | %X to %X\n", start->value, (start->address/2) & (CRAM_SIZE-1));
write_cram(context, start->address, start->value);
- context->last_fifo_val = start->value;
break;
}
case VSRAM_WRITE:
if (((start->address/2) & 63) < VSRAM_SIZE) {
//printf("VSRAM Write: %X to %X\n", start->value, context->address);
context->vsram[(start->address/2) & 63] = start->value;
- context->last_fifo_val = start->value;
}
break;
@@ -452,54 +449,57 @@ void run_dma_src(vdp_context * context, uint32_t slot)
if (context->fifo_write == context->fifo_read) {
return;
}
- uint16_t read_val;
- uint8_t ran_source = 0, partial = 0;
- uint16_t dma_len;
- uint8_t cd = context->cd;
+ fifo_entry * cur = NULL;
switch(context->regs[REG_DMASRC_H] & 0xC0)
{
//68K -> VDP
case 0:
case 0x40:
if (!slot || !is_refresh(context, slot-1)) {
- read_val = read_dma_value((context->regs[REG_DMASRC_H] << 16) | (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]);
- ran_source = 1;
+ cur = context->fifo + context->fifo_write;
+ cur->cycle = context->cycles + ((context->latched_mode & BIT_H40) ? 16 : 20)*FIFO_LATENCY;
+ cur->address = context->address;
+ cur->value = read_dma_value((context->regs[REG_DMASRC_H] << 16) | (context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L]);
+ cur->cd = context->cd;
+ cur->partial = 0;
+ if (context->fifo_read < 0) {
+ context->fifo_read = context->fifo_write;
+ }
+ context->fifo_write = (context->fifo_write + 1) & (FIFO_SIZE-1);
}
break;
//Copy
case 0xC0:
- if (context->flags & FLAG_UNUSED_SLOT) {
- read_val = context->vdpmem[(context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L] ^ 1] | (context->fifo[context->fifo_write].value & 0xFF00);
- cd = VRAM_WRITE;
- partial = 1;
- ran_source = 1;
+ if (context->flags & FLAG_UNUSED_SLOT && context->fifo_read < 0) {
+ //TODO: Fix this to not use the FIFO at all once read-caching is properly implemented
+ context->fifo_read = (context->fifo_write-1) & (FIFO_SIZE-1);
+ cur = context->fifo + context->fifo_read;
+ cur->cycle = context->cycles;
+ cur->address = context->address;
+ cur->partial = 1;
+ cur->value = context->vdpmem[(context->regs[REG_DMASRC_M] << 8) | context->regs[REG_DMASRC_L] ^ 1] | (cur->value & 0xFF00);
+ cur->cd = VRAM_WRITE;
context->flags &= ~FLAG_UNUSED_SLOT;
}
break;
case 0x80:
- read_val = (context->cd & 0xF) == VRAM_WRITE ? context->last_write_val >> 8 : context->last_write_val;
- partial = 1;
- ran_source = 1;
+ if (context->fifo_read < 0) {
+ context->fifo_read = (context->fifo_write-1) & (FIFO_SIZE-1);
+ cur = context->fifo + context->fifo_read;
+ cur->cycle = context->cycles;
+ cur->address = context->address;
+ cur->partial = 2;
+ }
break;
}
- if (ran_source) {
- fifo_entry * cur = context->fifo + context->fifo_write;
- cur->cycle = context->cycles + ((context->latched_mode & BIT_H40) ? 16 : 20)*FIFO_LATENCY;
- cur->address = context->address;
- cur->value = read_val;
- cur->cd = cd;
- cur->partial = partial;
- if (context->fifo_read < 0) {
- context->fifo_read = context->fifo_write;
- }
- context->fifo_write = (context->fifo_write+1) & (FIFO_SIZE-1);
+ if (cur) {
context->regs[REG_DMASRC_L] += 1;
if (!context->regs[REG_DMASRC_L]) {
context->regs[REG_DMASRC_M] += 1;
}
context->address += context->regs[REG_AUTOINC];
- dma_len = ((context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L]) - 1;
+ uint16_t dma_len = ((context->regs[REG_DMALEN_H] << 8) | context->regs[REG_DMALEN_L]) - 1;
context->regs[REG_DMALEN_H] = dma_len >> 8;
context->regs[REG_DMALEN_L] = dma_len;
if (!dma_len) {
@@ -1508,7 +1508,6 @@ int vdp_data_port_write(vdp_context * context, uint16_t value)
cur->cycle = context->cycles + ((context->latched_mode & BIT_H40) ? 16 : 20)*FIFO_LATENCY;
cur->address = context->address;
cur->value = value;
- context->last_write_val = value;
if (context->cd & 0x20 && (context->regs[REG_DMASRC_H] & 0xC0) == 0x80) {
context->flags |= FLAG_DMA_RUN;
}
diff --git a/vdp.h b/vdp.h
index 75a603d..9d976e4 100644
--- a/vdp.h
+++ b/vdp.h
@@ -152,8 +152,6 @@ typedef struct {
sprite_info sprite_info_list[MAX_SPRITES_LINE];
uint16_t col_1;
uint16_t col_2;
- uint16_t last_write_val;
- uint16_t last_fifo_val;
uint8_t v_offset;
uint8_t dma_cd;
uint8_t hint_counter;