1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-01 13:58:20 +00:00

One painful step at a time, this now starts the disk rotating and gets as far as deciding whether it's about to head off on a read or a write.

This commit is contained in:
Thomas Harte 2016-09-22 21:25:31 -04:00
parent 8db0030068
commit 75eb62b577
2 changed files with 50 additions and 10 deletions

View File

@ -13,7 +13,13 @@ using namespace WD;
WD1770::WD1770() :
Storage::Disk::Drive(1000000, 8, 300),
state_(State::Waiting), status_(0), has_command_(false) {}
state_(State::Waiting), status_(0), has_command_(false) {
Storage::Time bit_length;
// TODO: this should be a function of the double density line
bit_length.length = 1;
bit_length.clock_rate = 500000;
set_expected_bit_length(bit_length);
}
//void WD1770::set_disk(std::shared_ptr<Storage::Disk::Disk> disk)
//{
@ -57,6 +63,7 @@ void WD1770::run_for_cycles(unsigned int number_of_cycles)
while(cycles > 8)
{
cycles -= 8;
if(status_ & Flag::MotorOn) Storage::Disk::Drive::run_for_cycles(1);
switch(state_)
{
@ -71,6 +78,13 @@ void WD1770::run_for_cycles(unsigned int number_of_cycles)
}
continue;
case State::WaitForSixIndexPulses:
status_ |= Flag::MotorOn;
// deliberately empty; logic is in ::process_index_hole
continue;
#pragma mark - Type 1
case State::BeginType1:
status_ |= Flag::Busy;
status_ &= ~(Flag::DataRequest | Flag::CRCError);
@ -79,14 +93,11 @@ void WD1770::run_for_cycles(unsigned int number_of_cycles)
if(command_ & 0x08)
{
wait_six_index_pulses_.next_state = state_;
wait_six_index_pulses_.count = 0;
index_hole_count_ = 0;
state_ = State::WaitForSixIndexPulses;
}
continue;
// case State::WaitForSixIndexPulses:
// continue;
case State::BeginType1PostSpin:
switch(command_ >> 4)
{
@ -139,7 +150,7 @@ void WD1770::run_for_cycles(unsigned int number_of_cycles)
state_ = State::StepDelay;
step_delay_.count = 0;
}
break;
continue;
case State::StepDelay:
if(step_delay_.count == (command_&3))
@ -147,7 +158,7 @@ void WD1770::run_for_cycles(unsigned int number_of_cycles)
state_ = (command_ >> 5) ? State::TestVerify : State::TestTrack;
}
step_delay_.count++;
break;
continue;
case State::TestVerify:
if(command_ & 0x04)
@ -160,7 +171,29 @@ void WD1770::run_for_cycles(unsigned int number_of_cycles)
status_ &= ~Flag::Busy;
state_ = State::Waiting;
}
break;
continue;
#pragma mark - Type 2
case State::BeginType2:
status_ |= Flag::Busy;
status_ &= ~(Flag::DataRequest | Flag::LostData | Flag::RecordNotFound | 0x60);
state_ = State::TestPause;
if(!(command_&0x08))
{
wait_six_index_pulses_.next_state = state_;
index_hole_count_ = 0;
state_ = State::WaitForSixIndexPulses;
}
continue;
case State::TestPause:
// TODO: pause for 30ms if E is set
state_ = State::TestWrite;
continue;
// case State::TestWrite:
// continue;
// +------+----------+-------------------------+
// ! ! ! BITS !
@ -197,4 +230,10 @@ void WD1770::process_input_bit(int value, unsigned int cycles_since_index_hole)
void WD1770::process_index_hole()
{
index_hole_count_++;
if(state_ == State::WaitForSixIndexPulses && index_hole_count_ == 6)
{
state_ = wait_six_index_pulses_.next_state;
}
}

View File

@ -48,12 +48,11 @@ class WD1770: public Storage::Disk::Drive {
WaitForSixIndexPulses,
TestTrack, TestDirection, TestHead,
TestVerify, VerifyTrack,
StepDelay
StepDelay, TestPause, TestWrite
} state_;
union {
struct {
int count;
State next_state;
} wait_six_index_pulses_;
struct {
@ -61,6 +60,8 @@ class WD1770: public Storage::Disk::Drive {
} step_delay_;
};
int index_hole_count_;
uint8_t status_;
uint8_t track_;
uint8_t sector_;