From ada804741957e813602bd33f2989b5bceea42913 Mon Sep 17 00:00:00 2001 From: Timothy O'Barr Date: Thu, 5 Nov 2020 11:03:49 -0700 Subject: [PATCH] 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 --- pcsx2/CDVD/CDVD.cpp | 70 ++------------------------------------------ pcsx2/CDVD/CDVD.h | 1 + pcsx2/CDVD/CdRom.cpp | 34 ++++++++++++++++----- pcsx2/CDVD/CdRom.h | 4 +-- pcsx2/HwWrite.cpp | 2 +- 5 files changed, 32 insertions(+), 79 deletions(-) diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index f91f565138..13680bd63c 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -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); diff --git a/pcsx2/CDVD/CDVD.h b/pcsx2/CDVD/CDVD.h index d972c88e2f..2f0b74b442 100644 --- a/pcsx2/CDVD/CDVD.h +++ b/pcsx2/CDVD/CDVD.h @@ -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(); diff --git a/pcsx2/CDVD/CdRom.cpp b/pcsx2/CDVD/CdRom.cpp index d1e175040e..2c0e285c91 100644 --- a/pcsx2/CDVD/CdRom.cpp +++ b/pcsx2/CDVD/CdRom.cpp @@ -13,7 +13,6 @@ * If not, see . */ - #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; diff --git a/pcsx2/CDVD/CdRom.h b/pcsx2/CDVD/CdRom.h index 355449256c..e1df2878a0 100644 --- a/pcsx2/CDVD/CdRom.h +++ b/pcsx2/CDVD/CdRom.h @@ -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); diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index f2aa97a897..0f2a459fd6 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -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;