diff cdd_mcu.c @ 2080:bafb757e1cd2

Implement CD audio
author Michael Pavone <pavone@retrodev.com>
date Wed, 02 Feb 2022 01:10:07 -0800
parents 5a2b759f6b2d
children cfd53c94fffb
line wrap: on
line diff
--- a/cdd_mcu.c	Tue Feb 01 01:14:27 2022 -0800
+++ b/cdd_mcu.c	Wed Feb 02 01:10:07 2022 -0800
@@ -39,7 +39,7 @@
 	context->next_int_cycle = CYCLE_NEVER;
 	context->last_subcode_cycle = CYCLE_NEVER;
 	context->last_nibble_cycle = CYCLE_NEVER;
-	context->last_byte_cycle = CYCLE_NEVER;
+	context->last_byte_cycle = 0;
 	context->requested_format = SF_NOTREADY;
 	context->media = media;
 	context->current_status_nibble = -1;
@@ -52,6 +52,11 @@
 	GAO_CDD_STATUS,
 	GAO_CDD_CMD = GAO_CDD_STATUS+5
 };
+//GAO_CDD_CTRL
+#define BIT_MUTE 0x100
+#define BIT_HOCK 0x0004
+#define BIT_DRS  0x0002
+#define BIT_DTS  0x0001
 
 static uint8_t checksum(uint8_t *vbuffer)
 {
@@ -105,15 +110,19 @@
 	context->status_buffer.b.time.frame_low = frames % 10;
 }
 
-static void update_status(cdd_mcu *context)
+static void update_status(cdd_mcu *context, uint16_t *gate_array)
 {
+	gate_array[GAO_CDD_CTRL] |= BIT_MUTE;
 	switch (context->status)
 	{
 	case DS_PLAY:
 		handle_seek(context);
 		if (!context->seeking) {
 			context->head_pba++;
-			context->media->seek(context->media, context->head_pba - LEADIN_SECTORS);
+			uint8_t track = context->media->seek(context->media, context->head_pba - LEADIN_SECTORS);
+			if (context->media->tracks[track].type == TRACK_AUDIO) {
+				gate_array[GAO_CDD_CTRL] &= ~BIT_MUTE;
+			}
 		}
 		break;
 	case DS_PAUSE:
@@ -287,7 +296,7 @@
 			context->error_status = DS_STOP;
 		}
 		if (context->requested_format != SF_TOCN) {
-			context->status_buffer.b.time.flags = 1; //TODO: populate these
+			context->status_buffer.b.time.flags = !!(gate_array[GAO_CDD_CTRL] & BIT_MUTE); //TODO: populate these
 		}
 	} else {
 		// Did not receive our first command so just send zeroes
@@ -432,34 +441,37 @@
 	}
 }
 
-#define BIT_HOCK 0x4
-#define BIT_DRS  0x2
-#define BIT_DTS  0x1
-
-void cdd_mcu_run(cdd_mcu *context, uint32_t cycle, uint16_t *gate_array, lc8951* cdc)
+void cdd_mcu_run(cdd_mcu *context, uint32_t cycle, uint16_t *gate_array, lc8951* cdc, cdd_fader* fader)
 {
 	uint32_t cd_cycle = mclks_to_cd_block(cycle);
+	uint32_t next_byte = context->last_byte_cycle + BYTE_CLOCKS;
 	if (!(gate_array[GAO_CDD_CTRL] & BIT_HOCK)) {
 		//it's a little unclear if this gates the actual cd block clock or just handshaking
 		//assum it's actually the clock for now
-		context->cycle = cd_cycle;
+		for (; context->cycle < cd_cycle; context->cycle += CDD_MCU_DIVIDER) {
+			if (context->cycle >= next_byte) {
+				cdd_fader_data(fader, 0);
+				next_byte = context->cycle + BYTE_CLOCKS;
+				context->last_byte_cycle = context->cycle;
+			}
+		}
+		gate_array[GAO_CDD_CTRL] |= BIT_MUTE;
 		return;
 	}
 	uint32_t next_subcode = context->last_subcode_cycle + SECTOR_CLOCKS;
 	uint32_t next_nibble = context->current_status_nibble >= 0 ? context->last_nibble_cycle + NIBBLE_CLOCKS : CYCLE_NEVER;
 	uint32_t next_cmd_nibble = context->current_cmd_nibble >= 0 ? context->last_nibble_cycle + NIBBLE_CLOCKS : CYCLE_NEVER;
-	uint32_t next_byte = context->current_sector_byte >= 0 ? context->last_byte_cycle + BYTE_CLOCKS : CYCLE_NEVER;
+
 	for (; context->cycle < cd_cycle; context->cycle += CDD_MCU_DIVIDER)
 	{
 		if (context->cycle >= next_subcode) {
 			context->last_subcode_cycle = context->cycle;
 			next_subcode = context->cycle + SECTOR_CLOCKS;
-			update_status(context);
+			update_status(context, gate_array);
 			next_nibble = context->cycle;
 			context->current_status_nibble = 0;
 			gate_array[GAO_CDD_STATUS] |= BIT_DRS;
 			if (context->status == DS_PLAY && !context->seeking) {
-				next_byte = context->cycle;
 				context->current_sector_byte = 0;
 			}
 		}
@@ -508,15 +520,18 @@
 			}
 		}
 		if (context->cycle >= next_byte) {
-			uint8_t byte = context->media->read(context->media, context->current_sector_byte);
-			lc8951_write_byte(cdc, cd_block_to_mclks(context->cycle), context->current_sector_byte++, byte);
+			if (context->current_sector_byte >= 0) {
+				uint8_t byte = context->media->read(context->media, context->current_sector_byte);
+				lc8951_write_byte(cdc, cd_block_to_mclks(context->cycle), context->current_sector_byte++, byte);
+				cdd_fader_data(fader, gate_array[GAO_CDD_CTRL] & BIT_MUTE ? 0 : byte);
+			} else {
+				cdd_fader_data(fader, 0);
+			}
 			context->last_byte_cycle = context->cycle;
 			if (context->current_sector_byte == 2352) {
 				context->current_sector_byte = -1;
-				next_byte = CYCLE_NEVER;
-			} else {
-				next_byte = context->cycle + BYTE_CLOCKS;
 			}
+			next_byte = context->cycle + BYTE_CLOCKS;
 		}
 	}
 }
@@ -544,7 +559,6 @@
 	context->last_subcode_cycle = CYCLE_NEVER;
 	context->next_int_cycle = CYCLE_NEVER;
 	context->last_nibble_cycle = CYCLE_NEVER;
-	context->last_byte_cycle = CYCLE_NEVER;
 	context->current_status_nibble = -1;
 	context->current_cmd_nibble = -1;
 }