summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2017-05-23 21:09:38 -0700
committerMichael Pavone <pavone@retrodev.com>2017-05-23 21:09:38 -0700
commitd45cb844c7bd14bc7449b40f0b8153a139c070b0 (patch)
tree0ad30293a004da6cc35117f800881e6ffe73be50
parent76b3c462c295537542370f50be6bfbf2dfa215b3 (diff)
Remove HINT_FUDGE and make a small adjustment to how VDP syncs with rest of system instead. Worse results on CRAM dot issue, but much less of a hack
-rw-r--r--genesis.c4
-rw-r--r--sms.c3
-rw-r--r--vdp.c38
-rw-r--r--vdp.h1
4 files changed, 28 insertions, 18 deletions
diff --git a/genesis.c b/genesis.c
index 3b86692..382950f 100644
--- a/genesis.c
+++ b/genesis.c
@@ -299,6 +299,7 @@ static m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context,
//context->current_cycle = v_context->cycles;
}
} else if(vdp_port < 8) {
+ vdp_run_context_full(v_context, context->current_cycle);
blocked = vdp_control_port_write(v_context, value);
if (blocked) {
while (blocked) {
@@ -373,10 +374,11 @@ static void * z80_vdp_port_write(uint32_t vdp_port, void * vcontext, uint8_t val
}
if (vdp_port < 0x10) {
//These probably won't currently interact well with the 68K accessing the VDP
- vdp_run_context(gen->vdp, context->current_cycle);
if (vdp_port < 4) {
+ vdp_run_context(gen->vdp, context->current_cycle);
vdp_data_port_write(gen->vdp, value << 8 | value);
} else if (vdp_port < 8) {
+ vdp_run_context_full(gen->vdp, context->current_cycle);
vdp_control_port_write(gen->vdp, value << 8 | value);
} else {
fatal_error("Illegal write to HV Counter port %X\n", vdp_port);
diff --git a/sms.c b/sms.c
index 6993095..2c8c3e6 100644
--- a/sms.c
+++ b/sms.c
@@ -81,11 +81,12 @@ static void *vdp_write(uint32_t location, void *vcontext, uint8_t value)
{
z80_context *z80 = vcontext;
sms_context *sms = z80->system;
- vdp_run_context(sms->vdp, z80->current_cycle);
if (location & 1) {
+ vdp_run_context_full(sms->vdp, z80->current_cycle);
vdp_control_port_write_pbc(sms->vdp, value);
update_interrupts(sms);
} else {
+ vdp_run_context(sms->vdp, z80->current_cycle);
vdp_data_port_write_pbc(sms->vdp, value);
}
return vcontext;
diff --git a/vdp.c b/vdp.c
index 2878760..f222b83 100644
--- a/vdp.c
+++ b/vdp.c
@@ -2758,7 +2758,7 @@ static void vdp_inactive(vdp_context *context, uint32_t target_cycles, uint8_t i
}
}
-void vdp_run_context(vdp_context * context, uint32_t target_cycles)
+void vdp_run_context_full(vdp_context * context, uint32_t target_cycles)
{
uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40;
uint8_t mode_5 = context->regs[REG_MODE_2] & BIT_MODE_5;
@@ -2782,11 +2782,22 @@ void vdp_run_context(vdp_context * context, uint32_t target_cycles)
}
}
+void vdp_run_context(vdp_context *context, uint32_t target_cycles)
+{
+ //TODO: Deal with H40 hsync shenanigans
+ uint32_t slot_cyc = context->regs[REG_MODE_4] & BIT_H40 ? 15 : 19;
+ if (target_cycles < slot_cyc) {
+ //avoid overflow
+ return;
+ }
+ vdp_run_context_full(context, target_cycles - slot_cyc);
+}
+
uint32_t vdp_run_to_vblank(vdp_context * context)
{
uint32_t old_frame = context->frame;
while (context->frame == old_frame) {
- vdp_run_context(context, context->cycles + MCLKS_LINE);
+ vdp_run_context_full(context, context->cycles + MCLKS_LINE);
}
return context->cycles;
}
@@ -2809,10 +2820,10 @@ void vdp_run_dma_done(vdp_context * context, uint32_t target_cycles)
}
min_dma_complete += context->cycles;
if (target_cycles < min_dma_complete) {
- vdp_run_context(context, target_cycles);
+ vdp_run_context_full(context, target_cycles);
return;
} else {
- vdp_run_context(context, min_dma_complete);
+ vdp_run_context_full(context, min_dma_complete);
if (!(context->flags & FLAG_DMA_RUN)) {
return;
}
@@ -2882,7 +2893,7 @@ int vdp_control_port_write(vdp_context * context, uint16_t value)
//logic analyzer captures made it seem like the proper value is 4 slots, but that seems to cause trouble with the Nemesis' FIFO Wait State test
//only captures are from a direct color DMA demo which will generally start DMA at a very specific point in display so other values are plausible
//sticking with 3 slots for now until I can do some more captures
- vdp_run_context(context, context->cycles + 12 * ((context->regs[REG_MODE_2] & BIT_MODE_5) && (context->regs[REG_MODE_4] & BIT_H40) ? 4 : 5));
+ vdp_run_context_full(context, context->cycles + 12 * ((context->regs[REG_MODE_2] & BIT_MODE_5) && (context->regs[REG_MODE_4] & BIT_H40) ? 4 : 5));
context->flags |= FLAG_DMA_RUN;
return 1;
} else {
@@ -2970,7 +2981,7 @@ int vdp_data_port_write(vdp_context * context, uint16_t value)
context->flags &= ~FLAG_DMA_RUN;
}
while (context->fifo_write == context->fifo_read) {
- vdp_run_context(context, context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20));
+ vdp_run_context_full(context, context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20));
}
fifo_entry * cur = context->fifo + context->fifo_write;
cur->cycle = context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20)*FIFO_LATENCY;
@@ -3006,7 +3017,7 @@ void vdp_data_port_write_pbc(vdp_context * context, uint8_t value)
context->flags &= ~FLAG_DMA_RUN;
}
while (context->fifo_write == context->fifo_read) {
- vdp_run_context(context, context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20));
+ vdp_run_context_full(context, context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20));
}
fifo_entry * cur = context->fifo + context->fifo_write;
cur->cycle = context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20)*FIFO_LATENCY;
@@ -3091,7 +3102,7 @@ uint16_t vdp_data_port_read(vdp_context * context)
warning("Read from VDP data port while writes are configured, CPU is now frozen. VDP Address: %X, CD: %X\n", context->address, context->cd);
}
while (!(context->flags & FLAG_READ_FETCHED)) {
- vdp_run_context(context, context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20));
+ vdp_run_context_full(context, context->cycles + ((context->regs[REG_MODE_4] & BIT_H40) ? 16 : 20));
}
context->flags &= ~FLAG_READ_FETCHED;
return context->prefetch;
@@ -3243,18 +3254,13 @@ uint32_t vdp_cycles_to_frame_end(vdp_context * context)
return context->cycles + vdp_cycles_to_line(context, context->inactive_start);
}
-//This gives correct values in my test ROM. Kind of a hack, might be partly
-//due to interrupts getting latched at the end of a "dbi" micro-instruction
-//but that would only account for 28 of the 36 cycles. More hardware testing
-//necessary to determine the cause of the discrepency
-#define HINT_FUDGE 36
uint32_t vdp_next_hint(vdp_context * context)
{
if (!(context->regs[REG_MODE_1] & BIT_HINT_EN)) {
return 0xFFFFFFFF;
}
if (context->flags2 & FLAG2_HINT_PENDING) {
- return context->pending_hint_start - HINT_FUDGE;
+ return context->pending_hint_start;
}
uint32_t hint_line;
if (context->state != ACTIVE) {
@@ -3275,7 +3281,7 @@ uint32_t vdp_next_hint(vdp_context * context)
//is higher than the line we're on now so just passing
//that line number to vdp_cycles_to_line will yield the wrong
//result
- return context->cycles + vdp_cycles_to_line(context, 0) + hint_line * MCLKS_LINE - HINT_FUDGE;
+ return context->cycles + vdp_cycles_to_line(context, 0) + hint_line * MCLKS_LINE;
}
}
} else {
@@ -3289,7 +3295,7 @@ uint32_t vdp_next_hint(vdp_context * context)
}
}
}
- return context->cycles + vdp_cycles_to_line(context, hint_line) - HINT_FUDGE;
+ return context->cycles + vdp_cycles_to_line(context, hint_line);
}
static uint32_t vdp_next_vint_real(vdp_context * context)
diff --git a/vdp.h b/vdp.h
index bee6014..18f0142 100644
--- a/vdp.h
+++ b/vdp.h
@@ -215,6 +215,7 @@ typedef struct {
void init_vdp_context(vdp_context * context, uint8_t region_pal);
void vdp_free(vdp_context *context);
+void vdp_run_context_full(vdp_context * context, uint32_t target_cycles);
void vdp_run_context(vdp_context * context, uint32_t target_cycles);
//runs from current cycle count to VBLANK for the current mode, returns ending cycle count
uint32_t vdp_run_to_vblank(vdp_context * context);