Rework the layout stuff to be more correct. Physical skew no longer affects the

order in the resulting images.
This commit is contained in:
dg
2022-12-04 19:19:37 +00:00
parent e3219087c9
commit a91dee27e7
13 changed files with 167 additions and 36 deletions

View File

@@ -31,7 +31,7 @@ void Image::createBlankImage()
unsigned side = trackAndHead.second;
auto trackLayout = Layout::getLayoutOfTrack(track, side);
Bytes blank(trackLayout->sectorSize);
for (unsigned sectorId : trackLayout->logicalSectorOrder)
for (unsigned sectorId : trackLayout->naturalSectorOrder)
put(track, side, sectorId)->data = blank;
}
}

View File

@@ -112,7 +112,7 @@ std::unique_ptr<Image> ImageReader::readMappedImage()
auto newSector = std::make_shared<Sector>();
*newSector = *e;
newSector->logicalSector =
trackLayout->filesystemToLogicalSectorMap.at(e->logicalSector);
trackLayout->filesystemToNaturalSectorMap.at(e->logicalSector);
sectors.insert(newSector);
}

View File

@@ -40,7 +40,7 @@ public:
break;
auto trackLayout = Layout::getLayoutOfTrack(track, side);
for (int sectorId : trackLayout->logicalSectorOrder)
for (int sectorId : trackLayout->naturalSectorOrder)
{
Bytes data(trackLayout->sectorSize);
inputFile.read((char*)data.begin(), data.size());

View File

@@ -218,7 +218,7 @@ void ImageWriter::writeMappedImage(const Image& image)
auto newSector = std::make_shared<Sector>();
*newSector = *e;
newSector->logicalSector =
trackLayout->logicalToFilesystemSectorMap.at(e->logicalSector);
trackLayout->naturalToFilesystemSectorMap.at(e->logicalSector);
sectors.insert(newSector);
}

View File

