spu: don't leave garbage in capture buffers
[pcsx_rearmed.git] / libpcsxcore / cdrom.c
index 24ff961..5da24c8 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;
 
@@ -660,6 +660,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 +702,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);
@@ -701,6 +710,30 @@ void cdrPlayReadInterrupt(void)
        CDRPLAYREAD_INT(cdReadTime, 0);
 }
 
+static void softReset(void)
+{
+       CDR_getStatus(&stat);
+       if (stat.Status & STATUS_SHELLOPEN) {
+               cdr.DriveState = DRIVESTATE_LID_OPEN;
+               cdr.StatP = STATUS_SHELLOPEN;
+       }
+       else if (CdromId[0] == '\0') {
+               cdr.DriveState = DRIVESTATE_STOPPED;
+               cdr.StatP = 0;
+       }
+       else {
+               cdr.DriveState = DRIVESTATE_STANDBY;
+               cdr.StatP = STATUS_ROTATING;
+       }
+
+       cdr.FifoOffset = DATA_SIZE; // fifo empty
+       cdr.LocL[0] = LOCL_INVALID;
+       cdr.Mode = MODE_SIZE_2340;
+       cdr.Muted = FALSE;
+       SPU_setCDvol(cdr.AttenuatorLeftToLeft, cdr.AttenuatorLeftToRight,
+               cdr.AttenuatorRightToLeft, cdr.AttenuatorRightToRight, psxRegs.cycle);
+}
+
 #define CMD_PART2           0x100
 #define CMD_WHILE_NOT_READY 0x200
 
@@ -983,15 +1016,11 @@ void cdrInterrupt(void) {
 
                case CdlReset:
                case CdlReset + CMD_WHILE_NOT_READY:
+                       // note: nocash and Duckstation calls this 'Init', but
+                       // the official SDK calls it 'Reset', and so do we
                        StopCdda();
                        StopReading();
-                       SetPlaySeekRead(cdr.StatP, 0);
-                       cdr.LocL[0] = LOCL_INVALID;
-                       cdr.Mode = MODE_SIZE_2340; /* This fixes This is Football 2, Pooh's Party lockups */
-                       cdr.DriveState = DRIVESTATE_PAUSED;
-                       cdr.Muted = FALSE;
-                       SPU_setCDvol(cdr.AttenuatorLeftToLeft, cdr.AttenuatorLeftToRight,
-                               cdr.AttenuatorRightToLeft, cdr.AttenuatorRightToRight, psxRegs.cycle);
+                       softReset();
                        second_resp_time = not_ready ? 70000 : 4100000;
                        start_rotating = 1;
                        break;
@@ -1089,6 +1118,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
@@ -1226,6 +1257,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;
@@ -1403,6 +1436,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);
 }
@@ -1588,8 +1622,8 @@ void cdrWrite3(unsigned char rt) {
                            rl == cdr.AttenuatorRightToLeft &&
                            rr == cdr.AttenuatorRightToRight)
                                return;
-                       cdr.AttenuatorLeftToLeftT = ll; cdr.AttenuatorLeftToRightT = lr;
-                       cdr.AttenuatorRightToLeftT = rl; cdr.AttenuatorRightToRightT = rr;
+                       cdr.AttenuatorLeftToLeft = ll; cdr.AttenuatorLeftToRight = lr;
+                       cdr.AttenuatorRightToLeft = rl; cdr.AttenuatorRightToRight = rr;
                        CDR_LOG_I("CD-XA Volume: %02x %02x | %02x %02x\n", ll, lr, rl, rr);
                        SPU_setCDvol(ll, lr, rl, rr, psxRegs.cycle);
                }
@@ -1715,30 +1749,14 @@ void cdrReset() {
        cdr.FilterChannel = 0;
        cdr.IrqMask = 0x1f;
        cdr.IrqStat = NoIntr;
-       cdr.FifoOffset = DATA_SIZE; // fifo empty
 
-       CDR_getStatus(&stat);
-       if (stat.Status & STATUS_SHELLOPEN) {
-               cdr.DriveState = DRIVESTATE_LID_OPEN;
-               cdr.StatP = STATUS_SHELLOPEN;
-       }
-       else if (CdromId[0] == '\0') {
-               cdr.DriveState = DRIVESTATE_STOPPED;
-               cdr.StatP = 0;
-       }
-       else {
-               cdr.DriveState = DRIVESTATE_STANDBY;
-               cdr.StatP = STATUS_ROTATING;
-       }
-       
        // BIOS player - default values
        cdr.AttenuatorLeftToLeft = 0x80;
        cdr.AttenuatorLeftToRight = 0x00;
        cdr.AttenuatorRightToLeft = 0x00;
        cdr.AttenuatorRightToRight = 0x80;
-       SPU_setCDvol(cdr.AttenuatorLeftToLeft, cdr.AttenuatorLeftToRight,
-               cdr.AttenuatorRightToLeft, cdr.AttenuatorRightToRight, psxRegs.cycle);
 
+       softReset();
        getCdInfo();
 }