#define CdlReset 28
#define CdlReadToc 30
-/* don't set 255, it's reserved */
-
char *CmdName[0x100]= {
"CdlSync", "CdlNop", "CdlSetloc", "CdlPlay",
"CdlForward", "CdlBackward", "CdlReadN", "CdlStandby",
enum seeked_state {
SEEK_PENDING = 0,
SEEK_DONE = 1,
- SEEK_DOING_CMD = 2,
};
static struct CdrStat stat;
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;
CDR_INT(ecycle);
}
-
-void Set_Track()
-{
- if (CDR_getTN(cdr.ResultTN) != -1) {
- int lcv;
-
- for( lcv = 1; lcv < cdr.ResultTN[1]; lcv++ ) {
- if (CDR_getTD((u8)(lcv), cdr.ResultTD) != -1) {
- CDR_LOG( "settrack %d %d %d | %d %d %d | %d\n",
- cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2],
- cdr.ResultTD[2], cdr.ResultTD[1], cdr.ResultTD[0],
- cdr.CurTrack );
-
- // check if time matches track start (only need min, sec accuracy)
- // - m:s:f vs f:s:m
- if( cdr.SetSectorPlay[0] == cdr.ResultTD[2] &&
- cdr.SetSectorPlay[1] == cdr.ResultTD[1] ) {
- // skip pregap frames
- if( cdr.SetSectorPlay[2] < cdr.ResultTD[0] )
- cdr.SetSectorPlay[2] = cdr.ResultTD[0];
-
- break;
- }
- else if( cdr.SetSectorPlay[0] < cdr.ResultTD[2] )
- break;
- }
- }
- }
-}
-
-
static u8 fake_subq_local[3], fake_subq_real[3], fake_subq_index, fake_subq_change;
static void Create_Fake_Subq()
{
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
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;
}
// 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);
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",
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]++;
return;
}
- cdr.Irq = 0xff;
+ cdr.Irq = 0;
cdr.Ctrl &= ~0x80;
switch (Irq) {
cdr.Seeked = SEEK_DONE;
}
+ // BIOS CD Player
+ // - Pause player, hit Track 01/02/../xx (Setloc issued!!)
+
+ if (cdr.ParamC == 0 || cdr.Param[0] == 0) {
+ CDR_LOG("PLAY Resume @ %d:%d:%d\n",
+ cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]);
+ }
+ else
+ {
+ int track = btoi( cdr.Param[0] );
+
+ if (track <= cdr.ResultTN[1])
+ cdr.CurTrack = track;
+
+ CDR_LOG("PLAY track %d\n", cdr.CurTrack);
+
+ if (CDR_getTD((u8)cdr.CurTrack, cdr.ResultTD) != -1) {
+ cdr.SetSectorPlay[0] = cdr.ResultTD[2];
+ cdr.SetSectorPlay[1] = cdr.ResultTD[1];
+ cdr.SetSectorPlay[2] = cdr.ResultTD[0];
+ }
+ }
+
/*
Rayman: detect track changes
- fixes logo freeze
Wild 9: skip PREGAP + starting accurate SubQ
- plays tracks without retry play
*/
- /* unneeded with correct cdriso?
- Set_Track();
- */
Find_CurTrack();
- ReadTrack( cdr.SetSectorPlay );
-
- // GameShark CD Player: Calls 2x + Play 2x
- if( cdr.FastBackward || cdr.FastForward ) {
- if( cdr.FastForward ) cdr.FastForward--;
- if( cdr.FastBackward ) cdr.FastBackward--;
-
- if( cdr.FastBackward == 0 && cdr.FastForward == 0 ) {
- if( cdr.Play && CDR_getStatus(&stat) != -1 ) {
- cdr.SetSectorPlay[0] = stat.Time[0];
- cdr.SetSectorPlay[1] = stat.Time[1];
- cdr.SetSectorPlay[2] = stat.Time[2];
- }
- }
- }
-
-
- if (!Config.Cdda) {
- // BIOS CD Player
- // - Pause player, hit Track 01/02/../xx (Setloc issued!!)
-
- // GameShark CD Player: Resume play
- if( cdr.ParamC == 0 ) {
- CDR_LOG( "PLAY Resume @ %d:%d:%d\n",
- cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] );
-
- //CDR_play( cdr.SetSectorPlay );
- }
- else
- {
- // BIOS CD Player: Resume play
- if( cdr.Param[0] == 0 ) {
- CDR_LOG( "PLAY Resume T0 @ %d:%d:%d\n",
- cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] );
-
- //CDR_play( cdr.SetSectorPlay );
- }
- else {
- CDR_LOG( "PLAY Resume Td @ %d:%d:%d\n",
- cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] );
-
- // BIOS CD Player: Allow track replaying
- StopCdda();
-
-
- cdr.CurTrack = btoi( cdr.Param[0] );
-
- if (CDR_getTN(cdr.ResultTN) != -1) {
- // check last track
- if (cdr.CurTrack > cdr.ResultTN[1])
- cdr.CurTrack = cdr.ResultTN[1];
-
- if (CDR_getTD((u8)(cdr.CurTrack), cdr.ResultTD) != -1) {
- cdr.SetSectorPlay[0] = cdr.ResultTD[2];
- cdr.SetSectorPlay[1] = cdr.ResultTD[1];
- cdr.SetSectorPlay[2] = cdr.ResultTD[0];
-
- // reset data
- //Set_Track();
- Find_CurTrack();
- ReadTrack( cdr.SetSectorPlay );
-
- //CDR_play(cdr.SetSectorPlay);
- }
- }
- }
- }
- }
+ ReadTrack(cdr.SetSectorPlay);
+ if (!Config.Cdda)
+ CDR_play(cdr.SetSectorPlay);
// Vib Ribbon: gameplay checks flag
cdr.StatP &= ~STATUS_SEEK;
-
cdr.CmdProcess = 0;
SetResultSize(1);
cdr.StatP |= STATUS_ROTATING;
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;
}
}
} 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);
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 );
- fix capcom logo
*/
CDRMISC_INT(cdr.Seeked == SEEK_DONE ? 0x800 : cdReadTime * 4);
- cdr.Seeked = SEEK_DOING_CMD;
+ cdr.Seeked = SEEK_PENDING;
break;
case CdlTest:
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 (*)
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);
}
for (i = 0; i < 3; i++)
set_loc[i] = btoi(cdr.Param[i]);
- i = abs(msf2sec(cdr.SetSector) - msf2sec(set_loc));
+ // FIXME: clean up this SetSector/SetSectorPlay mess,
+ // there should be single var tracking current sector pos
+ if (cdr.Play)
+ i = msf2sec(cdr.SetSectorPlay);
+ else
+ i = msf2sec(cdr.SetSector);
+ i = abs(i - msf2sec(set_loc));
if (i > 16)
cdr.Seeked = SEEK_PENDING;
// Vib Ribbon: try same track again
StopCdda();
+#if 0
if (!cdr.SetSector[0] & !cdr.SetSector[1] & !cdr.SetSector[2]) {
if (CDR_getTN(cdr.ResultTN) != -1) {
if (cdr.CurTrack > cdr.ResultTN[1])
if (!Config.Cdda) CDR_play(cdr.ResultTD);
}
}
- } else if (!Config.Cdda) {
- CDR_play(cdr.SetSector);
}
-
+#endif
// Vib Ribbon - decoded buffer IRQ for CDDA reading
// - fixes ribbon timing + music CD mode
//TODO?
case CdlStop:
// GameShark CD Player: Reset CDDA to track start
- if( cdr.Play && CDR_getStatus(&stat) != -1 ) {
- cdr.SetSectorPlay[0] = stat.Time[0];
- cdr.SetSectorPlay[1] = stat.Time[1];
- cdr.SetSectorPlay[2] = stat.Time[2];
-
+ if (cdr.Play) {
Find_CurTrack();
// grab time for current track
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;
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;
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;