1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-26 19:17:52 +00:00

Introduces real hard disk images to the nascent world of SCSI.

This commit is contained in:
Thomas Harte
2019-08-25 17:03:41 -04:00
parent 30cef1ee22
commit ca08716c52
8 changed files with 74 additions and 46 deletions
@@ -10,13 +10,15 @@
using namespace SCSI;
bool DirectAccessDevice::read(const Target::CommandState &state, Target::Responder &responder) {
std::vector<uint8_t> data(512);
for(size_t c = 0; c < 512; ++c) {
data[c] = uint8_t(c);
}
responder.send_data(std::move(data), [] (const Target::CommandState &state, Target::Responder &responder) {
void DirectAccessDevice::set_storage(const std::shared_ptr<Storage::MassStorage::MassStorageDevice> &device) {
device_ = device;
}
bool DirectAccessDevice::read(const Target::CommandState &state, Target::Responder &responder) {
if(!device_) return false;
responder.send_data(device_->get_block(state.address()), [] (const Target::CommandState &state, Target::Responder &responder) {
responder.end_command();
});
@@ -10,12 +10,25 @@
#define SCSI_DirectAccessDevice_hpp
#include "Target.hpp"
#include "../MassStorageDevice.hpp"
#include <memory>
namespace SCSI {
class DirectAccessDevice: public Target::Executor {
public:
/*!
Sets the backing storage exposed by this direct-access device.
*/
void set_storage(const std::shared_ptr<Storage::MassStorage::MassStorageDevice> &device);
/* SCSI commands. */
bool read(const Target::CommandState &, Target::Responder &);
private:
std::shared_ptr<Storage::MassStorage::MassStorageDevice> device_;
};
}
+2 -2
View File
@@ -12,7 +12,7 @@ using namespace SCSI::Target;
CommandState::CommandState(const std::vector<uint8_t> &data) : data_(data) {}
uint32_t CommandState::address() {
uint32_t CommandState::address() const {
switch(data_.size()) {
default: return 0;
case 6:
@@ -30,7 +30,7 @@ uint32_t CommandState::address() {
}
}
uint16_t CommandState::number_of_blocks() {
uint16_t CommandState::number_of_blocks() const {
switch(data_.size()) {
default: return 0;
case 6:
+7 -3
View File
@@ -24,8 +24,8 @@ class CommandState {
public:
CommandState(const std::vector<uint8_t> &data);
uint32_t address();
uint16_t number_of_blocks();
uint32_t address() const;
uint16_t number_of_blocks() const;
private:
const std::vector<uint8_t> &data_;
@@ -134,9 +134,13 @@ template <typename Executor> class Target: public Bus::Observer, public Responde
*/
Target(Bus &bus, int scsi_id);
Executor executor;
inline Executor *operator->() {
return &executor_;
}
private:
Executor executor_;
// Bus::Observer.
void scsi_bus_did_change(Bus *, BusState new_state) final;
@@ -147,29 +147,29 @@ template <typename Executor> bool Target<Executor>::dispatch_command() {
switch(command_[0]) {
default: return false;
case G0(0x00): return executor.test_unit_ready(arguments, *this);
case G0(0x01): return executor.rezero_unit(arguments, *this);
case G0(0x03): return executor.request_sense(arguments, *this);
case G0(0x04): return executor.format_unit(arguments, *this);
case G0(0x08): return executor.read(arguments, *this);
case G0(0x0a): return executor.write(arguments, *this);
case G0(0x0b): return executor.seek(arguments, *this);
case G0(0x16): return executor.reserve_unit(arguments, *this);
case G0(0x17): return executor.release_unit(arguments, *this);
case G0(0x1c): return executor.read_diagnostic(arguments, *this);
case G0(0x1d): return executor.write_diagnostic(arguments, *this);
case G0(0x12): return executor.inquiry(arguments, *this);
case G0(0x00): return executor_.test_unit_ready(arguments, *this);
case G0(0x01): return executor_.rezero_unit(arguments, *this);
case G0(0x03): return executor_.request_sense(arguments, *this);
case G0(0x04): return executor_.format_unit(arguments, *this);
case G0(0x08): return executor_.read(arguments, *this);
case G0(0x0a): return executor_.write(arguments, *this);
case G0(0x0b): return executor_.seek(arguments, *this);
case G0(0x16): return executor_.reserve_unit(arguments, *this);
case G0(0x17): return executor_.release_unit(arguments, *this);
case G0(0x1c): return executor_.read_diagnostic(arguments, *this);
case G0(0x1d): return executor_.write_diagnostic(arguments, *this);
case G0(0x12): return executor_.inquiry(arguments, *this);
case G1(0x05): return executor.read_capacity(arguments, *this);
case G1(0x08): return executor.read(arguments, *this);
case G1(0x0a): return executor.write(arguments, *this);
case G1(0x0e): return executor.write_and_verify(arguments, *this);
case G1(0x0f): return executor.verify(arguments, *this);
case G1(0x11): return executor.search_data_equal(arguments, *this);
case G1(0x10): return executor.search_data_high(arguments, *this);
case G1(0x12): return executor.search_data_low(arguments, *this);
case G1(0x05): return executor_.read_capacity(arguments, *this);
case G1(0x08): return executor_.read(arguments, *this);
case G1(0x0a): return executor_.write(arguments, *this);
case G1(0x0e): return executor_.write_and_verify(arguments, *this);
case G1(0x0f): return executor_.verify(arguments, *this);
case G1(0x11): return executor_.search_data_equal(arguments, *this);
case G1(0x10): return executor_.search_data_high(arguments, *this);
case G1(0x12): return executor_.search_data_low(arguments, *this);
case G5(0x09): return executor.set_block_limits(arguments, *this);
case G5(0x09): return executor_.set_block_limits(arguments, *this);
}
#undef G0