mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Hack in boilerplate for a ZDos filesystem.
This commit is contained in:
13
lib/build.mk
13
lib/build.mk
@@ -77,14 +77,15 @@ LIBFLUXENGINE_SRCS = \
|
||||
lib/vfs/cbmfs.cc \
|
||||
lib/vfs/cpmfs.cc \
|
||||
lib/vfs/fatfs.cc \
|
||||
lib/vfs/lif.cc \
|
||||
lib/vfs/machfs.cc \
|
||||
lib/vfs/prodos.cc \
|
||||
lib/vfs/smaky6fs.cc \
|
||||
lib/vfs/philefs.cc \
|
||||
lib/vfs/vfs.cc \
|
||||
lib/vfs/fluxsectorinterface.cc \
|
||||
lib/vfs/imagesectorinterface.cc \
|
||||
lib/vfs/lif.cc \
|
||||
lib/vfs/machfs.cc \
|
||||
lib/vfs/philefs.cc \
|
||||
lib/vfs/prodos.cc \
|
||||
lib/vfs/smaky6fs.cc \
|
||||
lib/vfs/vfs.cc \
|
||||
lib/vfs/zdos.cc \
|
||||
|
||||
LIBFLUXENGINE_OBJS = $(patsubst %.cc, $(OBJDIR)/%.o, $(LIBFLUXENGINE_SRCS))
|
||||
OBJS += $(LIBFLUXENGINE_OBJS)
|
||||
|
||||
@@ -216,6 +216,9 @@ std::unique_ptr<Filesystem> Filesystem::createFilesystem(
|
||||
case FilesystemProto::LIF:
|
||||
return Filesystem::createLifFilesystem(config, image);
|
||||
|
||||
case FilesystemProto::ZDOS:
|
||||
return Filesystem::createZDosFilesystem(config, image);
|
||||
|
||||
default:
|
||||
error("no filesystem configured");
|
||||
return std::unique_ptr<Filesystem>();
|
||||
|
||||
@@ -256,6 +256,8 @@ public:
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> image);
|
||||
static std::unique_ptr<Filesystem> createLifFilesystem(
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> image);
|
||||
static std::unique_ptr<Filesystem> createZDosFilesystem(
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> image);
|
||||
|
||||
static std::unique_ptr<Filesystem> createFilesystem(
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> image);
|
||||
|
||||
@@ -88,7 +88,11 @@ message LifProto
|
||||
[ default = 256, (help) = "LIF filesystem block size" ];
|
||||
}
|
||||
|
||||
// NEXT_TAG: 15
|
||||
message ZDosProto
|
||||
{
|
||||
}
|
||||
|
||||
// NEXT_TAG: 16
|
||||
message FilesystemProto
|
||||
{
|
||||
enum FilesystemType
|
||||
@@ -106,6 +110,7 @@ message FilesystemProto
|
||||
APPLEDOS = 10;
|
||||
PHILE = 11;
|
||||
LIF = 12;
|
||||
ZDOS = 13;
|
||||
}
|
||||
|
||||
optional FilesystemType type = 10
|
||||
@@ -123,6 +128,7 @@ message FilesystemProto
|
||||
optional Smaky6FsProto smaky6 = 11;
|
||||
optional PhileProto phile = 13;
|
||||
optional LifProto lif = 14;
|
||||
optional ZDosProto zdos = 15;
|
||||
|
||||
optional SectorListProto sector_order = 9
|
||||
[ (help) = "specify the filesystem order of sectors" ];
|
||||
|
||||
208
lib/vfs/zdos.cc
Normal file
208
lib/vfs/zdos.cc
Normal file
@@ -0,0 +1,208 @@
|
||||
#include "lib/globals.h"
|
||||
#include "lib/vfs/vfs.h"
|
||||
#include "lib/config.pb.h"
|
||||
|
||||
class ZDosFilesystem : public Filesystem
|
||||
{
|
||||
#if 0
|
||||
class ZDosDirent : public Dirent
|
||||
{
|
||||
public:
|
||||
ZDosDirent(const ZDosProto& config, Bytes& bytes)
|
||||
{
|
||||
file_type = TYPE_FILE;
|
||||
|
||||
ByteReader br(bytes);
|
||||
filename = trimWhitespace(br.read(10));
|
||||
uint16_t type = br.read_be16();
|
||||
location = br.read_be32();
|
||||
length = br.read_be32() * config.block_size();
|
||||
int year = unbcd(br.read_8());
|
||||
int month = unbcd(br.read_8()) + 1;
|
||||
int day = unbcd(br.read_8());
|
||||
int hour = unbcd(br.read_8());
|
||||
int minute = unbcd(br.read_8());
|
||||
int second = unbcd(br.read_8());
|
||||
uint16_t volume = br.read_be16();
|
||||
uint16_t protection = br.read_be16();
|
||||
uint16_t recordSize = br.read_be16();
|
||||
|
||||
if (year >= 70)
|
||||
year += 1900;
|
||||
else
|
||||
year += 2000;
|
||||
|
||||
std::tm tm = {.tm_sec = second,
|
||||
.tm_min = minute,
|
||||
.tm_hour = hour,
|
||||
.tm_mday = day,
|
||||
.tm_mon = month,
|
||||
.tm_year = year - 1900,
|
||||
.tm_isdst = -1};
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(&tm, "%FT%T%z");
|
||||
ctime = ss.str();
|
||||
|
||||
auto it = numberToFileType.find(type);
|
||||
if (it != numberToFileType.end())
|
||||
mode = it->second;
|
||||
else
|
||||
mode = fmt::format("0x{:04x}", type);
|
||||
|
||||
path = {filename};
|
||||
|
||||
attributes[Filesystem::FILENAME] = filename;
|
||||
attributes[Filesystem::LENGTH] = std::to_string(length);
|
||||
attributes[Filesystem::FILE_TYPE] = "file";
|
||||
attributes[Filesystem::MODE] = mode;
|
||||
attributes["lif.ctime"] = ctime;
|
||||
attributes["lif.volume"] = std::to_string(volume & 0x7fff);
|
||||
attributes["lif.protection"] = fmt::format("0x{:x}", protection);
|
||||
attributes["lif.record_size"] = std::to_string(recordSize);
|
||||
}
|
||||
|
||||
public:
|
||||
uint32_t location;
|
||||
std::string ctime;
|
||||
};
|
||||
#endif
|
||||
|
||||
public:
|
||||
ZDosFilesystem(
|
||||
const ZDosProto& config, std::shared_ptr<SectorInterface> sectors):
|
||||
Filesystem(sectors),
|
||||
_config(config)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t capabilities() const
|
||||
{
|
||||
return OP_GETFSDATA | OP_LIST | OP_GETFILE | OP_GETDIRENT;
|
||||
}
|
||||
|
||||
FilesystemStatus check() override
|
||||
{
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
std::map<std::string, std::string> getMetadata() override
|
||||
{
|
||||
mount();
|
||||
|
||||
std::map<std::string, std::string> attributes;
|
||||
|
||||
attributes[VOLUME_NAME] = _volumeLabel;
|
||||
attributes[TOTAL_BLOCKS] = std::to_string(_totalBlocks);
|
||||
attributes[USED_BLOCKS] = std::to_string(_usedBlocks);
|
||||
attributes[BLOCK_SIZE] = std::to_string(_config.block_size());
|
||||
attributes["lif.directory_block"] = std::to_string(_directoryBlock);
|
||||
attributes["lif.directory_size"] = std::to_string(_directorySize);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
std::shared_ptr<Dirent> getDirent(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
if (path.size() != 1)
|
||||
throw BadPathException();
|
||||
|
||||
return findFile(path.front());
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
if (!path.empty())
|
||||
throw FileNotFoundException();
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> result;
|
||||
for (auto& de : _dirents)
|
||||
result.push_back(de);
|
||||
return result;
|
||||
}
|
||||
|
||||
Bytes getFile(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
if (path.size() != 1)
|
||||
throw BadPathException();
|
||||
|
||||
auto dirent = findFile(path.front());
|
||||
|
||||
return getZDosBlock(
|
||||
dirent->location, dirent->length / _config.block_size());
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
void mount()
|
||||
{
|
||||
#if 0
|
||||
_sectorSize = getLogicalSectorSize();
|
||||
_sectorsPerBlock = _sectorSize / _config.block_size();
|
||||
|
||||
_rootBlock = getZDosBlock(0);
|
||||
|
||||
ByteReader rbr(_rootBlock);
|
||||
if (rbr.read_be16() != 0x8000)
|
||||
throw BadFilesystemException();
|
||||
_volumeLabel = trimWhitespace(rbr.read(6));
|
||||
_directoryBlock = rbr.read_be32();
|
||||
rbr.skip(4);
|
||||
_directorySize = rbr.read_be32();
|
||||
unsigned tracks = rbr.read_be32();
|
||||
unsigned heads = rbr.read_be32();
|
||||
unsigned sectors = rbr.read_be32();
|
||||
_usedBlocks = 1 + _directorySize;
|
||||
|
||||
Bytes directory = getZDosBlock(_directoryBlock, _directorySize);
|
||||
|
||||
_dirents.clear();
|
||||
ByteReader br(directory);
|
||||
while (!br.eof())
|
||||
{
|
||||
Bytes direntBytes = br.read(32);
|
||||
if (direntBytes[0] != 0xff)
|
||||
{
|
||||
auto dirent = std::make_unique<ZDosDirent>(_config, direntBytes);
|
||||
_usedBlocks += dirent->length / _config.block_size();
|
||||
_dirents.push_back(std::move(dirent));
|
||||
}
|
||||
}
|
||||
_totalBlocks = std::max(tracks * heads * sectors, _usedBlocks);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
std::shared_ptr<ZDosDirent> findFile(const std::string filename)
|
||||
{
|
||||
for (const auto& dirent : _dirents)
|
||||
{
|
||||
if (dirent->filename == filename)
|
||||
return dirent;
|
||||
}
|
||||
|
||||
throw FileNotFoundException();
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
const ZDosProto& _config;
|
||||
int _sectorSize;
|
||||
int _sectorsPerBlock;
|
||||
Bytes _rootBlock;
|
||||
std::string _volumeLabel;
|
||||
unsigned _directoryBlock;
|
||||
unsigned _directorySize;
|
||||
unsigned _totalBlocks;
|
||||
unsigned _usedBlocks;
|
||||
//std::vector<std::shared_ptr<ZDosDirent>> _dirents;
|
||||
};
|
||||
|
||||
std::unique_ptr<Filesystem> Filesystem::createZDosFilesystem(
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> sectors)
|
||||
{
|
||||
return std::make_unique<ZDosFilesystem>(config.zdos(), sectors);
|
||||
}
|
||||
|
||||
@@ -254,12 +254,12 @@ public:
|
||||
ignoreInapplicableValueExceptions(
|
||||
[&]()
|
||||
{
|
||||
globalConfig().setImageReader(_selectedImagefilename);
|
||||
globalConfig().setImageReader(_selectedImagefilename);
|
||||
});
|
||||
ignoreInapplicableValueExceptions(
|
||||
[&]()
|
||||
{
|
||||
globalConfig().setImageWriter(_selectedImagefilename);
|
||||
globalConfig().setImageWriter(_selectedImagefilename);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user