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

Cdrom misc #1023

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 2 additions & 0 deletions src/cdrom/cdriso.cc
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ bool PCSX::CDRIso::open(void) {
PCSX::g_system->printf("[2048]");
m_isMode1ISO = true;
}
} else {
m_isMode1ISO = false;
}
m_cdHandle->rSeek(0, SEEK_SET);
}
Expand Down
1 change: 1 addition & 0 deletions src/cdrom/cdriso.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class CDRIso {
unsigned m_cdrIsoMultidiskSelect;

bool CheckSBI(const uint8_t* time);
bool IsMode1ISO() { return m_isMode1ISO; }

private:
bool open();
Expand Down
132 changes: 82 additions & 50 deletions src/core/cdrom.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ class CDRomImpl : public PCSX::CDRom {
STATUS_SEEK = 1 << 6, // 0x40
STATUS_READ = 1 << 5, // 0x20
STATUS_SHELLOPEN = 1 << 4, // 0x10
STATUS_UNKNOWN3 = 1 << 3, // 0x08
STATUS_UNKNOWN2 = 1 << 2, // 0x04
STATUS_IDERROR = 1 << 3, // 0x08
STATUS_SEEKERROR = 1 << 2, // 0x04
STATUS_ROTATING = 1 << 1, // 0x02
STATUS_ERROR = 1 << 0, // 0x01
};
Expand All @@ -128,6 +128,20 @@ class CDRomImpl : public PCSX::CDRom {
ERROR_INVALIDARG = 1 << 5, // 0x20
};

/* Disc Flags */
enum {
FLAG_CDDA = 1 << 4, // 0x10
FLAG_NODISC = 1 << 6, // 0x40
FLAG_UNLICENSED = 1 << 7, // 0x80
};

/* Disc Types */
enum {
DISCTYPE_CDROM = 0x00,
DISCTYPE_CDI = 0x10,
DISCTYPE_CDROMXA = 0x20,
};

// 1x = 75 sectors per second
// PCSX::g_emulator->m_psxClockSpeed = 1 sec in the ps
// so (PCSX::g_emulator->m_psxClockSpeed / 75) = m_cdr read time (linuzappz)
Expand Down Expand Up @@ -297,6 +311,9 @@ class CDRomImpl : public PCSX::CDRom {
StopCdda();
m_driveState = DRIVESTATE_LID_OPEN;
scheduleCDLidIRQ(8 * irqReschedule);
}else if (cdr_stat.Type == magic_enum::enum_integer(TrackType::CLOSED) || cdr_stat.Type == 0xff) {
// No Disc
m_statP &= ~(STATUS_PLAY | STATUS_READ | STATUS_ROTATING);
}
break;

Expand Down Expand Up @@ -572,9 +589,10 @@ class CDRomImpl : public PCSX::CDRom {
}

m_ctrl &= ~BUSYSTS; // Command/parameter transmission not busy

// default response
SetResultSize(1);
memset(m_result, 0, sizeof(m_result)); // Clear result buffer
m_result[0] = m_statP;
m_stat = Acknowledge;

Expand Down Expand Up @@ -655,32 +673,44 @@ class CDRomImpl : public PCSX::CDRom {
break;

case CdlForward:
// TODO: error 80 if stopped
m_stat = Complete;
m_suceeded = true;

// GameShark CD Player: Calls 2x + Play 2x
if (m_fastForward == 0) {
m_fastForward = 2;
if ((m_statP & STATUS_PLAY) == 0) {
SetResultSize(2);
m_stat = DiskError;
m_result[0] += 1;
m_result[1] = ERROR_NOTREADY;
} else {
m_fastForward++;
// GameShark CD Player: Calls 2x + Play 2x
if (m_fastForward == 0) {
m_fastForward = 2;
} else {
m_fastForward++;
}

m_fastBackward = 0;

m_stat = Acknowledge;
m_suceeded = true;
}

m_fastBackward = 0;
break;

case CdlBackward:
m_stat = Complete;
m_suceeded = true;

// GameShark CD Player: Calls 2x + Play 2x
if (m_fastBackward == 0) {
m_fastBackward = 2;
if ((m_statP & STATUS_PLAY) == 0) {
SetResultSize(2);
m_stat = DiskError;
m_result[0] += 1;
m_result[1] = ERROR_NOTREADY;
} else {
m_fastBackward++;
// GameShark CD Player: Calls 2x + Play 2x
if (m_fastBackward == 0) {
m_fastBackward = 2;
} else {
m_fastBackward++;
}
m_fastForward = 0;

m_stat = Acknowledge;
m_suceeded = true;
}

m_fastForward = 0;
break;

case CdlStandby:
Expand Down Expand Up @@ -840,10 +870,9 @@ class CDRomImpl : public PCSX::CDRom {
m_result[0] |= STATUS_ERROR;
} else {
m_track = PCSX::IEC60908b::btoi(m_param[0]);
SetResultSize(4);
SetResultSize(3);
m_stat = Acknowledge;
MSF td = m_iso->getTD(m_track);
m_result[0] = m_statP;
m_result[1] = PCSX::IEC60908b::itob(td.m);
m_result[2] = PCSX::IEC60908b::itob(td.s);
}
Expand Down Expand Up @@ -898,34 +927,31 @@ class CDRomImpl : public PCSX::CDRom {
break;

case CdlID + 0x100:
SetResultSize(8);
SetResultSize(8); // m_result = {stat,flags,type,atip,"PCSX"}

if (m_iso->failed()) {
m_result[0] = 0x08;
m_result[1] = 0x40;
memset((char *)&m_result[2], 0, 6);
// No Disc
getStatus(&cdr_stat);
if (cdr_stat.Type == magic_enum::enum_integer(TrackType::CLOSED) || cdr_stat.Type == 0xff) {
m_result[0] |= STATUS_IDERROR;
m_result[1] = FLAG_NODISC;
m_stat = DiskError;
break;
}
} else {
if (isBootable()) {
strncpy((char *)&m_result[4], "PCSX", 4);
m_stat = Complete;
} else {
m_result[0] |= STATUS_IDERROR;
m_result[1] |= FLAG_UNLICENSED;
m_stat = DiskError;
}

m_result[0] = m_statP;
m_result[1] = 0;
m_result[2] = 0;
m_result[3] = 0;
if (cdr_stat.Type == magic_enum::enum_integer(TrackType::CDDA)) {
m_result[1] |= FLAG_CDDA; // Audio
}

// 0x10 - audio | 0x40 - disk missing | 0x80 - unlicensed
getStatus(&cdr_stat);
if (cdr_stat.Type == 0 || cdr_stat.Type == 0xff) {
m_result[1] = 0xc0;
} else {
// Audio, unlicensed
if (cdr_stat.Type == 2) m_result[1] |= (0x10 | 0x80);
m_result[2] = m_iso->IsMode1ISO() ? DISCTYPE_CDROM : DISCTYPE_CDROMXA;
m_suceeded = true;
}
m_result[0] |= (m_result[1] >> 4) & 0x08;

strncpy((char *)&m_result[4], "PCSX", 4);
m_stat = Complete;
m_suceeded = true;
break;

case CdlInit:
Expand Down Expand Up @@ -1556,16 +1582,15 @@ class CDRomImpl : public PCSX::CDRom {
m_transferIndex = 0;
m_reg2 = 0x1f;
m_stat = NoIntr;
m_driveState = DRIVESTATE_STANDBY;
m_driveState = DRIVESTATE_RESCAN_CD;
scheduleCDLidIRQ(cdReadTime * 105);
m_statP = STATUS_ROTATING;

// BIOS player - default values
m_attenuatorLeftToLeft = 0x80;
m_attenuatorLeftToRight = 0x00;
m_attenuatorRightToLeft = 0x00;
m_attenuatorRightToRight = 0x80;

getCdInfo();
}

void load() final {
Expand Down Expand Up @@ -1663,6 +1688,7 @@ PCSX::CDRom *PCSX::CDRom::factory() { return new CDRomImpl; }
void PCSX::CDRom::check() {
m_cdromId.clear();
m_cdromLabel.clear();
m_bootable = false;
ISO9660Reader reader(m_iso);
if (reader.failed()) return;
IO<File> systemcnf(reader.open("SYSTEM.CNF;1"));
Expand Down Expand Up @@ -1694,16 +1720,22 @@ void PCSX::CDRom::check() {
m_cdromId += filename.substr(9, 2);
}

if (filename.size() > 0) {
m_bootable = true;
}

break;
}
} else {
IO<File> psxexe(reader.open("PSX.EXE;1"));
if (!psxexe->failed()) {
m_cdromId = "SLUS99999";
exename = "PSX.EXE;1";
m_bootable = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the check function should display a warning at the end that the disc isn't bootable in case this boolean is still false.

}
}

g_system->printf(_("CD-ROM is %s\n"), m_bootable ? _("Bootable") : _("Not Bootable"));
g_system->printf(_("CD-ROM Label: %.32s\n"), m_cdromLabel);
g_system->printf(_("CD-ROM ID: %.9s\n"), m_cdromId);
g_system->printf(_("CD-ROM EXE Name: %.255s\n"), exename);
Expand Down
3 changes: 3 additions & 0 deletions src/core/cdrom.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ struct CdrStat {

class CDRom {
public:
using TrackType = PCSX::CDRIso::TrackType;
using MSF = PCSX::IEC60908b::MSF;
CDRom() : m_iso(new CDRIso()) {}
virtual ~CDRom() {}
static CDRom* factory();
bool isBootable() { return m_bootable; }
bool isLidOpened() { return m_lidOpenTime < 0 || m_lidOpenTime > (int64_t)time(nullptr); }
void setLidOpenTime(int64_t time) { m_lidOpenTime = time; }
void check();
Expand Down Expand Up @@ -163,6 +165,7 @@ class CDRom {
friend class Widgets::IsoBrowser;
std::string m_cdromId;
std::string m_cdromLabel;
bool m_bootable;
};

} // namespace PCSX