1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 16:31:31 +00:00

Switches Oric MFM DSK serialisation to feeding a track serialisation to a shifter.

Thereby eliminates the parser's need to offer get_track.
This commit is contained in:
Thomas Harte 2017-09-27 22:14:50 -04:00
parent 51c0c45e04
commit f488854720
3 changed files with 42 additions and 106 deletions

View File

@ -10,8 +10,9 @@
#include "../../Track/PCMTrack.hpp"
#include "../../Encodings/MFM/Constants.hpp"
#include "../../Encodings/MFM/Shifter.hpp"
#include "../../Encodings/MFM/Encoder.hpp"
#include "../../Encodings/MFM/Parser.hpp"
#include "../../Track/TrackSerialiser.hpp"
using namespace Storage::Disk;
@ -118,12 +119,48 @@ std::shared_ptr<Track> OricMFMDSK::get_track_at_position(unsigned int head, unsi
}
void OricMFMDSK::set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track) {
Storage::Encodings::MFM::Parser parser(true, track);
std::vector<uint8_t> parsed_track = parser.get_track(0);
PCMSegment segment = Storage::Disk::track_serialisation(*track, Storage::Encodings::MFM::MFMBitLength);
Storage::Encodings::MFM::Shifter shifter;
shifter.set_is_double_density(true);
shifter.set_should_obey_syncs(true);
std::vector<uint8_t> parsed_track;
int size = 0;
int offset = 0;
bool capture_size = false;
for(unsigned int bit = 0; bit < segment.number_of_bits; ++bit) {
shifter.add_input_bit(segment.bit(bit));
if(shifter.get_token() == Storage::Encodings::MFM::Shifter::Token::None) continue;
parsed_track.push_back(shifter.get_byte());
if(offset) {
offset--;
if(!offset) {
shifter.set_should_obey_syncs(true);
}
if(capture_size && offset == 2) {
size = parsed_track.back();
capture_size = false;
}
}
if( shifter.get_token() == Storage::Encodings::MFM::Shifter::Token::Data ||
shifter.get_token() == Storage::Encodings::MFM::Shifter::Token::DeletedData) {
offset = 128 << size;
shifter.set_should_obey_syncs(false);
}
if(shifter.get_token() == Storage::Encodings::MFM::Shifter::Token::ID) {
offset = 6;
shifter.set_should_obey_syncs(false);
capture_size = true;
}
}
long file_offset = get_file_offset_for_position(head, position);
std::lock_guard<std::mutex> lock_guard(file_access_mutex_);
fseek(file_, file_offset, SEEK_SET);
std::lock_guard<std::mutex> lock_guard(file_access_mutex_);
fseek(file_, file_offset, SEEK_SET);
size_t track_size = std::min((size_t)6400, parsed_track.size());
fwrite(parsed_track.data(), 1, track_size, file_);
}

View File

@ -89,11 +89,6 @@ std::shared_ptr<Sector> Parser::get_sector(uint8_t head, uint8_t track, uint8_t
return nullptr;
}
std::vector<uint8_t> Parser::get_track(uint8_t track) {
seek_to_track(track);
return get_track();
}
void Parser::process_input_bit(int value) {
shift_register_ = ((shift_register_ << 1) | (unsigned int)value) & 0xffff;
bit_count_++;
@ -131,89 +126,6 @@ uint8_t Parser::get_next_byte() {
return byte;
}
std::vector<uint8_t> Parser::get_track() {
std::vector<uint8_t> result;
int distance_until_permissible_sync = 0;
uint8_t last_id[6] = {0, 0, 0, 0, 0, 0};
int last_id_pointer = 0;
bool next_is_type = false;
// align to the next index hole
index_count_ = 0;
while(!index_count_) run_for(Cycles(1));
// capture every other bit until the next index hole
index_count_ = 0;
while(1) {
// wait until either another bit or the index hole arrives
bit_count_ = 0;
bool found_sync = false;
while(!index_count_ && !found_sync && bit_count_ < 16) {
int previous_bit_count = bit_count_;
run_for(Cycles(1));
if(!distance_until_permissible_sync && bit_count_ != previous_bit_count) {
uint16_t low_shift_register = (shift_register_&0xffff);
if(is_mfm_) {
found_sync = (low_shift_register == MFMIndexSync) || (low_shift_register == MFMSync);
} else {
found_sync =
(low_shift_register == FMIndexAddressMark) ||
(low_shift_register == FMIDAddressMark) ||
(low_shift_register == FMDataAddressMark) ||
(low_shift_register == FMDeletedDataAddressMark);
}
}
}
// if that was the index hole then finish
if(index_count_) {
if(bit_count_) result.push_back(get_byte_for_shift_value((uint16_t)(shift_register_ << (16 - bit_count_))));
break;
}
// store whatever the current byte is
uint8_t byte_value = get_byte_for_shift_value((uint16_t)shift_register_);
result.push_back(byte_value);
if(last_id_pointer < 6) last_id[last_id_pointer++] = byte_value;
// if no syncs are permissible here, decrement the waiting period and perform no further contemplation
bool found_id = false, found_data = false;
if(distance_until_permissible_sync) {
distance_until_permissible_sync--;
} else {
if(found_sync) {
if(is_mfm_) {
next_is_type = true;
} else {
switch(shift_register_&0xffff) {
case FMIDAddressMark: found_id = true; break;
case FMDataAddressMark:
case FMDeletedDataAddressMark: found_data = true; break;
}
}
} else if(next_is_type) {
switch(byte_value) {
case IDAddressByte: found_id = true; break;
case DataAddressByte:
case DeletedDataAddressByte: found_data = true; break;
}
}
}
if(found_id) {
distance_until_permissible_sync = 6;
last_id_pointer = 0;
}
if(found_data) {
distance_until_permissible_sync = 128 << last_id[3];
}
}
return result;
}
std::shared_ptr<Sector> Parser::get_next_sector() {
std::shared_ptr<Sector> sector(new Sector);
index_count_ = 0;

View File

@ -29,18 +29,6 @@ class Parser: public Storage::Disk::Controller {
*/
std::shared_ptr<Storage::Encodings::MFM::Sector> get_sector(uint8_t head, uint8_t track, uint8_t sector);
/*!
Attempts to read the track at @c track, starting from the index hole.
Decodes data bits only; clocks are omitted. Synchronisation values begin a new
byte. If a synchronisation value begins partway through a byte then
synchronisation-contributing bits will appear both in the preceding byte and
in the next.
@returns a vector of data found.
*/
std::vector<uint8_t> get_track(uint8_t track);
private:
Parser(bool is_mfm);
@ -61,7 +49,6 @@ class Parser: public Storage::Disk::Controller {
std::shared_ptr<Storage::Encodings::MFM::Sector> get_next_sector();
std::shared_ptr<Storage::Encodings::MFM::Sector> get_sector(uint8_t sector);
std::vector<uint8_t> get_track();
std::map<int, std::shared_ptr<Storage::Encodings::MFM::Sector>> sectors_by_index_;
std::set<int> decoded_tracks_;