mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-12 15:31:09 +00:00
Attempt implementation of disk sync.
This commit is contained in:
parent
3ceb378b9b
commit
c9bf2dda16
@ -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");
|
||||
|
@ -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<uint16_t, 4> 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 {
|
||||
|
@ -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_);
|
||||
|
||||
if(state_ == State::Reading) {
|
||||
buffer_[buffer_write_ & 3] = value;
|
||||
if(buffer_write_ == buffer_read_ + 4) {
|
||||
++buffer_read_;
|
||||
}
|
||||
++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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user