mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-21 21:33:54 +00:00
Made reading of data optional.
This commit is contained in:
parent
9acc80260f
commit
704495ff42
@ -233,7 +233,7 @@ Analyser::Static::TargetList Analyser::Static::AmstradCPC::GetTargets(const Medi
|
|||||||
|
|
||||||
for(auto &disk: media.disks) {
|
for(auto &disk: media.disks) {
|
||||||
// Check for an ordinary catalogue, making sure this isn't actually a ZX Spectrum disk.
|
// Check for an ordinary catalogue, making sure this isn't actually a ZX Spectrum disk.
|
||||||
std::unique_ptr<Storage::Disk::CPM::Catalogue> data_catalogue = Storage::Disk::CPM::GetCatalogue(disk, data_format);
|
std::unique_ptr<Storage::Disk::CPM::Catalogue> data_catalogue = Storage::Disk::CPM::GetCatalogue(disk, data_format, false);
|
||||||
if(data_catalogue && !data_catalogue->is_zx_spectrum_booter()) {
|
if(data_catalogue && !data_catalogue->is_zx_spectrum_booter()) {
|
||||||
InspectCatalogue(*data_catalogue, target);
|
InspectCatalogue(*data_catalogue, target);
|
||||||
target->media.disks.push_back(disk);
|
target->media.disks.push_back(disk);
|
||||||
@ -247,7 +247,7 @@ Analyser::Static::TargetList Analyser::Static::AmstradCPC::GetTargets(const Medi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Failing that check for a system catalogue.
|
// Failing that check for a system catalogue.
|
||||||
std::unique_ptr<Storage::Disk::CPM::Catalogue> system_catalogue = Storage::Disk::CPM::GetCatalogue(disk, system_format);
|
std::unique_ptr<Storage::Disk::CPM::Catalogue> system_catalogue = Storage::Disk::CPM::GetCatalogue(disk, system_format, false);
|
||||||
if(system_catalogue && !system_catalogue->is_zx_spectrum_booter()) {
|
if(system_catalogue && !system_catalogue->is_zx_spectrum_booter()) {
|
||||||
InspectCatalogue(*system_catalogue, target);
|
InspectCatalogue(*system_catalogue, target);
|
||||||
target->media.disks.push_back(disk);
|
target->media.disks.push_back(disk);
|
||||||
|
@ -97,7 +97,7 @@ bool IsSpectrumDisk(const std::shared_ptr<Storage::Disk::Disk> &disk) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ... otherwise read a CPM directory and look for a BASIC program called "DISK".
|
// ... otherwise read a CPM directory and look for a BASIC program called "DISK".
|
||||||
const auto catalogue = Storage::Disk::CPM::GetCatalogue(disk, cpm_format);
|
const auto catalogue = Storage::Disk::CPM::GetCatalogue(disk, cpm_format, false);
|
||||||
return catalogue && catalogue->is_zx_spectrum_booter();
|
return catalogue && catalogue->is_zx_spectrum_booter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
using namespace Storage::Disk::CPM;
|
using namespace Storage::Disk::CPM;
|
||||||
|
|
||||||
std::unique_ptr<Storage::Disk::CPM::Catalogue> Storage::Disk::CPM::GetCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk, const ParameterBlock ¶meters) {
|
std::unique_ptr<Storage::Disk::CPM::Catalogue> Storage::Disk::CPM::GetCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk, const ParameterBlock ¶meters, bool with_contents) {
|
||||||
Storage::Encodings::MFM::Parser parser(Encodings::MFM::Density::Double, disk);
|
Storage::Encodings::MFM::Parser parser(Encodings::MFM::Density::Double, disk);
|
||||||
|
|
||||||
// Assemble the actual bytes of the catalogue.
|
// Assemble the actual bytes of the catalogue.
|
||||||
@ -87,38 +87,42 @@ std::unique_ptr<Storage::Disk::CPM::Catalogue> Storage::Disk::CPM::GetCatalogue(
|
|||||||
|
|
||||||
// Sort the catalogue entries and then map to files.
|
// Sort the catalogue entries and then map to files.
|
||||||
std::sort(catalogue_entries.begin(), catalogue_entries.end());
|
std::sort(catalogue_entries.begin(), catalogue_entries.end());
|
||||||
|
auto result = std::make_unique<Catalogue>();
|
||||||
std::unique_ptr<Catalogue> result(new Catalogue);
|
|
||||||
|
|
||||||
bool has_long_allocation_units = (parameters.tracks * parameters.sectors_per_track * int(sector_size) / parameters.block_size) >= 256;
|
bool has_long_allocation_units = (parameters.tracks * parameters.sectors_per_track * int(sector_size) / parameters.block_size) >= 256;
|
||||||
std::size_t bytes_per_catalogue_entry = (has_long_allocation_units ? 8 : 16) * size_t(parameters.block_size);
|
std::size_t bytes_per_catalogue_entry = (has_long_allocation_units ? 8 : 16) * size_t(parameters.block_size);
|
||||||
int sectors_per_block = parameters.block_size / int(sector_size);
|
int sectors_per_block = parameters.block_size / int(sector_size);
|
||||||
int records_per_sector = int(sector_size) / 128;
|
int records_per_sector = int(sector_size) / 128;
|
||||||
|
|
||||||
|
result->files.reserve(catalogue_entries.size());
|
||||||
auto entry = catalogue_entries.begin();
|
auto entry = catalogue_entries.begin();
|
||||||
while(entry != catalogue_entries.end()) {
|
while(entry != catalogue_entries.end()) {
|
||||||
// Find final catalogue entry that relates to the same file.
|
// Find first catalogue entry that relates to a different file.
|
||||||
auto final_entry = entry + 1;
|
auto final_entry = entry;
|
||||||
while(final_entry != catalogue_entries.end() && final_entry->is_same_file(*entry)) {
|
do {
|
||||||
final_entry++;
|
++final_entry;
|
||||||
}
|
} while(final_entry != catalogue_entries.end() && final_entry->is_same_file(*entry));
|
||||||
final_entry--;
|
|
||||||
|
|
||||||
// Create file.
|
// Create file.
|
||||||
result->files.emplace_back();
|
File &new_file = result->files.emplace_back();
|
||||||
File &new_file = result->files.back();
|
|
||||||
new_file.user_number = entry->user_number;
|
new_file.user_number = entry->user_number;
|
||||||
new_file.name = std::move(entry->name);
|
new_file.name = std::move(entry->name);
|
||||||
new_file.type = std::move(entry->type);
|
new_file.type = std::move(entry->type);
|
||||||
new_file.read_only = entry->read_only;
|
new_file.read_only = entry->read_only;
|
||||||
new_file.system = entry->system;
|
new_file.system = entry->system;
|
||||||
|
|
||||||
|
// Skip contents if not required.
|
||||||
|
if(!with_contents) {
|
||||||
|
entry = final_entry;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Create storage for data.
|
// Create storage for data.
|
||||||
std::size_t required_size = final_entry->extent * bytes_per_catalogue_entry + size_t(final_entry->number_of_records) * 128;
|
std::size_t required_size = final_entry->extent * bytes_per_catalogue_entry + size_t(final_entry->number_of_records) * 128;
|
||||||
new_file.data.resize(required_size);
|
new_file.data.resize(required_size);
|
||||||
|
|
||||||
// Accumulate all data.
|
// Accumulate all data.
|
||||||
while(entry <= final_entry) {
|
while(entry != final_entry) {
|
||||||
int record = 0;
|
int record = 0;
|
||||||
int number_of_records = (entry->number_of_records != 0x80) ? entry->number_of_records : (has_long_allocation_units ? 8 : 16);
|
int number_of_records = (entry->number_of_records != 0x80) ? entry->number_of_records : (has_long_allocation_units ? 8 : 16);
|
||||||
for(std::size_t block = 0; block < (has_long_allocation_units ? 8 : 16) && record < number_of_records; block++) {
|
for(std::size_t block = 0; block < (has_long_allocation_units ? 8 : 16) && record < number_of_records; block++) {
|
||||||
@ -152,7 +156,7 @@ std::unique_ptr<Storage::Disk::CPM::Catalogue> Storage::Disk::CPM::GetCatalogue(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entry++;
|
++entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +168,7 @@ bool Catalogue::is_zx_spectrum_booter() {
|
|||||||
const auto file = std::find_if(files.begin(), files.end(), [](const auto &file) { return file.name == "DISK "; });
|
const auto file = std::find_if(files.begin(), files.end(), [](const auto &file) { return file.name == "DISK "; });
|
||||||
if(file == files.end()) return false;
|
if(file == files.end()) return false;
|
||||||
|
|
||||||
// TODO: check the file is valid ZX Spectrum BASIC.
|
// TODO: check the file is valid ZX Spectrum BASIC if it has contents.
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,6 @@ struct Catalogue {
|
|||||||
bool is_zx_spectrum_booter();
|
bool is_zx_spectrum_booter();
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Catalogue> GetCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk, const ParameterBlock ¶meters);
|
std::unique_ptr<Catalogue> GetCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk, const ParameterBlock ¶meters, bool with_contents);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user