diff --git a/Storage/Disk/Disk.cpp b/Storage/Disk/Disk.cpp index 5844e1bea..ffd714385 100644 --- a/Storage/Disk/Disk.cpp +++ b/Storage/Disk/Disk.cpp @@ -37,6 +37,7 @@ std::shared_ptr Disk::get_track_at_position(unsigned int head, unsigned i std::lock_guard lock_guard(file_access_mutex_); std::shared_ptr track = get_uncached_track_at_position(head, position); + if(!track) return nullptr; cached_tracks_[address] = track; return track; } diff --git a/Storage/Disk/Encodings/MFM.cpp b/Storage/Disk/Encodings/MFM.cpp index 3808baff2..ccace455a 100644 --- a/Storage/Disk/Encodings/MFM.cpp +++ b/Storage/Disk/Encodings/MFM.cpp @@ -11,6 +11,8 @@ #include "../PCMTrack.hpp" #include "../../../NumberTheory/CRC.hpp" +#include + using namespace Storage::Encodings::MFM; class MFMEncoder: public Encoder { @@ -173,6 +175,7 @@ template std::shared_ptr } while(segment.data.size() < expected_track_bytes) shifter.add_byte(0x00); + if(segment.data.size() > expected_track_bytes) segment.data.resize(expected_track_bytes); segment.number_of_bits = (unsigned int)(segment.data.size() * 8); return std::shared_ptr(new Storage::Disk::PCMTrack(std::move(segment))); @@ -273,13 +276,20 @@ std::shared_ptr Parser::get_sector(uint8_t head, uint8_t track, uint8_t seek_to_track(track); int track_index = get_index(head, track, 0); - // Populate the sector cache if it's not already populated. + // Populate the sector cache if it's not already populated by asking for sectors unless and until + // one is returned that has already been seen. if(decoded_tracks_.find(track_index) == decoded_tracks_.end()) { std::shared_ptr first_sector = get_next_sector(); + std::set visited_sectors; if(first_sector) { while(1) { std::shared_ptr next_sector = get_next_sector(); - if(!next_sector || next_sector->sector == first_sector->sector) break; + if(next_sector) { + if(visited_sectors.find(next_sector->sector) != visited_sectors.end()) { + break; + } + visited_sectors.insert(next_sector->sector); + } } } decoded_tracks_.insert(track_index); diff --git a/Storage/Disk/Formats/CPCDSK.cpp b/Storage/Disk/Formats/CPCDSK.cpp index ba57c539b..b67d5a007 100644 --- a/Storage/Disk/Formats/CPCDSK.cpp +++ b/Storage/Disk/Formats/CPCDSK.cpp @@ -57,8 +57,14 @@ std::shared_ptr CPCDSK::get_uncached_track_at_position(unsigned int head, // All DSK images reserve 0x100 bytes for their headers. long file_offset = 0x100; if(is_extended_) { - // Tracks are a variable size in the original DSK file format; sum the lengths - // of all tracks prior to the interesting one to get a file offset. + // Tracks are a variable size in the original DSK file format. + + // Check that there is anything stored for this track. + if(!track_sizes_[chronological_track]) { + return nullptr; + } + + // Sum the lengths of all tracks prior to the interesting one to get a file offset. unsigned int t = 0; while(t < chronological_track && t < track_sizes_.size()) { file_offset += track_sizes_[t];