diff --git a/HISTORY.txt b/HISTORY.txt index cda8c23..6a5d61c 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -58,9 +58,10 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke) * fixed byte access to font data registers * fixed memory mode register bits masking when read from MAIN-CPU and SUB-CPU (verified on real hardware, cf. Krikzz's mcd-verificator) * fixed pending level 1 interrupts when GFX interrupt is disabled (fixes random freezes when exiting "Batman Returns" option menu) -* fixed CDD seek command again (Final Fight CD freeze with model 2 BIOS) +* fixed CDD seek command again (fixes Final Fight CD freeze with model 2 BIOS) * fixed CDD status reported during seek/access time (fixes sound effect synchronization issue in Bari Arm) * fixed CDD position reset when disc is stopped (fixes random freezes in Spiderman vs Kingpin when switching between audio tracks) +* fixed CDD seeking start delay (fixes Radical Rex incorrect PRG-RAM & Word-RAM initialization, causing missing sprites during intro) */ * fixed word access to CDD control register (fixes spurious audio track playback on startup with Mode 1 patched games using MSU-MD driver) * fixed CD communication registers state on peripheral reset (fixes SUB-CPU side initialization in MSU-MD sample demo and some Mode 1 patched games using MSU-MD driver) * fixed 32x32 pixels stamp index masking during GFX operation (fixes graphics rotation/scaling effects in "Chuck Rock II - Son of Chuck") diff --git a/builds/genesis_plus_gx_libretro.dll b/builds/genesis_plus_gx_libretro.dll index 5b0f7fe..cf73ebf 100644 Binary files a/builds/genesis_plus_gx_libretro.dll and b/builds/genesis_plus_gx_libretro.dll differ diff --git a/builds/genplus_cube.dol b/builds/genplus_cube.dol index 16809a8..62ffa56 100644 Binary files a/builds/genplus_cube.dol and b/builds/genplus_cube.dol differ diff --git a/builds/genplus_wii.dol b/builds/genplus_wii.dol index f42c911..67ce077 100644 Binary files a/builds/genplus_wii.dol and b/builds/genplus_wii.dol differ diff --git a/core/cd_hw/cdd.c b/core/cd_hw/cdd.c index 18b320a..6bce898 100644 --- a/core/cd_hw/cdd.c +++ b/core/cd_hw/cdd.c @@ -1893,6 +1893,79 @@ void cdd_update(void) /* udpate current track index */ cdd.index = index; } + + /* seeking should start with at least one interrupt delay (fixes Radical Rex incorrect PRG-RAM & Word-RAM initialization, causing missing sprites during intro) */ + if (scd.regs[0x38>>1].byte.h == CD_SEEK) + { + /* reset track index */ + int index = 0; + + /* new LBA position */ + int lba = ((scd.regs[0x44>>1].byte.h * 10 + scd.regs[0x44>>1].byte.l) * 60 + + (scd.regs[0x46>>1].byte.h * 10 + scd.regs[0x46>>1].byte.l)) * 75 + + (scd.regs[0x48>>1].byte.h * 10 + scd.regs[0x48>>1].byte.l) - 150; + + /* CD drive latency */ + if (!cdd.latency) + { + /* Fixes a few games hanging because they expect data to be read with some delay */ + /* Wolf Team games (Annet Futatabi, Aisle Lord, Cobra Command, Earnest Evans, Road Avenger & Time Gal) need at least 11 interrupts delay */ + /* Space Adventure Cobra (2nd morgue scene) needs at least 13 interrupts delay (incl. seek time, so 11 is OK) */ + /* By default, at least two interrupts latency is required by current emulation model (BIOS hangs otherwise) */ + cdd.latency = 2 + 9*config.cd_latency; + } + + /* CD drive seek time */ + /* max. seek time = 1.5 s = 1.5 x 75 = 112.5 CDD interrupts (rounded to 120) for 270000 sectors max on disc. */ + /* Note: This is only a rough approximation since, on real hardware, seek time is much likely not linear and */ + /* latency much larger than above value, but this model works fine for Sonic CD (track 26 playback needs to */ + /* be enough delayed to start in sync with intro sequence, as compared with real hardware recording). */ + /* It also works fine for Switch/Panic! intro (at least 30 interrupts are needed while seeking from 00:05:63 */ + /* to 24:03:19 in Switch or when seeking from 00:05:60 to 24:06:07 in Panic!). */ + if (lba > cdd.lba) + { + cdd.latency += (((lba - cdd.lba) * 120 * config.cd_latency) / 270000); + } + else + { + cdd.latency += (((cdd.lba - lba) * 120 * config.cd_latency) / 270000); + } + + /* update current LBA */ + cdd.lba = lba; + + /* get track index */ + while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) + index++; + + /* audio track ? */ + if (cdd.toc.tracks[index].type == TYPE_AUDIO) + { + /* stay within track limits when seeking files */ + if (lba < cdd.toc.tracks[index].start) + { + lba = cdd.toc.tracks[index].start; + } + + /* seek to current track sector */ + cdd_seek_audio(index, lba); + } + + /* update current track index */ + cdd.index = index; + + /* seek to current subcode position */ + if (cdd.toc.sub) + { + cdStreamSeek(cdd.toc.sub, lba * 96, SEEK_SET); + } + + /* no audio track playing (yet) */ + scd.regs[0x36>>1].byte.h = 0x01; + + /* update CDD status to either PLAY or PAUSE depending on host command (will be reported to host once seeking has ended) */ + cdd.status = scd.regs[0x42>>1].byte.h & 0x05; + } } void cdd_process(void) @@ -2069,73 +2142,7 @@ void cdd_process(void) case 0x03: /* Play */ { - /* reset track index */ - int index = 0; - - /* new LBA position */ - int lba = ((scd.regs[0x44>>1].byte.h * 10 + scd.regs[0x44>>1].byte.l) * 60 + - (scd.regs[0x46>>1].byte.h * 10 + scd.regs[0x46>>1].byte.l)) * 75 + - (scd.regs[0x48>>1].byte.h * 10 + scd.regs[0x48>>1].byte.l) - 150; - - /* CD drive latency */ - if (!cdd.latency) - { - /* Fixes a few games hanging because they expect data to be read with some delay */ - /* Wolf Team games (Annet Futatabi, Aisle Lord, Cobra Command, Earnest Evans, Road Avenger & Time Gal) need at least 11 interrupts delay */ - /* Space Adventure Cobra (2nd morgue scene) needs at least 13 interrupts delay (incl. seek time, so 11 is OK) */ - /* By default, at least two interrupts latency is required by current emulation model (BIOS hangs otherwise) */ - cdd.latency = 2 + 9*config.cd_latency; - } - - /* CD drive seek time */ - /* max. seek time = 1.5 s = 1.5 x 75 = 112.5 CDD interrupts (rounded to 120) for 270000 sectors max on disc. */ - /* Note: This is only a rough approximation since, on real hardware, seek time is much likely not linear and */ - /* latency much larger than above value, but this model works fine for Sonic CD (track 26 playback needs to */ - /* be enough delayed to start in sync with intro sequence, as compared with real hardware recording). */ - if (lba > cdd.lba) - { - cdd.latency += (((lba - cdd.lba) * 120 * config.cd_latency) / 270000); - } - else - { - cdd.latency += (((cdd.lba - lba) * 120 * config.cd_latency) / 270000); - } - - /* update current LBA */ - cdd.lba = lba; - - /* get track index */ - while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) index++; - - /* audio track ? */ - if (cdd.toc.tracks[index].type == TYPE_AUDIO) - { - /* stay within track limits when seeking files */ - if (lba < cdd.toc.tracks[index].start) - { - lba = cdd.toc.tracks[index].start; - } - - /* seek to current track sector */ - cdd_seek_audio(index, lba); - } - - /* update current track index */ - cdd.index = index; - - /* seek to current subcode position */ - if (cdd.toc.sub) - { - cdStreamSeek(cdd.toc.sub, lba * 96, SEEK_SET); - } - - /* no audio track playing (yet) */ - scd.regs[0x36>>1].byte.h = 0x01; - - /* update status (reported to host once seeking has ended) */ - cdd.status = CD_PLAY; - - /* RS0 should indicates seeking until drive is ready (fixes audio delay in Bari Arm) */ + /* RS0 should indicate seeking until drive is ready (fixes audio delay in Bari Arm) */ /* RS1=0xf to invalidate track infos in RS2-RS8 until drive is ready (fixes Snatcher Act 2 start cutscene) */ scd.regs[0x38>>1].w = (CD_SEEK << 8) | 0x0f; scd.regs[0x3a>>1].w = 0x0000; @@ -2147,61 +2154,6 @@ void cdd_process(void) case 0x04: /* Seek */ { - /* reset track index */ - int index = 0; - - /* new LBA position */ - int lba = ((scd.regs[0x44>>1].byte.h * 10 + scd.regs[0x44>>1].byte.l) * 60 + - (scd.regs[0x46>>1].byte.h * 10 + scd.regs[0x46>>1].byte.l)) * 75 + - (scd.regs[0x48>>1].byte.h * 10 + scd.regs[0x48>>1].byte.l) - 150; - - /* CD drive seek time */ - /* We are using similar linear model as above, although still not exactly accurate, */ - /* it works fine for Switch/Panic! intro (Switch needs at least 30 interrupts while */ - /* seeking from 00:05:63 to 24:03:19, Panic! when seeking from 00:05:60 to 24:06:07) */ - if (lba > cdd.lba) - { - cdd.latency = ((lba - cdd.lba) * 120 * config.cd_latency) / 270000; - } - else - { - cdd.latency = ((cdd.lba - lba) * 120 * config.cd_latency) / 270000; - } - - /* update current LBA */ - cdd.lba = lba; - - /* get current track index */ - while ((cdd.toc.tracks[index].end <= lba) && (index < cdd.toc.last)) index++; - - /* audio track ? */ - if (cdd.toc.tracks[index].type == TYPE_AUDIO) - { - /* stay within track limits when seeking files */ - if (lba < cdd.toc.tracks[index].start) - { - lba = cdd.toc.tracks[index].start; - } - - /* seek to current track sector */ - cdd_seek_audio(index, lba); - } - - /* update current track index */ - cdd.index = index; - - /* seek to current subcode position */ - if (cdd.toc.sub) - { - cdStreamSeek(cdd.toc.sub, lba * 96, SEEK_SET); - } - - /* no audio track playing */ - scd.regs[0x36>>1].byte.h = 0x01; - - /* update status (reported to host once seeking has ended) */ - cdd.status = CD_PAUSE; - /* RS1=0xf to invalidate track infos in RS2-RS8 while seeking (fixes Final Fight CD intro when seek time is emulated) */ scd.regs[0x38>>1].w = (CD_SEEK << 8) | 0x0f; scd.regs[0x3a>>1].w = 0x0000;