From f48885472002d507e580b4d9c0f2f5fbc46c4739 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 27 Sep 2017 22:14:50 -0400 Subject: [PATCH] Switches Oric MFM DSK serialisation to feeding a track serialisation to a shifter. Thereby eliminates the parser's need to offer get_track. --- Storage/Disk/DiskImage/Formats/OricMFMDSK.cpp | 47 ++++++++-- Storage/Disk/Encodings/MFM/Parser.cpp | 88 ------------------- Storage/Disk/Encodings/MFM/Parser.hpp | 13 --- 3 files changed, 42 insertions(+), 106 deletions(-) diff --git a/Storage/Disk/DiskImage/Formats/OricMFMDSK.cpp b/Storage/Disk/DiskImage/Formats/OricMFMDSK.cpp index ee644a242..db7264138 100644 --- a/Storage/Disk/DiskImage/Formats/OricMFMDSK.cpp +++ b/Storage/Disk/DiskImage/Formats/OricMFMDSK.cpp @@ -10,8 +10,9 @@ #include "../../Track/PCMTrack.hpp" #include "../../Encodings/MFM/Constants.hpp" +#include "../../Encodings/MFM/Shifter.hpp" #include "../../Encodings/MFM/Encoder.hpp" -#include "../../Encodings/MFM/Parser.hpp" +#include "../../Track/TrackSerialiser.hpp" using namespace Storage::Disk; @@ -118,12 +119,48 @@ std::shared_ptr OricMFMDSK::get_track_at_position(unsigned int head, unsi } void OricMFMDSK::set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr &track) { - Storage::Encodings::MFM::Parser parser(true, track); - std::vector parsed_track = parser.get_track(0); + PCMSegment segment = Storage::Disk::track_serialisation(*track, Storage::Encodings::MFM::MFMBitLength); + Storage::Encodings::MFM::Shifter shifter; + shifter.set_is_double_density(true); + shifter.set_should_obey_syncs(true); + std::vector parsed_track; + int size = 0; + int offset = 0; + bool capture_size = false; + + for(unsigned int bit = 0; bit < segment.number_of_bits; ++bit) { + shifter.add_input_bit(segment.bit(bit)); + if(shifter.get_token() == Storage::Encodings::MFM::Shifter::Token::None) continue; + parsed_track.push_back(shifter.get_byte()); + + if(offset) { + offset--; + if(!offset) { + shifter.set_should_obey_syncs(true); + } + if(capture_size && offset == 2) { + size = parsed_track.back(); + capture_size = false; + } + } + + if( shifter.get_token() == Storage::Encodings::MFM::Shifter::Token::Data || + shifter.get_token() == Storage::Encodings::MFM::Shifter::Token::DeletedData) { + offset = 128 << size; + shifter.set_should_obey_syncs(false); + } + + if(shifter.get_token() == Storage::Encodings::MFM::Shifter::Token::ID) { + offset = 6; + shifter.set_should_obey_syncs(false); + capture_size = true; + } + } + long file_offset = get_file_offset_for_position(head, position); - std::lock_guard lock_guard(file_access_mutex_); -fseek(file_, file_offset, SEEK_SET); + std::lock_guard lock_guard(file_access_mutex_); + fseek(file_, file_offset, SEEK_SET); size_t track_size = std::min((size_t)6400, parsed_track.size()); fwrite(parsed_track.data(), 1, track_size, file_); } diff --git a/Storage/Disk/Encodings/MFM/Parser.cpp b/Storage/Disk/Encodings/MFM/Parser.cpp index 9a9aa332c..74195c3fb 100644 --- a/Storage/Disk/Encodings/MFM/Parser.cpp +++ b/Storage/Disk/Encodings/MFM/Parser.cpp @@ -89,11 +89,6 @@ std::shared_ptr Parser::get_sector(uint8_t head, uint8_t track, uint8_t return nullptr; } -std::vector Parser::get_track(uint8_t track) { - seek_to_track(track); - return get_track(); -} - void Parser::process_input_bit(int value) { shift_register_ = ((shift_register_ << 1) | (unsigned int)value) & 0xffff; bit_count_++; @@ -131,89 +126,6 @@ uint8_t Parser::get_next_byte() { return byte; } -std::vector Parser::get_track() { - std::vector result; - int distance_until_permissible_sync = 0; - uint8_t last_id[6] = {0, 0, 0, 0, 0, 0}; - int last_id_pointer = 0; - bool next_is_type = false; - - // align to the next index hole - index_count_ = 0; - while(!index_count_) run_for(Cycles(1)); - - // capture every other bit until the next index hole - index_count_ = 0; - while(1) { - // wait until either another bit or the index hole arrives - bit_count_ = 0; - 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_) { - if(bit_count_) result.push_back(get_byte_for_shift_value((uint16_t)(shift_register_ << (16 - bit_count_)))); - break; - } - - // 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) { - distance_until_permissible_sync--; - } else { - if(found_sync) { - 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; - } - } - } else if(next_is_type) { - switch(byte_value) { - case IDAddressByte: found_id = true; break; - case DataAddressByte: - case DeletedDataAddressByte: 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]; - } - } - - return result; -} - std::shared_ptr Parser::get_next_sector() { std::shared_ptr sector(new Sector); index_count_ = 0; diff --git a/Storage/Disk/Encodings/MFM/Parser.hpp b/Storage/Disk/Encodings/MFM/Parser.hpp index d71f5c096..a34648c4b 100644 --- a/Storage/Disk/Encodings/MFM/Parser.hpp +++ b/Storage/Disk/Encodings/MFM/Parser.hpp @@ -29,18 +29,6 @@ class Parser: public Storage::Disk::Controller { */ std::shared_ptr get_sector(uint8_t head, uint8_t track, uint8_t sector); - /*! - Attempts to read the track at @c track, starting from the index hole. - - 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. - */ - std::vector get_track(uint8_t track); - private: Parser(bool is_mfm); @@ -61,7 +49,6 @@ class Parser: public Storage::Disk::Controller { std::shared_ptr get_next_sector(); std::shared_ptr get_sector(uint8_t sector); - std::vector get_track(); std::map> sectors_by_index_; std::set decoded_tracks_;