1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-29 12:50:28 +00:00

Handles SCSI changes on-demand.

This commit is contained in:
Thomas Harte 2021-01-31 21:24:54 -05:00
parent 07df7572b3
commit 274b3c7d24

View File

@ -45,7 +45,9 @@ template <bool has_scsi_bus> class ConcreteMachine:
public CPU::MOS6502::BusHandler,
public Tape::Delegate,
public Utility::TypeRecipient<CharacterMapper>,
public Activity::Source {
public Activity::Source,
public SCSI::Bus::Observer,
public ClockingHint::Observer {
public:
ConcreteMachine(const Analyser::Static::Acorn::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
m6502_(*this),
@ -143,6 +145,11 @@ template <bool has_scsi_bus> class ConcreteMachine:
if(target.should_shift_restart) {
shift_restart_counter_ = 1000000;
}
if(has_scsi_bus) {
scsi_bus_.add_observer(this);
scsi_bus_.set_clocking_hint_observer(this);
}
}
~ConcreteMachine() {
@ -498,13 +505,9 @@ template <bool has_scsi_bus> class ConcreteMachine:
}
}
// TODO: clock/change observe.
if(has_scsi_bus) {
if constexpr (has_scsi_bus) {
if(scsi_is_clocked_) {
scsi_bus_.run_for(Cycles(int(cycles)));
if(scsi_acknowledge_ && !(scsi_bus_.get_state() & SCSI::Line::Request)) {
scsi_acknowledge_ = false;
push_scsi_output();
}
}
@ -541,6 +544,18 @@ template <bool has_scsi_bus> class ConcreteMachine:
m6502_.run_for(cycles);
}
void scsi_bus_did_change(SCSI::Bus *, SCSI::BusState new_state, double) final {
// Release acknowledge when request is released.
if(scsi_acknowledge_ && !(new_state & SCSI::Line::Request)) {
scsi_acknowledge_ = false;
push_scsi_output();
}
}
void set_component_prefers_clocking(ClockingHint::Source *, ClockingHint::Preference preference) final {
scsi_is_clocked_ = preference != ClockingHint::Preference::None;
}
void tape_did_change_interrupt_status(Tape *) final {
interrupt_status_ = (interrupt_status_ & ~(Interrupt::TransmitDataEmpty | Interrupt::ReceiveDataFull | Interrupt::HighToneDetect)) | tape_.get_interrupt_status();
evaluate_interrupts();
@ -745,6 +760,7 @@ template <bool has_scsi_bus> class ConcreteMachine:
uint8_t scsi_data_ = 0;
bool scsi_select_ = false;
bool scsi_acknowledge_ = false;
bool scsi_is_clocked_ = false;
void push_scsi_output() {
scsi_bus_.set_device_output(scsi_device_,
scsi_data_ |