mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
@@ -1,6 +1,8 @@
|
||||
#include "lib/globals.h"
|
||||
#include "lib/vfs/vfs.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include "lib/proto.h"
|
||||
#include "lib/layout.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "adflib.h"
|
||||
@@ -54,6 +56,26 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void create(bool quick, const std::string& volumeName)
|
||||
{
|
||||
if (!quick)
|
||||
eraseEverythingOnDisk();
|
||||
AdfMount m(this);
|
||||
|
||||
struct Device dev = {};
|
||||
dev.readOnly = false;
|
||||
dev.isNativeDev = true;
|
||||
dev.devType = DEVTYPE_FLOPDD;
|
||||
dev.cylinders = config.layout().tracks();
|
||||
dev.heads = config.layout().sides();
|
||||
dev.sectors =
|
||||
Layout::getSectorsInTrack(Layout::getLayoutOfTrack(0, 0)).size();
|
||||
adfInitDevice(&dev, nullptr, false);
|
||||
int res = adfCreateFlop(&dev, (char*)volumeName.c_str(), 0);
|
||||
if (res != RC_OK)
|
||||
throw CannotWriteException();
|
||||
}
|
||||
|
||||
FilesystemStatus check()
|
||||
{
|
||||
return FS_OK;
|
||||
@@ -65,7 +87,7 @@ public:
|
||||
|
||||
std::vector<std::unique_ptr<Dirent>> results;
|
||||
|
||||
auto* vol = m.getVolume();
|
||||
auto* vol = m.mount();
|
||||
changeDir(vol, path);
|
||||
|
||||
auto list = AdfList(adfGetDirEnt(vol, vol->curDirPtr));
|
||||
@@ -93,7 +115,7 @@ public:
|
||||
if (path.size() == 0)
|
||||
throw BadPathException();
|
||||
|
||||
auto* vol = m.getVolume();
|
||||
auto* vol = m.mount();
|
||||
changeDirButOne(vol, path);
|
||||
|
||||
auto entry = AdfEntry(adfFindEntry(vol, (char*)path.back().c_str()));
|
||||
@@ -126,7 +148,7 @@ public:
|
||||
if (path.size() == 0)
|
||||
throw BadPathException();
|
||||
|
||||
auto* vol = m.getVolume();
|
||||
auto* vol = m.mount();
|
||||
changeDirButOne(vol, path);
|
||||
|
||||
auto* file = adfOpenFile(vol, (char*)path.back().c_str(), (char*)"r");
|
||||
@@ -153,7 +175,7 @@ public:
|
||||
if (path.size() == 0)
|
||||
throw BadPathException();
|
||||
|
||||
auto* vol = m.getVolume();
|
||||
auto* vol = m.mount();
|
||||
changeDirButOne(vol, path);
|
||||
|
||||
auto* file = adfOpenFile(vol, (char*)path.back().c_str(), (char*)"w");
|
||||
@@ -229,19 +251,21 @@ private:
|
||||
AdfMount(AmigaFfsFilesystem* self): self(self)
|
||||
{
|
||||
currentAmigaFfs = self;
|
||||
self->_ffs = nullptr;
|
||||
|
||||
adfEnvInitDefault();
|
||||
self->_ffs = adfMountDev(nullptr, false);
|
||||
}
|
||||
|
||||
~AdfMount()
|
||||
{
|
||||
adfUnMountDev(self->_ffs);
|
||||
if (self->_ffs)
|
||||
adfUnMountDev(self->_ffs);
|
||||
adfEnvCleanUp();
|
||||
}
|
||||
|
||||
struct Volume* getVolume()
|
||||
struct Volume* mount()
|
||||
{
|
||||
self->_ffs = adfMountDev(nullptr, false);
|
||||
return adfMount(self->_ffs, 0, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,20 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void create(bool quick, const std::string& volumeName)
|
||||
{
|
||||
if (!quick)
|
||||
eraseEverythingOnDisk();
|
||||
|
||||
char buffer[FF_MAX_SS * 2];
|
||||
currentFatFs = this;
|
||||
FRESULT res = f_mkfs("", nullptr, buffer, sizeof(buffer));
|
||||
throwError(res);
|
||||
|
||||
mount();
|
||||
f_setlabel(volumeName.c_str());
|
||||
}
|
||||
|
||||
FilesystemStatus check()
|
||||
{
|
||||
return FS_OK;
|
||||
@@ -162,9 +176,14 @@ public:
|
||||
case GET_SECTOR_SIZE:
|
||||
*(DWORD*)buffer = getLogicalSectorSize();
|
||||
break;
|
||||
|
||||
case GET_SECTOR_COUNT:
|
||||
*(DWORD*)buffer = getLogicalSectorCount();
|
||||
break;
|
||||
|
||||
case CTRL_SYNC:
|
||||
break;
|
||||
|
||||
default:
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,15 @@ public:
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
void create(bool quick, const std::string& volumeName)
|
||||
{
|
||||
if (!quick)
|
||||
eraseEverythingOnDisk();
|
||||
|
||||
hfs_format(
|
||||
(const char*)this, 0, HFS_MODE_ANY, volumeName.c_str(), 0, nullptr);
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Dirent>> list(const Path& path)
|
||||
{
|
||||
HfsMount m(this);
|
||||
|
||||
@@ -33,7 +33,7 @@ std::string Path::to_str(const std::string sep) const
|
||||
return join(*this, sep);
|
||||
}
|
||||
|
||||
void Filesystem::create()
|
||||
void Filesystem::create(bool quick, const std::string& volumeName)
|
||||
{
|
||||
throw UnimplementedFilesystemException();
|
||||
}
|
||||
@@ -215,3 +215,9 @@ unsigned Filesystem::getLogicalSectorSize(unsigned track, unsigned side)
|
||||
auto trackdata = Layout::getLayoutOfTrack(track, side);
|
||||
return trackdata.sector_size();
|
||||
}
|
||||
|
||||
void Filesystem::eraseEverythingOnDisk()
|
||||
{
|
||||
for (int i = 0; i < getLogicalSectorCount(); i++)
|
||||
putLogicalSector(i, Bytes(1));
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
class Filesystem
|
||||
{
|
||||
public:
|
||||
virtual void create();
|
||||
virtual void create(bool quick, const std::string& name);
|
||||
virtual FilesystemStatus check();
|
||||
virtual std::vector<std::unique_ptr<Dirent>> list(const Path& path);
|
||||
virtual Bytes getFile(const Path& path);
|
||||
@@ -125,6 +125,8 @@ protected:
|
||||
unsigned getLogicalSectorCount();
|
||||
unsigned getLogicalSectorSize(unsigned track = 0, unsigned side = 0);
|
||||
|
||||
void eraseEverythingOnDisk();
|
||||
|
||||
private:
|
||||
typedef std::tuple<unsigned, unsigned, unsigned> location_t;
|
||||
std::vector<location_t> _locations;
|
||||
|
||||
@@ -3,6 +3,7 @@ include src/formats/build.mk
|
||||
FLUXENGINE_SRCS = \
|
||||
src/fe-analysedriveresponse.cc \
|
||||
src/fe-analyselayout.cc \
|
||||
src/fe-format.cc \
|
||||
src/fe-getfile.cc \
|
||||
src/fe-getfileinfo.cc \
|
||||
src/fe-inspect.cc \
|
||||
|
||||
43
src/fe-format.cc
Normal file
43
src/fe-format.cc
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "fluxmap.h"
|
||||
#include "sector.h"
|
||||
#include "proto.h"
|
||||
#include "readerwriter.h"
|
||||
#include "imagereader/imagereader.h"
|
||||
#include "imagewriter/imagewriter.h"
|
||||
#include "lib/fluxsource/fluxsource.h"
|
||||
#include "lib/decoders/decoders.h"
|
||||
#include "fmt/format.h"
|
||||
#include "fluxengine.h"
|
||||
#include "lib/vfs/sectorinterface.h"
|
||||
#include "lib/vfs/vfs.h"
|
||||
#include "src/fileutils.h"
|
||||
#include <google/protobuf/text_format.h>
|
||||
#include <fstream>
|
||||
|
||||
static FlagGroup flags({&fileFlags});
|
||||
|
||||
static StringFlag volumeName({"-n", "--name"}, "volume name", "FluxEngine");
|
||||
static SettableFlag quick({"-q", "--quick"},
|
||||
"perform quick format (requires the disk to be previously formatted)");
|
||||
|
||||
int mainFormat(int argc, const char* argv[])
|
||||
{
|
||||
if (argc == 1)
|
||||
showProfiles("format", formats);
|
||||
flags.parseFlagsWithConfigFiles(argc, argv, formats);
|
||||
|
||||
try
|
||||
{
|
||||
auto filesystem = createFilesystemFromConfig();
|
||||
filesystem->create(quick, volumeName);
|
||||
filesystem->flush();
|
||||
}
|
||||
catch (const FilesystemException& e)
|
||||
{
|
||||
Error() << e.message;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -6,6 +6,7 @@ typedef int command_cb(int agrc, const char* argv[]);
|
||||
|
||||
extern command_cb mainAnalyseDriveResponse;
|
||||
extern command_cb mainAnalyseLayout;
|
||||
extern command_cb mainFormat;
|
||||
extern command_cb mainGetFile;
|
||||
extern command_cb mainGetFileInfo;
|
||||
extern command_cb mainInspect;
|
||||
@@ -36,6 +37,7 @@ static std::vector<Command> commands =
|
||||
{ "analyse", mainAnalyse, "Disk and drive analysis tools." },
|
||||
{ "read", mainRead, "Reads a disk, producing a sector image.", },
|
||||
{ "write", mainWrite, "Writes a sector image to a disk.", },
|
||||
{ "format", mainFormat, "Format a disk and make a file system on it.", },
|
||||
{ "rawread", mainRawRead, "Reads raw flux from a disk. Warning: you can't use this to copy disks.", },
|
||||
{ "rawwrite", mainRawWrite, "Writes a flux file to a disk. Warning: you can't use this to copy disks.", },
|
||||
{ "ls", mainLs, "Show files on disk (or image).", },
|
||||
|
||||
Reference in New Issue
Block a user