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: Added cdvdTrack, cdvdTrackIndex, assigned subQ from hardware reads #11800

Merged
merged 2 commits into from
Sep 21, 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
5 changes: 5 additions & 0 deletions pcsx2/CDVD/CDVDcommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ u32 lastLSN; // needed for block dumping

static OutputIsoFile blockDumpFile;

// Information about tracks on disc
u8 strack;
u8 etrack;
cdvdTrack tracks[100];

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

typedef struct _cdvdTrackIndex
{
bool isPregap;
u8 trackM; // current minute offset from first track (BCD encoded)
u8 trackS; // current sector offset from first track (BCD encoded)
u8 trackF; // current frame offset from first track (BCD encoded)
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)

} cdvdTrackIndex;

typedef struct _cdvdTrack
{
u32 start_lba; // Starting lba of track, note that some formats will be missing 2 seconds, cue, bin
u8 type; // Track Type
u8 trackNum; // current track number (1 to 99)
u8 trackIndex; // current index within track (0 to 99)
u8 trackM; // current minute offset from first track (BCD encoded)
u8 trackS; // current sector offset from first track (BCD encoded)
u8 trackF; // current frame offset from first track (BCD encoded)
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)

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

typedef struct _cdvdSubQ
{
u8 ctrl : 4; // control and mode bits
u8 mode : 4; // control and mode bits
u8 ctrl : 4; // control and adr bits
u8 adr : 4; // control and adr bits, note that adr determines what SubQ info we're recieving.
u8 trackNum; // current track number (1 to 99)
u8 trackIndex; // current index within track (0 to 99)
u8 trackM; // current minute location on the disc (BCD encoded)
u8 trackS; // current sector location on the disc (BCD encoded)
u8 trackF; // current frame location on the disc (BCD encoded)
u8 trackM; // current minute offset from first track (BCD encoded)
u8 trackS; // current sector offset from first track (BCD encoded)
u8 trackF; // current frame offset from first track (BCD encoded)
u8 pad; // unused
u8 discM; // current minute offset from first track (BCD encoded)
u8 discS; // current sector offset from first track (BCD encoded)
u8 discF; // current frame offset from first track (BCD encoded)
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
Expand Down Expand Up @@ -65,6 +94,12 @@ typedef struct _cdvdTN
#define CDVD_TYPE_DETCT 0x01 // Detecting
#define CDVD_TYPE_NODISC 0x00 // No Disc

// SUBQ CONTROL:
#define CDVD_CONTROL_AUDIO_PREEMPHASIS(control) ((control & (4 << 1)))
#define CDVD_CONTROL_DIGITAL_COPY_ALLOWED(control) ((control & (5 << 1)))
#define CDVD_CONTROL_IS_DATA(control) ((control & (6 << 1))) // Detects if track is Data or Audio
#define CDVD_CONTROL_IS_QUADRAPHONIC_AUDIO(control) ((control & (7 << 1)))

// CDVDgetTrayStatus returns:
#define CDVD_TRAY_CLOSE 0x00
#define CDVD_TRAY_OPEN 0x01
Expand Down Expand Up @@ -148,6 +183,10 @@ extern const CDVD_API CDVDapi_Iso;
extern const CDVD_API CDVDapi_Disc;
extern const CDVD_API CDVDapi_NoDisc;

extern u8 strack;
extern u8 etrack;
extern cdvdTrack tracks[100];

extern void CDVDsys_ChangeSource(CDVD_SourceType type);
extern void CDVDsys_SetFile(CDVD_SourceType srctype, std::string newfile);
extern const std::string& CDVDsys_GetFile(CDVD_SourceType srctype);
Expand Down
40 changes: 22 additions & 18 deletions pcsx2/CDVD/CDVDdiscReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "CDVDdiscReader.h"
weirdbeardgame marked this conversation as resolved.
Show resolved Hide resolved
#include "CDVD/CDVD.h"
#include "Host.h"
#include "common/Console.h"

#include "common/Error.h"

Expand All @@ -23,10 +24,6 @@ static std::thread s_keepalive_thread;
///////////////////////////////////////////////////////////////////////////////
// State Information //

u8 strack;
u8 etrack;
track tracks[100];

int curDiskType;
int curTrayStatus;

Expand Down Expand Up @@ -79,31 +76,35 @@ void cdvdParseTOC()
strack = 0xFF;
etrack = 0;

int i = 0;

for (auto& entry : src->ReadTOC())
{
if (entry.track < 1 || entry.track > 99)
continue;
strack = std::min(strack, entry.track);
etrack = std::max(etrack, entry.track);
tracks[entry.track].start_lba = entry.lba;
tracks[i].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[entry.track].type = CDVD_MODE2_TRACK;
tracks[i].type = CDVD_MODE2_TRACK;
}
else
{
tracks[entry.track].type = CDVD_MODE1_TRACK;
tracks[i].type = CDVD_MODE1_TRACK;
}
}
else
{
tracks[entry.track].type = CDVD_AUDIO_TRACK;
tracks[i].type = CDVD_AUDIO_TRACK;
}
fprintf(stderr, "Track %u start sector: %u\n", entry.track, entry.lba);

