1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-01 14:29:51 +00:00

Adds better support for WD-esque false sync, improves STX track patching.

This commit is contained in:
Thomas Harte 2020-01-13 22:19:48 -05:00
parent fab35b360a
commit 1f539822ee
4 changed files with 36 additions and 14 deletions

View File

@ -67,7 +67,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableASanStackUseAfterReturn = "YES"

View File

@ -83,6 +83,7 @@ class TrackConstructor {
using Shifter = Storage::Encodings::MFM::Shifter;
Shifter shifter;
shifter.set_should_obey_syncs(true);
shifter.set_is_double_density(true);
// Add whatever comes from the track.
for(auto bit: segment.data) {
@ -127,8 +128,7 @@ class TrackConstructor {
// To reconcile the list of sectors with the WD get track-style track image,
// use sector bodies as definitive and refer to the track image for in-fill.
auto track_position = track_data_.begin();
const auto address_mark = {0xa1, 0xa1, 0xfe};
const auto track_mark = {0xa1, 0xa1, 0xfb};
const auto sync_mark = {0xa1, 0xa1};
struct Location {
enum Type {
Address, Data
@ -148,15 +148,16 @@ class TrackConstructor {
// the next thing that looks like a header of any sort.
auto address_position = std::search(track_position, track_data_.end(), track_address.begin(), track_address.end());
if(address_position == track_data_.end()) {
address_position = std::search(track_position, track_data_.end(), address_mark.begin(), address_mark.end());
address_position = std::search(track_position, track_data_.end(), sync_mark.begin(), sync_mark.end());
}
// Stop now if there's nowhere obvious to put this sector.
if(address_position == track_data_.end()) break;
locations.emplace_back(Location::Address, address_position, sector);
// Place this address only if somewhere to put it was found.
if(address_position != track_data_.end()) {
locations.emplace_back(Location::Address, address_position, sector);
// Advance the track position.
track_position = address_position;
// Advance the track position.
track_position = address_position;
}
}
// Do much the same thing for the data, if it exists.
@ -165,9 +166,12 @@ class TrackConstructor {
auto data_position = std::search(track_position, track_data_.end(), track_data.begin(), track_data.end());
if(data_position == track_data_.end()) {
data_position = std::search(track_position, track_data_.end(), track_mark.begin(), track_mark.end());
data_position = std::search(track_position, track_data_.end(), sync_mark.begin(), sync_mark.end());
}
if(data_position == track_data_.end()) {
// Desperation: guess from the given offset.
data_position = track_data_.begin() + (sector.bit_position / 16);
}
if(data_position == track_data_.end()) break;
locations.emplace_back(Location::Data, data_position, sector);
track_position = data_position;

View File

@ -25,7 +25,7 @@ void Shifter::set_should_obey_syncs(bool should_obey_syncs) {
void Shifter::add_input_bit(int value) {
shift_register_ = (shift_register_ << 1) | static_cast<unsigned int>(value);
bits_since_token_++;
++bits_since_token_;
token_ = Token::None;
if(should_obey_syncs_) {
@ -57,6 +57,20 @@ void Shifter::add_input_bit(int value) {
} else {
switch(shift_register_ & 0xffff) {
case Storage::Encodings::MFM::MFMIndexSync:
// This models a bit of slightly weird WD behaviour;
// if an index sync was detected where it wasn't expected,
// the WD will resync but also may return the clock bits
// rather than data bits as the next byte read, depending
// on framing.
//
// TODO: make this optional, if ever a Shifter with
// well-defined non-WD behaviour is needed.
//
// TODO: Verify WD behaviour.
if(bits_since_token_&1) {
shift_register_ >>= 1;
}
bits_since_token_ = 0;
is_awaiting_marker_value_ = true;

View File

@ -27,6 +27,10 @@ namespace MFM {
It will ordinarily honour sync patterns; that should be turned off when within
a sector because false syncs can occur. See @c set_should_obey_syncs.
It aims to implement the same behaviour as WD177x-series controllers when
detecting a false sync the received byte value will be either a 0xc1 or 0x14,
depending on phase.
Bits should be fed in with @c add_input_bit.
The current output token can be read with @c get_token. It will usually be None but
@ -62,14 +66,14 @@ class Shifter {
}
private:
// Bit stream input state
// Bit stream input state.
int bits_since_token_ = 0;
unsigned int shift_register_ = 0;
bool is_awaiting_marker_value_ = false;
bool should_obey_syncs_ = true;
Token token_ = None;
// input configuration
// Input configuration.
bool is_double_density_ = false;
std::unique_ptr<CRC::CCITT> owned_crc_generator_;