diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 45ef59fc9..d21e2190c 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -113,6 +113,9 @@ template class MOS6522: public MOS6522Base { /*! Gets a register value. */ uint8_t get_register(int address); + /*! @returns the bus handler. */ + T &bus_handler(); + private: T &bus_handler_; diff --git a/Components/6522/Implementation/6522Implementation.hpp b/Components/6522/Implementation/6522Implementation.hpp index eac2a0648..5efe8905e 100644 --- a/Components/6522/Implementation/6522Implementation.hpp +++ b/Components/6522/Implementation/6522Implementation.hpp @@ -145,6 +145,10 @@ template uint8_t MOS6522::get_port_input(Port port, uint8_t outp return (input & ~output_mask) | (output & output_mask); } +template T &MOS6522::bus_handler() { + return bus_handler_; +} + // Delegate and communications template void MOS6522::reevaluate_interrupts() { bool new_interrupt_status = get_interrupt_line(); diff --git a/Machines/Commodore/1540/Implementation/C1540.cpp b/Machines/Commodore/1540/Implementation/C1540.cpp index f08deb661..ec0140f71 100644 --- a/Machines/Commodore/1540/Implementation/C1540.cpp +++ b/Machines/Commodore/1540/Implementation/C1540.cpp @@ -108,6 +108,11 @@ void Machine::run_for(const Cycles cycles) { Storage::Disk::Controller::run_for(cycles); } +void MachineBase::set_activity_observer(Activity::Observer *observer) { + drive_VIA_.bus_handler().set_activity_observer(observer); + drive_->set_activity_observer(observer, "Drive", false); +} + // MARK: - 6522 delegate void MachineBase::mos6522_did_change_interrupt_status(void *mos6522) { @@ -209,8 +214,6 @@ void DriveVIA::set_delegate(Delegate *delegate) { } // write protect tab uncovered -DriveVIA::DriveVIA() : port_b_(0xff), port_a_(0xff), delegate_(nullptr) {} - uint8_t DriveVIA::get_port_input(MOS::MOS6522::Port port) { return port ? port_b_ : port_a_; } @@ -255,14 +258,22 @@ void DriveVIA::set_port_output(MOS::MOS6522::Port port, uint8_t value, uint8_t d delegate_->drive_via_did_set_data_density(this, (value >> 5)&3); } - // TODO: something with the drive LED -// printf("LED: %s\n", value&8 ? "On" : "Off"); + // post the LED status + if(observer_) observer_->set_led_status("Drive", !!(value&8)); previous_port_b_output_ = value; } } } +void DriveVIA::set_activity_observer(Activity::Observer *observer) { + observer_ = observer; + if(observer) { + observer->register_led("Drive"); + observer->set_led_status("Drive", !!(previous_port_b_output_&8)); + } +} + // MARK: - SerialPort void SerialPort::set_input(::Commodore::Serial::Line line, ::Commodore::Serial::LineLevel level) { diff --git a/Machines/Commodore/1540/Implementation/C1540Base.hpp b/Machines/Commodore/1540/Implementation/C1540Base.hpp index 3b54788e7..aef0b8686 100644 --- a/Machines/Commodore/1540/Implementation/C1540Base.hpp +++ b/Machines/Commodore/1540/Implementation/C1540Base.hpp @@ -14,6 +14,7 @@ #include "../../SerialBus.hpp" +#include "../../../../Activity/Source.hpp" #include "../../../../Storage/Disk/Disk.hpp" #include "../../../../Storage/Disk/Controller/DiskController.hpp" @@ -83,8 +84,6 @@ class DriveVIA: public MOS::MOS6522::IRQDelegatePortHandler { }; void set_delegate(Delegate *); - DriveVIA(); - uint8_t get_port_input(MOS::MOS6522::Port port); void set_sync_detected(bool); @@ -96,12 +95,15 @@ class DriveVIA: public MOS::MOS6522::IRQDelegatePortHandler { void set_port_output(MOS::MOS6522::Port, uint8_t value, uint8_t direction_mask); + void set_activity_observer(Activity::Observer *observer); + private: - uint8_t port_b_, port_a_; - bool should_set_overflow_; - bool drive_motor_; - uint8_t previous_port_b_output_; - Delegate *delegate_; + uint8_t port_b_ = 0xff, port_a_ = 0xff; + bool should_set_overflow_ = false; + bool drive_motor_ = false; + uint8_t previous_port_b_output_ = 0; + Delegate *delegate_ = nullptr; + Activity::Observer *observer_ = nullptr; }; /*! @@ -135,6 +137,9 @@ class MachineBase: void drive_via_did_step_head(void *driveVIA, int direction); void drive_via_did_set_data_density(void *driveVIA, int density); + /// Attaches the activity observer to this C1540. + void set_activity_observer(Activity::Observer *observer); + protected: CPU::MOS6502::Processor m6502_; std::shared_ptr drive_; diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index e119014bd..d2066ec9e 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -10,6 +10,7 @@ #include "Keyboard.hpp" +#include "../../../Activity/Source.hpp" #include "../../ConfigurationTarget.hpp" #include "../../CRTMachine.hpp" #include "../../KeyboardMachine.hpp" @@ -303,7 +304,8 @@ class ConcreteMachine: public Utility::TypeRecipient, public Storage::Tape::BinaryTapePlayer::Delegate, public Machine, - public Sleeper::SleepObserver { + public Sleeper::SleepObserver, + public Activity::Source { public: ConcreteMachine() : m6502_(*this), @@ -752,6 +754,11 @@ class ConcreteMachine: set_use_fast_tape(); } + // MARK: - Activity Source + void set_activity_observer(Activity::Observer *observer) override { + if(c1540_) c1540_->set_activity_observer(observer); + } + private: void update_video() { mos6560_->run_for(cycles_since_mos6560_update_.flush());