changeset 1371:5b20840711c1

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
author Michael Pavone <pavone@retrodev.com>
date Tue, 23 May 2017 21:09:38 -0700
parents eaca4443e831
children d78ef6f4fba2
files genesis.c sms.c vdp.c vdp.h
diffstat 4 files changed, 28 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/genesis.c	Tue May 23 21:07:56 2017 -0700
+++ b/genesis.c	Tue May 23 21:09:38 2017 -0700
@@ -299,6 +299,7 @@
 				//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 @@
 	}
 	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);
--- a/sms.c	Tue May 23 21:07:56 2017 -0700
+++ b/sms.c	Tue May 23 21:09:38 2017 -0700
@@ -81,11 +81,12 @@
 {
 	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;
--- a/vdp.c	Tue May 23 21:07:56 2017 -0700
+++ b/vdp.c	Tue May 23 21:09:38 2017 -0700
@@ -2758,7 +2758,7 @@
 	}
 }
 
-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)
+{
+	//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 @@
 		}
 		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 @@
 					//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 @@
 		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 @@
 		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 @@
 		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 @@
 	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 @@
 					//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 @@
 			}
 		}
 	}
-	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)
--- a/vdp.h	Tue May 23 21:07:56 2017 -0700
+++ b/vdp.h	Tue May 23 21:09:38 2017 -0700
@@ -215,6 +215,7 @@
 
 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);