1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 18:30:21 +00:00

Enhances the Disk II's ability to sleep.

Also enables Disk II sleep observation in the Oric.
This commit is contained in:
Thomas Harte 2018-05-19 23:15:28 -04:00
parent 4952657b31
commit e482929da8
3 changed files with 31 additions and 10 deletions

View File

@ -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() {

View File

@ -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<uint8_t> &);

View File

@ -201,6 +201,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> 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 <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
Apple::DiskII diskii_;
std::vector<uint8_t> 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_;