CD-ROM: Fix interpretation of session number.

In Read TOC format 2, Mac OS X passes zero for Session Number. I believe Read TOC is supposed to return the first session starting from that number so it should return info for Session 1 as it would if Mac OS X passed 1 for the Session Number.
This commit is contained in:
joevt 2023-08-20 20:27:29 -07:00 committed by Maxim Poliakovski
parent 6cfde29f00
commit 4bbc5ab0af
1 changed files with 13 additions and 9 deletions

View File

@ -143,9 +143,7 @@ AddrMsf CdromDrive::lba_to_msf(const int lba) {
}
uint32_t CdromDrive::read_toc(uint8_t *cmd_ptr, uint8_t *data_ptr) {
int tot_tracks, data_len, session_num;
uint8_t* out_ptr;
uint8_t start_track = cmd_ptr[6];
uint16_t alloc_len = READ_WORD_BE_U(&cmd_ptr[7]);
bool is_msf = !!(cmd_ptr[1] & 2);
@ -159,7 +157,9 @@ uint32_t CdromDrive::read_toc(uint8_t *cmd_ptr, uint8_t *data_ptr) {
return 0;
switch(format) {
case 0:
case 0: {
int tot_tracks, data_len;
uint8_t start_track = cmd_ptr[6];
if (!start_track) { // special case: track zero (lead-in) as starting track
// return all tracks starting with track 1 plus lead-out
start_track = 1;
@ -207,6 +207,7 @@ uint32_t CdromDrive::read_toc(uint8_t *cmd_ptr, uint8_t *data_ptr) {
}
}
return data_len;
}
case 1:
std::memset(data_ptr, 0, 12);
data_ptr[1] = 10; // TOC data length
@ -214,8 +215,10 @@ uint32_t CdromDrive::read_toc(uint8_t *cmd_ptr, uint8_t *data_ptr) {
data_ptr[3] = 1; // last session number
return 12;
case 2:
session_num = cmd_ptr[6];
if (session_num != 1) {
{
// TOC
int session_num = cmd_ptr[6];
if (session_num > 1) {
LOG_F(ERROR, "CDROM: unsupported session number %d", session_num);
this->set_error(ScsiSense::ILLEGAL_REQ, ScsiError::INVALID_CDB);
return 0;
@ -228,19 +231,19 @@ uint32_t CdromDrive::read_toc(uint8_t *cmd_ptr, uint8_t *data_ptr) {
out_ptr[3] = 1; // last session number
out_ptr += 4;
// descriptor #1 -> first track
out_ptr[0] = session_num;
out_ptr[0] = 1;
out_ptr[1] = this->tracks[0].adr_ctrl;
out_ptr[3] = 0xA0; // point -> first track
out_ptr[8] = 1; // first track number
out_ptr += 11;
// descriptor #2 -> last track
out_ptr[0] = session_num;
out_ptr[0] = 1;
out_ptr[1] = this->tracks[0].adr_ctrl;
out_ptr[3] = 0xA1; // point -> last track
out_ptr[8] = 1; // last track number
out_ptr += 11;
// descriptor #3 -> lead-out
out_ptr[0] = session_num;
out_ptr[0] = 1;
out_ptr[1] = this->tracks[0].adr_ctrl;
out_ptr[3] = 0xA2; // point -> lead-out
if (is_msf) {
@ -254,7 +257,7 @@ uint32_t CdromDrive::read_toc(uint8_t *cmd_ptr, uint8_t *data_ptr) {
}
out_ptr += 11;
// descriptor #4 -> data track
out_ptr[0] = session_num;
out_ptr[0] = 1;
out_ptr[1] = this->tracks[0].adr_ctrl;
out_ptr[3] = 1; // point -> data track
if (is_msf) {
@ -265,6 +268,7 @@ uint32_t CdromDrive::read_toc(uint8_t *cmd_ptr, uint8_t *data_ptr) {
out_ptr[10] = msf.frm;
}
return 48;
}
default:
LOG_F(ERROR, "CDROM: unsupported format in READ_TOC");
this->set_error(ScsiSense::ILLEGAL_REQ, ScsiError::INVALID_CDB);