From c9bf2dda164ff7b64d30f45862fa88a272017397 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 2 Nov 2021 18:18:59 -0700 Subject: [PATCH] Attempt implementation of disk sync. --- Machines/Amiga/Chipset.cpp | 2 +- Machines/Amiga/Chipset.hpp | 10 +++++++++- Machines/Amiga/Disk.cpp | 25 ++++++++++++++++--------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Machines/Amiga/Chipset.cpp b/Machines/Amiga/Chipset.cpp index fae7212c5..d244c673c 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -670,6 +670,7 @@ void Chipset::perform(const CPU::MC68000::Microcycle &cycle) { ApplySetClear(paula_disk_control_, 0x7fff); disk_controller_.set_control(paula_disk_control_); + disk_.set_control(paula_disk_control_); // TODO: should also post to Paula. break; case Read(0x010): // ADKCONR @@ -679,7 +680,6 @@ void Chipset::perform(const CPU::MC68000::Microcycle &cycle) { case Write(0x07e): // DSKSYNC disk_controller_.set_sync_word(cycle.value16()); - assert(false); // Not fully implemented. break; case Read(0x01a): // DSKBYTR LOG("TODO: disk status"); diff --git a/Machines/Amiga/Chipset.hpp b/Machines/Amiga/Chipset.hpp index 88903848e..7fbee2ca3 100644 --- a/Machines/Amiga/Chipset.hpp +++ b/Machines/Amiga/Chipset.hpp @@ -383,7 +383,8 @@ class Chipset: private ClockingHint::Observer { public: using DMADevice::DMADevice; - void set_length(uint16_t value); + void set_length(uint16_t); + void set_control(uint16_t); bool advance(); void enqueue(uint16_t value, bool matches_sync); @@ -393,9 +394,16 @@ class Chipset: private ClockingHint::Observer { bool dma_enable_ = false; bool write_ = false; uint16_t last_set_length_ = 0; + bool sync_with_word_ = false; std::array buffer_; size_t buffer_read_ = 0, buffer_write_ = 0; + + enum class State { + Inactive, + WaitingForSync, + Reading, + } state_ = State::Inactive; } disk_; class DiskController: public Storage::Disk::Controller { diff --git a/Machines/Amiga/Disk.cpp b/Machines/Amiga/Disk.cpp index 4e3eb074b..7e18ff580 100644 --- a/Machines/Amiga/Disk.cpp +++ b/Machines/Amiga/Disk.cpp @@ -16,18 +16,22 @@ using namespace Amiga; // MARK: - Disk DMA. void Chipset::DiskDMA::enqueue(uint16_t value, bool matches_sync) { - if(matches_sync) { - // TODO: start buffering from the next word onwards if - // syncing is enabled. + if(matches_sync && state_ == State::WaitingForSync) { + state_ = State::Reading; + return; } -// LOG("In: " << buffer_write_); - - buffer_[buffer_write_ & 3] = value; - if(buffer_write_ == buffer_read_ + 4) { - ++buffer_read_; + if(state_ == State::Reading) { + buffer_[buffer_write_ & 3] = value; + if(buffer_write_ == buffer_read_ + 4) { + ++buffer_read_; + } + ++buffer_write_; } - ++buffer_write_; +} + +void Chipset::DiskDMA::set_control(uint16_t control) { + sync_with_word_ = control & 0x400; } void Chipset::DiskDMA::set_length(uint16_t value) { @@ -40,6 +44,8 @@ void Chipset::DiskDMA::set_length(uint16_t value) { if(dma_enable_) { LOG("Disk DMA " << (write_ ? "write" : "read") << " of " << length_ << " to " << PADHEX(8) << pointer_[0]); } + + state_ = sync_with_word_ ? State::WaitingForSync : State::Reading; } last_set_length_ = value; @@ -57,6 +63,7 @@ bool Chipset::DiskDMA::advance() { if(!length_) { chipset_.posit_interrupt(InterruptFlag::DiskBlock); + state_ = State::Inactive; } return true;