# HG changeset patch # User Michael Pavone # Date 1644107902 28800 # Node ID c9d3b8e1ea56cfefd058b73f8aefd0617d192703 # Parent 372625dd9590c13818e6898cd9172811ece94482 Implement a couple more CDD commands force CDDA mute when seeking diff -r 372625dd9590 -r c9d3b8e1ea56 cdd_mcu.c --- a/cdd_mcu.c Thu Feb 03 23:41:53 2022 -0800 +++ b/cdd_mcu.c Sat Feb 05 16:38:22 2022 -0800 @@ -122,13 +122,19 @@ } if (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) { + if (!context->seeking && context->media->tracks[track].type == TRACK_AUDIO) { gate_array[GAO_CDD_CTRL] &= ~BIT_MUTE; } } break; case DS_PAUSE: handle_seek(context); + if (context->head_pba >= LEADIN_SECTORS) { + uint8_t track = context->media->seek(context->media, context->head_pba - LEADIN_SECTORS); + if (!context->seeking && context->media->tracks[track].type == TRACK_AUDIO) { + gate_array[GAO_CDD_CTRL] &= ~BIT_MUTE; + } + } break; case DS_TOC_READ: handle_seek(context); @@ -147,7 +153,18 @@ } } break; - + case DS_TRACKING: + handle_seek(context); + if (!context->seeking) { + context->status = DS_PAUSE; + } + if (context->head_pba >= LEADIN_SECTORS) { + uint8_t track = context->media->seek(context->media, context->head_pba - LEADIN_SECTORS); + if (!context->seeking && context->media->tracks[track].type == TRACK_AUDIO) { + gate_array[GAO_CDD_CTRL] &= ~BIT_MUTE; + } + } + break; } if (context->first_cmd_received) { switch (context->requested_format) @@ -287,7 +304,7 @@ if (context->error_status == DS_STOP) { if (context->requested_format >= SF_TOCO && context->requested_format <= SF_TOCN) { context->status_buffer.status = DS_TOC_READ; - } else if (context->seeking) { + } else if (context->seeking && context->status != DS_TRACKING) { context->status_buffer.status = DS_SEEK; } else { context->status_buffer.status = context->status; @@ -438,6 +455,53 @@ } context->status = DS_PAUSE; break; + case CMD_PLAY: + if (context->status == DS_DOOR_OPEN || context->status == DS_TRAY_MOVING || context->status == DS_DISC_LEADOUT || context->status == DS_DISC_LEADIN) { + context->error_status = DS_CMD_ERROR; + break; + } + if (context->requested_format == SF_TOCT || context->requested_format == SF_TOCN) { + context->requested_format = SF_ABSOLUTE; + } + if (!context->toc_valid) { + context->error_status = DS_CMD_ERROR; + break; + } + if (context->status == DS_STOP || context->status == DS_TOC_READ) { + context->seeking = 1; + context->seek_pba = LEADIN_SECTORS + context->media->tracks[0].fake_pregap + context->media->tracks[0].start_lba; + printf("CDD CMD: PAUSE, seeking to %u\n", context->seek_pba); + } else { + puts("CDD CMD: PAUSE"); + } + break; + //TODO: CMD_FFWD, CMD_RWD + case CMD_TRACK_SKIP: + if (context->status != DS_PLAY && context->status != DS_PAUSE && context->status != DS_DISC_LEADOUT) { + context->error_status = DS_CMD_ERROR; + break; + } + if (context->requested_format == SF_TOCT || context->requested_format == SF_TOCN) { + context->requested_format = SF_ABSOLUTE; + } + if (!context->toc_valid) { + context->error_status = DS_CMD_ERROR; + break; + } + { + int32_t to_skip = context->cmd_buffer.b.skip.tracks_highest << 12 | context->cmd_buffer.b.skip.tracks_midhigh << 8 + | context->cmd_buffer.b.skip.tracks_midlow << 4 | context->cmd_buffer.b.skip.tracks_lowest; + if (context->cmd_buffer.b.skip.direction) { + to_skip = -to_skip; + } + printf("CDD CMD: TRACK_SKIP direction %u, num_tracks %i, delta %i\n", context->cmd_buffer.b.skip.direction, abs(to_skip), to_skip); + //circumference at 83mm point (roughly half way between inner and outer edge of program area) + //~ 260.75cm ~ 15 sectors + context->seek_pba = context->head_pba + to_skip * 15; + context->seeking = 1; + } + context->status = DS_TRACKING; + break; default: printf("CDD CMD: Unimplemented(%d)\n", context->cmd_buffer.cmd_type); } @@ -473,7 +537,7 @@ next_nibble = context->cycle; context->current_status_nibble = 0; gate_array[GAO_CDD_STATUS] |= BIT_DRS; - if (context->status == DS_PLAY && context->head_pba >= LEADIN_SECTORS) { + if ((context->status == DS_PLAY || context->status == DS_PAUSE) && context->head_pba >= LEADIN_SECTORS) { context->current_sector_byte = 0; } }