# HG changeset patch # User Michael Pavone # Date 1643572697 28800 # Node ID f22e04b69272c0354e69163856b61a6a522e5d45 # Parent a61a8a87410c3b04a86406180f28b7bff2097b64 More CDC/CDD improvements diff -r a61a8a87410c -r f22e04b69272 cdd_mcu.c --- a/cdd_mcu.c Sun Jan 30 00:21:58 2022 -0800 +++ b/cdd_mcu.c Sun Jan 30 11:58:17 2022 -0800 @@ -61,26 +61,30 @@ } return (~sum) & 0xF; } -#define SEEK_SPEED 2200 //made up number +#define COARSE_SEEK 2200 //made up numbers +#define FINE_SEEK 10 static void handle_seek(cdd_mcu *context) { + //TODO: more realistic seeking behavior if (context->seeking) { if (context->seek_pba == context->head_pba) { context->seeking = 0; } else if (context->seek_pba > context->head_pba) { - context->head_pba += SEEK_SPEED; - if (context->head_pba > context->seek_pba) { - context->head_pba = context->seek_pba; + if (context->seek_pba - context->head_pba >= COARSE_SEEK) { + context->head_pba += COARSE_SEEK; + } else if (context->seek_pba - context->head_pba >= FINE_SEEK) { + context->head_pba += FINE_SEEK; + } else { + context->head_pba++; } } else { - if (context->head_pba >= SEEK_SPEED) { - context->head_pba -= SEEK_SPEED; + if (context->head_pba - context->seek_pba >= COARSE_SEEK) { + context->head_pba -= COARSE_SEEK; + } else if (context->head_pba >= FINE_SEEK) { + context->head_pba -= FINE_SEEK; } else { context->head_pba = 0; } - if (context->head_pba < context->seek_pba) { - context->head_pba = context->seek_pba; - } } } } @@ -352,7 +356,8 @@ lba += context->cmd_buffer.b.time.sec_high * 10 + context->cmd_buffer.b.time.sec_low; lba *= 75; lba += context->cmd_buffer.b.time.frame_high * 10 + context->cmd_buffer.b.time.frame_low; - printf("READ/SEEK cmd for lba %d, MM:SS:FF %u%u:%u%u:%u%u\n", lba, + printf("CDD CMD: %s cmd for lba %d, MM:SS:FF %u%u:%u%u:%u%u\n", + context->cmd_buffer.cmd_type == CMD_READ ? "READ" : "SEEK", lba, context->cmd_buffer.b.time.min_high, context->cmd_buffer.b.time.min_low, context->cmd_buffer.b.time.sec_high, context->cmd_buffer.b.time.sec_low, context->cmd_buffer.b.time.frame_high, context->cmd_buffer.b.time.frame_low @@ -411,6 +416,27 @@ } printf("CDD CMD: REPORT REQUEST(%d), format set to %d\n", context->cmd_buffer.b.format.status_type, context->requested_format); break; + case CMD_PAUSE: + 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->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"); + } + context->status = DS_PAUSE; + break; default: printf("CDD CMD: Unimplemented(%d)\n", context->cmd_buffer.cmd_type); } diff -r a61a8a87410c -r f22e04b69272 lc8951.c --- a/lc8951.c Sun Jan 30 00:21:58 2022 -0800 +++ b/lc8951.c Sun Jan 30 11:58:17 2022 -0800 @@ -57,11 +57,12 @@ #define BIT_DECEN 0x80 #define BIT_WRRQ 0x04 +//STAT0 +#define BIT_CRCOK 0x80 + //STAT3 #define BIT_VALST 0x80 -#define DECI_AUTO_CLEAR 575 - //datasheet timing info //3 cycles for memory operation //6 cycles min for DMA-mode host transfer @@ -77,7 +78,6 @@ context->handler_data = handler_data; context->decode_end = CYCLE_NEVER; context->transfer_end = CYCLE_NEVER; - context->deci_clear = CYCLE_NEVER; } void lc8951_reg_write(lc8951 *context, uint8_t value) @@ -142,9 +142,9 @@ break; case PTH_WRITE: context->regs[PTH] = value; - context->ptl_internal = (context->regs[PTL] | (context->regs[PTH] << 8)) & (sizeof(context->buffer) - 1); - context->decoding = 1; - context->decode_end = context->cycle + 2352 * context->clock_step * 4; + //TODO: Datasheet says any write to PT triggers a decode, but initial tests suggest that's not the case + //Need to do more tests with other CTRL0/CTRL1 settings + //context->decode_end = context->cycle + 2352 * context->clock_step * 4; break; case RESET: context->comin_count = 0; @@ -175,7 +175,6 @@ } if (context->ar == STAT3) { context->regs[IFSTAT] |= BIT_DECI; - context->deci_clear = CYCLE_NEVER; } if (context->ar >= sizeof(context->regs)) { value = 0xFF; @@ -206,16 +205,18 @@ if (context->cycle >= context->decode_end) { context->decode_end = CYCLE_NEVER; context->regs[IFSTAT] &= ~BIT_DECI; - context->deci_clear = context->cycle + DECI_AUTO_CLEAR; context->regs[STAT3] &= ~BIT_VALST; - uint16_t block_start = (context->regs[PTL] | (context->regs[PTH] << 8)) & (sizeof(context->buffer)-1); - for (int reg = HEAD0; reg < PTL; reg++) - { - printf("Setting HEAD%d to buffer[%X]\n", reg - HEAD0, block_start); - context->regs[reg] =context->buffer[block_start++]; - block_start &= (sizeof(context->buffer)-1); + if (context->ctrl0 & BIT_WRRQ) { + uint16_t block_start = (context->regs[PTL] | (context->regs[PTH] << 8)) & (sizeof(context->buffer)-1); + for (int reg = HEAD0; reg < PTL; reg++) + { + printf("Setting HEAD%d to buffer[%X]\n", reg - HEAD0, block_start); + context->regs[reg] =context->buffer[block_start++]; + block_start &= (sizeof(context->buffer)-1); + } } printf("Decode done %X:%X:%X mode %X\n", context->regs[HEAD0], context->regs[HEAD1], context->regs[HEAD2], context->regs[HEAD3]); + context->regs[STAT0] |= BIT_CRCOK; } if (context->transfer_end != CYCLE_NEVER) { if (context->byte_handler(context->handler_data, context->buffer[context->dac & (sizeof(context->buffer)-1)])) { @@ -237,10 +238,6 @@ context->transfer_end = CYCLE_NEVER; } } - if (context->cycle >= context->deci_clear) { - context->regs[IFSTAT] |= BIT_DECI; - context->deci_clear = CYCLE_NEVER; - } } } @@ -272,12 +269,16 @@ //header/status regs no longer considered "valid" context->regs[STAT3] |= BIT_VALST; - if ((context->ctrl0 & (BIT_DECEN|BIT_WRRQ)) == (BIT_DECEN|BIT_WRRQ)) { - uint16_t block_start = current_write_addr - 2352; - context->regs[PTL] = block_start; - context->regs[PTH] = block_start >> 8; - printf("Decoding block starting at %X\n", block_start); - context->ptl_internal = block_start & (sizeof(context->buffer)-1); + //!DECI is set inactive at the same time as !VALST + context->regs[IFSTAT] |= BIT_DECI; + if (context->ctrl0 & BIT_DECEN) { + if (context->ctrl0 & BIT_WRRQ) { + uint16_t block_start = current_write_addr - 2352; + context->regs[PTL] = block_start; + context->regs[PTH] = block_start >> 8; + } + printf("Decoding block starting at %X\n", context->regs[PTL] | (context->regs[PTH] << 8)); + //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; } } @@ -322,7 +323,4 @@ if (context->transfer_end != CYCLE_NEVER) { context->transfer_end -= deduction; } - if (context->deci_clear != CYCLE_NEVER) { - context->transfer_end -= deduction; - } } diff -r a61a8a87410c -r f22e04b69272 lc8951.h --- a/lc8951.h Sun Jan 30 00:21:58 2022 -0800 +++ b/lc8951.h Sun Jan 30 11:58:17 2022 -0800 @@ -12,7 +12,6 @@ uint32_t clock_step; uint32_t decode_end; uint32_t transfer_end; - uint32_t deci_clear; uint8_t buffer[0x4000]; @@ -27,8 +26,6 @@ uint8_t ctrl1; uint8_t ar; uint8_t ar_mask; - uint8_t decoding; - uint16_t ptl_internal; } lc8951; void lc8951_init(lc8951 *context, lcd8951_byte_recv_fun byte_handler, void *handler_data);