changeset 2515:0775f5e0c468 default tip

Clear EDT on DTTRG. Fixes Cliffhanger and OrionNavattan's Mode 1 demo
author Michael Pavone <pavone@retrodev.com>
date Thu, 05 Sep 2024 23:44:01 -0700
parents 50cff4c9286e
children
files lc8951.c lc8951.h segacd.c
diffstat 3 files changed, 16 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/lc8951.c	Sat Aug 31 22:41:17 2024 -0700
+++ b/lc8951.c	Thu Sep 05 23:44:01 2024 -0700
@@ -484,3 +484,8 @@
 	context->triggered = load_int8(buf);
 	context->sync_counter = load_int8(buf);
 }
+
+uint8_t lc8951_dtbsy_state(lc8951 *context)
+{
+	return (context->regs[IFSTAT] & BIT_DTBSY) ? 1 : 0;
+}
--- a/lc8951.h	Sat Aug 31 22:41:17 2024 -0700
+++ b/lc8951.h	Thu Sep 05 23:44:01 2024 -0700
@@ -47,5 +47,6 @@
 void lc8951_adjust_cycles(lc8951 *context, uint32_t deduction);
 void lc8951_serialize(lc8951 *context, serialize_buffer *buf);
 void lc8951_deserialize(deserialize_buffer *buf, void *vcontext);
+uint8_t lc8951_dtbsy_state(lc8951 *context);
 
 #endif //LC8951_H_
--- a/segacd.c	Sat Aug 31 22:41:17 2024 -0700
+++ b/segacd.c	Thu Sep 05 23:44:01 2024 -0700
@@ -856,7 +856,7 @@
 		lc8951_ar_write(&cd->cdc, value);
 		//cd->gate_array[reg] &= 0xC000;
 		uint16_t old_dest = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7;
-		//apparently this clears EDT, should it also clear DSR?
+		//clears both EDT and DSR
 		cd->gate_array[reg] = value & 0x0700;
 		uint16_t dest = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7;
 		if (dest != old_dest) {
@@ -878,11 +878,18 @@
 		cdd_run(cd, m68k->cycles);
 		printf("CDC write %X: %X @ %u\n", cd->cdc.ar, value, m68k->cycles);
 		if (cd->cdc.ar == 6) {
+			//this next bit needs hardware confirmation
 			cd->cdc_dst_low = 0;
-			//TODO: Confirm if DSR is cleared here on hardware
+		}
+		lc8951_reg_write(&cd->cdc, value);
+		if (!lc8951_dtbsy_state(&cd->cdc)) {
+			//new transfer has started, this clears EDT
+			cd->gate_array[GA_CDC_CTRL] &= ~BIT_EDT;
+			//DSR does not seem to be cleared on hardware
+			//but doing this seems to fix Penn & Teller's Smoke and Mirrors
+			//needs more research
 			cd->gate_array[GA_CDC_CTRL] &= ~BIT_DSR;
 		}
-		lc8951_reg_write(&cd->cdc, value);
 		calculate_target_cycle(m68k);
 		break;
 	case GA_CDC_HOST_DATA:
@@ -893,8 +900,6 @@
 		cdd_run(cd, m68k->cycles);
 		cd->gate_array[reg] = value;
 		cd->cdc_dst_low = 0;
-		//TODO: Confirm if DSR is cleared here on hardware
-		cd->gate_array[GA_CDC_CTRL] &= ~BIT_DSR;
 		break;
 	case GA_STOP_WATCH:
 		//docs say you should only write zero to reset