1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-12 08:30:05 +00:00
CLK/Storage/Disk/Encodings/MFM/SegmentParser.cpp

89 lines
2.4 KiB
C++

//
// SegmentParser.cpp
// Clock Signal
//
// Created by Thomas Harte on 24/09/2017.
// Copyright 2017 Thomas Harte. All rights reserved.
//
#include "SegmentParser.hpp"
#include "Shifter.hpp"
using namespace Storage::Encodings::MFM;
std::map<std::size_t, Storage::Encodings::MFM::Sector> Storage::Encodings::MFM::sectors_from_segment(
const Storage::Disk::PCMSegment &segment,
Density density
) {
std::map<std::size_t, Sector> result;
Shifter shifter;
shifter.set_is_mfm(is_mfm(density));
shifter.set_should_obey_syncs(true);
std::unique_ptr<Storage::Encodings::MFM::Sector> new_sector;
bool is_reading = false;
std::size_t position = 0;
std::size_t size = 0;
std::size_t start_location = 0;
std::size_t bit_cursor = 0;
for(const auto bit: segment.data) {
shifter.add_input_bit(bit ? 1 : 0);
++bit_cursor;
switch(shifter.get_token()) {
case Shifter::Token::None:
case Shifter::Token::Sync:
case Shifter::Token::Index:
break;
case Shifter::Token::ID:
new_sector = std::make_unique<Storage::Encodings::MFM::Sector>();
is_reading = true;
start_location = bit_cursor;
position = 0;
shifter.set_should_obey_syncs(false);
break;
case Shifter::Token::Data:
case Shifter::Token::DeletedData:
if(new_sector) {
is_reading = true;
shifter.set_should_obey_syncs(false);
new_sector->is_deleted = (shifter.get_token() == Shifter::Token::DeletedData);
}
break;
case Shifter::Token::Byte:
if(is_reading) {
switch(position) {
case 0: new_sector->address.track = shifter.get_byte(); ++position; break;
case 1: new_sector->address.side = shifter.get_byte(); ++position; break;
case 2: new_sector->address.sector = shifter.get_byte(); ++position; break;
case 3:
new_sector->size = shifter.get_byte();
size = size_t(128 << (new_sector->size&7));
++position;
is_reading = false;
shifter.set_should_obey_syncs(true);
break;
default:
if(new_sector->samples.empty()) new_sector->samples.emplace_back();
new_sector->samples[0].push_back(shifter.get_byte());
++position;
if(position == size + 4) {
result.insert({start_location, std::move(*new_sector)});
is_reading = false;
shifter.set_should_obey_syncs(true);
new_sector.reset();
}
break;
}
}
break;
}
}
return result;
}