# HG changeset patch # User Michael Pavone # Date 1648190623 25200 # Node ID d9151d0894c78ec91a0ec2184344420c9a917809 # Parent 793715149f16c6603891fc32a29e98e00aa71f00 Fix some CD-ROM emulation issues diff -r 793715149f16 -r d9151d0894c7 cdd_mcu.c --- a/cdd_mcu.c Tue Mar 22 20:20:25 2022 -0700 +++ b/cdd_mcu.c Thu Mar 24 23:43:43 2022 -0700 @@ -602,7 +602,7 @@ if (context->next_subcode_int_cycle != CYCLE_NEVER) { context->subcode_int_pending = 1; } - if ((context->status == DS_PLAY || context->status == DS_PAUSE) && context->head_pba >= LEADIN_SECTORS) { + if ((context->status == DS_PLAY || context->status == DS_PAUSE) && context->head_pba >= LEADIN_SECTORS && !context->seeking) { context->current_sector_byte = 0; context->current_subcode_byte = 0; context->next_subcode_cycle = context->cycle; diff -r 793715149f16 -r d9151d0894c7 cdimage.c --- a/cdimage.c Tue Mar 22 20:20:25 2022 -0700 +++ b/cdimage.c Thu Mar 24 23:43:43 2022 -0700 @@ -124,10 +124,10 @@ static uint8_t fake_read(uint32_t sector, uint32_t offset) { - if (!offset || (offset >= 16)) { + if (!offset || offset == 11 || (offset >= 16)) { return 0; //TODO: error detection and correction bytes - } else if (offset < 12) { + } else if (offset < 11) { return 0xFF; } else if (offset == 12) { uint32_t minute = (sector / 75) / 60; diff -r 793715149f16 -r d9151d0894c7 lc8951.c --- a/lc8951.c Tue Mar 22 20:20:25 2022 -0700 +++ b/lc8951.c Thu Mar 24 23:43:43 2022 -0700 @@ -56,6 +56,8 @@ //CTRL0 #define BIT_DECEN 0x80 #define BIT_WRRQ 0x04 +#define BIT_ORQ 0x02 +#define BIT_PRQ 0x01 //CTRL1 #define BIT_SYIEN 0x80 @@ -67,10 +69,11 @@ #define BIT_NOSYNC 0x20 #define BIT_LBLK 0x10 #define BIT_SBLK 0x04 - +#define BIT_UCEBLK 0x01 //STAT3 #define BIT_VALST 0x80 +#define BIT_WLONG 0x40 //datasheet timing info //3 cycles for memory operation @@ -227,7 +230,26 @@ } } 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; + // This check is a hack until I properly implement error detection + if (context->regs[HEAD0] < 0x74 && (context->regs[HEAD0] & 0xF) < 0xA + && context->regs[HEAD1] < 0x60 && (context->regs[HEAD1] & 0xF) < 0xA + && context->regs[HEAD2] < 0x75 && (context->regs[HEAD2] & 0xF) < 0xA + && context->regs[HEAD3] < 3 && !(context->regs[STAT0] & (BIT_NOSYNC|BIT_ILSYNC)) + ) { + + if (context->ctrl0 & (BIT_ORQ|BIT_PRQ)) { + context->regs[STAT0] |= BIT_CRCOK; + } + context->regs[STAT1] = 0; + context->regs[STAT2] = 0x90; + } else { + if (context->ctrl0 & (BIT_ORQ|BIT_PRQ)) { + context->regs[STAT0] |= BIT_UCEBLK; + } + context->regs[STAT1] = 0xFF; + context->regs[STAT2] = 0xF2; + } + context->regs[STAT3] |= BIT_WLONG; } if (context->transfer_end != CYCLE_NEVER) { if (context->byte_handler(context->handler_data, context->buffer[context->dac & (sizeof(context->buffer)-1)])) { @@ -275,8 +297,6 @@ lc8951_run(context, cycle); uint16_t current_write_addr = context->regs[WAL] | (context->regs[WAH] << 8); - context->sector_counter++; - context->sector_counter &= 0xFFF; uint8_t sync_detected = 0, sync_ignored = 0; if (byte == 0) { if (context->sync_counter == 11 && ((sector_offset & 3) == 3)) { @@ -296,17 +316,26 @@ } uint8_t sync_inserted = 0; - if (context->ctrl1 & BIT_SYIEN && context->sector_counter == 2352) { + if (context->ctrl1 & BIT_SYIEN && context->sector_counter == 2351) { sync_inserted = 1; } + + if (context->sector_counter < 4) { + //TODO: Handle SHDREN = 1 + if ((context->ctrl0 & (BIT_DECEN|BIT_WRRQ)) == (BIT_DECEN)) { + //monitor only mode + context->regs[HEAD0 + context->sector_counter] = byte; + } + } + 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) { + if (sync_detected && context->sector_counter != 2351) { context->regs[STAT0] |= BIT_ILSYNC; } context->sector_counter = 0; @@ -315,6 +344,9 @@ context->regs[STAT3] |= BIT_VALST; //!DECI is set inactive at the same time as !VALST context->regs[IFSTAT] |= BIT_DECI; + //clear error detection status bits + context->regs[STAT0] &= ~(BIT_CRCOK|BIT_UCEBLK); + context->regs[STAT3] &= ~BIT_WLONG; if (context->ctrl0 & BIT_DECEN) { if (context->ctrl0 & BIT_WRRQ) { uint16_t block_start = current_write_addr + 1 - 2352; @@ -326,6 +358,8 @@ context->decode_end = context->cycle + 22030 * context->clock_step; } } else { + context->sector_counter++; + context->sector_counter &= 0xFFF; if (sync_ignored) { context->regs[STAT0] |= BIT_SBLK; } @@ -333,13 +367,6 @@ context->regs[STAT0] |= BIT_LBLK; } } - if (context->sector_counter < 4) { - //TODO: Handle SHDREN = 1 - if ((context->ctrl0 & (BIT_DECEN|BIT_WRRQ)) == (BIT_DECEN)) { - //monitor only mode - context->regs[HEAD0 + sector_offset - 12] = byte; - } - } if ((context->ctrl0 & (BIT_DECEN|BIT_WRRQ)) == (BIT_DECEN|BIT_WRRQ)) { context->buffer[current_write_addr & (sizeof(context->buffer)-1)] = byte; context->regs[WAL]++;