cdrom: change pause timing again
[pcsx_rearmed.git] / libpcsxcore / cdrom.c
index 872cc0c..d4d1474 100644 (file)
@@ -68,7 +68,7 @@ static struct {
        } subq;
        unsigned char TrackChanged;
        unsigned char ReportDelay;
-       unsigned char unused3;
+       unsigned char PhysCdPropagations;
        unsigned short sectorsRead;
        unsigned int  freeze_ver;
 
@@ -583,19 +583,15 @@ static int cdrSeekTime(unsigned char *target)
        int cyclesSinceRS = psxRegs.cycle - cdr.LastReadSeekCycles;
        seekTime = MAX_VALUE(seekTime, 20000);
 
-       // need this stupidly long penalty or else Spyro2 intro desyncs
-       // note: if misapplied this breaks MGS cutscenes among other things
-       if (cdr.DriveState == DRIVESTATE_PAUSED && cyclesSinceRS > cdReadTime * 50)
-               seekTime += cdReadTime * 25;
        // Transformers Beast Wars Transmetals does Setloc(x),SeekL,Setloc(x),ReadN
        // and then wants some slack time
-       else if (cdr.DriveState == DRIVESTATE_PAUSED || cyclesSinceRS < cdReadTime *3/2)
+       if (cdr.DriveState == DRIVESTATE_PAUSED || cyclesSinceRS < cdReadTime *3/2)
                seekTime += cdReadTime;
 
        seekTime = MIN_VALUE(seekTime, PSXCLK * 2 / 3);
-       CDR_LOG("seek: %.2f %.2f (%.2f) st %d\n", (float)seekTime / PSXCLK,
+       CDR_LOG("seek: %.2f %.2f (%.2f) st %d di %d\n", (float)seekTime / PSXCLK,
                (float)seekTime / cdReadTime, (float)cyclesSinceRS / cdReadTime,
-               cdr.DriveState);
+               cdr.DriveState, diff);
        return seekTime;
 }
 
@@ -660,6 +656,14 @@ static void msfiSub(u8 *msfi, u32 count)
 
 void cdrPlayReadInterrupt(void)
 {
+       int hit = CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]);
+       if (!hit && cdr.PhysCdPropagations++ < 222) {
+               // this propagates real cdrom delays to the emulated game
+               CDRPLAYREAD_INT(cdReadTime / 2, 0);
+               return;
+       }
+       cdr.PhysCdPropagations = 0;
+
        cdr.LastReadSeekCycles = psxRegs.cycle;
 
        if (cdr.Reading) {
@@ -694,6 +698,7 @@ void cdrPlayReadInterrupt(void)
        }
 
        msfiAdd(cdr.SetSectorPlay, 1);
+       CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]);
 
        // update for CdlGetlocP/autopause
        generate_subq(cdr.SetSectorPlay);
@@ -966,27 +971,19 @@ void cdrInterrupt(void) {
                        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
+                       ...
                        */
-                       /* 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 = 2 * 1097107;
                        }
                        SetPlaySeekRead(cdr.StatP, 0);
                        DriveStateOld = cdr.DriveState;
@@ -1109,6 +1106,8 @@ void cdrInterrupt(void) {
                        seekTime = cdrSeekTime(cdr.SetSector);
                        memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
                        cdr.DriveState = DRIVESTATE_SEEK;
+                       CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1],
+                                       cdr.SetSectorPlay[2]);
                        /*
                        Crusaders of Might and Magic = 0.5x-4x
                        - fix cutscene speech start
@@ -1246,6 +1245,8 @@ void cdrInterrupt(void) {
                        cdr.SubqForwardSectors = 1;
                        cdr.sectorsRead = 0;
                        cdr.DriveState = DRIVESTATE_SEEK;
+                       CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1],
+                                       cdr.SetSectorPlay[2]);
 
                        cycles = (cdr.Mode & MODE_SPEED) ? cdReadTime : cdReadTime * 2;
                        cycles += seekTime;
@@ -1386,7 +1387,7 @@ static void cdrReadInterrupt(void)
                        subhdr->file, subhdr->chan, cdr.CurFile, cdr.CurChannel, cdr.FilterFile, cdr.FilterChannel);
                if ((cdr.Mode & MODE_SF) && (subhdr->file != cdr.FilterFile || subhdr->chan != cdr.FilterChannel))
                        break;
-               if (subhdr->chan & 0xe0) { // ?
+               if (subhdr->chan & 0x80) { // ?
                        if (subhdr->chan != 0xff)
                                log_unhandled("adpcm %d:%d\n", subhdr->file, subhdr->chan);
                        break;
@@ -1423,6 +1424,7 @@ static void cdrReadInterrupt(void)
                cdrReadInterruptSetResult(cdr.StatP);
 
        msfiAdd(cdr.SetSectorPlay, 1);
+       CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]);
 
        CDRPLAYREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime, 0);
 }