From d2ad2c756e1488b50d2a796177bc6dc8c6ce7b5a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 25 Dec 2016 15:46:49 -0500 Subject: [PATCH] Added enough shovelling to write rubbish for an entire sector. --- Components/1770/1770.cpp | 45 ++++++++++++++++++++++++++ Components/1770/1770.hpp | 6 ++-- Storage/Disk/DiskController.cpp | 20 ++++++++---- Storage/Storage.hpp | 56 ++++++++++++++++++++++++++++----- 4 files changed, 111 insertions(+), 16 deletions(-) diff --git a/Components/1770/1770.cpp b/Components/1770/1770.cpp index f739115fb..35c1d8c5b 100644 --- a/Components/1770/1770.cpp +++ b/Components/1770/1770.cpp @@ -277,6 +277,12 @@ void WD1770::process_index_hole() } } +void WD1770::process_write_completed() +{ + posit_event(Event::DataWritten); +} + + // +------+----------+-------------------------+ // ! ! ! BITS ! // ! TYPE ! COMMAND ! 7 6 5 4 3 2 1 0 ! @@ -620,8 +626,47 @@ void WD1770::posit_event(Event new_event_type) for(int b = 0; b < 16; b++) write_bit(!(b&1)); } +// printf("%d\n", counter); + WAIT_FOR_EVENT(Event::DataWritten); + distance_into_section_ = 0; + + type2_write_loop: + // TODO: real data + for(int b = 0; b < 16; b++) + write_bit(!(b&1)); + update_status([] (Status &status) { + status.data_request = true; + }); + WAIT_FOR_EVENT(Event::DataWritten); + distance_into_section_++; + if(distance_into_section_ == 128 << header_[3]) + { + goto type2_write_crc; + } + + if(status_.data_request) + { + update_status([] (Status &status) { + status.lost_data = true; + }); + goto wait_for_command; + } + + type2_write_crc: + // TODO: write CRC and FF + for(int b = 0; b < 48; b++) + write_bit(!(b&1)); + WAIT_FOR_EVENT(Event::DataWritten); end_writing(); + if(command_ & 0x10) + { + sector_++; + goto test_type2_write_protection; + } + printf("Wrote sector %d\n", sector_); + goto wait_for_command; + begin_type_3: update_status([] (Status &status) { status.type = Status::Three; diff --git a/Components/1770/1770.hpp b/Components/1770/1770.hpp index edfe809e3..759423d5f 100644 --- a/Components/1770/1770.hpp +++ b/Components/1770/1770.hpp @@ -110,9 +110,10 @@ class WD1770: public Storage::Disk::Controller { 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. HeadLoad = (1 << 3), // Indicates the head has been loaded (1973 only). + DataWritten = (1 << 4), // Indicates that all queued bits have been written - 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_. + Timer = (1 << 5), // Indicates that the delay_time_-powered timer has timed out. + IndexHoleTarget = (1 << 6) // Indicates that index_hole_count_ has reached index_hole_count_target_. }; void posit_event(Event type); int interesting_event_mask_; @@ -131,6 +132,7 @@ class WD1770: public Storage::Disk::Controller { // Storage::Disk::Controller virtual void process_input_bit(int value, unsigned int cycles_since_index_hole); virtual void process_index_hole(); + virtual void process_write_completed(); }; } diff --git a/Storage/Disk/DiskController.cpp b/Storage/Disk/DiskController.cpp index 18bb0a1a3..8507141bc 100644 --- a/Storage/Disk/DiskController.cpp +++ b/Storage/Disk/DiskController.cpp @@ -67,7 +67,12 @@ void Controller::run_for_cycles(int number_of_cycles) { int cycles_until_next_event = (int)get_cycles_until_next_event(); int cycles_to_run_for = std::min(cycles_until_next_event, number_of_cycles); - if(!is_reading_ && cycles_until_bits_written_ > zero) cycles_to_run_for = std::min(cycles_to_run_for, (int)cycles_until_bits_written_.get_unsigned_int()); + if(!is_reading_ && cycles_until_bits_written_ > zero) + { + int write_cycles_target = (int)cycles_until_bits_written_.get_unsigned_int(); + if(cycles_until_bits_written_.length % cycles_until_bits_written_.clock_rate) write_cycles_target++; + cycles_to_run_for = std::min(cycles_to_run_for, write_cycles_target); + } cycles_since_index_hole_ += (unsigned int)cycles_to_run_for; @@ -78,17 +83,20 @@ void Controller::run_for_cycles(int number_of_cycles) } else { - if(cycles_until_bits_written_ > Storage::Time(0)) + if(cycles_until_bits_written_ > zero) { - Storage::Time number_of_cycles_time(number_of_cycles); - if(cycles_until_bits_written_ < number_of_cycles_time) + Storage::Time cycles_to_run_for_time(cycles_to_run_for); + if(cycles_until_bits_written_ < cycles_to_run_for_time) { - cycles_until_bits_written_.set_zero(); process_write_completed(); + if(cycles_until_bits_written_ < cycles_to_run_for_time) + cycles_until_bits_written_.set_zero(); + else + cycles_until_bits_written_ -= cycles_to_run_for_time; } else { - cycles_until_bits_written_ -= number_of_cycles_time; + cycles_until_bits_written_ -= cycles_to_run_for_time; } } } diff --git a/Storage/Storage.hpp b/Storage/Storage.hpp index a0456870f..3feff4d5f 100644 --- a/Storage/Storage.hpp +++ b/Storage/Storage.hpp @@ -89,30 +89,70 @@ struct Time { inline Time operator + (const Time &other) const { - uint64_t result_length = (uint64_t)length * (uint64_t)other.clock_rate + (uint64_t)other.length * (uint64_t)clock_rate; - uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + uint64_t result_length; + uint64_t result_clock_rate; + if(clock_rate == other.clock_rate) + { + result_length = (uint64_t)length + (uint64_t)other.length; + result_clock_rate = clock_rate; + } + else + { + result_length = (uint64_t)length * (uint64_t)other.clock_rate + (uint64_t)other.length * (uint64_t)clock_rate; + result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + } return Time(result_length, result_clock_rate); } inline Time &operator += (const Time &other) { - uint64_t result_length = (uint64_t)length * (uint64_t)other.clock_rate + (uint64_t)other.length * (uint64_t)clock_rate; - uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + uint64_t result_length; + uint64_t result_clock_rate; + if(clock_rate == other.clock_rate) + { + result_length = (uint64_t)length + (uint64_t)other.length; + result_clock_rate = (uint64_t)clock_rate; + } + else + { + result_length = (uint64_t)length * (uint64_t)other.clock_rate + (uint64_t)other.length * (uint64_t)clock_rate; + result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + } install_result(result_length, result_clock_rate); return *this; } inline Time operator - (const Time &other) const { - uint64_t result_length = (uint64_t)length * (uint64_t)other.clock_rate - (uint64_t)other.length * (uint64_t)clock_rate; - uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + uint64_t result_length; + uint64_t result_clock_rate; + if(clock_rate == other.clock_rate) + { + result_length = (uint64_t)length - (uint64_t)other.length; + result_clock_rate = clock_rate; + } + else + { + result_length = (uint64_t)length * (uint64_t)other.clock_rate - (uint64_t)other.length * (uint64_t)clock_rate; + result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + } return Time(result_length, result_clock_rate); } inline Time operator -= (const Time &other) { - uint64_t result_length = (uint64_t)length * (uint64_t)other.clock_rate - (uint64_t)other.length * (uint64_t)clock_rate; - uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + uint64_t result_length; + uint64_t result_clock_rate; + if(clock_rate == other.clock_rate) + { + result_length = (uint64_t)length - (uint64_t)other.length; + result_clock_rate = (uint64_t)clock_rate; + } + else + { + result_length = (uint64_t)length * (uint64_t)other.clock_rate - (uint64_t)other.length * (uint64_t)clock_rate; + result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + } install_result(result_length, result_clock_rate); return *this; }