1
0
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:
Thomas Harte 2016-12-01 20:12:22 -05:00
parent 82899f2f47
commit 442986ee2c
4 changed files with 66 additions and 7 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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_;