PSX/CDVD: Check register 14 (ps1 status register) for cd speed and CDDA ()

Fix to CD speed courtesy of Ref
Restored amount of old PCSX code for CDDA courtesy of pcsxr
This commit is contained in:
Timothy O'Barr 2020-11-05 11:03:49 -07:00 committed by GitHub
parent 0a312295db
commit ada8047419
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 79 deletions

View File

@ -37,7 +37,7 @@
// this string will be empty. // this string will be empty.
wxString DiscSerial; wxString DiscSerial;
static cdvdStruct cdvd; cdvdStruct cdvd;
s64 PSXCLK = 36864000; s64 PSXCLK = 36864000;
@ -1271,72 +1271,6 @@ static void cdvdWrite04(u8 rt)
cdvd.Reading = 1; cdvd.Reading = 1;
break; break;
case N_CD_READ_CDDA: // CdReadCDDA
case N_CD_READ_XCDDA: // CdReadXCDDA
// Assign the seek to sector based on cdvd.Param[0]-[3], and the number of sectors based on cdvd.Param[4]-[7].
cdvd.SeekToSector = *(u32*)(cdvd.Param + 0);
cdvd.nSectors = *(u32*)(cdvd.Param + 4);
if (cdvd.Param[8] == 0)
cdvd.RetryCnt = 0x100;
else
cdvd.RetryCnt = cdvd.Param[8];
cdvd.SpindlCtrl = cdvd.Param[9];
switch (cdvd.Param[9])
{
case 0x01:
cdvd.Speed = 1;
break;
case 0x02:
cdvd.Speed = 2;
break;
case 0x03:
cdvd.Speed = 4;
break;
case 0x04:
cdvd.Speed = 12;
break;
default:
cdvd.Speed = 24;
break;
}
switch (cdvd.Param[10])
{
case 1:
cdvd.ReadMode = CDVD_MODE_2368;
cdvd.BlockSize = 2368;
break;
case 2:
case 0:
cdvd.ReadMode = CDVD_MODE_2352;
cdvd.BlockSize = 2352;
break;
}
CDVD_LOG("CdReadCDDA > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%xx(%x), ReadMode=%x(%x) (1074=%x)",
cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074));
if (EmuConfig.CdvdVerboseReads)
Console.WriteLn(Color_Gray, L"CdAudioRead: Reading Sector %07d (%03d Blocks of Size %d) at Speed=%dx",
cdvd.Sector, cdvd.nSectors, cdvd.BlockSize, cdvd.Speed);
cdvd.ReadTime = cdvdBlockReadTime(MODE_CDROM);
CDVDREAD_INT(cdvdStartSeek(cdvd.SeekToSector, MODE_CDROM));
// Read-ahead by telling the plugin about the track now.
// This helps improve performance on actual from-cd emulation
// (ie, not using the hard drive)
cdvd.RErr = DoCDVDreadTrack(cdvd.SeekToSector, cdvd.ReadMode);
// Set the reading block flag. If a seek is pending then Readed will
// take priority in the handler anyway. If the read is contiguous then
// this'll skip the seek delay.
cdvd.Reading = 1;
break;
case N_DVD_READ: // DvdRead case N_DVD_READ: // DvdRead
// Assign the seek to sector based on cdvd.Param[0]-[3], and the number of sectors based on cdvd.Param[4]-[7]. // Assign the seek to sector based on cdvd.Param[0]-[3], and the number of sectors based on cdvd.Param[4]-[7].
cdvd.SeekToSector = *(u32*)(cdvd.Param + 0); cdvd.SeekToSector = *(u32*)(cdvd.Param + 0);

View File

@ -137,6 +137,7 @@ struct cdvdStruct
bool Spinning; // indicates if the Cdvd is spinning or needs a spinup delay bool Spinning; // indicates if the Cdvd is spinning or needs a spinup delay
}; };
extern cdvdStruct cdvd;
extern void cdvdReset(); extern void cdvdReset();
extern void cdvdVsync(); extern void cdvdVsync();

View File

