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