diff --git a/Components/DiskII/DiskII.cpp b/Components/DiskII/DiskII.cpp index b71c9238b..75c93bc1f 100644 --- a/Components/DiskII/DiskII.cpp +++ b/Components/DiskII/DiskII.cpp @@ -126,10 +126,19 @@ void DiskII::run_for(const Cycles cycles) { void DiskII::set_controller_can_sleep() { // Permit the controller to sleep if it's in sense write protect mode, and the shift register // has already filled with the result of shifting eight times. + bool controller_could_sleep = controller_can_sleep_; controller_can_sleep_ = - (inputs_ == (input_command | input_flux)) && - (shift_register_ == (is_write_protected() ? 0xff : 0x00)); - if(is_sleeping()) update_sleep_observer(); + ( + (inputs_ == input_flux) && + !motor_is_enabled_ && + !shift_register_ + ) || + ( + (inputs_ == (input_command | input_flux)) && + (shift_register_ == (is_write_protected() ? 0xff : 0x00)) + ); + if(controller_could_sleep != controller_can_sleep_) + update_sleep_observer(); } bool DiskII::is_write_protected() { diff --git a/Components/DiskII/DiskII.hpp b/Components/DiskII/DiskII.hpp index f85a5ab49..ee81e0892 100644 --- a/Components/DiskII/DiskII.hpp +++ b/Components/DiskII/DiskII.hpp @@ -61,10 +61,14 @@ class DiskII: the implementation as to the content of this ROM. Including: - If Q6 is set and Q7 is reset, the controller is testing + * If Q6 is set and Q7 is reset, the controller is testing for write protect. If and when the shift register has become full with the state of the write protect value, no further processing is required. + + * If both Q6 and Q7 are reset, the drive motor is disabled, + and the shift register is all zeroes, no further processing + is required. */ void set_state_machine(const std::vector &); diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index b37124de4..4e4ebf153 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -201,6 +201,7 @@ template class Co public Utility::TypeRecipient, public Storage::Tape::BinaryTapePlayer::Delegate, public Microdisc::Delegate, + public Sleeper::SleepObserver, public Activity::Source, public Machine { @@ -216,6 +217,10 @@ template class Co via_port_handler_.set_interrupt_delegate(this); tape_player_.set_delegate(this); Memory::Fuzz(ram_, sizeof(ram_)); + + if(disk_interface == Analyser::Static::Oric::Target::DiskInterface::Pravetz) { + diskii_.set_sleep_observer(this); + } } ~ConcreteMachine() { @@ -439,8 +444,10 @@ template class Co microdisc_.run_for(Cycles(8)); break; case Analyser::Static::Oric::Target::DiskInterface::Pravetz: - diskii_.set_data_input(*value); - diskii_.run_for(Cycles(2)); + if(!diskii_is_sleeping_) { + diskii_.set_data_input(*value); + diskii_.run_for(Cycles(2)); + } break; } cycles_since_video_update_++; @@ -564,6 +571,10 @@ template class Co } } + void set_component_is_sleeping(Sleeper *component, bool is_sleeping) override final { + diskii_is_sleeping_ = diskii_.is_sleeping(); + } + private: const uint16_t basic_invisible_ram_top_ = 0xffff; const uint16_t basic_visible_ram_top_ = 0xbfff; @@ -608,10 +619,7 @@ template class Co Apple::DiskII diskii_; std::vector pravetz_rom_; std::size_t pravetz_rom_base_pointer_ = 0; -// Cycles cycles_since_diskii_update_; -// void update_diskii() { -// diskii_.run_for(cycles_since_diskii_update_.flush()); -// } + bool diskii_is_sleeping_ = false; // Overlay RAM uint16_t ram_top_ = basic_visible_ram_top_;