Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDVD: Fix OSDSYS Audio CD regressions. #12032

Merged
merged 5 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion pcsx2/CDVD/CDVD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3013,6 +3013,20 @@ void cdvdWrite(u8 key, u8 rt)
case 0x08:
cdvdWrite08(rt);
break;
case 0x09:
/*
The register 0xC, 0xD, 0xE give back MSF of the current sector being read/played from the actual DSP hardware. They are named "where" registers : where0, where1, where2.
They can be read anytime on hw as long as there is a valid disc and mode configured properly. Register 0x9 is where_select register which determines the mode for this registers. The mode must be set according to the used disc.
0 = CDDA
1 = CDROM
2 = DVD

If no disc or invalid mode for disc type then those registers return 0. Only official usage so far is cdvdman reading those registers and waiting to sync while doing SubQ.
Only logging writes different than 0 is enough.
*/
if (rt != 0)
Console.Warning("8bit write to addr 0x1f402009 = 0x%x", rt);
break;
case 0x0A:
cdvdWrite0A(rt);
break;
Expand All @@ -3035,7 +3049,7 @@ void cdvdWrite(u8 key, u8 rt)
cdvdWrite3A(rt);
break;
default:
Console.Warning("IOP Unknown 8bit write to addr 0x1f4020%x = 0x%x", key, rt);
Console.Warning("IOP Unknown 8bit write to addr 0x1f4020%02x = 0x%x", key, rt);
break;
}
}
3 changes: 2 additions & 1 deletion pcsx2/CDVD/CDVDcommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "common/ProgressCallback.h"
#include "common/StringUtil.h"

#include <array>
#include <ctype.h>
#include <exception>
#include <memory>
Expand Down Expand Up @@ -55,7 +56,7 @@ static OutputIsoFile blockDumpFile;
// Information about tracks on disc
u8 strack;
u8 etrack;
cdvdTrack tracks[100];
std::array<cdvdTrack, 100> tracks;

// Assertion check for CDVD != NULL (in devel and debug builds), because its handier than
// relying on DEP exceptions -- and a little more reliable too.
Expand Down
24 changes: 12 additions & 12 deletions pcsx2/CDVD/CDVDcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
class Error;
class ProgressCallback;

typedef struct _cdvdTrackIndex
struct cdvdTrackIndex
{
bool isPregap;
u8 trackM; // current minute offset from first track (BCD encoded)
Expand All @@ -20,9 +20,9 @@ typedef struct _cdvdTrackIndex
u8 discS; // current sector location on the disc (BCD encoded)
u8 discF; // current frame location on the disc (BCD encoded)

} cdvdTrackIndex;
};

typedef struct _cdvdTrack
struct cdvdTrack
{
u32 start_lba; // Starting lba of track, note that some formats will be missing 2 seconds, cue, bin
u8 type; // Track Type
Expand All @@ -36,10 +36,10 @@ typedef struct _cdvdTrack
u8 discF; // current frame location on the disc (BCD encoded)

// 0 is pregap, 1 is data
_cdvdTrackIndex index[2];
} cdvdTrack;
cdvdTrackIndex index[2];
};

typedef struct _cdvdSubQ
struct cdvdSubQ
{
u8 ctrl : 4; // control and adr bits
u8 adr : 4; // control and adr bits, note that adr determines what SubQ info we're recieving.
Expand All @@ -52,19 +52,19 @@ typedef struct _cdvdSubQ
u8 discM; // current minute location on the disc (BCD encoded)
u8 discS; // current sector location on the disc (BCD encoded)
u8 discF; // current frame location on the disc (BCD encoded)
} cdvdSubQ;
};

typedef struct _cdvdTD
struct cdvdTD
{ // NOT bcd coded
u32 lsn;
u8 type;
} cdvdTD;
};

typedef struct _cdvdTN
struct cdvdTN
{
u8 strack; //number of the first track (usually 1)
u8 etrack; //number of the last track
} cdvdTN;
};

// SpindleCtrl Masks
#define CDVD_SPINDLE_SPEED 0x7 // Speed ranges from 0-3 (1, 2, 3, 4x for DVD) and 0-5 (1, 2, 4, 12, 24x for CD)
Expand Down Expand Up @@ -185,7 +185,7 @@ extern const CDVD_API CDVDapi_NoDisc;

