Wire up some more control panel buttons. Create an in-memory sector

interface for doing filesystem stuff.
This commit is contained in:
David Given
2025-09-15 20:06:16 +02:00
parent 98f7febef7
commit 6127c9a46d
12 changed files with 210 additions and 47 deletions

View File

@@ -85,6 +85,22 @@ std::vector<CylinderHead> Layout::computePhysicalLocations()
return locations;
}
std::vector<CylinderHead> Layout::computeLogicalLocations()
{
if (!globalConfig()->tracks().empty())
return parseCylinderHeadsString(globalConfig()->tracks());
std::set<unsigned> tracks = iterate(0, globalConfig()->layout().tracks());
std::set<unsigned> heads = iterate(0, globalConfig()->layout().sides());
std::vector<CylinderHead> locations;
for (unsigned logicalCylinder : tracks)
for (unsigned logicalHead : heads)
locations.push_back(CylinderHead{logicalCylinder, logicalHead});
return locations;
}
Layout::LayoutBounds Layout::getBounds(
const std::vector<CylinderHead>& locations)
{
@@ -105,7 +121,9 @@ Layout::LayoutBounds Layout::getBounds(
}
std::vector<std::pair<int, int>> Layout::getTrackOrdering(
LayoutProto::Order ordering, unsigned guessedCylinders, unsigned guessedHeads)
LayoutProto::Order ordering,
unsigned guessedCylinders,
unsigned guessedHeads)
{
auto layout = globalConfig()->layout();
int tracks = layout.has_tracks() ? layout.tracks() : guessedCylinders;
@@ -206,7 +224,8 @@ std::shared_ptr<const TrackInfo> Layout::getLayoutOfTrack(
for (const auto& f : globalConfig()->layout().layoutdata())
{
if (f.has_track() && f.has_up_to_track() &&
((logicalCylinder < f.track()) || (logicalCylinder > f.up_to_track())))
((logicalCylinder < f.track()) ||
(logicalCylinder > f.up_to_track())))
continue;
if (f.has_track() && !f.has_up_to_track() &&
(logicalCylinder != f.track()))
@@ -222,7 +241,8 @@ std::shared_ptr<const TrackInfo> Layout::getLayoutOfTrack(
trackInfo->sectorSize = layoutdata.sector_size();
trackInfo->logicalCylinder = logicalCylinder;
trackInfo->logicalHead = logicalHead;
trackInfo->physicalCylinder = remapCylinderLogicalToPhysical(logicalCylinder);
trackInfo->physicalCylinder =
remapCylinderLogicalToPhysical(logicalCylinder);
trackInfo->physicalHead =
logicalHead ^ globalConfig()->layout().swap_sides();
trackInfo->groupSize = getTrackStep();
@@ -290,7 +310,8 @@ int Layout::getHeadWidth()
}
}
std::vector<LogicalLocation> Layout::computeFilesystemLogicalOrdering(){
std::vector<LogicalLocation> Layout::computeFilesystemLogicalOrdering()
{
std::vector<LogicalLocation> result;
auto& layout = globalConfig()->layout();
if (layout.has_tracks() && layout.has_sides())
@@ -309,8 +330,7 @@ std::vector<LogicalLocation> Layout::computeFilesystemLogicalOrdering(){
continue;
for (unsigned sectorId : trackLayout->filesystemSectorOrder)
result.push_back(
{track, side, sectorId});
result.push_back({track, side, sectorId});
}
}
return result;

View File

@@ -25,9 +25,10 @@ public:
static unsigned remapHeadLogicalToPhysical(unsigned logicalHead);
/* Uses the layout and current track and heads settings to determine
* which physical tracks are going to be read from or written to.
* which physical/logical tracks are going to be read from or written to.
*/
static std::vector<CylinderHead> computePhysicalLocations();
static std::vector<CylinderHead> computeLogicalLocations();
/* Uses the current layout to compute the filesystem's block order, in
* _logical_ tracks. */

View File

@@ -37,7 +37,11 @@ struct Sector : public LogicalLocation
Bytes data;
std::vector<std::shared_ptr<Record>> records;
Sector(std::shared_ptr<const TrackInfo>& layout, const LogicalLocation& location);
Sector(const Sector& other) = default;
Sector& operator=(const Sector& other) = default;
Sector(std::shared_ptr<const TrackInfo>& layout,
const LogicalLocation& location);
std::tuple<int, int, int, Status> key() const
{
@@ -45,19 +49,9 @@ struct Sector : public LogicalLocation
logicalCylinder, logicalHead, logicalSector, status);
}
bool operator==(const Sector& rhs) const
std::strong_ordering operator<=>(const Sector& rhs) const
{
return key() == rhs.key();
}
bool operator!=(const Sector& rhs) const
{
return key() != rhs.key();
}
bool operator<(const Sector& rhs) const
{
return key() < rhs.key();
return key() <=> rhs.key();
}
};

View File

@@ -35,6 +35,7 @@ cxxlibrary(
"./imagesectorinterface.cc",
"./lif.cc",
"./machfs.cc",
"./memorysectorinterface.cc",
"./microdos.cc",
"./philefs.cc",
"./prodos.cc",

View File

@@ -0,0 +1,71 @@
#include "lib/core/globals.h"
#include "lib/vfs/sectorinterface.h"
#include "lib/imagereader/imagereader.h"
#include "lib/imagewriter/imagewriter.h"
#include "lib/data/image.h"
#include "lib/data/layout.h"
#include "lib/data/sector.h"
#include "lib/core/bytes.h"
class MemorySectorInterface : public SectorInterface
{
public:
MemorySectorInterface(std::shared_ptr<Image> image): _backupImage(image)
{
discardChanges();
}
public:
std::shared_ptr<const Sector> get(
unsigned track, unsigned side, unsigned sectorId) override
{
return _liveImage->get(track, side, sectorId);
}
std::shared_ptr<Sector> put(
unsigned track, unsigned side, unsigned sectorId) override
{
_changed = true;
return _liveImage->put(track, side, sectorId);
}
bool isReadOnly() override
{
return false;
}
bool needsFlushing() override
{
return _changed;
}
void flushChanges() override
{
// _writer->writeImage(*_image);
_changed = false;
}
void discardChanges() override
{
_liveImage = std::make_unique<Image>();
for (auto sector : *_backupImage)
{
auto s = _liveImage->put(sector->logicalCylinder,
sector->logicalHead,
sector->logicalSector);
*s = *sector;
}
_changed = false;
}
private:
std::shared_ptr<Image> _backupImage;
std::shared_ptr<Image> _liveImage;
bool _changed = false;
};
std::unique_ptr<SectorInterface> SectorInterface::createMemorySectorInterface(
std::shared_ptr<Image> image)
{
return std::make_unique<MemorySectorInterface>(image);
}

View File

@@ -1,6 +1,7 @@
#ifndef SECTORINTERFACE_H
#define SECTORINTERFACE_H
class Image;
class ImageReader;
class ImageWriter;
class Sector;
@@ -35,6 +36,8 @@ public:
virtual void discardChanges() {}
public:
static std::unique_ptr<SectorInterface> createMemorySectorInterface(
std::shared_ptr<Image> image);
static std::unique_ptr<SectorInterface> createImageSectorInterface(
std::shared_ptr<ImageReader> reader,
std::shared_ptr<ImageWriter> writer);