2017-09-25 02:41:16 +00:00
|
|
|
//
|
|
|
|
// SegmentParser.cpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 24/09/2017.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2017 Thomas Harte. All rights reserved.
|
2017-09-25 02:41:16 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#include "SegmentParser.hpp"
|
|
|
|
#include "Shifter.hpp"
|
|
|
|
|
|
|
|
using namespace Storage::Encodings::MFM;
|
|
|
|
|
2023-12-11 03:17:23 +00:00
|
|
|
std::map<std::size_t, Storage::Encodings::MFM::Sector> Storage::Encodings::MFM::sectors_from_segment(
|
|
|
|
const Storage::Disk::PCMSegment &segment,
|
|
|
|
Density density
|
|
|
|
) {
|
2017-11-11 20:28:40 +00:00
|
|
|
std::map<std::size_t, Sector> result;
|
2017-09-25 02:41:16 +00:00
|
|
|
Shifter shifter;
|
2023-12-11 03:17:23 +00:00
|
|
|
shifter.set_is_mfm(is_mfm(density));
|
2017-09-25 23:57:11 +00:00
|
|
|
shifter.set_should_obey_syncs(true);
|
2017-09-25 02:41:16 +00:00
|
|
|
|
|
|
|
std::unique_ptr<Storage::Encodings::MFM::Sector> new_sector;
|
|
|
|
bool is_reading = false;
|
2017-11-11 20:28:40 +00:00
|
|
|
std::size_t position = 0;
|
|
|
|
std::size_t size = 0;
|
|
|
|
std::size_t start_location = 0;
|
2017-09-25 02:41:16 +00:00
|
|
|
|
2018-07-01 19:53:48 +00:00
|
|
|
std::size_t bit_cursor = 0;
|
2018-07-01 16:05:41 +00:00
|
|
|
for(const auto bit: segment.data) {
|
|
|
|
shifter.add_input_bit(bit ? 1 : 0);
|
2018-07-01 19:53:48 +00:00
|
|
|
++bit_cursor;
|
|
|
|
|
2017-09-25 02:41:16 +00:00
|
|
|
switch(shifter.get_token()) {
|
|
|
|
case Shifter::Token::None:
|
|
|
|
case Shifter::Token::Sync:
|
|
|
|
case Shifter::Token::Index:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Shifter::Token::ID:
|
2019-12-24 02:31:46 +00:00
|
|
|
new_sector = std::make_unique<Storage::Encodings::MFM::Sector>();
|
2017-09-25 02:41:16 +00:00
|
|
|
is_reading = true;
|
2018-07-01 19:53:48 +00:00
|
|
|
start_location = bit_cursor;
|
2017-09-25 02:41:16 +00:00
|
|
|
position = 0;
|
2017-09-25 23:57:11 +00:00
|
|
|
shifter.set_should_obey_syncs(false);
|
2017-09-25 02:41:16 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case Shifter::Token::Data:
|
|
|
|
case Shifter::Token::DeletedData:
|
|
|
|
if(new_sector) {
|
|
|
|
is_reading = true;
|
2017-09-25 23:57:11 +00:00
|
|
|
shifter.set_should_obey_syncs(false);
|
2017-09-25 02:41:16 +00:00
|
|
|
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();
|
2020-05-10 03:00:39 +00:00
|
|
|
size = size_t(128 << (new_sector->size&7));
|
2017-09-25 02:41:16 +00:00
|
|
|
++position;
|
|
|
|
is_reading = false;
|
2017-09-25 23:57:11 +00:00
|
|
|
shifter.set_should_obey_syncs(true);
|
2017-09-25 02:41:16 +00:00
|
|
|
break;
|
|
|
|
default:
|
2017-11-01 01:32:28 +00:00
|
|
|
if(new_sector->samples.empty()) new_sector->samples.emplace_back();
|
|
|
|
new_sector->samples[0].push_back(shifter.get_byte());
|
2017-09-25 02:41:16 +00:00
|
|
|
++position;
|
|
|
|
if(position == size + 4) {
|
2024-05-30 01:42:46 +00:00
|
|
|
result.insert({start_location, std::move(*new_sector)});
|
2017-09-25 02:41:16 +00:00
|
|
|
is_reading = false;
|
2017-09-25 23:57:11 +00:00
|
|
|
shifter.set_should_obey_syncs(true);
|
2017-09-25 02:41:16 +00:00
|
|
|
new_sector.reset();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|