cdrom: rework seek hack
[pcsx_rearmed.git] / libpcsxcore / cdrom.c
index eebd8ed..ff03b7d 100644 (file)
@@ -78,8 +78,6 @@ static unsigned char *pTransfer;
 #define CdlReset       28
 #define CdlReadToc     30
 
-/* don't set 255, it's reserved */
-
 char *CmdName[0x100]= {
     "CdlSync",     "CdlNop",       "CdlSetloc",  "CdlPlay",
     "CdlForward",  "CdlBackward",  "CdlReadN",   "CdlStandby",
@@ -136,7 +134,6 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 };
 enum seeked_state {
        SEEK_PENDING = 0,
        SEEK_DONE = 1,
-       SEEK_DOING_CMD = 2,
 };
 
 static struct CdrStat stat;
@@ -423,7 +420,7 @@ static void ReadTrack( u8 *time ) {
 
 
 static void AddIrqQueue(unsigned char irq, unsigned long ecycle) {
-       if (cdr.Irq != 0 && cdr.Irq != 0xff)
+       if (cdr.Irq != 0)
                CDR_LOG_I("cdr: override cmd %02x -> %02x\n", cdr.Irq, irq);
 
        cdr.Irq = irq;
@@ -550,12 +547,6 @@ static void cdrPlayInterrupt_Autopause()
        struct SubQ *subq = (struct SubQ *)CDR_getBufferSub();
        int track_changed = 0;
        if (subq != NULL ) {
-               // update subq
-               ReadTrack( cdr.SetSectorPlay );
-
-               CDR_LOG( "CDDA SUB - %X:%X:%X\n",
-                       subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] );
-
                /*
                CDDA Autopause
 
@@ -568,10 +559,6 @@ static void cdrPlayInterrupt_Autopause()
                if( cdr.CurTrack + 1 == btoi( subq->TrackNumber ) )
                        track_changed = 1;
        } else {
-               Create_Fake_Subq();
-               CDR_LOG( "CDDA FAKE SUB - %d:%d:%d\n",
-                       fake_subq_real[0], fake_subq_real[1], fake_subq_real[2] );
-
                track_changed = fake_subq_change;
                fake_subq_change = 0;
        }
@@ -638,7 +625,7 @@ static void cdrPlayInterrupt_Autopause()
 // also handles seek
 void cdrPlayInterrupt()
 {
-       if (cdr.Seeked == SEEK_DOING_CMD) {
+       if (cdr.Seeked == SEEK_PENDING) {
                if (cdr.Stat) {
                        CDR_LOG_I("cdrom: seek stat hack\n");
                        CDRMISC_INT(0x1000);
@@ -648,24 +635,25 @@ void cdrPlayInterrupt()
                cdr.StatP |= STATUS_ROTATING;
                cdr.StatP &= ~STATUS_SEEK;
                cdr.Result[0] = cdr.StatP;
-               if (cdr.Irq == 0 || cdr.Irq == 0xff) {
+               cdr.Seeked = SEEK_DONE;
+               if (cdr.Irq == 0) {
                        cdr.Stat = Complete;
                        setIrq();
                }
 
-               cdr.Seeked = SEEK_PENDING;
-               CDRMISC_INT(cdReadTime * 20); // ???
-               return;
-       }
-       else if (cdr.Seeked == SEEK_PENDING) {
-               cdr.Seeked = SEEK_DONE;
-               if (!cdr.Play && !cdr.Reading) {
-                       memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
-                       Find_CurTrack();
-                       ReadTrack(cdr.SetSector);
-               }
+               memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
+               Find_CurTrack();
+               ReadTrack(cdr.SetSectorPlay);
        }
 
+       // update for CdlGetlocP/autopause
+       struct SubQ *subq = (struct SubQ *)CDR_getBufferSub();
+       if (subq != NULL)
+               // update subq
+               ReadTrack(cdr.SetSectorPlay);
+       else
+               Create_Fake_Subq();
+
        if (!cdr.Play) return;
 
        CDR_LOG( "CDDA - %d:%d:%d\n",
@@ -673,7 +661,7 @@ void cdrPlayInterrupt()
 
        CDRMISC_INT( cdReadTime );
 
-       if (!cdr.Irq && !cdr.Stat && (cdr.Mode & MODE_CDDA) && (cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT)))
+       if (!cdr.Irq && !cdr.Stat && (cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT)))
                cdrPlayInterrupt_Autopause();
 
        cdr.SetSectorPlay[2]++;
@@ -701,7 +689,7 @@ void cdrInterrupt() {
                return;
        }
 
-       cdr.Irq = 0xff;
+       cdr.Irq = 0;
        cdr.Ctrl &= ~0x80;
 
        switch (Irq) {
@@ -988,9 +976,8 @@ void cdrInterrupt() {
                        subq = (struct SubQ *)CDR_getBufferSub();
 
                        if (subq != NULL) {
-                               if( cdr.Play && (cdr.Mode & MODE_CDDA) && !(cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT)) )
-                                       // update subq
-                                       ReadTrack( cdr.SetSectorPlay );
+                               // update subq
+                               ReadTrack( cdr.SetSector );
 
                                cdr.Result[0] = subq->TrackNumber;
                                cdr.Result[1] = subq->IndexNumber;
@@ -1005,10 +992,9 @@ void cdrInterrupt() {
                                }
                                }
                        } else {
-                               if( cdr.Play == FALSE || !(cdr.Mode & MODE_CDDA) || !(cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT)) )
+                               if (cdr.Play == FALSE)
                                        Create_Fake_Subq();
 
-
                                // track # / index #
                                cdr.Result[0] = itob(cdr.CurTrack);
                                cdr.Result[1] = itob(fake_subq_index);
@@ -1024,6 +1010,9 @@ void cdrInterrupt() {
                                cdr.Result[7] = itob( fake_subq_real[2] );
                        }
 
+                       if (!cdr.Play && !cdr.Reading)
+                               cdr.Result[1] = 0; // HACK?
+
                        // redump.org - wipe time
                        if( !cdr.Play && CheckSBI(cdr.Result+5) ) {
                                memset( cdr.Result+2, 0, 6 );
@@ -1091,7 +1080,7 @@ void cdrInterrupt() {
                        - fix capcom logo
                        */
                        CDRMISC_INT(cdr.Seeked == SEEK_DONE ? 0x800 : cdReadTime * 4);
-                       cdr.Seeked = SEEK_DOING_CMD;
+                       cdr.Seeked = SEEK_PENDING;
                        break;
 
                case CdlTest:
@@ -1358,17 +1347,7 @@ void cdrReadInterrupt() {
 
        cdr.Readed = 0;
 
-       // G-Police: Don't autopause ADPCM even if mode set (music)
-       if ((cdr.Transfer[4 + 2] & 0x80) && (cdr.Mode & MODE_AUTOPAUSE) &&
-                       (cdr.Transfer[4 + 2] & 0x4) != 0x4 ) { // EOF
-
-               CDR_LOG("cdrReadInterrupt() Log: Autopausing read\n");
-
-               AddIrqQueue(CdlPause, 0x2000);
-       }
-       else {
-               CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime);
-       }
+       CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime);
 
        /*
        Croc 2: $40 - only FORM1 (*)
@@ -1376,14 +1355,10 @@ void cdrReadInterrupt() {
        Sim Theme Park - no adpcm at all (zero)
        */
 
-       if( (cdr.Mode & MODE_STRSND) == 0 || (cdr.Transfer[4+2] & 0x4) != 0x4 ) {
+       if (!(cdr.Mode & MODE_STRSND) || !(cdr.Transfer[4+2] & 0x4)) {
                cdr.Stat = DataReady;
-       } else {
-               // Breath of Fire 3 - fix inn sleeping
-               // Rockman X5 - no music restart problem
-               cdr.Stat = NoIntr;
+               setIrq();
        }
-       setIrq();
 
        Check_Shell(0);
 }
@@ -1693,9 +1668,13 @@ void cdrWrite3(unsigned char rt) {
 
        switch (cdr.Ctrl & 3) {
        case 0:
-               goto transfer;
+               break; // transfer
        case 1:
-               break; // irq
+               cdr.Stat &= ~rt;
+
+               if (rt & 0x40)
+                       cdr.ParamC = 0;
+               return;
        case 2:
                cdr.AttenuatorLeft[1] = rt;
                return;
@@ -1707,34 +1686,6 @@ void cdrWrite3(unsigned char rt) {
                return;
        }
 
-       cdr.Stat &= ~rt;
-
-       if (rt & 0x40)
-               cdr.ParamC = 0;
-
-       if (rt == 0x07) {
-               if (cdr.Irq == 0xff) {
-                       cdr.Irq = 0;
-                       return;
-               }
-
-               // XA streaming - incorrect timing because of this reschedule
-               // - Final Fantasy Tactics
-               // - various other games
-
-               if (cdr.Reading && !cdr.ResultReady) {
-                       int left = psxRegs.intCycle[PSXINT_CDREAD].sCycle + psxRegs.intCycle[PSXINT_CDREAD].cycle - psxRegs.cycle;
-                       int time = (cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime;
-                       if (Config.CdrReschedule != 2)
-                       if (left < time / 2 || Config.CdrReschedule) { // rearmed guesswork hack
-                               CDR_LOG_I("-- resched %d -> %d\n", left, time);
-                               CDREAD_INT(time);
-                       }
-               }
-       }
-       return;
-
-transfer:
        if ((rt & 0x80) && cdr.Readed == 0) {
                cdr.Readed = 1;
                pTransfer = cdr.Transfer;
@@ -1879,7 +1830,7 @@ void LidInterrupt() {
        cdr.LidCheck = 0x20; // start checker
 
        CDRLID_INT( cdReadTime * 3 );
-       
+
        // generate interrupt if none active - open or close
        if (cdr.Irq == 0 || cdr.Irq == 0xff) {
                cdr.Ctrl |= 0x80;