}
}
+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;
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",
CDRMISC_INT(cdReadTime);
// update for CdlGetlocP/autopause
- ReadTrack(cdr.SetSectorPlay);
+ generate_subq(cdr.SetSectorPlay);
}
void cdrInterrupt() {
// Fighting Force 2 - update subq time immediately
// - fixes new game
- cdr.CurTrack = 1;
+ Find_CurTrack(cdr.SetSector);
ReadTrack(cdr.SetSector);
cdr.Result[0] = cdr.StatP;
cdr.Seeked = SEEK_DONE;
- ReadTrack( cdr.SetSector );
+ ReadTrack(cdr.SetSector);
buf = CDR_getBuffer();
if (buf == NULL)
if (Mode == 0 && !Config.Cdda)
CDR_stop();
+ cdr.freeze_ver = 0x63647201;
gzfreeze(&cdr, sizeof(cdr));
if (Mode == 1) {
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;