mirror of
https://github.com/TomHarte/CLK.git
synced 2024-09-28 09:54:49 +00:00
Implements multi-sector read/write.
This once again unblocks Apple HD SC Setup. Progress!
This commit is contained in:
parent
210129c3a1
commit
2ce1f0a3b1
@ -27,6 +27,8 @@ void NCR5380::write(int address, uint8_t value, bool dma_acknowledge) {
|
|||||||
data_bus_ = value;
|
data_bus_ = value;
|
||||||
|
|
||||||
if(dma_request_ && dma_operation_ == DMAOperation::Send) {
|
if(dma_request_ && dma_operation_ == DMAOperation::Send) {
|
||||||
|
if(value)
|
||||||
|
printf("!");
|
||||||
printf("w %02x\n", value);
|
printf("w %02x\n", value);
|
||||||
dma_acknowledge_ = true;
|
dma_acknowledge_ = true;
|
||||||
dma_request_ = false;
|
dma_request_ = false;
|
||||||
|
@ -18,7 +18,15 @@ void DirectAccessDevice::set_storage(const std::shared_ptr<Storage::MassStorage:
|
|||||||
bool DirectAccessDevice::read(const Target::CommandState &state, Target::Responder &responder) {
|
bool DirectAccessDevice::read(const Target::CommandState &state, Target::Responder &responder) {
|
||||||
if(!device_) return false;
|
if(!device_) return false;
|
||||||
|
|
||||||
responder.send_data(device_->get_block(state.address()), [] (const Target::CommandState &state, Target::Responder &responder) {
|
const auto specs = state.read_write_specs();
|
||||||
|
|
||||||
|
std::vector<uint8_t> output = device_->get_block(specs.address);
|
||||||
|
for(uint32_t offset = 1; offset < specs.number_of_blocks; ++offset) {
|
||||||
|
const auto next_block = device_->get_block(specs.address + offset);
|
||||||
|
std::copy(next_block.begin(), next_block.end(), std::back_inserter(output));
|
||||||
|
}
|
||||||
|
|
||||||
|
responder.send_data(std::move(output), [] (const Target::CommandState &state, Target::Responder &responder) {
|
||||||
responder.terminate_command(Target::Responder::Status::Good);
|
responder.terminate_command(Target::Responder::Status::Good);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -28,8 +36,16 @@ bool DirectAccessDevice::read(const Target::CommandState &state, Target::Respond
|
|||||||
bool DirectAccessDevice::write(const Target::CommandState &state, Target::Responder &responder) {
|
bool DirectAccessDevice::write(const Target::CommandState &state, Target::Responder &responder) {
|
||||||
if(!device_) return false;
|
if(!device_) return false;
|
||||||
|
|
||||||
responder.receive_data(device_->get_block_size(), [this] (const Target::CommandState &state, Target::Responder &responder) {
|
const auto specs = state.read_write_specs();
|
||||||
this->device_->set_block(state.address(), state.received_data());
|
|
||||||
|
responder.receive_data(device_->get_block_size() * specs.number_of_blocks, [this, specs] (const Target::CommandState &state, Target::Responder &responder) {
|
||||||
|
const auto received_data = state.received_data();
|
||||||
|
const auto block_size = device_->get_block_size();
|
||||||
|
for(uint32_t offset = 0; offset < specs.number_of_blocks; ++offset) {
|
||||||
|
// TODO: clean up this gross inefficiency when std::span is standard.
|
||||||
|
std::vector<uint8_t> sub_vector(received_data.begin() + size_t(offset)*block_size, received_data.begin() + size_t(offset+1)*block_size);
|
||||||
|
this->device_->set_block(specs.address + offset, sub_vector);
|
||||||
|
}
|
||||||
responder.terminate_command(Target::Responder::Status::Good);
|
responder.terminate_command(Target::Responder::Status::Good);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -40,6 +40,15 @@ uint16_t CommandState::number_of_blocks() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandState::ReadWrite CommandState::read_write_specs() const {
|
||||||
|
ReadWrite specs;
|
||||||
|
|
||||||
|
specs.address = address();
|
||||||
|
specs.number_of_blocks = number_of_blocks();
|
||||||
|
|
||||||
|
return specs;
|
||||||
|
}
|
||||||
|
|
||||||
size_t CommandState::allocated_inquiry_bytes() const {
|
size_t CommandState::allocated_inquiry_bytes() const {
|
||||||
// 0 means 256 bytes allocated for inquiry.
|
// 0 means 256 bytes allocated for inquiry.
|
||||||
return size_t(((data_[4] - 1) & 0xff) + 1);
|
return size_t(((data_[4] - 1) & 0xff) + 1);
|
||||||
|
@ -26,8 +26,11 @@ class CommandState {
|
|||||||
CommandState(const std::vector<uint8_t> &command, const std::vector<uint8_t> &received);
|
CommandState(const std::vector<uint8_t> &command, const std::vector<uint8_t> &received);
|
||||||
|
|
||||||
// For read and write commands.
|
// For read and write commands.
|
||||||
uint32_t address() const;
|
struct ReadWrite {
|
||||||
uint16_t number_of_blocks() const;
|
uint32_t address;
|
||||||
|
uint16_t number_of_blocks;
|
||||||
|
};
|
||||||
|
ReadWrite read_write_specs() const;
|
||||||
|
|
||||||
// For inquiry commands.
|
// For inquiry commands.
|
||||||
size_t allocated_inquiry_bytes() const;
|
size_t allocated_inquiry_bytes() const;
|
||||||
@ -73,6 +76,8 @@ class CommandState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint32_t address() const;
|
||||||
|
uint16_t number_of_blocks() const;
|
||||||
const std::vector<uint8_t> &data_;
|
const std::vector<uint8_t> &data_;
|
||||||
const std::vector<uint8_t> &received_;
|
const std::vector<uint8_t> &received_;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user