@@ -37,7 +37,7 @@ public:
int side = p.second;
auto trackLayout = Layout::getLayoutOfTrack(track, side);
for (int sectorId : trackLayout->logicalSectorOrder)
for (int sectorId : trackLayout->naturalSectorOrder)
{
const auto& sector = image.get(track, side, sectorId);
if (sector)

View File

@@ -167,10 +167,10 @@ std::shared_ptr<const TrackInfo> Layout::getLayoutOfTrack(
trackInfo->physicalSide = logicalSide ^ config.layout().swap_sides();
trackInfo->groupSize = getTrackStep();
trackInfo->diskSectorOrder = expandSectorList(layoutdata.physical());
trackInfo->logicalSectorOrder = trackInfo->diskSectorOrder;
trackInfo->naturalSectorOrder = trackInfo->diskSectorOrder;
std::sort(
trackInfo->diskSectorOrder.begin(), trackInfo->diskSectorOrder.end());
trackInfo->numSectors = trackInfo->logicalSectorOrder.size();
trackInfo->naturalSectorOrder.begin(), trackInfo->naturalSectorOrder.end());
trackInfo->numSectors = trackInfo->naturalSectorOrder.size();
if (layoutdata.has_filesystem())
{
@@ -182,17 +182,14 @@ std::shared_ptr<const TrackInfo> Layout::getLayoutOfTrack(
"number of sectors";
}
else
{
for (unsigned sectorId : trackInfo->logicalSectorOrder)
trackInfo->filesystemSectorOrder.push_back(sectorId);
}
trackInfo->filesystemSectorOrder = trackInfo->naturalSectorOrder;
for (int i = 0; i < trackInfo->numSectors; i++)
{
unsigned f = trackInfo->logicalSectorOrder[i];
unsigned l = trackInfo->filesystemSectorOrder[i];
trackInfo->filesystemToLogicalSectorMap[f] = l;
trackInfo->logicalToFilesystemSectorMap[l] = f;
unsigned fid = trackInfo->naturalSectorOrder[i];
unsigned lid = trackInfo->filesystemSectorOrder[i];
trackInfo->filesystemToNaturalSectorMap[fid] = lid;
trackInfo->naturalToFilesystemSectorMap[lid] = fid;
}
return trackInfo;

View File

@@ -27,10 +27,14 @@ public:
*/
static std::vector<std::shared_ptr<const TrackInfo>> computeLocations();
/* Given a list of locations, determines the minimum and maximum track
* and side settings. */
static void getBounds(const std::vector<std::shared_ptr<const TrackInfo>>& locations,
int& minTrack, int& maxTrack, int& minSide, int& maxSide);
/* Given a list of locations, determines the minimum and maximum track
* and side settings. */
static void getBounds(
const std::vector<std::shared_ptr<const TrackInfo>>& locations,
int& minTrack,
int& maxTrack,
int& minSide,
int& maxSide);
/* Returns a series of <track, side> pairs representing the filesystem
* ordering of the disk, in logical numbers. */
@@ -50,9 +54,10 @@ public:
const SectorListProto& sectorsProto);
};
class TrackInfo {
class TrackInfo
{
public:
TrackInfo() {}
TrackInfo() {}
private:
/* Can't copy. */
@@ -85,20 +90,23 @@ public:
/* Number of bytes in a sector. */
unsigned sectorSize = 0;
/* Sector IDs in disk order. */
/* Sector IDs in sector ID order. This is the order in which the appear in
* disk images. */
std::vector<unsigned> naturalSectorOrder;
/* Sector IDs in disk order. This is the order they are written to the disk.
*/
std::vector<unsigned> diskSectorOrder;
/* Sector IDs in logical order. */
std::vector<unsigned> logicalSectorOrder;
/* Sector IDs in filesystem order. */
/* Sector IDs in filesystem order. This is the order in which the filesystem
* uses them. */
std::vector<unsigned> filesystemSectorOrder;
/* Mapping of filesystem order to logical order. */
std::map<unsigned, unsigned> filesystemToLogicalSectorMap;
/* Mapping of filesystem order to natural order. */
std::map<unsigned, unsigned> filesystemToNaturalSectorMap;
/* Mapping of logical order to filesystem order. */
std::map<unsigned, unsigned> logicalToFilesystemSectorMap;
/* Mapping of natural order to filesystem order. */
std::map<unsigned, unsigned> naturalToFilesystemSectorMap;
};
#endif

View File

@@ -168,7 +168,7 @@ BadSectorsState combineRecordAndSectors(TrackFlux& trackFlux,
/* Add the sectors which should be there. */
for (unsigned sectorId : trackLayout->logicalSectorOrder)
for (unsigned sectorId : trackLayout->naturalSectorOrder)
{
auto sector = std::make_shared<Sector>(LogicalLocation{
trackLayout->logicalTrack, trackLayout->logicalSide, sectorId});

View File

@@ -72,7 +72,7 @@ public:
if (!imageContainsAllSectorsOf(_changedSectors,
track,
side,
trackLayout->logicalSectorOrder))
trackLayout->naturalSectorOrder))
{
/* If we don't have any loaded sectors for this track, pre-read
* it. */
@@ -83,7 +83,7 @@ public:
/* Now merge the loaded track with the changed one, and write
* the result back. */
for (unsigned sectorId : trackLayout->logicalSectorOrder)
for (unsigned sectorId : trackLayout->naturalSectorOrder)
{
if (!_changedSectors.contains(track, side, sectorId))
_changedSectors.put(track, side, sectorId)->data =

View File

@@ -18,7 +18,7 @@ layout {
physical {
start_sector: 0
count: 12
#skew: 5
skew: 5
}
}
}

View File

@@ -18,7 +18,7 @@ layout {
physical {
start_sector: 0
count: 12
#skew: 5
skew: 5
}
}
}

View File

@@ -35,6 +35,7 @@ $(call declare-test,flx)
$(call declare-test,fmmfm)
$(call declare-test,greaseweazle)
$(call declare-test,kryoflux)
$(call declare-test,layout)
$(call declare-test,ldbs)
$(call declare-test,proto)
$(call declare-test,utils)

125
tests/layout.cc Normal file
View File

@@ -0,0 +1,125 @@
#include "lib/globals.h"
#include "lib/bytes.h"
#include "lib/config.pb.h"
#include "lib/proto.h"
#include "lib/layout.h"
#include "snowhouse/snowhouse.h"
#include <google/protobuf/text_format.h>
#include <regex>
using namespace snowhouse;
static std::string cleanup(const std::string& s)
{
auto outs = std::regex_replace(s, std::regex("[ \t\n]+"), " ");
outs = std::regex_replace(outs, std::regex("^[ \t\n]+"), "");
outs = std::regex_replace(outs, std::regex("[ \t\n]+$"), "");
return outs;
}
static void load_config(const std::string s)
{
config.Clear();
if (!google::protobuf::TextFormat::MergeFromString(cleanup(s), &config))
Error() << "couldn't load test config";
}
static void test_physical_sectors()
{
load_config(R"M(
layout {
tracks: 78
sides: 2
layoutdata {
sector_size: 256
physical {
sector: 0
sector: 2
sector: 1
sector: 3
}
}
}
)M");
auto layout = Layout::getLayoutOfTrack(0, 0);
AssertThat(
layout->naturalSectorOrder, Equals(std::vector<unsigned>{0, 1, 2, 3}));
AssertThat(
layout->diskSectorOrder, Equals(std::vector<unsigned>{0, 2, 1, 3}));
AssertThat(layout->filesystemSectorOrder,
Equals(std::vector<unsigned>{0, 1, 2, 3}));
}
static void test_logical_sectors()
{
load_config(R"M(
layout {
tracks: 78
sides: 2
layoutdata {
sector_size: 256
physical {
sector: 0
sector: 1
sector: 2
sector: 3
}
filesystem {
sector: 0
sector: 2
sector: 1
sector: 3
}
}
}
)M");
auto layout = Layout::getLayoutOfTrack(0, 0);
AssertThat(
layout->naturalSectorOrder, Equals(std::vector<unsigned>{0, 1, 2, 3}));
AssertThat(
layout->diskSectorOrder, Equals(std::vector<unsigned>{0, 1, 2, 3}));
AssertThat(layout->filesystemSectorOrder,
Equals(std::vector<unsigned>{0, 2, 1, 3}));
}
static void test_both_sectors()
{
load_config(R"M(
layout {
tracks: 78
sides: 2
layoutdata {
sector_size: 256
physical {
sector: 3
sector: 2
sector: 1
sector: 0
}
filesystem {
sector: 0
sector: 2
sector: 1
sector: 3
}
}
}
)M");
auto layout = Layout::getLayoutOfTrack(0, 0);
AssertThat(
layout->naturalSectorOrder, Equals(std::vector<unsigned>{0, 1, 2, 3}));
AssertThat(
layout->diskSectorOrder, Equals(std::vector<unsigned>{3, 2, 1, 0}));
AssertThat(layout->filesystemSectorOrder,
Equals(std::vector<unsigned>{0, 2, 1, 3}));
}
int main(int argc, const char* argv[])
{
test_physical_sectors();
test_logical_sectors();
test_both_sectors();
}