# HG changeset patch # User Michael Pavone # Date 1705647838 28800 # Node ID 0871f555eff6fa83b0012482ed5196c62b9ab4e1 # Parent cc07f544c620568710dd32f1571825ea3a2290de Fix some CD-ROM emulation issues and make timing better match my MCD2. Seems to fix or at least improve video playback in Iron Helix and Power Rangers diff -r cc07f544c620 -r 0871f555eff6 cdd_mcu.c --- a/cdd_mcu.c Wed Jan 17 23:51:37 2024 -0800 +++ b/cdd_mcu.c Thu Jan 18 23:03:58 2024 -0800 @@ -11,7 +11,7 @@ #define NIBBLE_CLOCKS (CDD_MCU_DIVIDER * 77) #define BYTE_CLOCKS (SECTOR_CLOCKS/2352) // 96 #define SUBCODE_CLOCKS (SECTOR_CLOCKS/98) -#define PROCESSING_DELAY 54000 //approximate, based on Wondermega M1 measurements +#define PROCESSING_DELAY 121600 //approximate, based on relative level 4 and level 5 interrupt timing on MCD2 in pause_test //lead in start max diameter 46 mm //program area start max diameter 50 mm @@ -179,7 +179,6 @@ static void update_status(cdd_mcu *context, uint16_t *gate_array) { gate_array[GAO_CDD_CTRL] |= BIT_MUTE; - uint32_t prev_pba = context->head_pba; switch (context->status) { case DS_STOP: @@ -255,16 +254,16 @@ switch (force_not_ready ? SF_NOTREADY : context->requested_format) { case SF_ABSOLUTE: - if (context->toc_valid && prev_pba >= LEADIN_SECTORS) { - lba_to_status(context, prev_pba - LEADIN_SECTORS); + if (context->toc_valid && context->head_pba >= LEADIN_SECTORS) { + lba_to_status(context, context->head_pba - LEADIN_SECTORS); context->status_buffer.format = SF_ABSOLUTE; } else { context->status_buffer.format = SF_NOTREADY; } break; case SF_RELATIVE: - if (context->toc_valid && prev_pba >= LEADIN_SECTORS) { - uint32_t lba =prev_pba - LEADIN_SECTORS; + if (context->toc_valid && context->head_pba >= LEADIN_SECTORS) { + uint32_t lba =context->head_pba - LEADIN_SECTORS; for (uint32_t i = 0; i < context->media->num_tracks; i++) { if (lba < context->media->tracks[i].end_lba) { @@ -295,8 +294,8 @@ } break; case SF_TRACK: - if (context->toc_valid && prev_pba >= LEADIN_SECTORS) { - uint32_t lba =prev_pba - LEADIN_SECTORS; + if (context->toc_valid && context->head_pba >= LEADIN_SECTORS) { + uint32_t lba =context->head_pba - LEADIN_SECTORS; uint32_t i; for (i = 0; i < context->media->num_tracks; i++) { @@ -373,7 +372,7 @@ } lba_to_status(context, lba); if (context->media->tracks[context->requested_track - 1].type == TRACK_DATA) { - context->status_buffer.b.tocn.frame_low |= 0x80; + context->status_buffer.b.tocn.frame_high |= 0x8; } context->status_buffer.b.tocn.track_low = context->requested_track % 10; context->status_buffer.format = SF_TOCN; @@ -663,10 +662,7 @@ context->next_subcode_int_cycle = CYCLE_NEVER; } if (old_coarse != context->coarse_seek) { - context->next_int_cycle = cd_block_to_mclks(context->cycle + PROCESSING_DELAY + 7 * NIBBLE_CLOCKS); - if (context->coarse_seek % 3) { - context->next_int_cycle += cd_block_to_mclks(SECTOR_CLOCKS * (3 - (context->coarse_seek % 3))); - } + context->next_int_cycle = cd_block_to_mclks(next_nibble + 7 * NIBBLE_CLOCKS); } } if (context->cycle >= next_nibble) { @@ -721,7 +717,16 @@ } } if (context->cycle >= context->next_byte_cycle) { - if (context->current_sector_byte >= 0 && (!fader->byte_counter || context->current_sector_byte)) { + if (context->current_sector_byte >= 0/* && (!fader->byte_counter || context->current_sector_byte)*/) { + if (!context->current_sector_byte) { + //HACK: things can get a little out of sync currently which causes a mess in the fader code + // since it expects even multiples of 4 bytes (1 stereo sample) + while (fader->byte_counter) + { + lc8951_write_byte(cdc, cd_block_to_mclks(context->cycle), 0, 0); + cdd_fader_data(fader, 0); + } + } uint8_t byte = context->media->read(context->media, context->current_sector_byte); if (context->status != DS_PLAY) { byte = 0; @@ -731,10 +736,6 @@ } 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; - context->last_sector_cycle += BYTE_CLOCKS; - } } if (context->current_sector_byte == 2352) { context->current_sector_byte = -1; diff -r cc07f544c620 -r 0871f555eff6 lc8951.c --- a/lc8951.c Wed Jan 17 23:51:37 2024 -0800 +++ b/lc8951.c Thu Jan 18 23:03:58 2024 -0800 @@ -56,6 +56,7 @@ //CTRL0 #define BIT_DECEN 0x80 +#define BIT_EDCRQ 0x40 #define BIT_WRRQ 0x04 #define BIT_ORQ 0x02 #define BIT_PRQ 0x01 @@ -240,11 +241,12 @@ uint16_t block_start = (context->regs[PTL] | (context->regs[PTH] << 8)) & (sizeof(context->buffer)-1); for (int reg = HEAD0; reg < PTL; reg++) { + printf("Setting header reg %X to %X: %X\n", reg, block_start, context->buffer[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]); + printf("Decode done %X:%X:%X mode %X @ %u\n", context->regs[HEAD0], context->regs[HEAD1], context->regs[HEAD2], context->regs[HEAD3], context->cycle); // 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 @@ -258,7 +260,7 @@ context->regs[STAT1] = 0; context->regs[STAT2] = 0x10; } else { - if (context->ctrl0 & (BIT_WRRQ|BIT_ORQ|BIT_PRQ)) { + if (context->ctrl0 & (BIT_EDCRQ|BIT_ORQ|BIT_PRQ)) { context->regs[STAT0] |= BIT_UCEBLK; } context->regs[STAT1] = 0xFF; @@ -341,7 +343,19 @@ if ((context->ctrl0 & (BIT_DECEN|BIT_WRRQ)) == (BIT_DECEN)) { //monitor only mode context->regs[HEAD0 + context->sector_counter] = byte; + if (context->sector_counter == 3) { + printf("Monitoring sector %02d:%02d:%02d\n", context->regs[HEAD0], context->regs[HEAD1], context->regs[HEAD2]); + } + } else { + if (context->sector_counter == 3) { + printf("Writing sector %02d:%02d:%02d @ %u\n", + context->buffer[(current_write_addr - 3) & (sizeof(context->buffer)-1)], + context->buffer[(current_write_addr - 2) & (sizeof(context->buffer)-1)], + context->buffer[(current_write_addr - 1) & (sizeof(context->buffer)-1)], + context->cycle); + } } + } if (sync_detected || sync_inserted) { @@ -369,9 +383,10 @@ context->regs[PTL] = block_start; context->regs[PTH] = block_start >> 8; } - printf("Decoding block starting at %X (WRRQ: %d, sector_offset: %X)\n", context->regs[PTL] | (context->regs[PTH] << 8), !!(context->ctrl0 & BIT_WRRQ), sector_offset); - //Based on measurements of a Wondermega M1 (LC8951) with SYDEN, SYIEN and DECEN only - context->decode_end = context->cycle + 22030 * context->clock_step; + printf("Decoding block starting at %X (WRRQ: %d, sector_offset: %X), current write address: %X @ %u\n", context->regs[PTL] | (context->regs[PTH] << 8), !!(context->ctrl0 & BIT_WRRQ), sector_offset, current_write_addr, context->cycle); + //Based on mcd-verificator results on an MCD2 with LC89515 + //value seems to be between ~132500 and ~133500 + context->decode_end = context->cycle + 133000 * context->clock_step; } } else { context->sector_counter++;