summaryrefslogtreecommitdiff
path: root/vdp.c
diff options
context:
space:
mode:
Diffstat (limited to 'vdp.c')
-rw-r--r--vdp.c61
1 files changed, 30 insertions, 31 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;
}