u8 AdpcmActive;
u32 LastReadSeekCycles;
- u8 unused7;
+ u8 RetryDetected;
u8 DriveState; // enum drive_state
u8 FastForward;
DRIVESTATE_SEEK,
};
-static struct CdrStat stat;
+static struct CdrStat cdr_stat;
static unsigned int msf2sec(const u8 *msf) {
return ((msf[0] * 60 + msf[1]) * 75) + msf[2];
//StopReading();
SetPlaySeekRead(cdr.StatP, 0);
- if (CDR_getStatus(&stat) == -1)
+ if (CDR_getStatus(&cdr_stat) == -1)
return;
- if (stat.Status & STATUS_SHELLOPEN)
+ if (cdr_stat.Status & STATUS_SHELLOPEN)
{
memset(cdr.Prev, 0xff, sizeof(cdr.Prev));
cdr.DriveState = DRIVESTATE_LID_OPEN;
break;
case DRIVESTATE_LID_OPEN:
- if (CDR_getStatus(&stat) == -1)
- stat.Status &= ~STATUS_SHELLOPEN;
+ if (CDR_getStatus(&cdr_stat) == -1)
+ cdr_stat.Status &= ~STATUS_SHELLOPEN;
// 02, 12, 10
if (!(cdr.StatP & STATUS_SHELLOPEN)) {
else if (cdr.StatP & STATUS_ROTATING) {
cdr.StatP &= ~STATUS_ROTATING;
}
- else if (!(stat.Status & STATUS_SHELLOPEN)) {
+ else if (!(cdr_stat.Status & STATUS_SHELLOPEN)) {
// closed now
CheckCdrom();
cdr.ReportDelay--;
}
+static boolean canDoTurbo(void)
+{
+ u32 c = psxRegs.cycle;
+ return Config.TurboCD && !cdr.RetryDetected && !cdr.AdpcmActive
+ //&& c - psxRegs.intCycle[PSXINT_SPUDMA].sCycle > (u32)cdReadTime * 2
+ && c - psxRegs.intCycle[PSXINT_MDECOUTDMA].sCycle > (u32)cdReadTime * 16;
+}
+
static int cdrSeekTime(unsigned char *target)
{
int diff = msf2sec(cdr.SetSectorPlay) - msf2sec(target);
}
}
+static int msfiEq(const u8 *a, const u8 *b)
+{
+ return a[0] == b[0] && a[1] == b[1] && a[2] == b[2];
+}
+
void cdrPlayReadInterrupt(void)
{
int hit = CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]);
static void softReset(void)
{
- CDR_getStatus(&stat);
- if (stat.Status & STATUS_SHELLOPEN) {
+ CDR_getStatus(&cdr_stat);
+ if (cdr_stat.Status & STATUS_SHELLOPEN) {
cdr.DriveState = DRIVESTATE_LID_OPEN;
cdr.StatP = STATUS_SHELLOPEN;
}
{
for (i = 0; i < 3; i++)
set_loc[i] = btoi(cdr.Param[i]);
+ if ((msfiEq(cdr.SetSector, set_loc)) //|| msfiEq(cdr.Param, cdr.Transfer))
+ && !cdr.SetlocPending)
+ cdr.RetryDetected++;
+ else
+ cdr.RetryDetected = 0;
memcpy(cdr.SetSector, set_loc, 3);
cdr.SetSector[3] = 0;
cdr.SetlocPending = 1;
cdr.sectorsRead = 0;
/*
- Gundam Battle Assault 2: much slower (*)
- - Fixes boot, gameplay
-
- Hokuto no Ken 2: slower
- - Fixes intro + subtitles
-
- InuYasha - Feudal Fairy Tale: slower
- - Fixes battles
+ Gundam Battle Assault 2
+ Hokuto no Ken 2
+ InuYasha - Feudal Fairy Tale
+ Dance Dance Revolution Konamix
+ Digimon Rumble Arena
+ ...
*/
- /* Gameblabla - Tightening the timings (as taken from Duckstation).
- * The timings from Duckstation are based upon hardware tests.
- * Mednafen's timing don't work for Gundam Battle Assault 2 in PAL/50hz mode,
- * seems to be timing sensitive as it can depend on the CPU's clock speed.
- * */
if (!(cdr.StatP & (STATUS_PLAY | STATUS_READ)))
{
second_resp_time = 7000;
}
else
{
- second_resp_time = (((cdr.Mode & MODE_SPEED) ? 1 : 2) * 1097107);
+ second_resp_time = 2100011;
+ // a hack to try to avoid weird cmd vs irq1 races causing games to retry
+ second_resp_time += (cdr.RetryDetected & 15) * 100001;
}
SetPlaySeekRead(cdr.StatP, 0);
DriveStateOld = cdr.DriveState;
StopReading();
SetPlaySeekRead(cdr.StatP, STATUS_SEEK | STATUS_ROTATING);
- seekTime = cdrSeekTime(cdr.SetSector);
+ if (!canDoTurbo())
+ seekTime = cdrSeekTime(cdr.SetSector);
memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
cdr.DriveState = DRIVESTATE_SEEK;
CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1],
cdr.Result[3] = 0;
// 0x10 - audio | 0x40 - disk missing | 0x80 - unlicensed
- if (CDR_getStatus(&stat) == -1 || stat.Type == 0 || stat.Type == 0xff) {
+ if (CDR_getStatus(&cdr_stat) == -1 || cdr_stat.Type == 0 || cdr_stat.Type == 0xff) {
cdr.Result[1] = 0xc0;
}
else {
- if (stat.Type == 2)
+ if (cdr_stat.Type == 2)
cdr.Result[1] |= 0x10;
if (CdromId[0] == '\0')
cdr.Result[1] |= 0x80;
cycles += seekTime;
if (Config.hacks.cdr_read_timing)
cycles = cdrAlignTimingHack(cycles);
+ else if (canDoTurbo())
+ cycles = cdReadTime / 2;
CDRPLAYREAD_INT(cycles, 1);
SetPlaySeekRead(cdr.StatP, STATUS_SEEK);
cdr.Ctrl |= cdr.AdpcmActive << 2;
cdr.Ctrl |= cdr.ResultReady << 5;
+ //cdr.Ctrl &= ~0x40;
+ //if (cdr.FifoOffset != DATA_SIZE)
cdr.Ctrl |= 0x40; // data fifo not empty
// What means the 0x10 and the 0x08 bits? I only saw it used by the bios
}
void psxDma3(u32 madr, u32 bcr, u32 chcr) {
- u32 cdsize, max_words;
+ u32 cdsize, max_words, cycles;
int size;
u8 *ptr;
}
psxCpu->Clear(madr, cdsize / 4);
- set_event(PSXINT_CDRDMA, (cdsize / 4) * 24);
+ cycles = (cdsize / 4) * 24;
+ set_event(PSXINT_CDRDMA, cycles);
HW_DMA3_CHCR &= SWAPu32(~0x10000000);
if (chcr & 0x100) {
}
else {
// halted
- psxRegs.cycle += (cdsize/4) * 24 - 20;
+ psxRegs.cycle += cycles - 20;
}
+ if (canDoTurbo() && cdr.Reading && cdr.FifoOffset >= 2048)
+ CDRPLAYREAD_INT(cycles + 4096, 1);
return;
default: