mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-09 00:37:27 +00:00
Generalises the concept of multiple samplings of an FM/MFM sector, simplifying CPC DSK support and paving the way for generic weak/fuzzy bit support.
This commit is contained in:
parent
833f8c02a4
commit
f807a6b608
@ -23,17 +23,18 @@ std::unique_ptr<Catalogue> StaticAnalyser::Acorn::GetDFSCatalogue(const std::sha
|
||||
Storage::Encodings::MFM::Sector *details = parser.get_sector(0, 0, 1);
|
||||
|
||||
if(!names || !details) return nullptr;
|
||||
if(names->data.size() != 256 || details->data.size() != 256) return nullptr;
|
||||
if(names->samples.empty() || details->samples.empty()) return nullptr;
|
||||
if(names->samples[0].size() != 256 || details->samples[0].size() != 256) return nullptr;
|
||||
|
||||
uint8_t final_file_offset = details->data[5];
|
||||
uint8_t final_file_offset = details->samples[0][5];
|
||||
if(final_file_offset&7) return nullptr;
|
||||
if(final_file_offset < 8) return nullptr;
|
||||
|
||||
char disk_name[13];
|
||||
snprintf(disk_name, 13, "%.8s%.4s", &names->data[0], &details->data[0]);
|
||||
snprintf(disk_name, 13, "%.8s%.4s", &names->samples[0][0], &details->samples[0][0]);
|
||||
catalogue->name = disk_name;
|
||||
|
||||
switch((details->data[6] >> 4)&3) {
|
||||
switch((details->samples[0][6] >> 4)&3) {
|
||||
case 0: catalogue->bootOption = Catalogue::BootOption::None; break;
|
||||
case 1: catalogue->bootOption = Catalogue::BootOption::LoadBOOT; break;
|
||||
case 2: catalogue->bootOption = Catalogue::BootOption::RunBOOT; break;
|
||||
@ -45,14 +46,14 @@ std::unique_ptr<Catalogue> StaticAnalyser::Acorn::GetDFSCatalogue(const std::sha
|
||||
for(size_t file_offset = final_file_offset - 8; file_offset > 0; file_offset -= 8) {
|
||||
File new_file;
|
||||
char name[10];
|
||||
snprintf(name, 10, "%c.%.7s", names->data[file_offset + 7] & 0x7f, &names->data[file_offset]);
|
||||
snprintf(name, 10, "%c.%.7s", names->samples[0][file_offset + 7] & 0x7f, &names->samples[0][file_offset]);
|
||||
new_file.name = name;
|
||||
new_file.load_address = (uint32_t)(details->data[file_offset] | (details->data[file_offset+1] << 8) | ((details->data[file_offset+6]&0x0c) << 14));
|
||||
new_file.execution_address = (uint32_t)(details->data[file_offset+2] | (details->data[file_offset+3] << 8) | ((details->data[file_offset+6]&0xc0) << 10));
|
||||
new_file.is_protected = !!(names->data[file_offset + 7] & 0x80);
|
||||
new_file.load_address = (uint32_t)(details->samples[0][file_offset] | (details->samples[0][file_offset+1] << 8) | ((details->samples[0][file_offset+6]&0x0c) << 14));
|
||||
new_file.execution_address = (uint32_t)(details->samples[0][file_offset+2] | (details->samples[0][file_offset+3] << 8) | ((details->samples[0][file_offset+6]&0xc0) << 10));
|
||||
new_file.is_protected = !!(names->samples[0][file_offset + 7] & 0x80);
|
||||
|
||||
long data_length = static_cast<long>(details->data[file_offset+4] | (details->data[file_offset+5] << 8) | ((details->data[file_offset+6]&0x30) << 12));
|
||||
int start_sector = details->data[file_offset+7] | ((details->data[file_offset+6]&0x03) << 8);
|
||||
long data_length = static_cast<long>(details->samples[0][file_offset+4] | (details->samples[0][file_offset+5] << 8) | ((details->samples[0][file_offset+6]&0x30) << 12));
|
||||
int start_sector = details->samples[0][file_offset+7] | ((details->samples[0][file_offset+6]&0x03) << 8);
|
||||
new_file.data.reserve(static_cast<size_t>(data_length));
|
||||
|
||||
if(start_sector < 2) continue;
|
||||
@ -65,7 +66,7 @@ std::unique_ptr<Catalogue> StaticAnalyser::Acorn::GetDFSCatalogue(const std::sha
|
||||
if(!next_sector) break;
|
||||
|
||||
long length_from_sector = std::min(data_length, 256l);
|
||||
new_file.data.insert(new_file.data.end(), next_sector->data.begin(), next_sector->data.begin() + length_from_sector);
|
||||
new_file.data.insert(new_file.data.end(), next_sector->samples[0].begin(), next_sector->samples[0].begin() + length_from_sector);
|
||||
data_length -= length_from_sector;
|
||||
}
|
||||
if(!data_length) catalogue->files.push_front(new_file);
|
||||
@ -85,7 +86,7 @@ std::unique_ptr<Catalogue> StaticAnalyser::Acorn::GetADFSCatalogue(const std::sh
|
||||
for(uint8_t c = 2; c < 7; c++) {
|
||||
Storage::Encodings::MFM::Sector *sector = parser.get_sector(0, 0, c);
|
||||
if(!sector) return nullptr;
|
||||
root_directory.insert(root_directory.end(), sector->data.begin(), sector->data.end());
|
||||
root_directory.insert(root_directory.end(), sector->samples[0].begin(), sector->samples[0].end());
|
||||
}
|
||||
|
||||
// Quick sanity checks.
|
||||
@ -93,7 +94,7 @@ std::unique_ptr<Catalogue> StaticAnalyser::Acorn::GetADFSCatalogue(const std::sh
|
||||
if(root_directory[1] != 'H' || root_directory[2] != 'u' || root_directory[3] != 'g' || root_directory[4] != 'o') return nullptr;
|
||||
if(root_directory[0x4FB] != 'H' || root_directory[0x4FC] != 'u' || root_directory[0x4FD] != 'g' || root_directory[0x4FE] != 'o') return nullptr;
|
||||
|
||||
switch(free_space_map_second_half->data[0xfd]) {
|
||||
switch(free_space_map_second_half->samples[0][0xfd]) {
|
||||
default: catalogue->bootOption = Catalogue::BootOption::None; break;
|
||||
case 1: catalogue->bootOption = Catalogue::BootOption::LoadBOOT; break;
|
||||
case 2: catalogue->bootOption = Catalogue::BootOption::RunBOOT; break;
|
||||
|
@ -153,12 +153,12 @@ static void InspectCatalogue(
|
||||
static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, StaticAnalyser::Target &target) {
|
||||
Storage::Encodings::MFM::Parser parser(true, disk);
|
||||
Storage::Encodings::MFM::Sector *boot_sector = parser.get_sector(0, 0, 0x41);
|
||||
if(boot_sector != nullptr) {
|
||||
if(boot_sector != nullptr && !boot_sector->samples.empty()) {
|
||||
// Check that the first 64 bytes of the sector aren't identical; if they are then probably
|
||||
// this disk was formatted and the filler byte never replaced.
|
||||
bool matched = true;
|
||||
for(size_t c = 1; c < 64; c++) {
|
||||
if(boot_sector->data[c] != boot_sector->data[0]) {
|
||||
if(boot_sector->samples[0][c] != boot_sector->samples[0][0]) {
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ CPCDSK::CPCDSK(const char *file_name) :
|
||||
head_count_ = fgetc(file_);
|
||||
|
||||
// Used only for non-extended disks.
|
||||
long size_of_a_track;
|
||||
long size_of_a_track = 0;
|
||||
|
||||
// Used only for extended disks.
|
||||
std::vector<size_t> track_sizes;
|
||||
@ -89,13 +89,33 @@ CPCDSK::CPCDSK(const char *file_name) :
|
||||
|
||||
// Track, side, sector, size and two FDC8272-esque status bytes are stored
|
||||
// per sector, in both regular and extended DSK files.
|
||||
sector.track = static_cast<uint8_t>(fgetc(file_));
|
||||
sector.side = static_cast<uint8_t>(fgetc(file_));
|
||||
sector.sector = static_cast<uint8_t>(fgetc(file_));
|
||||
sector.address.track = static_cast<uint8_t>(fgetc(file_));
|
||||
sector.address.side = static_cast<uint8_t>(fgetc(file_));
|
||||
sector.address.sector = static_cast<uint8_t>(fgetc(file_));
|
||||
sector.size = static_cast<uint8_t>(fgetc(file_));
|
||||
sector.fdc_status1 = static_cast<uint8_t>(fgetc(file_));
|
||||
sector.fdc_status2 = static_cast<uint8_t>(fgetc(file_));
|
||||
|
||||
if(sector.fdc_status2 & 0x20) {
|
||||
// The CRC failed in the data field.
|
||||
sector.has_data_crc_error = true;
|
||||
} else {
|
||||
if(sector.fdc_status1 & 0x20) {
|
||||
// The CRC failed in the ID field.
|
||||
sector.has_header_crc_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(sector.fdc_status2 & 0x40) {
|
||||
// This sector is marked as deleted.
|
||||
sector.is_deleted = true;
|
||||
}
|
||||
|
||||
if(sector.fdc_status2 & 0x01) {
|
||||
// Data field wasn't found.
|
||||
sector.samples.clear();
|
||||
}
|
||||
|
||||
// Figuring out the actual data size is a little more work...
|
||||
size_t data_size = static_cast<size_t>(128 << sector.size);
|
||||
size_t stored_data_size = data_size;
|
||||
@ -130,16 +150,17 @@ CPCDSK::CPCDSK(const char *file_name) :
|
||||
|
||||
// As per the weak/fuzzy sector extension, multiple samplings may be stored here.
|
||||
// Plan to tead as many as there were.
|
||||
sector.data.resize(number_of_samplings);
|
||||
sector.samples.emplace_back();
|
||||
sector.samples.resize(number_of_samplings);
|
||||
while(number_of_samplings--) {
|
||||
sector.data[number_of_samplings].resize(stored_data_size);
|
||||
sector.samples[number_of_samplings].resize(stored_data_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sector contents are at offset 0x100 into the track.
|
||||
fseek(file_, file_offset + 0x100, SEEK_SET);
|
||||
for(auto §or: track->sectors) {
|
||||
for(auto &data : sector.data) {
|
||||
for(auto &data : sector.samples) {
|
||||
fread(data.data(), 1, data.size(), file_);
|
||||
}
|
||||
}
|
||||
@ -174,40 +195,9 @@ std::shared_ptr<Track> CPCDSK::get_track_at_position(::Storage::Disk::Track::Add
|
||||
Track *track = tracks_[chronological_track].get();
|
||||
if(!track) return nullptr;
|
||||
|
||||
// Transcribe sectors and return.
|
||||
// TODO: is this transcription really necessary?
|
||||
std::vector<Storage::Encodings::MFM::Sector> sectors;
|
||||
std::vector<const Storage::Encodings::MFM::Sector *> sectors;
|
||||
for(auto §or : track->sectors) {
|
||||
Storage::Encodings::MFM::Sector new_sector;
|
||||
new_sector.address.track = sector.track;
|
||||
new_sector.address.side = sector.side;
|
||||
new_sector.address.sector = sector.sector;
|
||||
new_sector.size = sector.size;
|
||||
|
||||
// TODO: deal with weak/fuzzy sectors.
|
||||
new_sector.data.insert(new_sector.data.begin(), sector.data[0].begin(), sector.data[0].end());
|
||||
|
||||
if(sector.fdc_status2 & 0x20) {
|
||||
// The CRC failed in the data field.
|
||||
new_sector.has_data_crc_error = true;
|
||||
} else {
|
||||
if(sector.fdc_status1 & 0x20) {
|
||||
// The CRC failed in the ID field.
|
||||
new_sector.has_header_crc_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(sector.fdc_status2 & 0x40) {
|
||||
// This sector is marked as deleted.
|
||||
new_sector.is_deleted = true;
|
||||
}
|
||||
|
||||
if(sector.fdc_status2 & 0x01) {
|
||||
// Data field wasn't found.
|
||||
new_sector.data.clear();
|
||||
}
|
||||
|
||||
sectors.push_back(std::move(new_sector));
|
||||
sectors.push_back(§or);
|
||||
}
|
||||
|
||||
// TODO: FM encoding, data rate?
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "../DiskImage.hpp"
|
||||
#include "../../../FileHolder.hpp"
|
||||
#include "../../Encodings/MFM/Sector.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -54,17 +55,9 @@ class CPCDSK: public DiskImage, public Storage::FileHolder {
|
||||
uint8_t gap3_length;
|
||||
uint8_t filler_byte;
|
||||
|
||||
struct Sector {
|
||||
uint8_t track;
|
||||
uint8_t side;
|
||||
uint8_t sector;
|
||||
uint8_t size;
|
||||
struct Sector: public ::Storage::Encodings::MFM::Sector {
|
||||
uint8_t fdc_status1;
|
||||
uint8_t fdc_status2;
|
||||
|
||||
// If multiple copies are present, that implies a sector with weak bits, for which multiple
|
||||
// samplings were obtained.
|
||||
std::vector<std::vector<uint8_t>> data;
|
||||
};
|
||||
|
||||
std::vector<Sector> sectors;
|
||||
|
@ -31,7 +31,8 @@ std::shared_ptr<Track> Storage::Disk::track_for_sectors(uint8_t *const source, u
|
||||
first_sector++;
|
||||
new_sector.size = size;
|
||||
|
||||
new_sector.data.insert(new_sector.data.begin(), source + source_pointer, source + source_pointer + byte_size);
|
||||
new_sector.samples.emplace_back();
|
||||
new_sector.samples[0].insert(new_sector.samples[0].begin(), source + source_pointer, source + source_pointer + byte_size);
|
||||
source_pointer += byte_size;
|
||||
}
|
||||
|
||||
@ -53,6 +54,7 @@ void Storage::Disk::decode_sectors(Track &track, uint8_t *const destination, uin
|
||||
if(pair.second.address.sector > last_sector) continue;
|
||||
if(pair.second.address.sector < first_sector) continue;
|
||||
if(pair.second.size != sector_size) continue;
|
||||
memcpy(&destination[pair.second.address.sector * byte_size], pair.second.data.data(), std::min(pair.second.data.size(), byte_size));
|
||||
if(pair.second.samples.empty()) continue;
|
||||
memcpy(&destination[pair.second.address.sector * byte_size], pair.second.samples[0].data(), std::min(pair.second.samples[0].size(), byte_size));
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ class FMEncoder: public Encoder {
|
||||
|
||||
template<class T> std::shared_ptr<Storage::Disk::Track>
|
||||
GetTrackWithSectors(
|
||||
const std::vector<Sector> §ors,
|
||||
const std::vector<const Sector *> §ors,
|
||||
size_t post_index_address_mark_bytes, uint8_t post_index_address_mark_value,
|
||||
size_t pre_address_mark_bytes,
|
||||
size_t post_address_mark_bytes, uint8_t post_address_mark_value,
|
||||
@ -137,38 +137,39 @@ template<class T> std::shared_ptr<Storage::Disk::Track>
|
||||
for(size_t c = 0; c < post_index_address_mark_bytes; c++) shifter.add_byte(post_index_address_mark_value);
|
||||
|
||||
// add sectors
|
||||
for(const Sector §or : sectors) {
|
||||
for(const Sector *sector : sectors) {
|
||||
// gap
|
||||
for(size_t c = 0; c < pre_address_mark_bytes; c++) shifter.add_byte(0x00);
|
||||
|
||||
// sector header
|
||||
shifter.add_ID_address_mark();
|
||||
shifter.add_byte(sector.address.track);
|
||||
shifter.add_byte(sector.address.side);
|
||||
shifter.add_byte(sector.address.sector);
|
||||
shifter.add_byte(sector.size);
|
||||
shifter.add_crc(sector.has_header_crc_error);
|
||||
shifter.add_byte(sector->address.track);
|
||||
shifter.add_byte(sector->address.side);
|
||||
shifter.add_byte(sector->address.sector);
|
||||
shifter.add_byte(sector->size);
|
||||
shifter.add_crc(sector->has_header_crc_error);
|
||||
|
||||
// gap
|
||||
for(size_t c = 0; c < post_address_mark_bytes; c++) shifter.add_byte(post_address_mark_value);
|
||||
for(size_t c = 0; c < pre_data_mark_bytes; c++) shifter.add_byte(0x00);
|
||||
|
||||
// data, if attached
|
||||
if(!sector.data.empty()) {
|
||||
if(sector.is_deleted)
|
||||
// TODO: allow for weak/fuzzy data.
|
||||
if(!sector->samples.empty()) {
|
||||
if(sector->is_deleted)
|
||||
shifter.add_deleted_data_address_mark();
|
||||
else
|
||||
shifter.add_data_address_mark();
|
||||
|
||||
size_t c = 0;
|
||||
size_t declared_length = static_cast<size_t>(128 << sector.size);
|
||||
for(c = 0; c < sector.data.size() && c < declared_length; c++) {
|
||||
shifter.add_byte(sector.data[c]);
|
||||
size_t declared_length = static_cast<size_t>(128 << sector->size);
|
||||
for(c = 0; c < sector->samples[0].size() && c < declared_length; c++) {
|
||||
shifter.add_byte(sector->samples[0][c]);
|
||||
}
|
||||
for(; c < declared_length; c++) {
|
||||
shifter.add_byte(0x00);
|
||||
}
|
||||
shifter.add_crc(sector.has_data_crc_error);
|
||||
shifter.add_crc(sector->has_data_crc_error);
|
||||
}
|
||||
|
||||
// gap
|
||||
@ -202,7 +203,26 @@ void Encoder::add_crc(bool incorrectly) {
|
||||
|
||||
const size_t Storage::Encodings::MFM::DefaultSectorGapLength = std::numeric_limits<size_t>::max();
|
||||
|
||||
static std::vector<const Sector *> sector_pointers(const std::vector<Sector> §ors) {
|
||||
std::vector<const Sector *> pointers;
|
||||
for(const Sector §or: sectors) {
|
||||
pointers.push_back(§or);
|
||||
}
|
||||
return pointers;
|
||||
}
|
||||
|
||||
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetFMTrackWithSectors(const std::vector<Sector> §ors, size_t sector_gap_length, uint8_t sector_gap_filler_byte) {
|
||||
return GetTrackWithSectors<FMEncoder>(
|
||||
sector_pointers(sectors),
|
||||
26, 0xff,
|
||||
6,
|
||||
11, 0xff,
|
||||
6,
|
||||
(sector_gap_length != DefaultSectorGapLength) ? sector_gap_length : 27, 0xff,
|
||||
6250); // i.e. 250kbps (including clocks) * 60 = 15000kpm, at 300 rpm => 50 kbits/rotation => 6250 bytes/rotation
|
||||
}
|
||||
|
||||
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetFMTrackWithSectors(const std::vector<const Sector *> §ors, size_t sector_gap_length, uint8_t sector_gap_filler_byte) {
|
||||
return GetTrackWithSectors<FMEncoder>(
|
||||
sectors,
|
||||
26, 0xff,
|
||||
@ -214,6 +234,17 @@ std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetFMTrackWithSec
|
||||
}
|
||||
|
||||
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetMFMTrackWithSectors(const std::vector<Sector> §ors, size_t sector_gap_length, uint8_t sector_gap_filler_byte) {
|
||||
return GetTrackWithSectors<MFMEncoder>(
|
||||
sector_pointers(sectors),
|
||||
50, 0x4e,
|
||||
12,
|
||||
22, 0x4e,
|
||||
12,
|
||||
(sector_gap_length != DefaultSectorGapLength) ? sector_gap_length : 54, 0xff,
|
||||
12500); // unintelligently: double the single-density bytes/rotation (or: 500kbps @ 300 rpm)
|
||||
}
|
||||
|
||||
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetMFMTrackWithSectors(const std::vector<const Sector *> §ors, size_t sector_gap_length, uint8_t sector_gap_filler_byte) {
|
||||
return GetTrackWithSectors<MFMEncoder>(
|
||||
sectors,
|
||||
50, 0x4e,
|
||||
|
@ -28,6 +28,7 @@ extern const size_t DefaultSectorGapLength;
|
||||
@param sector_gap_filler_byte If specified, sets the value (unencoded) that is used to populate the gap between each ID and its data.
|
||||
*/
|
||||
std::shared_ptr<Storage::Disk::Track> GetMFMTrackWithSectors(const std::vector<Sector> §ors, size_t sector_gap_length = DefaultSectorGapLength, uint8_t sector_gap_filler_byte = 0x4e);
|
||||
std::shared_ptr<Storage::Disk::Track> GetMFMTrackWithSectors(const std::vector<const Sector *> §ors, size_t sector_gap_length = DefaultSectorGapLength, uint8_t sector_gap_filler_byte = 0x4e);
|
||||
|
||||
/*!
|
||||
Converts a vector of sectors into a properly-encoded FM track.
|
||||
@ -37,6 +38,7 @@ std::shared_ptr<Storage::Disk::Track> GetMFMTrackWithSectors(const std::vector<S
|
||||
@param sector_gap_filler_byte If specified, sets the value (unencoded) that is used to populate the gap between each ID and its data.
|
||||
*/
|
||||
std::shared_ptr<Storage::Disk::Track> GetFMTrackWithSectors(const std::vector<Sector> §ors, size_t sector_gap_length = DefaultSectorGapLength, uint8_t sector_gap_filler_byte = 0x4e);
|
||||
std::shared_ptr<Storage::Disk::Track> GetFMTrackWithSectors(const std::vector<const Sector *> §ors, size_t sector_gap_length = DefaultSectorGapLength, uint8_t sector_gap_filler_byte = 0x4e);
|
||||
|
||||
class Encoder {
|
||||
public:
|
||||
|
@ -34,7 +34,9 @@ struct Sector {
|
||||
|
||||
Address address;
|
||||
uint8_t size = 0;
|
||||
std::vector<uint8_t> data;
|
||||
|
||||
// Multiple samplings of the underlying data are accepted, to allow weak and fuzzy data to be communicated.
|
||||
std::vector<std::vector<uint8_t>> samples;
|
||||
|
||||
bool has_data_crc_error = false;
|
||||
bool has_header_crc_error = false;
|
||||
@ -45,7 +47,7 @@ struct Sector {
|
||||
Sector(const Sector &&rhs) noexcept :
|
||||
address(rhs.address),
|
||||
size(rhs.size),
|
||||
data(std::move(rhs.data)),
|
||||
samples(std::move(rhs.samples)),
|
||||
has_data_crc_error(rhs.has_data_crc_error),
|
||||
has_header_crc_error(rhs.has_header_crc_error),
|
||||
is_deleted(rhs.is_deleted ){}
|
||||
|
@ -62,7 +62,8 @@ std::map<size_t, Storage::Encodings::MFM::Sector> Storage::Encodings::MFM::secto
|
||||
shifter.set_should_obey_syncs(true);
|
||||
break;
|
||||
default:
|
||||
new_sector->data.push_back(shifter.get_byte());
|
||||
if(new_sector->samples.empty()) new_sector->samples.emplace_back();
|
||||
new_sector->samples[0].push_back(shifter.get_byte());
|
||||
++position;
|
||||
if(position == size + 4) {
|
||||
result.insert(std::make_pair(start_location, std::move(*new_sector)));
|
||||
|
@ -27,12 +27,12 @@ std::unique_ptr<Storage::Disk::CPM::Catalogue> Storage::Disk::CPM::GetCatalogue(
|
||||
size_t size_read = 0;
|
||||
do {
|
||||
Storage::Encodings::MFM::Sector *sector_contents = parser.get_sector(0, static_cast<uint8_t>(track), static_cast<uint8_t>(parameters.first_sector + sector));
|
||||
if(!sector_contents) {
|
||||
if(!sector_contents || sector_contents->samples.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
catalogue.insert(catalogue.end(), sector_contents->data.begin(), sector_contents->data.end());
|
||||
sector_size = sector_contents->data.size();
|
||||
catalogue.insert(catalogue.end(), sector_contents->samples[0].begin(), sector_contents->samples[0].end());
|
||||
sector_size = sector_contents->samples[0].size();
|
||||
|
||||
size_read += sector_size;
|
||||
sector++;
|
||||
@ -136,7 +136,7 @@ std::unique_ptr<Storage::Disk::CPM::Catalogue> Storage::Disk::CPM::GetCatalogue(
|
||||
|
||||
for(int s = 0; s < sectors_per_block && record < number_of_records; s++) {
|
||||
Storage::Encodings::MFM::Sector *sector_contents = parser.get_sector(0, static_cast<uint8_t>(track), static_cast<uint8_t>(parameters.first_sector + sector));
|
||||
if(!sector_contents) break;
|
||||
if(!sector_contents || sector_contents->samples.empty()) break;
|
||||
sector++;
|
||||
if(sector == parameters.sectors_per_track) {
|
||||
sector = 0;
|
||||
@ -144,7 +144,7 @@ std::unique_ptr<Storage::Disk::CPM::Catalogue> Storage::Disk::CPM::GetCatalogue(
|
||||
}
|
||||
|
||||
int records_to_copy = std::min(entry->number_of_records - record, records_per_sector);
|
||||
memcpy(&new_file.data[entry->extent * bytes_per_catalogue_entry + static_cast<size_t>(record) * 128], sector_contents->data.data(), static_cast<size_t>(records_to_copy) * 128);
|
||||
memcpy(&new_file.data[entry->extent * bytes_per_catalogue_entry + static_cast<size_t>(record) * 128], sector_contents->samples[0].data(), static_cast<size_t>(records_to_copy) * 128);
|
||||
record += records_to_copy;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user