1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +00:00

Taking a whole bunch of guesses, this might be correct.

This commit is contained in:
Thomas Harte 2017-08-10 22:33:08 -04:00
parent 6a65c7a52a
commit 994179f188
3 changed files with 87 additions and 3 deletions

View File

@ -27,9 +27,10 @@ void StaticAnalyser::AmstradCPC::AddTargets(
// This is CPC data format.
Storage::Disk::CPM::ParameterBlock parameters;
parameters.sectors_per_track = 9;
parameters.sector_size = 512;
parameters.block_size = 1024;
parameters.first_sector = 0xc1;
parameters.catalogue_allocation_bitmap = 0xc000;
parameters.logic_extents_per_physical = 1;
parameters.reserved_tracks = 0;
Storage::Disk::CPM::GetCatalogue(target.disks.front(), parameters);

View File

@ -17,7 +17,9 @@ std::unique_ptr<Storage::Disk::CPM::Catalogue> Storage::Disk::CPM::GetCatalogue(
// Assemble the actual bytes of the catalogue.
std::vector<uint8_t> catalogue;
size_t sector_size = 1;
uint16_t catalogue_allocation_bitmap = parameters.catalogue_allocation_bitmap;
if(!catalogue_allocation_bitmap) return nullptr;
int sector = 0;
int track = parameters.reserved_tracks;
while(catalogue_allocation_bitmap) {
@ -28,6 +30,7 @@ std::unique_ptr<Storage::Disk::CPM::Catalogue> Storage::Disk::CPM::GetCatalogue(
}
catalogue.insert(catalogue.end(), sector_contents->data.begin(), sector_contents->data.end());
sector_size = sector_contents->data.size();
}
catalogue_allocation_bitmap <<= 1;
@ -39,5 +42,73 @@ std::unique_ptr<Storage::Disk::CPM::Catalogue> Storage::Disk::CPM::GetCatalogue(
}
}
return nullptr;
std::unique_ptr<Catalogue> result(new Catalogue);
// From the catalogue, create files.
std::map<std::vector<uint8_t>, size_t> indices_by_name;
File empty_file;
for(size_t c = 0; c < catalogue.size(); c += 32) {
// Skip this file if it's deleted; this is marked by it having 0xe5 as its user number
if(catalogue[c] == 0xe5) continue;
// Check whether this file has yet been seen; if not then add it to the list
std::vector<uint8_t> descriptor;
size_t index;
descriptor.insert(descriptor.begin(), &catalogue[c], &catalogue[c + 12]);
auto iterator = indices_by_name.find(descriptor);
if(iterator != indices_by_name.end()) {
index = iterator->second;
} else {
File new_file;
new_file.user_number = catalogue[c];
for(size_t s = 0; s < 8; s++) new_file.name.push_back((char)catalogue[c + s + 1]);
for(size_t s = 0; s < 3; s++) new_file.type.push_back((char)catalogue[c + s + 9] & 0x7f);
new_file.read_only = catalogue[c + 9] & 0x80;
new_file.system = catalogue[c + 10] & 0x80;
index = result->files.size();
result->files.push_back(new_file);
indices_by_name[descriptor] = index;
printf("%s\n", new_file.name.c_str());
}
// figure out where this data needs to be pasted in
int extent = catalogue[c + 12] + (catalogue[c + 14] << 5);
int number_of_records = catalogue[c + 15];
size_t required_size = (size_t)(extent * 128 + number_of_records) * 128;
if(result->files[index].data.size() < required_size) {
result->files[index].data.resize(required_size);
}
printf("%d records for extent %d: ", number_of_records, extent);
int sectors_per_block = parameters.block_size / (int)sector_size;
int records_per_sector = (int)sector_size / 128;
int record = 0;
for(size_t block = 0; block < 16; block++) {
int block_number = catalogue[c + 16 + block];
if(!block_number) continue;
int first_sector = block_number * sectors_per_block;
sector = first_sector % parameters.sectors_per_track;
track = first_sector / parameters.sectors_per_track;
for(int s = 0; s < sectors_per_block && record < number_of_records; s++) {
std::shared_ptr<Storage::Encodings::MFM::Sector> sector_contents = parser.get_sector((uint8_t)track, (uint8_t)(parameters.first_sector + sector));
if(!sector_contents) break;
sector++;
if(sector == parameters.sectors_per_track) {
sector = 0;
track++;
}
int records_to_copy = std::min(number_of_records - record, records_per_sector);
memcpy(&result->files[index].data[extent * 16384 + record * 128], sector_contents->data.data(), records_to_copy * 128);
record += records_to_copy;
}
}
printf("\n");
}
return result;
}

View File

@ -10,7 +10,11 @@
#define Storage_Disk_Parsers_CPM_hpp
#include "../Disk.hpp"
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
namespace Storage {
namespace Disk {
@ -18,16 +22,24 @@ namespace CPM {
struct ParameterBlock {
int sectors_per_track;
int sector_size;
int block_size;
int first_sector;
int logic_extents_per_physical;
uint16_t catalogue_allocation_bitmap;
int reserved_tracks;
};
struct File {
uint8_t user_number;
std::string name;
std::string type;
bool read_only;
bool system;
std::vector<uint8_t> data;
};
struct Catalogue {
std::vector<File> files;
};
std::unique_ptr<Catalogue> GetCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk, const ParameterBlock &parameters);