@ -13,7 +13,6 @@
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "IopCommon.h" #include "IopCommon.h"
@ -662,13 +661,11 @@ void cdrWrite0(u8 rt)
} }
} }
void setPsxSpeed() void setPs1CDVDSpeed(int speed)
{ {
// psxmode: trying to get delays right (fix "dma3 not ready" and mdec glitches) //DevCon.WriteLn("SPEED: " + speed);
// odd.. tests suggest this should be exactly * 2. could it be that the old psx 1x / 2x speeds aren't handled the same on PS2? cdReadTime = (PSXCLK / (75 * speed));
// used Chrono Cross intro music and see that it doesn't stutter, then use any other FMV game (with sound) and see that it doesn't stall. //DevCon.WriteLn("cdReadTime: " + unsigned(cdReadTime));
// result: cdReadTime = ((PSXCLK / 75) / BIAS) * 2; is exactly right
cdReadTime = ((PSXCLK / 75) / BIAS) * 2;
} }
u8 cdrRead1(void) u8 cdrRead1(void)
@ -748,11 +745,22 @@ void cdrWrite1(u8 rt)
cdr.Ctrl |= 0x80; cdr.Ctrl |= 0x80;
cdr.Stat = NoIntr; cdr.Stat = NoIntr;
cdr.SetlocPending = 1;
AddIrqQueue(cdr.Cmd, 0x800); // the seek delay occurs on the next read / seek command (CdlReadS, CdlSeekL, etc) AddIrqQueue(cdr.Cmd, 0x800); // the seek delay occurs on the next read / seek command (CdlReadS, CdlSeekL, etc)
} }
break; break;
do_CdlPlay:
case CdlPlay: case CdlPlay:
// Taken from pcsxr
if (cdr.Reading)
{
StopReading();
}
if (cdr.SetlocPending)
{
memcpy(cdr.SetSectorSeek, cdr.SetSector, 4);
cdr.SetlocPending = 0;
}
cdr.Play = 1; cdr.Play = 1;
cdr.Ctrl |= 0x80; cdr.Ctrl |= 0x80;
cdr.Stat = NoIntr; cdr.Stat = NoIntr;
@ -844,6 +852,14 @@ void cdrWrite1(u8 rt)
cdr.Mode = cdr.Param[0]; cdr.Mode = cdr.Param[0];
cdr.Ctrl |= 0x80; cdr.Ctrl |= 0x80;
cdr.Stat = NoIntr; cdr.Stat = NoIntr;
if (cdr.Mode && MODE_CDDA)
{
StopCdda();
cdvd.Type = CDVD_TYPE_CDDA;
}
cdvd.Speed = 1 + ((cdr.Mode >> 7) & 0x1);
setPs1CDVDSpeed(cdvd.Speed);
AddIrqQueue(cdr.Cmd, 0x800); AddIrqQueue(cdr.Cmd, 0x800);
break; break;
@ -910,6 +926,8 @@ void cdrWrite1(u8 rt)
break; break;
case CdlReadS: case CdlReadS:
if (cdvd.Type == CDVD_TYPE_CDDA) // Taken from pcsxr
goto do_CdlPlay;
cdr.Irq = 0; cdr.Irq = 0;
StopReading(); StopReading();
cdr.Ctrl |= 0x80; cdr.Ctrl |= 0x80;

View File

@ -60,6 +60,7 @@ struct cdrStruct
u8 ResultP; u8 ResultP;
u8 ResultReady; u8 ResultReady;
u8 Cmd; u8 Cmd;
u8 SetlocPending;
u8 Readed; u8 Readed;
u32 Reading; u32 Reading;
@ -74,7 +75,6 @@ struct cdrStruct
int Reset; int Reset;
int RErr; int RErr;
int FirstSector; int FirstSector;
xa_decode_t Xa; xa_decode_t Xa;
int Init; int Init;
@ -95,7 +95,7 @@ u8 cdrRead0(void);
u8 cdrRead1(void); u8 cdrRead1(void);
u8 cdrRead2(void); u8 cdrRead2(void);
u8 cdrRead3(void); u8 cdrRead3(void);
void setPsxSpeed(); void setPs1CDVDSpeed(int speed);
void cdrWrite0(u8 rt); void cdrWrite0(u8 rt);
void cdrWrite1(u8 rt); void cdrWrite1(u8 rt);
void cdrWrite2(u8 rt); void cdrWrite2(u8 rt);

View File

@ -185,7 +185,7 @@ void __fastcall _hwWrite32( u32 mem, u32 value )
psxReset(); psxReset();
PSXCLK = 33868800; PSXCLK = 33868800;
SPU2ps1reset(); SPU2ps1reset();
setPsxSpeed(); setPs1CDVDSpeed(cdvd.Speed);
psxHu32(0x1f801450) = 0x8; psxHu32(0x1f801450) = 0x8;
psxHu32(0x1f801078) = 1; psxHu32(0x1f801078) = 1;
psxRegs.cycle = cycle; psxRegs.cycle = cycle;