Merge from master.

This commit is contained in:
David Given
2021-12-12 19:49:32 +00:00
27 changed files with 598 additions and 287 deletions

View File

@@ -138,6 +138,9 @@ public:
auto bits = readRawBits(recordSize*16);
auto bytes = decodeFmMfm(bits).slice(0, recordSize);
IbmDecoderProto::TrackdataProto trackdata;
getTrackFormat(trackdata, _sector->physicalCylinder, _sector->physicalHead);
ByteReader br(bytes);
br.seek(_currentHeaderLength);
br.read_8(); /* skip ID byte */
@@ -150,11 +153,11 @@ public:
if (wantCrc == gotCrc)
_sector->status = Sector::DATA_MISSING; /* correct but unintuitive */
if (_config.swap_sides())
if (trackdata.swap_sides())
_sector->logicalSide ^= 1;
if (_config.ignore_side_byte())
if (trackdata.ignore_side_byte())
_sector->logicalSide = _sector->physicalHead;
if (_config.ignore_track_byte())
if (trackdata.ignore_track_byte())
_sector->logicalTrack = _sector->physicalCylinder;
}
@@ -176,12 +179,42 @@ public:
std::set<unsigned> requiredSectors(unsigned cylinder, unsigned head) const override
{
IbmDecoderProto::TrackdataProto trackdata;
getTrackFormat(trackdata, cylinder, head);
std::set<unsigned> s;
for (int sectorId : _config.sectors().sector())
s.insert(sectorId);
if (trackdata.has_sectors())
{
for (int sectorId : trackdata.sectors().sector())
s.insert(sectorId);
}
else if (trackdata.has_sector_range())
{
int sectorId = trackdata.sector_range().min_sector();
while (sectorId <= trackdata.sector_range().max_sector())
{
s.insert(sectorId);
sectorId++;
}
}
return s;
}
private:
void getTrackFormat(IbmDecoderProto::TrackdataProto& trackdata, unsigned cylinder, unsigned head) const
{
trackdata.Clear();
for (const auto& f : _config.trackdata())
{
if (f.has_cylinder() && (f.cylinder() != cylinder))
continue;
if (f.has_head() && (f.head() != head))
continue;
trackdata.MergeFrom(f);
}
}
private:
const IbmDecoderProto& _config;
unsigned _currentSectorSize;

View File

@@ -101,6 +101,27 @@ private:
}
}
private:
static std::set<unsigned> getSectorIds(const IbmEncoderProto::TrackdataProto& trackdata)
{
std::set<unsigned> s;
if (trackdata.has_sectors())
{
for (int sectorId : trackdata.sectors().sector())
s.insert(sectorId);
}
else if (trackdata.has_sector_range())
{
int sectorId = trackdata.sector_range().min_sector();
while (sectorId <= trackdata.sector_range().max_sector())
{
s.insert(sectorId);
sectorId++;
}
}
return s;
}
public:
std::vector<std::shared_ptr<Sector>> collectSectors(int physicalTrack, int physicalSide, const Image& image) override
{
@@ -109,7 +130,7 @@ public:
getTrackFormat(trackdata, physicalTrack, physicalSide);
int logicalSide = physicalSide ^ trackdata.swap_sides();
for (int sectorId : trackdata.sectors().sector())
for (int sectorId : getSectorIds(trackdata))
{
const auto& sector = image.get(physicalTrack, logicalSide, sectorId);
if (sector)

View File

@@ -2,24 +2,43 @@ syntax = "proto2";
import "lib/common.proto";
// Next: 7
message IbmDecoderProto {
message SectorsProto {
repeated int32 sector = 1 [(help) = "require these sectors to exist for a good read"];
// Next: 10
message TrackdataProto {
message SectorsProto {
repeated int32 sector = 1 [(help) = "require these sectors to exist for a good read"];
}
message SectorRangeProto {
optional int32 min_sector = 1 [(help) = "require these sectors to exist for a good read"];
optional int32 max_sector = 2 [(help) = "require these sectors to exist for a good read"];
}
optional int32 cylinder = 7 [(help) = "if set, the format applies only to this track"];
optional int32 head = 8 [(help) = "if set, the format applies only to this head"];
optional bool ignore_side_byte = 2 [default = false, (help) = "ignore side byte in sector header"];
optional bool ignore_track_byte = 6 [default = false, (help) = "ignore track byte in sector header"];
optional bool swap_sides = 4 [default = false, (help) = "put logical side 1 on physical side 0"];
oneof required_sectors {
SectorsProto sectors = 5 [(help) = "require these sectors to exist for a good read"];
SectorRangeProto sector_range = 9 [(help) = "require these sectors to exist for a good read"];
}
}
optional bool ignore_side_byte = 2 [default = false, (help) = "ignore side byte in sector header"];
optional bool ignore_track_byte = 6 [default = false, (help) = "ignore track byte in sector header"];
optional bool swap_sides = 4 [default = false, (help) = "put logical side 1 on physical side 0"];
optional SectorsProto sectors = 5 [(help) = "require these sectors to exist for a good read"];
repeated TrackdataProto trackdata = 1;
}
message IbmEncoderProto {
// Next: 19
// Next: 20
message TrackdataProto {
message SectorsProto {
repeated int32 sector = 1 [(help) = "write these sectors (in order) on each track"];
}
message SectorRangeProto {
optional int32 min_sector = 1 [(help) = "write these sectors (in order) on each track"];
optional int32 max_sector = 2 [(help) = "write these sectors (in order) on each track"];
}
optional int32 cylinder = 15 [(help) = "if set, the format applies only to this track"];
optional int32 head = 16 [(help) = "if set, the format applies only to this head"];
@@ -36,8 +55,12 @@ message IbmEncoderProto {
optional int32 gap2 = 11 [default=22, (help) = "size of gap 3 (the pre-data gap)"];
optional int32 gap3 = 12 [default=80, (help) = "size of gap 4 (the post-data or format gap)"];
optional bool swap_sides = 14 [default=false, (help) = "swap side bytes when writing"];
optional SectorsProto sectors = 17 [(help) = "write these sectors (in order) on each track"];
optional int32 gap_fill_byte = 18 [default=0x9254, (help) = "16-bit raw bit pattern of gap fill byte"];
oneof required_sectors {
SectorsProto sectors = 17 [(help) = "require these sectors to exist for a good read"];
SectorRangeProto sector_range = 19 [(help) = "require these sectors to exist for a good read"];
}
}
repeated TrackdataProto trackdata = 1;