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:
parent
51c0c45e04
commit
f488854720
@ -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_);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user