mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Rework the layout stuff to be more correct. Physical skew no longer affects the
order in the resulting images.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
38
lib/layout.h
38
lib/layout.h
@@ -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
|
||||
|
||||
@@ -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});
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -18,7 +18,7 @@ layout {
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 12
|
||||
#skew: 5
|
||||
skew: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ layout {
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 12
|
||||
#skew: 5
|
||||
skew: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
125
tests/layout.cc
Normal 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();
|
||||
}
|
||||
Reference in New Issue
Block a user