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

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.
wxString DiscSerial;
static cdvdStruct cdvd;
cdvdStruct cdvd;
s64 PSXCLK = 36864000;
@ -1270,73 +1270,7 @@ static void cdvdWrite04(u8 rt)
// this'll skip the seek delay.
cdvd.Reading = 1;
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
// 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);

View File

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

View File

@ -13,7 +13,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.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)
// 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?
// 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.
// result: cdReadTime = ((PSXCLK / 75) / BIAS) * 2; is exactly right
cdReadTime = ((PSXCLK / 75) / BIAS) * 2;
//DevCon.WriteLn("SPEED: " + speed);
cdReadTime = (PSXCLK / (75 * speed));
//DevCon.WriteLn("cdReadTime: " + unsigned(cdReadTime));
}
u8 cdrRead1(void)
@ -748,11 +745,22 @@ void cdrWrite1(u8 rt)
cdr.Ctrl |= 0x80;
cdr.Stat = NoIntr;
cdr.SetlocPending = 1;
AddIrqQueue(cdr.Cmd, 0x800); // the seek delay occurs on the next read / seek command (CdlReadS, CdlSeekL, etc)
}
break;
do_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.Ctrl |= 0x80;
cdr.Stat = NoIntr;
@ -844,6 +852,14 @@ void cdrWrite1(u8 rt)
cdr.Mode = cdr.Param[0];
cdr.Ctrl |= 0x80;
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);
break;
@ -910,6 +926,8 @@ void cdrWrite1(u8 rt)
break;
case CdlReadS:
if (cdvd.Type == CDVD_TYPE_CDDA) // Taken from pcsxr
goto do_CdlPlay;
cdr.Irq = 0;
StopReading();
cdr.Ctrl |= 0x80;

View File

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

View File

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