extern u8 strack;
extern u8 etrack;
extern cdvdTrack tracks[100];
extern std::array<cdvdTrack, 100> tracks;

extern void CDVDsys_ChangeSource(CDVD_SourceType type);
extern void CDVDsys_SetFile(CDVD_SourceType srctype, std::string newfile);
Expand Down
68 changes: 40 additions & 28 deletions pcsx2/CDVD/CDVDdiscReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static void lsn_to_msf(u8* minute, u8* second, u8* frame, u32 lsn)
// TocStuff
void cdvdParseTOC()
{
tracks[1].start_lba = 0;
tracks.fill(cdvdTrack{});

if (!src->GetSectorCount())
{
Expand All @@ -76,35 +76,37 @@ void cdvdParseTOC()
strack = 0xFF;
etrack = 0;

int i = 0;

for (auto& entry : src->ReadTOC())
{
if (entry.track < 1 || entry.track > 99)
const u8 track = entry.track;
if (track < 1 || track >= tracks.size())
{
Console.Warning("CDVD: Invalid track index %u, ignoring\n", track);
continue;
strack = std::min(strack, entry.track);
etrack = std::max(etrack, entry.track);
tracks[i].start_lba = entry.lba;
}
strack = std::min(strack, track);
etrack = std::max(etrack, track);
tracks[track].start_lba = entry.lba;
if ((entry.control & 0x0C) == 0x04)
{
std::array<u8, 2352> buffer;
// Byte 15 of a raw CD data sector determines the track mode
if (src->ReadSectors2352(entry.lba, 1, buffer.data()) && (buffer[15] & 3) == 2)
{
tracks[i].type = CDVD_MODE2_TRACK;
tracks[track].type = CDVD_MODE2_TRACK;
}
else
{
tracks[i].type = CDVD_MODE1_TRACK;
tracks[track].type = CDVD_MODE1_TRACK;
}
}
else
{
tracks[i].type = CDVD_AUDIO_TRACK;
tracks[track].type = CDVD_AUDIO_TRACK;
}
fprintf(stderr, "Track %u start sector: %u\n", entry.track, entry.lba);

i += 1;
#ifdef PCSX2_DEBUG
DevCon.Write("cdvdParseTOC: Track %u: LBA %u, Type %u\n", track, tracks[track].start_lba, tracks[track].type);
#endif
}
}

Expand All @@ -131,7 +133,7 @@ static void keepAliveThread()
std::unique_lock<std::mutex> guard(s_keepalive_lock);

while (!s_keepalive_cv.wait_for(guard, std::chrono::seconds(30),
[]() { return !s_keepalive_is_open; }))
[]() { return !s_keepalive_is_open; }))
{

//printf(" * keepAliveThread: polling drive.\n");
Expand Down Expand Up @@ -271,20 +273,28 @@ static s32 DISCreadSubQ(u32 lsn, cdvdSubQ* subq)

memset(subq, 0, sizeof(cdvdSubQ));

if (!src->ReadTrackSubQ(subq))
{
lsn_to_msf(&subq->discM, &subq->discS, &subq->discF, lsn + 150);
lsn_to_msf(&subq->discM, &subq->discS, &subq->discF, lsn + 150);

u8 i = strack;
while (i < etrack && lsn >= tracks[i + 1].start_lba)
++i;

u8 i = strack;
while (i < etrack && lsn >= tracks[i + 1].start_lba)
++i;
lsn -= tracks[i].start_lba;

lsn -= tracks[i].start_lba;
lsn_to_msf(&subq->trackM, &subq->trackS, &subq->trackF, lsn);

lsn_to_msf(&subq->trackM, &subq->trackS, &subq->trackF, lsn);
subq->ctrl = tracks[i].type;

// It's important to note that we do _not_ use the current MSF values
// from the host's device. We use the MSF values from the lsn.
// An easy way to test an implementation is to see if the OSDSYS
// CD player can display the correct minute and second values.
// From my testing, the IOCTL returns 0 for ctrl. This also breaks
// the OSDSYS player. The only "safe" values to receive from the IOCTL
// are ADR, trackNum and trackIndex.
if (!src->ReadTrackSubQ(subq))
{
subq->adr = 1;
subq->ctrl = tracks[i].type;
subq->trackNum = i;
subq->trackIndex = 1;
}
Expand Down Expand Up @@ -470,11 +480,13 @@ static s32 DISCgetTOC(void* toc)
{
err = DISCgetTD(i, &trackInfo);
lba_to_msf(trackInfo.lsn, &min, &sec, &frm);
tocBuff[i * 10 + 30] = trackInfo.type;
tocBuff[i * 10 + 32] = err == -1 ? 0 : dec_to_bcd(i); //number
tocBuff[i * 10 + 37] = dec_to_bcd(min);
tocBuff[i * 10 + 38] = dec_to_bcd(sec);
tocBuff[i * 10 + 39] = dec_to_bcd(frm);

const u8 tocIndex = i - diskInfo.strack;
tocBuff[tocIndex * 10 + 30] = trackInfo.type;
tocBuff[tocIndex * 10 + 32] = err == -1 ? 0 : dec_to_bcd(i); //number
tocBuff[tocIndex * 10 + 37] = dec_to_bcd(min);
tocBuff[tocIndex * 10 + 38] = dec_to_bcd(sec);
tocBuff[tocIndex * 10 + 39] = dec_to_bcd(frm);
fprintf(stderr, "Track %u: %u mins %u secs %u frames\n", i, min, sec, frm);
}
}
Expand Down
10 changes: 0 additions & 10 deletions pcsx2/CDVD/Linux/IOCtlSrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,18 +208,8 @@ bool IOCtlSrc::ReadTrackSubQ(cdvdSubQ* subQ) const
}

