mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-23 21:29:28 +00:00
scsicdrom: use READ_TOC implementation from cdromdrive.cpp
This commit is contained in:
parent
0831182e39
commit
55f91c5d3f
@ -200,6 +200,8 @@ public:
|
||||
this->bus_obj = bus_obj_ptr;
|
||||
}
|
||||
|
||||
void report_error(uint8_t sense_key, uint8_t asc);
|
||||
|
||||
protected:
|
||||
uint8_t cmd_buf[16] = {};
|
||||
uint8_t msg_buf[16] = {}; // TODO: clarify how big this one should be
|
||||
|
@ -34,6 +34,11 @@ using namespace std;
|
||||
|
||||
ScsiCdrom::ScsiCdrom(std::string name, int my_id) : CdromDrive(), ScsiDevice(name, my_id)
|
||||
{
|
||||
this->set_error_callback(
|
||||
[this](uint8_t sense_key, uint8_t asc) {
|
||||
this->report_error(sense_key, asc);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void ScsiCdrom::process_command()
|
||||
@ -85,7 +90,11 @@ void ScsiCdrom::process_command()
|
||||
|
||||
// CD-ROM specific commands
|
||||
case ScsiCommand::READ_TOC:
|
||||
this->read_toc();
|
||||
this->bytes_out = read_toc(cmd, this->data_buf);
|
||||
if (this->status == ScsiStatus::GOOD) {
|
||||
this->msg_buf[0] = ScsiMessage::COMMAND_COMPLETE;
|
||||
this->switch_phase(ScsiPhase::DATA_IN);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_F(ERROR, "%s: unsupported command 0x%X", this->name.c_str(), cmd[0]);
|
||||
@ -270,85 +279,6 @@ void ScsiCdrom::mode_select_6(uint8_t param_len)
|
||||
this->switch_phase(ScsiPhase::DATA_OUT);
|
||||
}
|
||||
|
||||
void ScsiCdrom::read_toc()
|
||||
{
|
||||
int tot_tracks;
|
||||
uint8_t start_track = this->cmd_buf[6];
|
||||
uint16_t alloc_len = (this->cmd_buf[7] << 8) + this->cmd_buf[8];
|
||||
bool is_msf = !!(this->cmd_buf[1] & 2);
|
||||
|
||||
if (this->cmd_buf[2] & 0xF) {
|
||||
ABORT_F("%s: unsupported format in READ_TOC", this->name.c_str());
|
||||
}
|
||||
|
||||
if (!alloc_len) {
|
||||
LOG_F(WARNING, "%s: zero allocation length passed to READ_TOC", this->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
tot_tracks = this->num_tracks + 1;
|
||||
} else if (start_track == LEAD_OUT_TRK_NUM) {
|
||||
start_track = this->num_tracks + 1;
|
||||
tot_tracks = 1;
|
||||
} else if (start_track <= this->num_tracks) {
|
||||
tot_tracks = (this->num_tracks - start_track) + 2;
|
||||
} else {
|
||||
LOG_F(ERROR, "%s: invalid starting track %d in READ_TOC", this->name.c_str(),
|
||||
start_track);
|
||||
this->status = ScsiStatus::CHECK_CONDITION;
|
||||
this->sense = ScsiSense::ILLEGAL_REQ;
|
||||
this->asc = ScsiError::INVALID_CDB;
|
||||
this->ascq = 0;
|
||||
this->sksv = 0xc0; // sksv=1, C/D=Command, BPV=0, BP=0
|
||||
this->field = 6; // offset of start_track
|
||||
this->switch_phase(ScsiPhase::STATUS);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* buf_ptr = this->data_buf;
|
||||
|
||||
int data_len = (tot_tracks * 8) + 2;
|
||||
|
||||
// write TOC data header
|
||||
*buf_ptr++ = (data_len >> 8) & 0xFFU;
|
||||
*buf_ptr++ = (data_len >> 0) & 0xFFU;
|
||||
*buf_ptr++ = 1; // 1st track number
|
||||
*buf_ptr++ = this->num_tracks; // last track number
|
||||
|
||||
for (int tx = 0; tx < tot_tracks; tx++) {
|
||||
if ((buf_ptr - this->data_buf + 8) > alloc_len)
|
||||
break; // exit the loop if the output buffer length is exhausted
|
||||
|
||||
TrackDescriptor& td = this->tracks[start_track + tx - 1];
|
||||
|
||||
*buf_ptr++ = 0; // reserved
|
||||
*buf_ptr++ = td.adr_ctrl;
|
||||
*buf_ptr++ = td.trk_num;
|
||||
*buf_ptr++ = 0; // reserved
|
||||
|
||||
if (is_msf) {
|
||||
AddrMsf msf = lba_to_msf(td.start_lba + 150);
|
||||
*buf_ptr++ = 0; // reserved
|
||||
*buf_ptr++ = msf.min;
|
||||
*buf_ptr++ = msf.sec;
|
||||
*buf_ptr++ = msf.frm;
|
||||
} else {
|
||||
*buf_ptr++ = (td.start_lba >> 24) & 0xFFU;
|
||||
*buf_ptr++ = (td.start_lba >> 16) & 0xFFU;
|
||||
*buf_ptr++ = (td.start_lba >> 8) & 0xFFU;
|
||||
*buf_ptr++ = (td.start_lba >> 0) & 0xFFU;
|
||||
}
|
||||
}
|
||||
|
||||
this->bytes_out = alloc_len;
|
||||
this->msg_buf[0] = ScsiMessage::COMMAND_COMPLETE;
|
||||
|
||||
this->switch_phase(ScsiPhase::DATA_IN);
|
||||
}
|
||||
|
||||
void ScsiCdrom::read_capacity_10()
|
||||
{
|
||||
uint32_t lba = READ_DWORD_BE_U(&this->cmd_buf[2]);
|
||||
|
@ -48,7 +48,6 @@ protected:
|
||||
void mode_select_6(uint8_t param_len);
|
||||
|
||||
void mode_sense_6();
|
||||
void read_toc();
|
||||
void read_capacity_10();
|
||||
|
||||
private:
|
||||
|
@ -246,3 +246,12 @@ void ScsiDevice::illegal_command(const uint8_t *cmd) {
|
||||
this->field = 0;
|
||||
this->switch_phase(ScsiPhase::STATUS);
|
||||
}
|
||||
|
||||
void ScsiDevice::report_error(uint8_t sense_key, uint8_t asc) {
|
||||
this->status = ScsiStatus::CHECK_CONDITION;
|
||||
this->sense = sense_key;
|
||||
this->asc = asc;
|
||||
this->ascq = 0;
|
||||
this->sksv = 0xC0; // sksv=1, C/D=Command, BPV=0, BP=0
|
||||
this->switch_phase(ScsiPhase::STATUS);
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ uint32_t CdromDrive::read_toc(uint8_t *cmd_ptr, uint8_t *data_ptr) {
|
||||
out_ptr += 4;
|
||||
}
|
||||
}
|
||||
return data_len;
|
||||
return alloc_len;
|
||||
case 1: // Multi-session info
|
||||
std::memset(data_ptr, 0, 12);
|
||||
data_ptr[1] = 10; // TOC data length
|
||||
|
Loading…
Reference in New Issue
Block a user