1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-30 04:50:08 +00:00

Collate descriptions of all tracks.

This commit is contained in:
Thomas Harte 2021-12-26 14:49:51 -05:00
parent 28572d4392
commit 9d3cf9c73c
2 changed files with 83 additions and 3 deletions

View File

@ -25,6 +25,10 @@ constexpr uint32_t block(const char (& src)[5]) {
IPF::IPF(const std::string &file_name) : file_(file_name) {
std::map<uint32_t, Track::Address> tracks_by_data_key;
// For now, just build up a list of tracks that exist, noting the file position at which their data begins
// plus the other fields that'll be necessary to convert them into flux on demand later.
while(true) {
const auto start_of_block = file_.tell();
const uint32_t type = file_.get32be();
@ -96,12 +100,63 @@ IPF::IPF(const std::string &file_name) : file_(file_name) {
// Ignore: disk number, creator ID, reserved area.
} break;
case block("IMGE"):
break;
case block("IMGE"): {
// Get track location.
const uint32_t track = file_.get32be();
const uint32_t side = file_.get32be();
const Track::Address address{int(side), HeadPosition(int(track))};
// Hence generate a TrackDescription.
auto pair = tracks_.emplace(address, TrackDescription());
TrackDescription &description = pair.first->second;
// Read those fields of interest...
// Bit density. I've no idea why the density can't just be given as a measurement.
description.density = TrackDescription::Density(file_.get32be());
if(description.density > TrackDescription::Density::Max) {
description.density = TrackDescription::Density::Unknown;
}
file_.seek(12, SEEK_CUR); // Skipped: signal type, track bytes, start byte position.
description.start_bit_pos = file_.get32be();
description.data_bits = file_.get32be();
description.gap_bits = file_.get32be();
file_.seek(4, SEEK_CUR); // Skipped: track bits, which is entirely redundant.
description.block_count = file_.get32be();
file_.seek(4, SEEK_CUR); // Skipped: encoder process.
description.has_fuzzy_bits = file_.get32be() & 1;
// For some reason the authors decided to introduce another primary key,
// in addition to that which naturally exists of (track, side). So set up
// a mapping from the one to the other.
const uint32_t data_key = file_.get32be();
tracks_by_data_key.emplace(data_key, address);
} break;
case block("DATA"): {
length += file_.get32be();
printf("Handling DATA block at %ld of length %d\n", start_of_block, length);
file_.seek(8, SEEK_CUR); // Skipped: bit size, CRC.
// Grab the data key and use that to establish the file starting
// position for this track.
//
// Assumed here: DATA records will come after corresponding IMGE records.
const uint32_t data_key = file_.get32be();
const auto pair = tracks_by_data_key.find(data_key);
if(pair == tracks_by_data_key.end()) {
break;
}
auto description = tracks_.find(pair->second);
if(description == tracks_.end()) {
break;
}
description->second.file_offset = file_.tell();
} break;
}

View File

@ -14,6 +14,7 @@
#include "../../../TargetPlatforms.hpp"
#include <string>
#include <map>
namespace Storage {
namespace Disk {
@ -41,8 +42,32 @@ class IPF: public DiskImage, public TargetPlatform::TypeDistinguisher {
Storage::FileHolder file_;
uint16_t seek_track(Track::Address address);
struct TrackDescription {
long file_offset = 0;
enum class Density {
Unknown,
Noise,
Auto,
CopylockAmiga,
CopylockAmigaNew,
CopylockST,
SpeedlockAmiga,
OldSpeedlockAmiga,
AdamBrierleyAmiga,
AdamBrierleyDensityKeyAmiga,
Max = AdamBrierleyDensityKeyAmiga
} density = Density::Unknown;
uint32_t start_bit_pos = 0;
uint32_t data_bits = 0;
uint32_t gap_bits = 0;
uint32_t block_count;
bool has_fuzzy_bits = false;
};
int head_count_;
int track_count_;
std::map<Track::Address, TrackDescription> tracks_;
TargetPlatform::Type target_platform_type() final {
return TargetPlatform::Type(platform_type_);