sbi: update according to Nocash doc
[pcsx_rearmed.git] / libpcsxcore / cdrom.c
index 6923c02..f227b1b 100644 (file)
@@ -394,6 +394,55 @@ static void Find_CurTrack(const u8 *time)
        }
 }
 
+static void generate_subq(const u8 *time)
+{
+       unsigned char start[3], next[3];
+       unsigned int this_s, start_s, next_s, pregap;
+       int relative_s;
+
+       CDR_getTD(cdr.CurTrack, start);
+       if (cdr.CurTrack + 1 <= cdr.ResultTN[1]) {
+               pregap = 150;
+               CDR_getTD(cdr.CurTrack + 1, next);
+       }
+       else {
+               // last track - cd size
+               pregap = 0;
+               next[0] = cdr.SetSectorEnd[2];
+               next[1] = cdr.SetSectorEnd[1];
+               next[2] = cdr.SetSectorEnd[0];
+       }
+
+       this_s = msf2sec(time);
+       start_s = fsm2sec(start);
+       next_s = fsm2sec(next);
+
+       cdr.TrackChanged = FALSE;
+
+       if (next_s - this_s < pregap) {
+               cdr.TrackChanged = TRUE;
+               cdr.CurTrack++;
+               start_s = next_s;
+       }
+
+       cdr.subq.Index = 1;
+
+       relative_s = this_s - start_s;
+       if (relative_s < 0) {
+               cdr.subq.Index = 0;
+               relative_s = -relative_s;
+       }
+       sec2msf(relative_s, cdr.subq.Relative);
+
+       cdr.subq.Track = itob(cdr.CurTrack);
+       cdr.subq.Relative[0] = itob(cdr.subq.Relative[0]);
+       cdr.subq.Relative[1] = itob(cdr.subq.Relative[1]);
+       cdr.subq.Relative[2] = itob(cdr.subq.Relative[2]);
+       cdr.subq.Absolute[0] = itob(time[0]);
+       cdr.subq.Absolute[1] = itob(time[1]);
+       cdr.subq.Absolute[2] = itob(time[2]);
+}
+
 static void ReadTrack(const u8 *time) {
        unsigned char tmp[3];
        struct SubQ *subq;
@@ -411,73 +460,25 @@ static void ReadTrack(const u8 *time) {
        cdr.RErr = CDR_readTrack(tmp);
        memcpy(cdr.Prev, tmp, 3);
 
-       cdr.TrackChanged = FALSE;
-
        if (CheckSBI(time))
                return;
 
        subq = (struct SubQ *)CDR_getBufferSub();
-       if (subq != NULL) {
+       if (subq != NULL && cdr.CurTrack == 1) {
                crc = calcCrc((u8 *)subq + 12, 10);
                if (crc == (((u16)subq->CRC[0] << 8) | subq->CRC[1])) {
                        cdr.subq.Track = subq->TrackNumber;
                        cdr.subq.Index = subq->IndexNumber;
                        memcpy(cdr.subq.Relative, subq->TrackRelativeAddress, 3);
                        memcpy(cdr.subq.Absolute, subq->AbsoluteAddress, 3);
-
-                       // .. + 1 is probably wrong, but deals with corrupted
-                       // subq + good checksum
-                       // (how does real thing handle that?)
-                       if (cdr.CurTrack + 1 == btoi(subq->TrackNumber)) {
-                               cdr.CurTrack++;
-                               cdr.TrackChanged = TRUE;
-                       }
-               }
-       }
-       else {
-               unsigned char start[3], next[3];
-               unsigned int this_s, start_s, next_s, pregap;
-               int relative_s;
-
-               CDR_getTD(cdr.CurTrack, start);
-               if (cdr.CurTrack + 1 <= cdr.ResultTN[1]) {
-                       pregap = 150;
-                       CDR_getTD(cdr.CurTrack + 1, next);
                }
                else {
-                       // last track - cd size
-                       pregap = 0;
-                       next[0] = cdr.SetSectorEnd[2];
-                       next[1] = cdr.SetSectorEnd[1];
-                       next[2] = cdr.SetSectorEnd[0];
+                       CDR_LOG_I("subq bad crc @%02x:%02x:%02x\n",
+                               tmp[0], tmp[1], tmp[2]);
                }
-
-               this_s = msf2sec(time);
-               start_s = fsm2sec(start);
-               next_s = fsm2sec(next);
-
-               if (next_s - this_s < pregap) {
-                       cdr.TrackChanged = TRUE;
-                       cdr.CurTrack++;
-                       start_s = next_s;
-               }
-
-               cdr.subq.Index = 1;
-
-               relative_s = this_s - start_s;
-               if (relative_s < 0) {
-                       cdr.subq.Index = 0;
-                       relative_s = -relative_s;
-               }
-               sec2msf(relative_s, cdr.subq.Relative);
-
-               cdr.subq.Track = itob(cdr.CurTrack);
-               cdr.subq.Relative[0] = itob(cdr.subq.Relative[0]);
-               cdr.subq.Relative[1] = itob(cdr.subq.Relative[1]);
-               cdr.subq.Relative[2] = itob(cdr.subq.Relative[2]);
-               cdr.subq.Absolute[0] = tmp[0];
-               cdr.subq.Absolute[1] = tmp[1];
-               cdr.subq.Absolute[2] = tmp[2];
+       }
+       else {
+               generate_subq(time);
        }
 
        CDR_LOG(" -> %02x,%02x %02x:%02x:%02x %02x:%02x:%02x\n",
@@ -594,7 +595,7 @@ void cdrPlayInterrupt()
        CDRMISC_INT(cdReadTime);
 
        // update for CdlGetlocP/autopause
-       ReadTrack(cdr.SetSectorPlay);
+       generate_subq(cdr.SetSectorPlay);
 }
 
 void cdrInterrupt() {
@@ -1015,7 +1016,7 @@ void cdrInterrupt() {
 
                        // Fighting Force 2 - update subq time immediately
                        // - fixes new game
-                       cdr.CurTrack = 1;
+                       Find_CurTrack(cdr.SetSector);
                        ReadTrack(cdr.SetSector);
 
 
@@ -1094,7 +1095,7 @@ void cdrReadInterrupt() {
        cdr.Result[0] = cdr.StatP;
        cdr.Seeked = SEEK_DONE;
 
-       ReadTrack( cdr.SetSector );
+       ReadTrack(cdr.SetSector);
 
        buf = CDR_getBuffer();
        if (buf == NULL)
@@ -1648,6 +1649,7 @@ int cdrFreeze(void *f, int Mode) {
        if (Mode == 0 && !Config.Cdda)
                CDR_stop();
        
+       cdr.freeze_ver = 0x63647201;
        gzfreeze(&cdr, sizeof(cdr));
        
        if (Mode == 1) {
@@ -1672,6 +1674,14 @@ int cdrFreeze(void *f, int Mode) {
                        if (!Config.Cdda)
                                CDR_play(cdr.SetSectorPlay);
                }
+
+               if ((cdr.freeze_ver & 0xffffff00) != 0x63647200) {
+                       // old versions did not latch Reg2, have to fixup..
+                       if (cdr.Reg2 == 0) {
+                               SysPrintf("cdrom: fixing up old savestate\n");
+                               cdr.Reg2 = 7;
+                       }
+               }
        }
 
        return 0;