mirror of
https://github.com/TomHarte/CLK.git
synced 2025-11-01 11:16:16 +00:00
Makes a first sweep at converting the storage underlying PCMSegment to vector<bool>.
This is to remove another pain point, in preparation for the work immediately forthcoming but also work as-yet unknown.
This commit is contained in:
@@ -26,9 +26,6 @@ HFE::HFE(const std::string &file_name) :
|
||||
track_list_offset_ = static_cast<long>(file_.get16le()) << 9;
|
||||
}
|
||||
|
||||
HFE::~HFE() {
|
||||
}
|
||||
|
||||
HeadPosition HFE::get_maximum_head_position() {
|
||||
return HeadPosition(track_count_);
|
||||
}
|
||||
@@ -49,13 +46,13 @@ uint16_t HFE::seek_track(Track::Address address) {
|
||||
// based on an assumption of two heads.
|
||||
file_.seek(track_list_offset_ + address.position.as_int() * 4, SEEK_SET);
|
||||
|
||||
long track_offset = static_cast<long>(file_.get16le()) << 9;
|
||||
uint16_t track_length = file_.get16le();
|
||||
long track_offset = static_cast<long>(file_.get16le()) << 9; // Track offset, in units of 512 bytes.
|
||||
uint16_t track_length = file_.get16le(); // Track length, in bytes, containing both the front and back track.
|
||||
|
||||
file_.seek(track_offset, SEEK_SET);
|
||||
if(address.head) file_.seek(256, SEEK_CUR);
|
||||
|
||||
return track_length / 2;
|
||||
return track_length / 2; // Divide by two to give the track length for a single side.
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> HFE::get_track_at_position(Track::Address address) {
|
||||
@@ -64,21 +61,42 @@ std::shared_ptr<Track> HFE::get_track_at_position(Track::Address address) {
|
||||
std::lock_guard<std::mutex> lock_guard(file_.get_file_access_mutex());
|
||||
uint16_t track_length = seek_track(address);
|
||||
|
||||
segment.data.resize(track_length);
|
||||
segment.number_of_bits = track_length * 8;
|
||||
segment.data.resize(track_length * 8);
|
||||
|
||||
// HFE tracks are stored as 256 bytes for side 1, then 256 bytes for side 2,
|
||||
// then 256 bytes for side 1, then 256 bytes for side 2, etc, until the final
|
||||
// 512-byte segment which will contain less than the full 256 bytes.
|
||||
//
|
||||
// seek_track will have advanced an extra initial 256 bytes if the address
|
||||
// refers to side 2, so the loop below can act ass though it were definitely
|
||||
// dealing with side 1.
|
||||
uint16_t c = 0;
|
||||
while(c < track_length) {
|
||||
// Decide how many bytes of at most 256 to read, and read them.
|
||||
uint16_t length = static_cast<uint16_t>(std::min(256, track_length - c));
|
||||
file_.read(&segment.data[c], length);
|
||||
std::vector<uint8_t> section = file_.read(length);
|
||||
|
||||
// Push those into the PCMSegment. In HFE the least-significant bit is
|
||||
// serialised first.
|
||||
for(uint16_t byte = 0; byte < length; ++byte) {
|
||||
const size_t base = (static_cast<size_t>(c) << 3) + static_cast<size_t>(byte);
|
||||
segment.data[base + 0] = !!(section[byte] & 0x01);
|
||||
segment.data[base + 1] = !!(section[byte] & 0x02);
|
||||
segment.data[base + 2] = !!(section[byte] & 0x04);
|
||||
segment.data[base + 3] = !!(section[byte] & 0x08);
|
||||
segment.data[base + 4] = !!(section[byte] & 0x10);
|
||||
segment.data[base + 5] = !!(section[byte] & 0x20);
|
||||
segment.data[base + 6] = !!(section[byte] & 0x40);
|
||||
segment.data[base + 7] = !!(section[byte] & 0x80);
|
||||
}
|
||||
|
||||
// Advance the target pointer, and skip the next 256 bytes of the file
|
||||
// (which will be for the other side of the disk).
|
||||
c += length;
|
||||
file_.seek(256, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
// Flip bytes; HFE's preference is that the least-significant bit
|
||||
// is serialised first, but PCMTrack posts the most-significant first.
|
||||
Storage::Data::BitReverse::reverse(segment.data);
|
||||
return std::make_shared<PCMTrack>(segment);
|
||||
}
|
||||
|
||||
@@ -88,9 +106,11 @@ void HFE::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tra
|
||||
uint16_t track_length = seek_track(track.first);
|
||||
lock_guard.unlock();
|
||||
|
||||
PCMSegment segment = Storage::Disk::track_serialisation(*track.second, Storage::Time(1, track_length * 8));
|
||||
Storage::Data::BitReverse::reverse(segment.data);
|
||||
uint16_t data_length = std::min(static_cast<uint16_t>(segment.data.size()), track_length);
|
||||
const PCMSegment segment = Storage::Disk::track_serialisation(*track.second, Storage::Time(1, track_length * 8));
|
||||
|
||||
// Convert the segment into a byte encoding, LSB first.
|
||||
std::vector<uint8_t> byte_segment = segment.byte_data(false);
|
||||
uint16_t data_length = std::min(static_cast<uint16_t>(byte_segment.size()), track_length);
|
||||
|
||||
lock_guard.lock();
|
||||
seek_track(track.first);
|
||||
@@ -98,7 +118,7 @@ void HFE::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tra
|
||||
uint16_t c = 0;
|
||||
while(c < data_length) {
|
||||
uint16_t length = static_cast<uint16_t>(std::min(256, data_length - c));
|
||||
file_.write(&segment.data[c], length);
|
||||
file_.write(&byte_segment[c], length);
|
||||
c += length;
|
||||
file_.seek(256, SEEK_CUR);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user