1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-02 19:54:35 +00:00

Takes a first shot at INQUIRY.

This commit is contained in:
Thomas Harte 2019-09-07 22:04:44 -04:00
parent 6e0e9afe2f
commit 00ce7f8ae0
5 changed files with 51 additions and 20 deletions

View File

@ -24,3 +24,26 @@ bool DirectAccessDevice::read(const Target::CommandState &state, Target::Respond
return true;
}
bool DirectAccessDevice::inquiry(const Target::CommandState &state, Target::Responder &responder) {
if(!device_) return false;
std::vector<uint8_t> response = {
0x00, /* Peripheral device type: directly addressible. */
0x00, /* Non-removeable (0x80 = removeable). */
0x00, /* Version: does not claim conformance to any standard. */
0x00, /* Response data format: 0 for SCSI-1? */
0x00, /* Additional length. */
};
const auto allocated_bytes = state.allocated_inquiry_bytes();
if(allocated_bytes < response.size()) {
response.resize(allocated_bytes);
}
responder.send_data(std::move(response), [] (const Target::CommandState &state, Target::Responder &responder) {
responder.terminate_command(Target::Responder::Status::Good);
});
return true;
}

View File

@ -26,6 +26,7 @@ class DirectAccessDevice: public Target::Executor {
/* SCSI commands. */
bool read(const Target::CommandState &, Target::Responder &);
bool inquiry(const Target::CommandState &, Target::Responder &);
private:
std::shared_ptr<Storage::MassStorage::MassStorageDevice> device_;

View File

@ -39,3 +39,7 @@ uint16_t CommandState::number_of_blocks() const {
return uint16_t((data_[7] << 8) | data_[8]);
}
}
size_t CommandState::allocated_inquiry_bytes() const {
return size_t(((data_[4] - 1) & 0xff) + 1);
}

View File

@ -24,9 +24,13 @@ class CommandState {
public:
CommandState(const std::vector<uint8_t> &data);
// For read and write commands.
uint32_t address() const;
uint16_t number_of_blocks() const;
// For inquiry commands.
size_t allocated_inquiry_bytes() const;
private:
const std::vector<uint8_t> &data_;
};
@ -88,12 +92,6 @@ struct Responder {
responder.end_command();
});
});
// send_message(Target::Responder::Message::CommandComplete, [status] (const Target::CommandState &state, Target::Responder &responder) {
// responder.send_status(status, [] (const Target::CommandState &state, Target::Responder &responder) {
// responder.end_command();
// });
// });
}
};

View File

@ -73,9 +73,12 @@ template <typename Executor> void Target<Executor>::scsi_bus_did_change(Bus *, B
command_[command_pointer_] = uint8_t(new_state);
++command_pointer_;
if(command_pointer_ == command_.size()) {
dispatch_command();
// TODO: if(!dispatch_command()) signal_error_somehow();
if(!dispatch_command()) {
// This is just a guess for now; I don't know how SCSI
// devices are supposed to respond if they don't support
// a command.
terminate_command(Responder::Status::TaskAborted);
}
}
}
break;
@ -103,9 +106,9 @@ template <typename Executor> void Target<Executor>::scsi_bus_did_change(Bus *, B
case 0:
if(data_pointer_ == data_.size()) {
next_function_(CommandState(command_), *this);
} else {
bus_state_ |= Line::Request;
}
bus_state_ |= Line::Request;
break;
}
set_device_output(bus_state_);
@ -129,16 +132,16 @@ template <typename Executor> void Target<Executor>::scsi_bus_did_change(Bus *, B
(phase_ == Phase::SendingData && data_pointer_ == data_.size())
) {
next_function_(CommandState(command_), *this);
}
} else {
bus_state_ |= Line::Request;
bus_state_ &= ~0xff;
bus_state_ |= Line::Request;
bus_state_ &= ~0xff;
switch(phase_) {
case Phase::SendingData: bus_state_ |= data_[data_pointer_]; break;
case Phase::SendingStatus: bus_state_ |= BusState(status_); break;
default:
case Phase::SendingMessage: bus_state_ |= BusState(message_); break;
switch(phase_) {
case Phase::SendingData: bus_state_ |= data_[data_pointer_]; break;
case Phase::SendingStatus: bus_state_ |= BusState(status_); break;
default:
case Phase::SendingMessage: bus_state_ |= BusState(message_); break;
}
}
break;
}
@ -171,6 +174,8 @@ template <typename Executor> bool Target<Executor>::dispatch_command() {
#define G1(x) (0x20|x)
#define G5(x) (0xa0|x)
printf("---Command %02x---\n", command_[0]);
switch(command_[0]) {
default: return false;