changeset 2131:d90d92ce5cab

Improve CDC decode timing accuracy
author Michael Pavone <pavone@retrodev.com>
date Wed, 16 Mar 2022 00:16:36 -0700
parents 28b6453cf7e3
children 7451f970ee66
files lc8951.c segacd.c
diffstat 2 files changed, 10 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/lc8951.c	Tue Mar 15 08:58:04 2022 -0700
+++ b/lc8951.c	Wed Mar 16 00:16:36 2022 -0700
@@ -276,6 +276,7 @@
 	uint16_t current_write_addr = context->regs[WAL] | (context->regs[WAH] << 8);
 
 	context->sector_counter++;
+	context->sector_counter &= 0xFFF;
 	uint8_t sync_detected = 0, sync_ignored = 0;
 	if (byte == 0) {
 		if (context->sync_counter == 11 && ((sector_offset & 3) == 3)) {
@@ -321,8 +322,8 @@
 				context->regs[PTH] = block_start >> 8;
 			}
 			printf("Decoding block starting at %X (WRRQ: %d)\n", context->regs[PTL] | (context->regs[PTH] << 8), !!(context->ctrl0 & BIT_WRRQ));
-			//TODO: Datasheet has some hints about how long decoding takes in the form of how long DECI is asserted
-			context->decode_end = context->cycle + 2352 * context->clock_step * 4;
+			//Based on measurements of a Wondermega M1 (LC8951) with SYDEN, SYIEN and DECEN only
+			context->decode_end = context->cycle + 22030 * context->clock_step;
 		}
 	} else {
 		if (sync_ignored) {
@@ -355,11 +356,11 @@
 		return context->cycle;
 	}
 	uint32_t deci_cycle = CYCLE_NEVER;
-	if (context->ifctrl & BIT_DECI) {
+	if (context->ifctrl & BIT_DECIEN) {
 		deci_cycle = context->decode_end;
 	}
 	uint32_t dtei_cycle = CYCLE_NEVER;
-	if (context->ifctrl & BIT_DTEI) {
+	if (context->ifctrl & BIT_DTEIEN) {
 		dtei_cycle = context->transfer_end;
 	}
 	return deci_cycle < dtei_cycle ? deci_cycle : dtei_cycle;
--- a/segacd.c	Tue Mar 15 08:58:04 2022 -0700
+++ b/segacd.c	Wed Mar 16 00:16:36 2022 -0700
@@ -502,6 +502,11 @@
 		uint32_t before = context->target_cycle - 2 * cd->cdc.clock_step;
 		if (before > context->current_cycle) {
 			context->target_cycle = context->sync_cycle = before;
+		} else {
+			before = context->target_cycle - cd->cdc.clock_step;
+			if (before > context->current_cycle) {
+				context->target_cycle = context->sync_cycle = before;
+			}
 		}
 	}
 }