mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-15 20:31:36 +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:
parent
51c0c45e04
commit
f488854720
@ -10,8 +10,9 @@
|
|||||||
|
|
||||||
#include "../../Track/PCMTrack.hpp"
|
#include "../../Track/PCMTrack.hpp"
|
||||||
#include "../../Encodings/MFM/Constants.hpp"
|
#include "../../Encodings/MFM/Constants.hpp"
|
||||||
|
#include "../../Encodings/MFM/Shifter.hpp"
|
||||||
#include "../../Encodings/MFM/Encoder.hpp"
|
#include "../../Encodings/MFM/Encoder.hpp"
|
||||||
#include "../../Encodings/MFM/Parser.hpp"
|
#include "../../Track/TrackSerialiser.hpp"
|
||||||
|
|
||||||
using namespace Storage::Disk;
|
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) {
|
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);
|
PCMSegment segment = Storage::Disk::track_serialisation(*track, Storage::Encodings::MFM::MFMBitLength);
|
||||||
std::vector<uint8_t> parsed_track = parser.get_track(0);
|
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);
|
long file_offset = get_file_offset_for_position(head, position);
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock_guard(file_access_mutex_);
|
std::lock_guard<std::mutex> lock_guard(file_access_mutex_);
|
||||||
fseek(file_, file_offset, SEEK_SET);
|
fseek(file_, file_offset, SEEK_SET);
|
||||||
size_t track_size = std::min((size_t)6400, parsed_track.size());
|
size_t track_size = std::min((size_t)6400, parsed_track.size());
|
||||||
fwrite(parsed_track.data(), 1, track_size, file_);
|
fwrite(parsed_track.data(), 1, track_size, file_);
|
||||||
}
|
}
|
||||||
|
@ -89,11 +89,6 @@ std::shared_ptr<Sector> Parser::get_sector(uint8_t head, uint8_t track, uint8_t
|
|||||||
return nullptr;
|
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) {
|
void Parser::process_input_bit(int value) {
|
||||||
shift_register_ = ((shift_register_ << 1) | (unsigned int)value) & 0xffff;
|
shift_register_ = ((shift_register_ << 1) | (unsigned int)value) & 0xffff;
|
||||||
bit_count_++;
|
bit_count_++;
|
||||||
@ -131,89 +126,6 @@ uint8_t Parser::get_next_byte() {
|
|||||||
return 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> Parser::get_next_sector() {
|
||||||
std::shared_ptr<Sector> sector(new Sector);
|
std::shared_ptr<Sector> sector(new Sector);
|
||||||
index_count_ = 0;
|
index_count_ = 0;
|
||||||
|
@ -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);
|
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:
|
private:
|
||||||
Parser(bool is_mfm);
|
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_next_sector();
|
||||||
std::shared_ptr<Storage::Encodings::MFM::Sector> get_sector(uint8_t 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::map<int, std::shared_ptr<Storage::Encodings::MFM::Sector>> sectors_by_index_;
|
||||||
std::set<int> decoded_tracks_;
|
std::set<int> decoded_tracks_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user