mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Switches to producing a single segment for NIBs and DSKs.
I've now seemingly verified that the values read back by the CPU are those I'm intending to produce, so I'm at a loss.
This commit is contained in:
parent
05e31d7594
commit
5e34c1b6b8
@ -47,7 +47,7 @@ std::shared_ptr<Track> AppleDSK::get_track_at_position(Track::Address address) {
|
||||
file_.seek(file_offset, SEEK_SET);
|
||||
const std::vector<uint8_t> track_data = file_.read(static_cast<size_t>(bytes_per_sector * sectors_per_track_));
|
||||
|
||||
std::vector<Storage::Disk::PCMSegment> segments;
|
||||
Storage::Disk::PCMSegment segment;
|
||||
const uint8_t track = static_cast<uint8_t>(address.position >> 2);
|
||||
|
||||
// In either case below, the code aims for exactly 50,000 bits per track.
|
||||
@ -55,11 +55,10 @@ std::shared_ptr<Track> AppleDSK::get_track_at_position(Track::Address address) {
|
||||
// Write the sectors.
|
||||
uint8_t sector_number_ = 0;
|
||||
for(std::size_t c = 0; c < 16; ++c) {
|
||||
segments.push_back(Encodings::AppleGCR::six_and_two_sync(10));
|
||||
segments.push_back(Encodings::AppleGCR::header(0, track, sector_number_));
|
||||
segments.push_back(Encodings::AppleGCR::six_and_two_sync(10));
|
||||
segments.push_back(Encodings::AppleGCR::six_and_two_data(&track_data[c * 256]));
|
||||
segments.push_back(Encodings::AppleGCR::six_and_two_sync(10));
|
||||
segment += Encodings::AppleGCR::six_and_two_sync(10);
|
||||
segment += Encodings::AppleGCR::header(0, track, sector_number_);
|
||||
segment += Encodings::AppleGCR::six_and_two_sync(10);
|
||||
segment += Encodings::AppleGCR::six_and_two_data(&track_data[c * 256]);
|
||||
|
||||
// DOS and Pro DOS interleave sectors on disk, and they're represented in a disk
|
||||
// image in physical order rather than logical. So that skew needs to be applied here.
|
||||
@ -68,13 +67,12 @@ std::shared_ptr<Track> AppleDSK::get_track_at_position(Track::Address address) {
|
||||
}
|
||||
|
||||
// Pad if necessary.
|
||||
int encoded_length = (80 + 112 + 80 + 2848 + 80) * sectors_per_track_;
|
||||
if(encoded_length < 50000) {
|
||||
segments.push_back(Encodings::AppleGCR::six_and_two_sync((50000 - encoded_length) >> 3));
|
||||
if(segment.number_of_bits < 50000) {
|
||||
segment += Encodings::AppleGCR::six_and_two_sync((50000 - segment.number_of_bits) >> 3);
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
return std::shared_ptr<PCMTrack>(new PCMTrack(segments));
|
||||
return std::make_shared<PCMTrack>(segment);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ std::shared_ptr<::Storage::Disk::Track> NIB::get_track_at_position(::Storage::Di
|
||||
// tracks and headers), then treat all following FFs as a sync
|
||||
// region, then switch back to ordinary behaviour as soon as a
|
||||
// non-FF appears.
|
||||
std::vector<Storage::Disk::PCMSegment> segments;
|
||||
PCMSegment segment;
|
||||
|
||||
std::size_t start_index = 0;
|
||||
std::set<size_t> sync_starts;
|
||||
@ -74,8 +74,9 @@ std::shared_ptr<::Storage::Disk::Track> NIB::get_track_at_position(::Storage::Di
|
||||
}
|
||||
}
|
||||
|
||||
if(start_index)
|
||||
segments.push_back(Encodings::AppleGCR::six_and_two_sync(static_cast<int>(start_index)));
|
||||
if(start_index) {
|
||||
segment += Encodings::AppleGCR::six_and_two_sync(static_cast<int>(start_index));
|
||||
}
|
||||
|
||||
std::size_t index = start_index;
|
||||
for(const auto &location: sync_starts) {
|
||||
@ -86,7 +87,7 @@ std::shared_ptr<::Storage::Disk::Track> NIB::get_track_at_position(::Storage::Di
|
||||
track_data.begin() + static_cast<off_t>(index),
|
||||
track_data.begin() + static_cast<off_t>(location));
|
||||
data_segment.number_of_bits = static_cast<unsigned int>(data_segment.data.size() * 8);
|
||||
segments.push_back(std::move(data_segment));
|
||||
segment += data_segment;
|
||||
|
||||
// Add a sync from sync_start to end of 0xffs.
|
||||
if(location == track_length-1) break;
|
||||
@ -94,8 +95,8 @@ std::shared_ptr<::Storage::Disk::Track> NIB::get_track_at_position(::Storage::Di
|
||||
index = location;
|
||||
while(index < track_length && track_data[index] == 0xff)
|
||||
++index;
|
||||
segments.push_back(Encodings::AppleGCR::six_and_two_sync(static_cast<int>(index - location)));
|
||||
segment += Encodings::AppleGCR::six_and_two_sync(static_cast<int>(index - location));
|
||||
}
|
||||
|
||||
return std::shared_ptr<PCMTrack>(new PCMTrack(segments));
|
||||
return std::make_shared<PCMTrack>(segment);
|
||||
}
|
||||
|
@ -43,6 +43,36 @@ void PCMSegmentEventSource::reset() {
|
||||
next_event_.type = Track::Event::FluxTransition;
|
||||
}
|
||||
|
||||
PCMSegment &PCMSegment::operator +=(const PCMSegment &rhs) {
|
||||
if(!rhs.number_of_bits) return *this;
|
||||
|
||||
if(number_of_bits&7) {
|
||||
auto target_number_of_bits = number_of_bits + rhs.number_of_bits;
|
||||
data.resize((target_number_of_bits + 7) >> 3);
|
||||
|
||||
std::size_t first_byte = number_of_bits >> 3;
|
||||
|
||||
int shift = number_of_bits&7;
|
||||
data[first_byte] |= rhs.data[0] >> shift;
|
||||
for(std::size_t target = first_byte+1; target < (data.size()-1); ++target) {
|
||||
data[target] =
|
||||
static_cast<uint8_t>(
|
||||
(rhs.data[target - first_byte - 1] << (8 - shift)) |
|
||||
(rhs.data[target - first_byte] >> shift)
|
||||
);
|
||||
}
|
||||
data.back() = static_cast<uint8_t>(rhs.data.back() << (8 - shift));
|
||||
|
||||
number_of_bits = target_number_of_bits;
|
||||
} else {
|
||||
data.insert(data.end(), rhs.data.begin(), rhs.data.end());
|
||||
number_of_bits += rhs.number_of_bits;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Storage::Disk::Track::Event PCMSegmentEventSource::get_next_event() {
|
||||
// track the initial bit pointer for potentially considering whether this was an
|
||||
// initial index hole or a subsequent one later on
|
||||
|
@ -41,6 +41,8 @@ struct PCMSegment {
|
||||
number_of_bits = 0;
|
||||
data.clear();
|
||||
}
|
||||
|
||||
PCMSegment &operator +=(const PCMSegment &rhs);
|
||||
};
|
||||
|
||||
/*!
|
||||
|
Loading…
x
Reference in New Issue
Block a user