Compare commits

..

1 Commits

Author SHA1 Message Date
David Given
bb82dc864a Make cross-track sector collation optional (as it usually just makes things
confusing).
2024-02-03 01:08:23 +01:00
9 changed files with 44 additions and 29 deletions

View File

@@ -29,7 +29,6 @@ IncludeBlocks: Preserve
IndentCaseLabels: 'true'
IndentWidth: '4'
IndentWrappedFunctionNames: 'false'
IndentPPDirectives: BeforeHash
KeepEmptyLinesAtTheStartOfBlocks: 'true'
NamespaceIndentation: All
PointerAlignment: Left

View File

@@ -19,13 +19,4 @@ message Apple2EncoderProto
optional uint32 side_one_track_offset = 3
[ default = 0, (help) = "offset to apply to track numbers on side 1" ];
optional uint32 post_index_gap_bytes = 4
[ default = 32, (help) = "the number of resync bytes to write after the index mark" ];
optional uint32 post_address_gap_bytes = 5
[ default = 6, (help) = "the number of resync bytes to write after the address gap" ];
optional uint32 post_data_gap_bytes = 6
[ default = 8, (help) = "the number of resync bytes to write after each sector" ];
}

View File

@@ -79,14 +79,18 @@ private:
auto write_bit = [&](bool val)
{
if (cursor <= bits.size())
{
bits[cursor] = val;
}
cursor++;
};
auto write_bits = [&](uint32_t bits, int width)
{
for (int i = width; i--;)
{
write_bit(bits & (1u << i));
}
};
auto write_gcr44 = [&](uint8_t value)
@@ -100,13 +104,15 @@ private:
};
// The special "FF40" sequence is used to synchronize the receiving
// shift register. It's written as "0 1111 1111 0"; FF indicates the
// 8 consecutive 1-bits, while "40" indicaes the total number of
// shift register. It's written as "1111 1111 00"; FF indicates the
// 8 consecutive 1-bits, while "40" indicates the total number of
// microseconds.
auto write_ff40 = [&](int n = 1)
{
for (; n--;)
write_bits(0xff << 1, 10);
{
write_bits(0xff << 2, 10);
}
};
// There is data to encode to disk.
@@ -121,9 +127,7 @@ private:
//
// In standard formatting, the first logical sector apparently gets
// extra padding.
write_ff40(sector.logicalSector == 0
? _config.post_index_gap_bytes()
: _config.post_data_gap_bytes());
write_ff40(sector.logicalSector == 0 ? 32 : 8);
int track = sector.logicalTrack;
if (sector.logicalSide == 1)
@@ -140,7 +144,7 @@ private:
// Write data syncing leader: FF40 + APPLE2_DATA_RECORD + sector
// data + sum + DE AA EB (+ mystery bits cut off of the scan?)
write_ff40(_config.post_address_gap_bytes());
write_ff40(8);
write_bits(APPLE2_DATA_RECORD, 24);
// Convert the sector data to GCR, append the checksum, and write it

View File

@@ -137,8 +137,10 @@ std::shared_ptr<TrackDataFlux> Decoder::decodeToSectors(
if (_sector->status != Sector::MISSING)
{
auto trackLayout = Layout::getLayoutOfTrack(
_sector->logicalTrack, _sector->logicalSide);
if ((_sector->status == Sector::OK) &&
((_sector->logicalTrack != trackInfo->logicalTrack) ||
(_sector->logicalSide != trackInfo->logicalSide)))
_sector->status == Sector::WRONG_PLACE;
_trackdata->sectors.push_back(_sector);
}
}

View File

@@ -21,7 +21,7 @@ import "arch/zilogmcz/zilogmcz.proto";
import "lib/fluxsink/fluxsink.proto";
import "lib/common.proto";
//NEXT: 32
//NEXT: 33
message DecoderProto {
optional double pulse_debounce_threshold = 1 [default = 0.30,
(help) = "ignore pulses with intervals shorter than this, in fractions of a clock"];
@@ -66,6 +66,7 @@ message DecoderProto {
optional string write_csv_to = 23
[(help) = "if set, write a CSV report of the disk state"];
optional bool skip_unnecessary_tracks = 29 [default = true,
(help) = "don't read tracks if we already have all necessary sectors"];
(help) = "don't read physical tracks if we already have all necessary sectors"];
optional bool collate_sectors_from_all_tracks = 32 [default = false,
(help) = "when creating the image, consider all valid sectors even if they're on the wrong track"];
}

View File

@@ -97,9 +97,16 @@ void measureDiskRotation()
log(EndSpeedOperationLogMessage{oneRevolution});
}
static int getEffectiveStatus(int status)
{
if ((status == Sector::WRONG_PLACE) &&
globalConfig()->decoder().collate_sectors_from_all_tracks())
return Sector::OK;
return status;
}
/* Given a set of sectors, deduplicates them sensibly (e.g. if there is a good
* and bad version of the same sector, the bad version is dropped). */
static std::set<std::shared_ptr<const Sector>> collectSectors(
std::set<std::shared_ptr<const Sector>>& track_sectors,
bool collapse_conflicts = true)
@@ -124,9 +131,11 @@ static std::set<std::shared_ptr<const Sector>> collectSectors(
it->second,
[&](auto left, auto& rightit) -> std::shared_ptr<const Sector>
{
int leftStatus = left->status;
auto& right = rightit.second;
if ((left->status == Sector::OK) &&
(right->status == Sector::OK) &&
int rightStatus = right->status;
if ((leftStatus == Sector::OK) &&
(rightStatus == Sector::OK) &&
(left->data != right->data))
{
if (!collapse_conflicts)
@@ -139,13 +148,13 @@ static std::set<std::shared_ptr<const Sector>> collectSectors(
s->status = Sector::CONFLICT;
return s;
}
if (left->status == Sector::CONFLICT)
if (leftStatus == Sector::CONFLICT)
return left;
if (right->status == Sector::CONFLICT)
if (rightStatus == Sector::CONFLICT)
return right;
if (left->status == Sector::OK)
if (leftStatus == Sector::OK)
return left;
if (right->status == Sector::OK)
if (rightStatus == Sector::OK)
return right;
return left;
});

View File

@@ -31,6 +31,8 @@ std::string Sector::statusToString(Status status)
return "present but no data found";
case Status::CONFLICT:
return "conflicting data";
case Status::WRONG_PLACE:
return "incorrectly placed";
default:
return fmt::format("unknown error {}", status);
}
@@ -50,6 +52,8 @@ std::string Sector::statusToChar(Status status)
return "!";
case Status::CONFLICT:
return "*";
case Status::WRONG_PLACE:
return "/";
default:
return "?";
}

View File

@@ -44,6 +44,7 @@ struct Sector : public LogicalLocation
DATA_MISSING,
CONFLICT,
INTERNAL_ERROR,
WRONG_PLACE,
};
static std::string statusToString(Status status);

View File

@@ -109,6 +109,10 @@ option_group {
set_by_default: true
config {
decoder {
collate_sectors_from_all_tracks: true
}
layout {
format_type: FORMATTYPE_80TRACK
}