# HG changeset patch # User Michael Pavone # Date 1647359884 25200 # Node ID 28b6453cf7e34aef4ef39a738d3153b0284a4e2f # Parent 4c9e447aa25b75f28f07ec43a9b3f0211bcf9701 Emulate CDC sync detection and sync insertion rather than relying on external knowledge about sector offset diff -r 4c9e447aa25b -r 28b6453cf7e3 cdd_mcu.c --- a/cdd_mcu.c Sun Mar 13 11:49:07 2022 -0700 +++ b/cdd_mcu.c Tue Mar 15 08:58:04 2022 -0700 @@ -543,6 +543,7 @@ for (; context->cycle < cd_cycle; context->cycle += CDD_MCU_DIVIDER) { if (context->cycle >= context->next_byte_cycle) { cdd_fader_data(fader, 0); + lc8951_write_byte(cdc, cd_block_to_mclks(context->cycle), 0, 0); context->next_byte_cycle += BYTE_CLOCKS; } } @@ -631,6 +632,7 @@ 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 { + lc8951_write_byte(cdc, cd_block_to_mclks(context->cycle), 0, 0); cdd_fader_data(fader, 0); if (context->current_sector_byte >= 0) { next_subcode += BYTE_CLOCKS; diff -r 4c9e447aa25b -r 28b6453cf7e3 lc8951.c --- a/lc8951.c Sun Mar 13 11:49:07 2022 -0700 +++ b/lc8951.c Tue Mar 15 08:58:04 2022 -0700 @@ -54,11 +54,20 @@ #define BIT_STEN 0x01 //CTRL0 -#define BIT_DECEN 0x80 -#define BIT_WRRQ 0x04 +#define BIT_DECEN 0x80 +#define BIT_WRRQ 0x04 + +//CTRL1 +#define BIT_SYIEN 0x80 +#define BIT_SYDEN 0x40 //STAT0 -#define BIT_CRCOK 0x80 +#define BIT_CRCOK 0x80 +#define BIT_ILSYNC 0x40 +#define BIT_NOSYNC 0x20 +#define BIT_LBLK 0x10 +#define BIT_SBLK 0x04 + //STAT3 #define BIT_VALST 0x80 @@ -265,8 +274,41 @@ { lc8951_run(context, cycle); uint16_t current_write_addr = context->regs[WAL] | (context->regs[WAH] << 8); - if (sector_offset == 12) { + + context->sector_counter++; + uint8_t sync_detected = 0, sync_ignored = 0; + if (byte == 0) { + if (context->sync_counter == 11 && ((sector_offset & 3) == 3)) { + if (context->ctrl1 & BIT_SYDEN) { + sync_detected = 1; + } else { + sync_ignored = 1; + } + context->sync_counter = 0; + } else { + context->sync_counter = 1; + } + } else if (byte == 0xFF && context->sync_counter) { + context->sync_counter++; + } else { + context->sync_counter = 0; + } + + uint8_t sync_inserted = 0; + if (context->ctrl1 & BIT_SYIEN && context->sector_counter == 2352) { + sync_inserted = 1; + } + + if (sync_detected || sync_inserted) { //we've recevied the sync pattern for the next block + context->regs[STAT0] &= ~(BIT_ILSYNC | BIT_NOSYNC | BIT_LBLK | BIT_SBLK); + if (sync_inserted && !(sync_detected || sync_ignored)) { + context->regs[STAT0] |= BIT_NOSYNC; + } + if (sync_detected && context->sector_counter != 2352) { + context->regs[STAT0] |= BIT_ILSYNC; + } + context->sector_counter = 0; //header/status regs no longer considered "valid" context->regs[STAT3] |= BIT_VALST; @@ -274,7 +316,7 @@ context->regs[IFSTAT] |= BIT_DECI; if (context->ctrl0 & BIT_DECEN) { if (context->ctrl0 & BIT_WRRQ) { - uint16_t block_start = current_write_addr - 2352; + uint16_t block_start = current_write_addr + 1 - 2352; context->regs[PTL] = block_start; context->regs[PTH] = block_start >> 8; } @@ -282,8 +324,15 @@ //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; } + } else { + if (sync_ignored) { + context->regs[STAT0] |= BIT_SBLK; + } + if (context->sector_counter == 2352) { + context->regs[STAT0] |= BIT_LBLK; + } } - if (sector_offset >= 12 && sector_offset < 16) { + if (context->sector_counter < 4) { //TODO: Handle SHDREN = 1 if ((context->ctrl0 & (BIT_DECEN|BIT_WRRQ)) == (BIT_DECEN)) { //monitor only mode diff -r 4c9e447aa25b -r 28b6453cf7e3 lc8951.h --- a/lc8951.h Sun Mar 13 11:49:07 2022 -0700 +++ b/lc8951.h Tue Mar 15 08:58:04 2022 -0700 @@ -12,6 +12,7 @@ uint32_t clock_step; uint32_t decode_end; uint32_t transfer_end; + uint16_t sector_counter; uint8_t buffer[0x4000]; @@ -26,6 +27,7 @@ uint8_t ctrl1; uint8_t ar; uint8_t ar_mask; + uint8_t sync_counter; } lc8951; void lc8951_init(lc8951 *context, lcd8951_byte_recv_fun byte_handler, void *handler_data);