diff --git a/Components/1770/1770.cpp b/Components/1770/1770.cpp index 65491fcff..609984826 100644 --- a/Components/1770/1770.cpp +++ b/Components/1770/1770.cpp @@ -108,8 +108,9 @@ uint8_t WD1770::get_register(int address) if(!has_motor_on_line()) { - // TODO: sample ready line for bit 7 - // TODO: report head loaded if reporting a Type 1 status + status |= get_drive_is_ready() ? 0 : Flag::NotReady; + if(status_.type == Status::One) + status |= (head_is_loaded_ ? Flag::HeadLoaded : 0); } else { @@ -365,7 +366,7 @@ void WD1770::posit_event(Event new_event_type) } set_head_load_request(true); if(head_is_loaded_) goto test_type1_type; - WAIT_FOR_EVENT(Event::HeadLoaded); + WAIT_FOR_EVENT(Event::HeadLoad); goto test_type1_type; begin_type1_spin_up: @@ -477,7 +478,7 @@ void WD1770::posit_event(Event new_event_type) begin_type2_load_head: set_head_load_request(true); if(head_is_loaded_) goto test_type2_delay; - WAIT_FOR_EVENT(Event::HeadLoaded); + WAIT_FOR_EVENT(Event::HeadLoad); goto test_type2_delay; begin_type2_spin_up: @@ -609,5 +610,5 @@ void WD1770::set_head_load_request(bool head_load) {} void WD1770::set_head_loaded(bool head_loaded) { head_is_loaded_ = head_loaded; - if(head_loaded) posit_event(Event::HeadLoaded); + if(head_loaded) posit_event(Event::HeadLoad); } diff --git a/Components/1770/1770.hpp b/Components/1770/1770.hpp index 3ad6c72a2..86bf87f7c 100644 --- a/Components/1770/1770.hpp +++ b/Components/1770/1770.hpp @@ -30,10 +30,12 @@ class WD1770: public Storage::Disk::Controller { void run_for_cycles(unsigned int number_of_cycles); enum Flag: uint8_t { + NotReady = 0x80, MotorOn = 0x80, WriteProtect = 0x40, RecordType = 0x20, SpinUp = 0x20, + HeadLoaded = 0x20, RecordNotFound = 0x10, SeekError = 0x10, CRCError = 0x08, @@ -106,7 +108,7 @@ class WD1770: public Storage::Disk::Controller { Command = (1 << 0), // Indicates receipt of a new command. Token = (1 << 1), // Indicates recognition of a new token in the flux stream. Interrogate latest_token_ for details. IndexHole = (1 << 2), // Indicates the passing of a physical index hole. - HeadLoaded = (1 << 3), // Indicates the head has been loaded (1973 only). + HeadLoad = (1 << 3), // Indicates the head has been loaded (1973 only). Timer = (1 << 4), // Indicates that the delay_time_-powered timer has timed out. IndexHoleTarget = (1 << 5) // Indicates that index_hole_count_ has reached index_hole_count_target_. diff --git a/Machines/Oric/Microdisc.cpp b/Machines/Oric/Microdisc.cpp index 5ea84f3c7..8b32f6cca 100644 --- a/Machines/Oric/Microdisc.cpp +++ b/Machines/Oric/Microdisc.cpp @@ -10,10 +10,15 @@ using namespace Oric; +namespace { + const int head_load_request_counter_target = 7653333; +} + Microdisc::Microdisc() : irq_enable_(false), delegate_(nullptr), paging_flags_(BASICDisable), + head_load_request_counter_(-1), WD1770(P1793) {} @@ -81,6 +86,28 @@ uint8_t Microdisc::get_data_request_register() void Microdisc::set_head_load_request(bool head_load) { set_motor_on(head_load); - // TODO: delay - set_head_loaded(head_load); + if(head_load) + { + head_load_request_counter_ = 0; + } + else + { + head_load_request_counter_ = head_load_request_counter_target; + set_head_loaded(head_load); + } +} + +void Microdisc::run_for_cycles(unsigned int number_of_cycles) +{ + if(head_load_request_counter_ < head_load_request_counter_target) + { + head_load_request_counter_ += number_of_cycles; + if(head_load_request_counter_ >= head_load_request_counter_target) set_head_loaded(true); + } + WD::WD1770::run_for_cycles(number_of_cycles); +} + +bool Microdisc::get_drive_is_ready() +{ + return true; } diff --git a/Machines/Oric/Microdisc.hpp b/Machines/Oric/Microdisc.hpp index 4b460c215..521ab2e7e 100644 --- a/Machines/Oric/Microdisc.hpp +++ b/Machines/Oric/Microdisc.hpp @@ -24,6 +24,8 @@ class Microdisc: public WD::WD1770 { bool get_interrupt_request_line(); + void run_for_cycles(unsigned int number_of_cycles); + enum PagingFlags { BASICDisable = (1 << 0), MicrodscDisable = (1 << 1) @@ -38,10 +40,12 @@ class Microdisc: public WD::WD1770 { private: void set_head_load_request(bool head_load); + bool get_drive_is_ready(); std::shared_ptr drives_[4]; int selected_drive_; bool irq_enable_; int paging_flags_; + int head_load_request_counter_; Delegate *delegate_; }; diff --git a/Storage/Disk/DiskController.cpp b/Storage/Disk/DiskController.cpp index f9eea6e7a..896bd4579 100644 --- a/Storage/Disk/DiskController.cpp +++ b/Storage/Disk/DiskController.cpp @@ -128,6 +128,12 @@ bool Controller::get_is_track_zero() return _drive->get_is_track_zero(); } +bool Controller::get_drive_is_ready() +{ + if(!_drive) return false; + return _drive->has_disk(); +} + void Controller::step(int direction) { if(_drive) _drive->step(direction); diff --git a/Storage/Disk/DiskController.hpp b/Storage/Disk/DiskController.hpp index e1371e96b..67779c7e9 100644 --- a/Storage/Disk/DiskController.hpp +++ b/Storage/Disk/DiskController.hpp @@ -78,6 +78,7 @@ class Controller: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop bool get_is_track_zero(); void step(int direction); + virtual bool get_drive_is_ready(); private: Time _bit_length;