mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-02-04 06:29:56 +00:00
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:
parent
6cfde29f00
commit
4bbc5ab0af
@ -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) {
|
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* out_ptr;
|
||||||
uint8_t start_track = cmd_ptr[6];
|
|
||||||
uint16_t alloc_len = READ_WORD_BE_U(&cmd_ptr[7]);
|
uint16_t alloc_len = READ_WORD_BE_U(&cmd_ptr[7]);
|
||||||
bool is_msf = !!(cmd_ptr[1] & 2);
|
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;
|
return 0;
|
||||||
|
|
||||||
switch(format) {
|
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
|
if (!start_track) { // special case: track zero (lead-in) as starting track
|
||||||
// return all tracks starting with track 1 plus lead-out
|
// return all tracks starting with track 1 plus lead-out
|
||||||
start_track = 1;
|
start_track = 1;
|
||||||
@ -207,6 +207,7 @@ uint32_t CdromDrive::read_toc(uint8_t *cmd_ptr, uint8_t *data_ptr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data_len;
|
return data_len;
|
||||||
|
}
|
||||||
case 1:
|
case 1:
|
||||||
std::memset(data_ptr, 0, 12);
|
std::memset(data_ptr, 0, 12);
|
||||||
data_ptr[1] = 10; // TOC data length
|
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
|
data_ptr[3] = 1; // last session number
|
||||||
return 12;
|
return 12;
|
||||||
case 2:
|
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);
|
LOG_F(ERROR, "CDROM: unsupported session number %d", session_num);
|
||||||
this->set_error(ScsiSense::ILLEGAL_REQ, ScsiError::INVALID_CDB);
|
this->set_error(ScsiSense::ILLEGAL_REQ, ScsiError::INVALID_CDB);
|
||||||
return 0;
|
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[3] = 1; // last session number
|
||||||
out_ptr += 4;
|
out_ptr += 4;
|
||||||
// descriptor #1 -> first track
|
// descriptor #1 -> first track
|
||||||
out_ptr[0] = session_num;
|
out_ptr[0] = 1;
|
||||||
out_ptr[1] = this->tracks[0].adr_ctrl;
|
out_ptr[1] = this->tracks[0].adr_ctrl;
|
||||||
out_ptr[3] = 0xA0; // point -> first track
|
out_ptr[3] = 0xA0; // point -> first track
|
||||||
out_ptr[8] = 1; // first track number
|
out_ptr[8] = 1; // first track number
|
||||||
out_ptr += 11;
|
out_ptr += 11;
|
||||||
// descriptor #2 -> last track
|
// descriptor #2 -> last track
|
||||||
out_ptr[0] = session_num;
|
out_ptr[0] = 1;
|
||||||
out_ptr[1] = this->tracks[0].adr_ctrl;
|
out_ptr[1] = this->tracks[0].adr_ctrl;
|
||||||
out_ptr[3] = 0xA1; // point -> last track
|
out_ptr[3] = 0xA1; // point -> last track
|
||||||
out_ptr[8] = 1; // last track number
|
out_ptr[8] = 1; // last track number
|
||||||
out_ptr += 11;
|
out_ptr += 11;
|
||||||
// descriptor #3 -> lead-out
|
// descriptor #3 -> lead-out
|
||||||
out_ptr[0] = session_num;
|
out_ptr[0] = 1;
|
||||||
out_ptr[1] = this->tracks[0].adr_ctrl;
|
out_ptr[1] = this->tracks[0].adr_ctrl;
|
||||||
out_ptr[3] = 0xA2; // point -> lead-out
|
out_ptr[3] = 0xA2; // point -> lead-out
|
||||||
if (is_msf) {
|
if (is_msf) {
|
||||||
@ -254,7 +257,7 @@ uint32_t CdromDrive::read_toc(uint8_t *cmd_ptr, uint8_t *data_ptr) {
|
|||||||
}
|
}
|
||||||
out_ptr += 11;
|
out_ptr += 11;
|
||||||
// descriptor #4 -> data track
|
// descriptor #4 -> data track
|
||||||
out_ptr[0] = session_num;
|
out_ptr[0] = 1;
|
||||||
out_ptr[1] = this->tracks[0].adr_ctrl;
|
out_ptr[1] = this->tracks[0].adr_ctrl;
|
||||||
out_ptr[3] = 1; // point -> data track
|
out_ptr[3] = 1; // point -> data track
|
||||||
if (is_msf) {
|
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;
|
out_ptr[10] = msf.frm;
|
||||||
}
|
}
|
||||||
return 48;
|
return 48;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
LOG_F(ERROR, "CDROM: unsupported format in READ_TOC");
|
LOG_F(ERROR, "CDROM: unsupported format in READ_TOC");
|
||||||
this->set_error(ScsiSense::ILLEGAL_REQ, ScsiError::INVALID_CDB);
|
this->set_error(ScsiSense::ILLEGAL_REQ, ScsiError::INVALID_CDB);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user