diff --git a/Machines/Oric/Microdisc.cpp b/Machines/Oric/Microdisc.cpp index a9701967e..a19966c30 100644 --- a/Machines/Oric/Microdisc.cpp +++ b/Machines/Oric/Microdisc.cpp @@ -22,10 +22,11 @@ Microdisc::Microdisc() : WD1770(P1793) { set_control_register(last_control_, 0xff); } -void Microdisc::set_disk(std::shared_ptr disk, int drive) { +void Microdisc::set_disk(std::shared_ptr disk, size_t drive) { if(!drives_[drive]) { drives_[drive].reset(new Storage::Disk::Drive(8000000, 300, 2)); if(drive == selected_drive_) set_drive(drives_[drive]); + drives_[drive]->set_activity_observer(observer_, "Drive" + std::to_string(drive), false); } drives_[drive]->set_disk(disk); } @@ -48,8 +49,8 @@ void Microdisc::set_control_register(uint8_t control, uint8_t changes) { // b4: side select if(changes & 0x10) { int head = (control & 0x10) ? 1 : 0; - for(int c = 0; c < 4; c++) { - if(drives_[c]) drives_[c]->set_head(head); + for(auto &drive : drives_) { + if(drive) drive->set_head(head); } } @@ -89,10 +90,12 @@ uint8_t Microdisc::get_data_request_register() { } void Microdisc::set_head_load_request(bool head_load) { + head_load_request_ = head_load; + // The drive motors (at present: I believe **all drive motors** regardless of the selected drive) receive // the current head load request state. - for(int c = 0; c < 4; c++) { - if(drives_[c]) drives_[c]->set_motor_on(head_load); + for(auto &drive : drives_) { + if(drive) drive->set_motor_on(head_load); } // A request to load the head results in a delay until the head is confirmed loaded. This delay is handled @@ -103,6 +106,10 @@ void Microdisc::set_head_load_request(bool head_load) { head_load_request_counter_ = head_load_request_counter_target; set_head_loaded(head_load); } + + if(observer_) { + observer_->set_led_status("Microdisc", head_load); + } } void Microdisc::run_for(const Cycles cycles) { @@ -116,3 +123,16 @@ void Microdisc::run_for(const Cycles cycles) { bool Microdisc::get_drive_is_ready() { return true; } + +void Microdisc::set_activity_observer(Activity::Observer *observer) { + observer_ = observer; + if(observer) { + observer->register_led("Microdisc"); + observer_->set_led_status("Microdisc", head_load_request_); + } + size_t c = 0; + for(auto &drive : drives_) { + if(drive) drive->set_activity_observer(observer, "Drive" + std::to_string(c), false); + ++c; + } +} diff --git a/Machines/Oric/Microdisc.hpp b/Machines/Oric/Microdisc.hpp index 1ea325dc7..f8e847ff3 100644 --- a/Machines/Oric/Microdisc.hpp +++ b/Machines/Oric/Microdisc.hpp @@ -10,6 +10,9 @@ #define Microdisc_hpp #include "../../Components/1770/1770.hpp" +#include "../../Activity/Observer.hpp" + +#include namespace Oric { @@ -17,7 +20,7 @@ class Microdisc: public WD::WD1770 { public: Microdisc(); - void set_disk(std::shared_ptr disk, int drive); + void set_disk(std::shared_ptr disk, size_t drive); void set_control_register(uint8_t control); uint8_t get_interrupt_request_register(); uint8_t get_data_request_register(); @@ -39,17 +42,21 @@ class Microdisc: public WD::WD1770 { inline void set_delegate(Delegate *delegate) { delegate_ = delegate; WD1770::set_delegate(delegate); } inline int get_paging_flags() { return paging_flags_; } + void set_activity_observer(Activity::Observer *observer); + private: void set_control_register(uint8_t control, uint8_t changes); void set_head_load_request(bool head_load); bool get_drive_is_ready(); - std::shared_ptr drives_[4]; - int selected_drive_; + std::array, 4> drives_; + size_t selected_drive_; bool irq_enable_ = false; int paging_flags_ = BASICDisable; int head_load_request_counter_ = -1; + bool head_load_request_ = false; Delegate *delegate_ = nullptr; uint8_t last_control_ = 0; + Activity::Observer *observer_ = nullptr; }; } diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index c5a8492a9..b1d8b0a2e 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -12,6 +12,7 @@ #include "Microdisc.hpp" #include "Video.hpp" +#include "../../Activity/Source.hpp" #include "../ConfigurationTarget.hpp" #include "../CRTMachine.hpp" #include "../KeyboardMachine.hpp" @@ -200,6 +201,7 @@ template class Co public Utility::TypeRecipient, public Storage::Tape::BinaryTapePlayer::Delegate, public Microdisc::Delegate, + public Activity::Source, public Machine { public: @@ -329,10 +331,10 @@ template class Co switch(disk_interface) { case Analyser::Static::Oric::Target::DiskInterface::Microdisc: { inserted = true; - int drive_index = 0; + size_t drive_index = 0; for(auto &disk : media.disks) { if(drive_index < 4) microdisc_.set_disk(disk, drive_index); - drive_index++; + ++drive_index; } } break; case Analyser::Static::Oric::Target::DiskInterface::Pravetz: { @@ -340,7 +342,7 @@ template class Co int drive_index = 0; for(auto &disk : media.disks) { if(drive_index < 2) diskii_.set_disk(disk, drive_index); - drive_index++; + ++drive_index; } } break; @@ -551,6 +553,18 @@ template class Co return selection_set; } + void set_activity_observer(Activity::Observer *observer) override { + switch(disk_interface) { + default: break; + case Analyser::Static::Oric::Target::DiskInterface::Microdisc: + microdisc_.set_activity_observer(observer); + break; + case Analyser::Static::Oric::Target::DiskInterface::Pravetz: + diskii_.set_activity_observer(observer); + break; + } + } + private: const uint16_t basic_invisible_ram_top_ = 0xffff; const uint16_t basic_visible_ram_top_ = 0xbfff;