mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-23 20:29:42 +00:00
Introduced a head loading path for 1793 machines.
This commit is contained in:
parent
82899f2f47
commit
442986ee2c
@ -33,7 +33,8 @@ WD1770::WD1770(Personality p) :
|
||||
is_awaiting_marker_value_(false),
|
||||
is_reading_data_(false),
|
||||
delegate_(nullptr),
|
||||
personality_(p)
|
||||
personality_(p),
|
||||
head_is_loaded_(false)
|
||||
{
|
||||
set_is_double_density(false);
|
||||
posit_event(Event::Command);
|
||||
@ -255,6 +256,12 @@ void WD1770::process_index_hole()
|
||||
{
|
||||
set_motor_on(false);
|
||||
}
|
||||
|
||||
// head unload
|
||||
if(index_hole_count_ == 15 && !status_.busy && has_head_load_line())
|
||||
{
|
||||
set_head_load_request(false);
|
||||
}
|
||||
}
|
||||
|
||||
// +------+----------+-------------------------+
|
||||
@ -301,6 +308,7 @@ void WD1770::process_index_hole()
|
||||
WAIT_FOR_EVENT(Event::IndexHoleTarget); \
|
||||
status_.spin_up = true;
|
||||
|
||||
|
||||
void WD1770::posit_event(Event new_event_type)
|
||||
{
|
||||
if(!(interesting_event_mask_ & (int)new_event_type)) return;
|
||||
@ -356,9 +364,24 @@ void WD1770::posit_event(Event new_event_type)
|
||||
status.data_request = false;
|
||||
});
|
||||
|
||||
if((command_&0x08) || get_motor_on() || !has_motor_on_line()) goto test_type1_type;
|
||||
if(!has_motor_on_line() && !has_head_load_line()) goto test_type1_type;
|
||||
|
||||
// Perform spin up.
|
||||
if(has_motor_on_line()) goto begin_type1_spin_up;
|
||||
goto begin_type1_load_head;
|
||||
|
||||
begin_type1_load_head:
|
||||
if(!(command_&0x08))
|
||||
{
|
||||
set_head_load_request(false);
|
||||
goto test_type1_type;
|
||||
}
|
||||
set_head_load_request(true);
|
||||
if(head_is_loaded_) goto test_type1_type;
|
||||
WAIT_FOR_EVENT(Event::HeadLoaded);
|
||||
goto test_type1_type;
|
||||
|
||||
begin_type1_spin_up:
|
||||
if((command_&0x08) || get_motor_on()) goto test_type1_type;
|
||||
SPIN_UP();
|
||||
|
||||
test_type1_type:
|
||||
@ -457,8 +480,20 @@ void WD1770::posit_event(Event new_event_type)
|
||||
});
|
||||
distance_into_section_ = 0;
|
||||
|
||||
if((command_&0x08) || get_motor_on() || !has_motor_on_line()) goto test_type2_delay;
|
||||
if((command_&0x08) && has_motor_on_line()) goto test_type2_delay;
|
||||
if(!has_motor_on_line() && !has_head_load_line()) goto test_type2_delay;
|
||||
|
||||
if(has_motor_on_line()) goto begin_type2_spin_up;
|
||||
goto begin_type2_load_head;
|
||||
|
||||
begin_type2_load_head:
|
||||
set_head_load_request(true);
|
||||
if(head_is_loaded_) goto test_type2_delay;
|
||||
WAIT_FOR_EVENT(Event::HeadLoaded);
|
||||
goto test_type2_delay;
|
||||
|
||||
begin_type2_spin_up:
|
||||
if(get_motor_on()) goto test_type2_delay;
|
||||
// Perform spin up.
|
||||
SPIN_UP();
|
||||
|
||||
@ -580,3 +615,11 @@ void WD1770::update_status(std::function<void(Status &)> updater)
|
||||
}
|
||||
else updater(status_);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -52,6 +52,10 @@ class WD1770: public Storage::Disk::Controller {
|
||||
};
|
||||
inline void set_delegate(Delegate *delegate) { delegate_ = delegate; }
|
||||
|
||||
protected:
|
||||
virtual void set_head_load_request(bool head_load);
|
||||
void set_head_loaded(bool head_loaded);
|
||||
|
||||
private:
|
||||
Personality personality_;
|
||||
inline bool has_motor_on_line() { return (personality_ != P1793 ) && (personality_ != P1773); }
|
||||
@ -102,9 +106,10 @@ 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).
|
||||
|
||||
Timer = (1 << 3), // Indicates that the delay_time_-powered timer has timed out.
|
||||
IndexHoleTarget = (1 << 4) // Indicates that index_hole_count_ has reached index_hole_count_target_.
|
||||
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_.
|
||||
};
|
||||
void posit_event(Event type);
|
||||
int interesting_event_mask_;
|
||||
@ -114,7 +119,10 @@ class WD1770: public Storage::Disk::Controller {
|
||||
// ID buffer
|
||||
uint8_t header_[6];
|
||||
|
||||
// output line statuses
|
||||
// 1793 head-loading logic
|
||||
bool head_is_loaded_;
|
||||
|
||||
// delegate
|
||||
Delegate *delegate_;
|
||||
|
||||
// Storage::Disk::Controller
|
||||
|
@ -77,3 +77,10 @@ uint8_t Microdisc::get_data_request_register()
|
||||
{
|
||||
return 0x7f | (get_data_request_line() ? 0x00 : 0x80);
|
||||
}
|
||||
|
||||
void Microdisc::set_head_load_request(bool head_load)
|
||||
{
|
||||
set_motor_on(head_load);
|
||||
// TODO: delay
|
||||
set_head_loaded(head_load);
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class Microdisc: public WD::WD1770 {
|
||||
inline int get_paging_flags() { return paging_flags_; }
|
||||
|
||||
private:
|
||||
void set_head_load_request(bool head_load);
|
||||
std::shared_ptr<Storage::Disk::Drive> drives_[4];
|
||||
int selected_drive_;
|
||||
bool irq_enable_;
|
||||
|
Loading…
Reference in New Issue
Block a user