subQ->adr = osSubQ.cdsc_adr;
subQ->ctrl = osSubQ.cdsc_ctrl;
subQ->trackNum = osSubQ.cdsc_trk;
subQ->trackIndex = osSubQ.cdsc_ind;

subQ->discM = osSubQ.cdsc_absaddr.msf.minute;
subQ->discS = osSubQ.cdsc_absaddr.msf.second;
subQ->discF = osSubQ.cdsc_absaddr.msf.frame;

subQ->trackM = osSubQ.cdsc_reladdr.msf.minute;
subQ->trackS = osSubQ.cdsc_reladdr.msf.second;
subQ->trackF = osSubQ.cdsc_reladdr.msf.frame;

return true;
}

Expand Down
9 changes: 0 additions & 9 deletions pcsx2/CDVD/Windows/IOCtlSrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,17 +320,8 @@ bool IOCtlSrc::ReadTrackSubQ(cdvdSubQ* subQ) const
else
{
subQ->adr = osSubQ.CurrentPosition.ADR;
subQ->ctrl = osSubQ.CurrentPosition.Control;
subQ->trackNum = osSubQ.CurrentPosition.TrackNumber;
subQ->trackIndex = osSubQ.CurrentPosition.IndexNumber;

subQ->trackM = osSubQ.CurrentPosition.TrackRelativeAddress[0];
subQ->trackS = osSubQ.CurrentPosition.TrackRelativeAddress[1];
subQ->trackF = osSubQ.CurrentPosition.TrackRelativeAddress[2];

subQ->discM = osSubQ.CurrentPosition.AbsoluteAddress[0];
subQ->discS = osSubQ.CurrentPosition.AbsoluteAddress[1];
subQ->discF = osSubQ.CurrentPosition.AbsoluteAddress[2];
}

return true;
Expand Down
5 changes: 3 additions & 2 deletions pcsx2/SPU2/spu2sys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,10 +420,11 @@ __forceinline void UpdateSpdifMode()
{
const int OPM = PlayMode;

if (Spdif.Out & 0x4 && SPU2::MsgToConsole()) // use 24/32bit PCM data streaming
if (Spdif.Out & 0x4) // use 24/32bit PCM data streaming
{
PlayMode = 8;
SPU2::ConLog("* SPU2: WARNING: Possibly CDDA mode set!\n");
if (SPU2::MsgToConsole())
SPU2::ConLog("* SPU2: WARNING: Possibly CDDA mode set!\n");
return;
}

Expand Down