From 0f399b0a0c97394a00dd6dc5b309a793b43013b3 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 30 Dec 2016 19:59:01 -0500 Subject: [PATCH 01/11] Made type conversion explicit. --- Storage/FileHolder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Storage/FileHolder.cpp b/Storage/FileHolder.cpp index 1395da998..bd4c47305 100644 --- a/Storage/FileHolder.cpp +++ b/Storage/FileHolder.cpp @@ -93,7 +93,7 @@ void FileHolder::ensure_file_is_at_least_length(long length) if(bytes_to_write > 0) { uint8_t *empty = new uint8_t[bytes_to_write]; - memset(empty, 0, bytes_to_write); + memset(empty, 0, (size_t)bytes_to_write); fwrite(empty, sizeof(uint8_t), (size_t)bytes_to_write, file_); delete[] empty; } From d581294479b842bd0d074785adf39dc0f327140f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 30 Dec 2016 19:59:23 -0500 Subject: [PATCH 02/11] Added `get_track` to get the PLL output for a complete track. --- Storage/Disk/Encodings/MFM.cpp | 43 +++++++++++++++++++++++++++++++++- Storage/Disk/Encodings/MFM.hpp | 12 ++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Storage/Disk/Encodings/MFM.cpp b/Storage/Disk/Encodings/MFM.cpp index d1740baeb..f7b0de008 100644 --- a/Storage/Disk/Encodings/MFM.cpp +++ b/Storage/Disk/Encodings/MFM.cpp @@ -267,7 +267,7 @@ Parser::Parser(bool is_mfm, const std::shared_ptr &track) drive->set_disk_with_track(track); } -std::shared_ptr Parser::get_sector(uint8_t track, uint8_t sector) +void Parser::seek_to_track(uint8_t track) { int difference = (int)track - (int)track_; track_ = track; @@ -279,10 +279,20 @@ std::shared_ptr Parser::get_sector(uint8_t trac for(int c = 0; c < difference; c++) step(direction); } +} +std::shared_ptr Parser::get_sector(uint8_t track, uint8_t sector) +{ + seek_to_track(track); return get_sector(sector); } +std::vector Parser::get_track(uint8_t track, size_t &number_of_bits) +{ + seek_to_track(track); + return get_track(number_of_bits); +} + void Parser::process_input_bit(int value, unsigned int cycles_since_index_hole) { shift_register_ = ((shift_register_ << 1) | (unsigned int)value) & 0xffff; @@ -311,6 +321,37 @@ uint8_t Parser::get_next_byte() return byte; } +std::vector Parser::get_track(size_t &number_of_bits) +{ + std::vector result; + number_of_bits = 0; + + // align to the first index hole + index_count_ = 0; + while(!index_count_) run_for_cycles(1); + + // capture every bit until the next index hole + index_count_ = 0; + while(1) + { + // wait until either another bit or the index hole arrives + bit_count_ = 0; + while(!bit_count_ && !index_count_) TimedEventLoop::run_for_cycles(1); + + // if that was the index hole then finish + if(index_count_) break; + + // otherwise, add another bit to the collection + int bit = number_of_bits & 7; + if(!bit) result.push_back(0); + result[number_of_bits >> 3] |= (shift_register_&1) << (7 - bit); + number_of_bits++; + } + + return result; +} + + std::shared_ptr Parser::get_next_sector() { std::shared_ptr sector(new Storage::Encodings::MFM::Sector); diff --git a/Storage/Disk/Encodings/MFM.hpp b/Storage/Disk/Encodings/MFM.hpp index f1545407d..0f0240566 100644 --- a/Storage/Disk/Encodings/MFM.hpp +++ b/Storage/Disk/Encodings/MFM.hpp @@ -73,6 +73,15 @@ class Parser: public Storage::Disk::Controller { */ std::shared_ptr get_sector(uint8_t track, uint8_t sector); + /*! + Attempts to read the track at @c track, starting from the index hole. + + All PLL-recognised bits are returned, filling their respective bytes from MSB to LSB. + + @returns a vector of data found. Also sets @c number_of_bits to the bit count. + */ + std::vector get_track(uint8_t track, size_t &number_of_bits); + private: Parser(bool is_mfm); @@ -84,11 +93,14 @@ class Parser: public Storage::Disk::Controller { NumberTheory::CRC16 crc_generator_; bool is_mfm_; + void seek_to_track(uint8_t track); void process_input_bit(int value, unsigned int cycles_since_index_hole); void process_index_hole(); uint8_t get_next_byte(); + std::shared_ptr get_next_sector(); std::shared_ptr get_sector(uint8_t sector); + std::vector get_track(size_t &number_of_bits); }; From 632b3c63b154f9548731cbefe2e9af99d6d6bc19 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 30 Dec 2016 22:51:48 -0500 Subject: [PATCH 03/11] Added the infrastructure necessary for Oric disks to appear writeable to the machine and to receive changed tracks. --- Storage/Disk/Formats/OricMFMDSK.cpp | 23 +++++++++++++++++++++-- Storage/Disk/Formats/OricMFMDSK.hpp | 5 +++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Storage/Disk/Formats/OricMFMDSK.cpp b/Storage/Disk/Formats/OricMFMDSK.cpp index c0de30f9e..2f0de70aa 100644 --- a/Storage/Disk/Formats/OricMFMDSK.cpp +++ b/Storage/Disk/Formats/OricMFMDSK.cpp @@ -26,6 +26,11 @@ OricMFMDSK::OricMFMDSK(const char *file_name) : throw ErrorNotOricMFMDSK; } +OricMFMDSK::~OricMFMDSK() +{ + flush_updates(); +} + unsigned int OricMFMDSK::get_head_position_count() { return track_count_; @@ -36,7 +41,12 @@ unsigned int OricMFMDSK::get_head_count() return head_count_; } -std::shared_ptr OricMFMDSK::get_uncached_track_at_position(unsigned int head, unsigned int position) +bool OricMFMDSK::get_is_read_only() +{ + return is_read_only_; +} + +long OricMFMDSK::get_file_offset_for_position(unsigned int head, unsigned int position) { long seek_offset = 0; switch(geometry_type_) @@ -48,7 +58,12 @@ std::shared_ptr OricMFMDSK::get_uncached_track_at_position(unsigned int h seek_offset = (position * track_count_ * head_count_) + head; break; } - fseek(file_, (seek_offset * 6400) + 256, SEEK_SET); + return (seek_offset * 6400) + 256; +} + +std::shared_ptr OricMFMDSK::get_uncached_track_at_position(unsigned int head, unsigned int position) +{ + fseek(file_, get_file_offset_for_position(head, position), SEEK_SET); PCMSegment segment; @@ -115,3 +130,7 @@ std::shared_ptr OricMFMDSK::get_uncached_track_at_position(unsigned int h std::shared_ptr track(new PCMTrack(segment)); return track; } + +void OricMFMDSK::store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr &track, std::mutex &file_access_mutex) +{ +} diff --git a/Storage/Disk/Formats/OricMFMDSK.hpp b/Storage/Disk/Formats/OricMFMDSK.hpp index f4d944a4b..53dac1904 100644 --- a/Storage/Disk/Formats/OricMFMDSK.hpp +++ b/Storage/Disk/Formats/OricMFMDSK.hpp @@ -27,6 +27,7 @@ class OricMFMDSK: public Disk, public Storage::FileHolder { @throws ErrorNotAcornADF if the file doesn't appear to contain an Acorn .ADF format image. */ OricMFMDSK(const char *file_name); + ~OricMFMDSK(); enum { ErrorNotOricMFMDSK, @@ -35,9 +36,13 @@ class OricMFMDSK: public Disk, public Storage::FileHolder { // implemented to satisfy @c Disk unsigned int get_head_position_count(); unsigned int get_head_count(); + bool get_is_read_only(); private: + void store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr &track, std::mutex &file_access_mutex); std::shared_ptr get_uncached_track_at_position(unsigned int head, unsigned int position); + long get_file_offset_for_position(unsigned int head, unsigned int position); + uint32_t head_count_; uint32_t track_count_; uint32_t geometry_type_; From 1f625fad66e6631895effc2a4242eda8c647adf5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 30 Dec 2016 23:10:52 -0500 Subject: [PATCH 04/11] Decided that if this is an [M]FM parsing function then it should be something more intelligent than a mere PLL record. Which I guess conveniently implies Oric DSK-esque behaviour. But properly defined, rather than very vaguely. --- Storage/Disk/Encodings/MFM.cpp | 48 ++++++++++++++++++++++++++-------- Storage/Disk/Encodings/MFM.hpp | 11 +++++--- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/Storage/Disk/Encodings/MFM.cpp b/Storage/Disk/Encodings/MFM.cpp index f7b0de008..031bebd30 100644 --- a/Storage/Disk/Encodings/MFM.cpp +++ b/Storage/Disk/Encodings/MFM.cpp @@ -126,7 +126,8 @@ static uint8_t logarithmic_size_for_size(size_t size) case 256: return 1; case 512: return 2; case 1024: return 3; - case 2048: return 4; + case 2048: return 4; std::vector get_track(uint8_t track); + case 4196: return 5; } } @@ -287,10 +288,10 @@ std::shared_ptr Parser::get_sector(uint8_t trac return get_sector(sector); } -std::vector Parser::get_track(uint8_t track, size_t &number_of_bits) +std::vector Parser::get_track(uint8_t track) { seek_to_track(track); - return get_track(number_of_bits); + return get_track(); } void Parser::process_input_bit(int value, unsigned int cycles_since_index_hole) @@ -321,16 +322,17 @@ uint8_t Parser::get_next_byte() return byte; } -std::vector Parser::get_track(size_t &number_of_bits) +std::vector Parser::get_track() { std::vector result; - number_of_bits = 0; + size_t number_of_bits = 0; + bool is_clock = false; // align to the first index hole index_count_ = 0; while(!index_count_) run_for_cycles(1); - // capture every bit until the next index hole + // capture every other bit until the next index hole index_count_ = 0; while(1) { @@ -341,11 +343,35 @@ std::vector Parser::get_track(size_t &number_of_bits) // if that was the index hole then finish if(index_count_) break; - // otherwise, add another bit to the collection - int bit = number_of_bits & 7; - if(!bit) result.push_back(0); - result[number_of_bits >> 3] |= (shift_register_&1) << (7 - bit); - number_of_bits++; + // otherwise, add another bit to the collection if it wasn't a clock + if(!is_clock) + { + int bit = number_of_bits & 7; + if(!bit) result.push_back(0); + result[number_of_bits >> 3] |= (shift_register_&1) << (7 - bit); + number_of_bits++; + } + is_clock ^= true; + + // if a synchronisation is detected then align + uint16_t low_shift_register = (shift_register_&0xffff); + bool is_sync = false; + if(is_mfm_) + { + is_sync = (low_shift_register == MFMIndexSync) || (low_shift_register == MFMSync); + } + else + { + is_sync = + (low_shift_register == FMIndexAddressMark) || + (low_shift_register == FMIDAddressMark) || + (low_shift_register == FMDataAddressMark) || + (low_shift_register == FMDeletedDataAddressMark); + } + if(is_sync) + { + if(number_of_bits) number_of_bits += 7 - (number_of_bits&7); + } } return result; diff --git a/Storage/Disk/Encodings/MFM.hpp b/Storage/Disk/Encodings/MFM.hpp index 0f0240566..b637127bd 100644 --- a/Storage/Disk/Encodings/MFM.hpp +++ b/Storage/Disk/Encodings/MFM.hpp @@ -76,11 +76,14 @@ class Parser: public Storage::Disk::Controller { /*! Attempts to read the track at @c track, starting from the index hole. - All PLL-recognised bits are returned, filling their respective bytes from MSB to LSB. + Decodes data bits only; clocks are omitted. Synchronisation values begin a new + byte. If a synchronisation value begins partway through a byte then + synchronisation-contributing bits will appear both in the preceding byte and + in the next. - @returns a vector of data found. Also sets @c number_of_bits to the bit count. + @returns a vector of data found. */ - std::vector get_track(uint8_t track, size_t &number_of_bits); + std::vector get_track(uint8_t track); private: Parser(bool is_mfm); @@ -100,7 +103,7 @@ class Parser: public Storage::Disk::Controller { std::shared_ptr get_next_sector(); std::shared_ptr get_sector(uint8_t sector); - std::vector get_track(size_t &number_of_bits); + std::vector get_track(); }; From f217d508b8bbd784d7e9ecb3271fbcfdb5f375d6 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 30 Dec 2016 23:12:46 -0500 Subject: [PATCH 05/11] Completed first attempt at write support for Oric disk images. --- Storage/Disk/Formats/OricMFMDSK.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Storage/Disk/Formats/OricMFMDSK.cpp b/Storage/Disk/Formats/OricMFMDSK.cpp index 2f0de70aa..6b6e6959b 100644 --- a/Storage/Disk/Formats/OricMFMDSK.cpp +++ b/Storage/Disk/Formats/OricMFMDSK.cpp @@ -133,4 +133,11 @@ std::shared_ptr OricMFMDSK::get_uncached_track_at_position(unsigned int h void OricMFMDSK::store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr &track, std::mutex &file_access_mutex) { + Storage::Encodings::MFM::Parser parser(true, track); + std::vector parsed_track = parser.get_track((uint8_t)position); + std::lock_guard lock_guard(file_access_mutex); + + long file_offset = get_file_offset_for_position(head, position); + fseek(file_, file_offset, SEEK_SET); + fwrite(parsed_track.data(), 1, parsed_track.size(), file_); } From ea4d85e1cdcc59a4cec7d409ae6165e8e9e4edfa Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 31 Dec 2016 00:10:35 -0500 Subject: [PATCH 06/11] The virtual disk constructed is the same across all tracks. So why not just request zero? --- Storage/Disk/Formats/OricMFMDSK.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Storage/Disk/Formats/OricMFMDSK.cpp b/Storage/Disk/Formats/OricMFMDSK.cpp index 6b6e6959b..c740e0f75 100644 --- a/Storage/Disk/Formats/OricMFMDSK.cpp +++ b/Storage/Disk/Formats/OricMFMDSK.cpp @@ -134,7 +134,7 @@ std::shared_ptr OricMFMDSK::get_uncached_track_at_position(unsigned int h void OricMFMDSK::store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr &track, std::mutex &file_access_mutex) { Storage::Encodings::MFM::Parser parser(true, track); - std::vector parsed_track = parser.get_track((uint8_t)position); + std::vector parsed_track = parser.get_track(0); std::lock_guard lock_guard(file_access_mutex); long file_offset = get_file_offset_for_position(head, position); From 0123b37213668ef2ad569519b0c1418882dc5ed3 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 31 Dec 2016 00:11:31 -0500 Subject: [PATCH 07/11] Made an attempt to include sync values in the stream and properly to align. --- Storage/Disk/Encodings/MFM.cpp | 37 ++++++++++++++++++++++------------ Storage/Disk/Encodings/MFM.hpp | 2 ++ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Storage/Disk/Encodings/MFM.cpp b/Storage/Disk/Encodings/MFM.cpp index 031bebd30..205504f33 100644 --- a/Storage/Disk/Encodings/MFM.cpp +++ b/Storage/Disk/Encodings/MFM.cpp @@ -305,19 +305,23 @@ void Parser::process_index_hole() index_count_++; } +uint8_t Parser::get_byte_for_shift_value(uint16_t value) +{ + return (uint8_t)( + ((value&0x0001) >> 0) | + ((value&0x0004) >> 1) | + ((value&0x0010) >> 2) | + ((value&0x0040) >> 3) | + ((value&0x0100) >> 4) | + ((value&0x0400) >> 5) | + ((value&0x1000) >> 6) | + ((value&0x4000) >> 7));} + uint8_t Parser::get_next_byte() { bit_count_ = 0; while(bit_count_ < 16) run_for_cycles(1); - uint8_t byte = (uint8_t)( - ((shift_register_&0x0001) >> 0) | - ((shift_register_&0x0004) >> 1) | - ((shift_register_&0x0010) >> 2) | - ((shift_register_&0x0040) >> 3) | - ((shift_register_&0x0100) >> 4) | - ((shift_register_&0x0400) >> 5) | - ((shift_register_&0x1000) >> 6) | - ((shift_register_&0x4000) >> 7)); + uint8_t byte = get_byte_for_shift_value((uint16_t)shift_register_); crc_generator_.add(byte); return byte; } @@ -328,7 +332,7 @@ std::vector Parser::get_track() size_t number_of_bits = 0; bool is_clock = false; - // align to the first index hole + // align to the next index hole index_count_ = 0; while(!index_count_) run_for_cycles(1); @@ -338,7 +342,7 @@ std::vector Parser::get_track() { // wait until either another bit or the index hole arrives bit_count_ = 0; - while(!bit_count_ && !index_count_) TimedEventLoop::run_for_cycles(1); + while(!bit_count_ && !index_count_) run_for_cycles(1); // if that was the index hole then finish if(index_count_) break; @@ -347,7 +351,11 @@ std::vector Parser::get_track() if(!is_clock) { int bit = number_of_bits & 7; - if(!bit) result.push_back(0); + if(!bit) + { + if(!result.empty()) printf("[%02x]", result.back()); + result.push_back(0); + } result[number_of_bits >> 3] |= (shift_register_&1) << (7 - bit); number_of_bits++; } @@ -370,7 +378,10 @@ std::vector Parser::get_track() } if(is_sync) { - if(number_of_bits) number_of_bits += 7 - (number_of_bits&7); + if(number_of_bits&7) number_of_bits += 8 - (number_of_bits&7); + result.push_back(get_byte_for_shift_value((uint16_t)shift_register_)); + number_of_bits += 8; + is_clock = true; } } diff --git a/Storage/Disk/Encodings/MFM.hpp b/Storage/Disk/Encodings/MFM.hpp index b637127bd..c542f3154 100644 --- a/Storage/Disk/Encodings/MFM.hpp +++ b/Storage/Disk/Encodings/MFM.hpp @@ -101,6 +101,8 @@ class Parser: public Storage::Disk::Controller { void process_index_hole(); uint8_t get_next_byte(); + uint8_t get_byte_for_shift_value(uint16_t value); + std::shared_ptr get_next_sector(); std::shared_ptr get_sector(uint8_t sector); std::vector get_track(); From 6f0b5427e4dd6a8bdb6de4650b17fa8b3fd2ce7a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 31 Dec 2016 00:20:00 -0500 Subject: [PATCH 08/11] Made an attempt to avoid repetition of sync bytes. --- Storage/Disk/Encodings/MFM.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Storage/Disk/Encodings/MFM.cpp b/Storage/Disk/Encodings/MFM.cpp index 205504f33..6148f7da7 100644 --- a/Storage/Disk/Encodings/MFM.cpp +++ b/Storage/Disk/Encodings/MFM.cpp @@ -378,9 +378,13 @@ std::vector Parser::get_track() } if(is_sync) { - if(number_of_bits&7) number_of_bits += 8 - (number_of_bits&7); - result.push_back(get_byte_for_shift_value((uint16_t)shift_register_)); - number_of_bits += 8; + if(number_of_bits&7) + { + number_of_bits += 8 - (number_of_bits&7); + if(!result.empty()) printf("[%02x]", result.back()); + result.push_back(get_byte_for_shift_value((uint16_t)shift_register_)); + number_of_bits += 8; + } is_clock = true; } } From 12549ff4121182784ede4f30cc973e44070ad7b0 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 31 Dec 2016 11:48:46 -0500 Subject: [PATCH 09/11] Might as well get the file offset before entering the critical section; also moved the lock guard down more explicitly to group with the second set of actions. --- Storage/Disk/Formats/OricMFMDSK.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Storage/Disk/Formats/OricMFMDSK.cpp b/Storage/Disk/Formats/OricMFMDSK.cpp index c740e0f75..142a54fa5 100644 --- a/Storage/Disk/Formats/OricMFMDSK.cpp +++ b/Storage/Disk/Formats/OricMFMDSK.cpp @@ -135,9 +135,9 @@ void OricMFMDSK::store_updated_track_at_position(unsigned int head, unsigned int { Storage::Encodings::MFM::Parser parser(true, track); std::vector parsed_track = parser.get_track(0); - std::lock_guard lock_guard(file_access_mutex); - long file_offset = get_file_offset_for_position(head, position); + + std::lock_guard lock_guard(file_access_mutex); fseek(file_, file_offset, SEEK_SET); fwrite(parsed_track.data(), 1, parsed_track.size(), file_); } From cfbab1448cfa13b0e77d4f0e7c5e28b232344eb1 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 31 Dec 2016 12:23:08 -0500 Subject: [PATCH 10/11] Switched to a track parsing that disallows synchronisation values within sector contents. --- Storage/Disk/Encodings/MFM.cpp | 108 ++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 35 deletions(-) diff --git a/Storage/Disk/Encodings/MFM.cpp b/Storage/Disk/Encodings/MFM.cpp index 6148f7da7..007fd0110 100644 --- a/Storage/Disk/Encodings/MFM.cpp +++ b/Storage/Disk/Encodings/MFM.cpp @@ -329,8 +329,10 @@ uint8_t Parser::get_next_byte() std::vector Parser::get_track() { std::vector result; - size_t number_of_bits = 0; - bool is_clock = false; + int distance_until_permissible_sync = 0; + uint8_t last_id[6]; + int last_id_pointer = 0; + bool next_is_type = false; // align to the next index hole index_count_ = 0; @@ -342,50 +344,86 @@ std::vector Parser::get_track() { // wait until either another bit or the index hole arrives bit_count_ = 0; - while(!bit_count_ && !index_count_) run_for_cycles(1); + bool found_sync = false; + while(!index_count_ && !found_sync && bit_count_ < 16) + { + int previous_bit_count = bit_count_; + run_for_cycles(1); + + if(!distance_until_permissible_sync && bit_count_ != previous_bit_count) + { + uint16_t low_shift_register = (shift_register_&0xffff); + if(is_mfm_) + { + found_sync = (low_shift_register == MFMIndexSync) || (low_shift_register == MFMSync); + } + else + { + found_sync = + (low_shift_register == FMIndexAddressMark) || + (low_shift_register == FMIDAddressMark) || + (low_shift_register == FMDataAddressMark) || + (low_shift_register == FMDeletedDataAddressMark); + } + } + } // if that was the index hole then finish - if(index_count_) break; - - // otherwise, add another bit to the collection if it wasn't a clock - if(!is_clock) + if(index_count_) { - int bit = number_of_bits & 7; - if(!bit) - { - if(!result.empty()) printf("[%02x]", result.back()); - result.push_back(0); - } - result[number_of_bits >> 3] |= (shift_register_&1) << (7 - bit); - number_of_bits++; + if(bit_count_) result.push_back(get_byte_for_shift_value((uint16_t)(shift_register_ << (16 - bit_count_)))); + break; } - is_clock ^= true; - // if a synchronisation is detected then align - uint16_t low_shift_register = (shift_register_&0xffff); - bool is_sync = false; - if(is_mfm_) + // store whatever the current byte is + uint8_t byte_value = get_byte_for_shift_value((uint16_t)shift_register_); + result.push_back(byte_value); + if(last_id_pointer < 6) last_id[last_id_pointer++] = byte_value; + + // if no syncs are permissible here, decrement the waiting period and perform no further contemplation + bool found_id = false, found_data = false; + if(distance_until_permissible_sync) { - is_sync = (low_shift_register == MFMIndexSync) || (low_shift_register == MFMSync); + distance_until_permissible_sync--; } else { - is_sync = - (low_shift_register == FMIndexAddressMark) || - (low_shift_register == FMIDAddressMark) || - (low_shift_register == FMDataAddressMark) || - (low_shift_register == FMDeletedDataAddressMark); - } - if(is_sync) - { - if(number_of_bits&7) + if(found_sync) { - number_of_bits += 8 - (number_of_bits&7); - if(!result.empty()) printf("[%02x]", result.back()); - result.push_back(get_byte_for_shift_value((uint16_t)shift_register_)); - number_of_bits += 8; + if(is_mfm_) + { + next_is_type = true; + } + else + { + switch(shift_register_&0xffff) + { + case FMIDAddressMark: found_id = true; break; + case FMDataAddressMark: + case FMDeletedDataAddressMark: found_data = true; break; + } + } } - is_clock = true; + else if(next_is_type) + { + switch(byte_value) + { + case MFMIDAddressByte: found_id = true; break; + case MFMDataAddressByte: + case MFMDeletedDataAddressByte: found_data = true; break; + } + } + } + + if(found_id) + { + distance_until_permissible_sync = 6; + last_id_pointer = 0; + } + + if(found_data) + { + distance_until_permissible_sync = 128 << last_id[3]; } } From 52b850a3f5a3248a868d5052a6604aff3894f592 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 31 Dec 2016 12:51:52 -0500 Subject: [PATCH 11/11] Quick extra: make sure parsed tracks don't overflow the 6400 byte space available in an MFM disk. Which might be better expressed as 6250? --- Storage/Disk/Formats/OricMFMDSK.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Storage/Disk/Formats/OricMFMDSK.cpp b/Storage/Disk/Formats/OricMFMDSK.cpp index 142a54fa5..49837c5bc 100644 --- a/Storage/Disk/Formats/OricMFMDSK.cpp +++ b/Storage/Disk/Formats/OricMFMDSK.cpp @@ -139,5 +139,6 @@ void OricMFMDSK::store_updated_track_at_position(unsigned int head, unsigned int std::lock_guard lock_guard(file_access_mutex); fseek(file_, file_offset, SEEK_SET); - fwrite(parsed_track.data(), 1, parsed_track.size(), file_); + size_t track_size = std::min((size_t)6400, parsed_track.size()); + fwrite(parsed_track.data(), 1, track_size, file_); }