i += 1;
}
}

Expand Down Expand Up @@ -270,20 +271,23 @@ static s32 DISCreadSubQ(u32 lsn, cdvdSubQ* subq)

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

lsn_to_msf(&subq->discM, &subq->discS, &subq->discF, lsn + 150);
if (!src->ReadTrackSubQ(subq))
{
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->mode = 1;
subq->ctrl = tracks[i].type;
subq->trackNum = i;
subq->trackIndex = 1;
subq->adr = 1;
subq->ctrl = tracks[i].type;
subq->trackNum = i;
subq->trackIndex = 1;
}

return 0;
}
Expand Down
12 changes: 2 additions & 10 deletions pcsx2/CDVD/CDVDdiscReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "common/RedtapeWindows.h"
#endif

#include "CDVDcommon.h"
#include "common/Pcsx2Defs.h"

#include <array>
Expand All @@ -17,16 +18,6 @@

class Error;

struct track
{
u32 start_lba;
u8 type;
};

extern u8 strack;
extern u8 etrack;
extern track tracks[100];

extern int curDiskType;
extern int curTrayStatus;

Expand Down Expand Up @@ -70,6 +61,7 @@ class IOCtlSrc
const std::vector<toc_entry>& ReadTOC() const;
bool ReadSectors2048(u32 sector, u32 count, u8* buffer) const;
bool ReadSectors2352(u32 sector, u32 count, u8* buffer) const;
bool ReadTrackSubQ(cdvdSubQ* subq) const;
u32 GetLayerBreakAddress() const;
s32 GetMediaType() const;
void SetSpindleSpeed(bool restore_defaults) const;
Expand Down
2 changes: 1 addition & 1 deletion pcsx2/CDVD/CDVDisoReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static s32 ISOreadSubQ(u32 lsn, cdvdSubQ* subq)
// fake it
u8 min, sec, frm;
subq->ctrl = 4;
subq->mode = 1;
subq->adr = 1;
subq->trackNum = itob(1);
subq->trackIndex = itob(1);

Expand Down
5 changes: 5 additions & 0 deletions pcsx2/CDVD/Darwin/IOCtlSrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@ bool IOCtlSrc::ReadCDInfo()
#endif
}

bool IOCtlSrc::ReadTrackSubQ(cdvdSubQ* subQ) const
{
return false;
}

bool IOCtlSrc::DiscReady()
{
#ifdef __APPLE__
Expand Down
30 changes: 30 additions & 0 deletions pcsx2/CDVD/Linux/IOCtlSrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "CDVD/CDVD.h"

#include "common/Error.h"
#include "common/Console.h"

#include <linux/cdrom.h>
#include <fcntl.h>
Expand Down Expand Up @@ -194,6 +195,35 @@ bool IOCtlSrc::ReadCDInfo()
return true;
}

bool IOCtlSrc::ReadTrackSubQ(cdvdSubQ* subQ) const
{
cdrom_subchnl osSubQ;

osSubQ.cdsc_format = CDROM_MSF;

if (ioctl(m_device, CDROMSUBCHNL, &osSubQ) == -1)
{
Console.Error("SUB CHANNEL READ ERROR: %s\n", strerror(errno));
return false;
}

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;
}


bool IOCtlSrc::DiscReady()
{
if (m_device == -1)
Expand Down
33 changes: 33 additions & 0 deletions pcsx2/CDVD/Windows/IOCtlSrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <winioctl.h>
#include <ntddcdvd.h>
#include <ntddcdrm.h>
#include <errno.h>
// "typedef ignored" warning will disappear once we move to the Windows 10 SDK.
#pragma warning(push)
#pragma warning(disable : 4091)
Expand Down Expand Up @@ -303,6 +304,38 @@ bool IOCtlSrc::ReadCDInfo()
return true;
}

bool IOCtlSrc::ReadTrackSubQ(cdvdSubQ* subQ) const
{
CDROM_SUB_Q_DATA_FORMAT format;
SUB_Q_CHANNEL_DATA osSubQ{};
DWORD unused;

format.Format = IOCTL_CDROM_CURRENT_POSITION;

if (!DeviceIoControl(m_device, IOCTL_CDROM_READ_Q_CHANNEL, &format, sizeof(format), &osSubQ, sizeof(osSubQ), &unused, nullptr))
{
Console.Error("SUB CHANNEL READ ERROR: %d\n", errno);
return false;
}
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];
}
weirdbeardgame marked this conversation as resolved.
Show resolved Hide resolved

return true;
}

bool IOCtlSrc::DiscReady()
{
if (m_device == INVALID_HANDLE_VALUE)
Expand Down