summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2021-03-04 10:49:33 +0100
committer Olivier Galibert <galibert@pobox.com>2021-03-05 10:17:20 +0100
commit92326e47afea2dd65ec6b5ec842454fc74f046cc (patch)
tree515de40cefa3c48bf30869f9031fbf78e4ba45d4 /src/lib
parentf7011c21e11e988ec26d095f48b9070760c72bc3 (diff)
floppy: Beginning of the support for preformatted floppy images.
What's missing: - parameters (like the disk name when it exists) - possibly a cleanup of ram_open and friends (but not sure of the appropriate direction in which to go)
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/formats/all.cpp9
-rw-r--r--src/lib/formats/all.h2
-rw-r--r--src/lib/formats/fs_prodos.cpp76
-rw-r--r--src/lib/formats/fs_prodos.h26
-rw-r--r--src/lib/formats/fs_unformatted.cpp99
-rw-r--r--src/lib/formats/fs_unformatted.h48
-rw-r--r--src/lib/formats/fsmgr.cpp81
-rw-r--r--src/lib/formats/fsmgr.h57
8 files changed, 398 insertions, 0 deletions
diff --git a/src/lib/formats/all.cpp b/src/lib/formats/all.cpp
index dbdc3be4d9b..2d4d48fef5b 100644
--- a/src/lib/formats/all.cpp
+++ b/src/lib/formats/all.cpp
@@ -19,6 +19,7 @@
#include "pc_dsk.h"
#include "d88_dsk.h"
#include "dfi_dsk.h"
+#include "fs_unformatted.h"
#ifdef HAS_FORMATS_2D_DSK
#include "2d_dsk.h"
@@ -664,9 +665,14 @@
#include "zx81_p.h"
#endif
+#ifdef HAS_FORMATS_FS_PRODOS
+#include "fs_prodos.h"
+#endif
+
void mame_formats_full_list(mame_formats_enumerator &en)
{
en.category("Generic");
+ en.add(FS_UNFORMATTED);
en.add(cassette_default_formats);
#ifdef HAS_FORMATS_UEF_CAS
en.add(uef_cassette_formats); // uef_cas.h
@@ -689,6 +695,9 @@ void mame_formats_full_list(mame_formats_enumerator &en)
#endif
en.category("Apple");
+#ifdef HAS_FORMATS_FS_PRODOS
+ en.add(FS_PRODOS);
+#endif
#ifdef HAS_FORMATS_AP2_DSK
en.add(FLOPPY_A216S_FORMAT); // ap2_dsk.h
en.add(FLOPPY_RWTS18_FORMAT); // ap2_dsk.h
diff --git a/src/lib/formats/all.h b/src/lib/formats/all.h
index 3c869336d1b..63de5560949 100644
--- a/src/lib/formats/all.h
+++ b/src/lib/formats/all.h
@@ -10,6 +10,7 @@
#include "cassimg.h"
#include "flopimg.h"
+#include "fsmgr.h"
struct mame_formats_enumerator {
virtual ~mame_formats_enumerator() = default;
@@ -17,6 +18,7 @@ struct mame_formats_enumerator {
virtual void category(const char *name) = 0;
virtual void add(const cassette_image::Format *const *formats) = 0;
virtual void add(floppy_format_type format) = 0;
+ virtual void add(filesystem_manager_type fs) = 0;
};
void mame_formats_full_list(mame_formats_enumerator &en);
diff --git a/src/lib/formats/fs_prodos.cpp b/src/lib/formats/fs_prodos.cpp
new file mode 100644
index 00000000000..bc5a42664df
--- /dev/null
+++ b/src/lib/formats/fs_prodos.cpp
@@ -0,0 +1,76 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// Creation of Apple ProDOS floppy images
+
+#include "emu.h"
+#include "fs_prodos.h"
+#include "ap_dsk35.h"
+
+const u8 fs_prodos::boot[512] = {
+ 0x01, 0x38, 0xb0, 0x03, 0x4c, 0x1c, 0x09, 0x78, 0x86, 0x43, 0xc9, 0x03, 0x08, 0x8a, 0x29, 0x70,
+ 0x4a, 0x4a, 0x4a, 0x4a, 0x09, 0xc0, 0x85, 0x49, 0xa0, 0xff, 0x84, 0x48, 0x28, 0xc8, 0xb1, 0x48,
+ 0xd0, 0x3a, 0xb0, 0x0e, 0xa9, 0x03, 0x8d, 0x00, 0x08, 0xe6, 0x3d, 0xa5, 0x49, 0x48, 0xa9, 0x5b,
+ 0x48, 0x60, 0x85, 0x40, 0x85, 0x48, 0xa0, 0x5e, 0xb1, 0x48, 0x99, 0x94, 0x09, 0xc8, 0xc0, 0xeb,
+ 0xd0, 0xf6, 0xa2, 0x06, 0xbc, 0x32, 0x09, 0xbd, 0x39, 0x09, 0x99, 0xf2, 0x09, 0xbd, 0x40, 0x09,
+ 0x9d, 0x7f, 0x0a, 0xca, 0x10, 0xee, 0xa9, 0x09, 0x85, 0x49, 0xa9, 0x86, 0xa0, 0x00, 0xc9, 0xf9,
+ 0xb0, 0x2f, 0x85, 0x48, 0x84, 0x60, 0x84, 0x4a, 0x84, 0x4c, 0x84, 0x4e, 0x84, 0x47, 0xc8, 0x84,
+ 0x42, 0xc8, 0x84, 0x46, 0xa9, 0x0c, 0x85, 0x61, 0x85, 0x4b, 0x20, 0x27, 0x09, 0xb0, 0x66, 0xe6,
+ 0x61, 0xe6, 0x61, 0xe6, 0x46, 0xa5, 0x46, 0xc9, 0x06, 0x90, 0xef, 0xad, 0x00, 0x0c, 0x0d, 0x01,
+ 0x0c, 0xd0, 0x52, 0xa9, 0x04, 0xd0, 0x02, 0xa5, 0x4a, 0x18, 0x6d, 0x23, 0x0c, 0xa8, 0x90, 0x0d,
+ 0xe6, 0x4b, 0xa5, 0x4b, 0x4a, 0xb0, 0x06, 0xc9, 0x0a, 0xf0, 0x71, 0xa0, 0x04, 0x84, 0x4a, 0xad,
+ 0x20, 0x09, 0x29, 0x0f, 0xa8, 0xb1, 0x4a, 0xd9, 0x20, 0x09, 0xd0, 0xdb, 0x88, 0x10, 0xf6, 0xa0,
+ 0x16, 0xb1, 0x4a, 0x4a, 0x6d, 0x1f, 0x09, 0x8d, 0x1f, 0x09, 0xa0, 0x11, 0xb1, 0x4a, 0x85, 0x46,
+ 0xc8, 0xb1, 0x4a, 0x85, 0x47, 0xa9, 0x00, 0x85, 0x4a, 0xa0, 0x1e, 0x84, 0x4b, 0x84, 0x61, 0xc8,
+ 0x84, 0x4d, 0x20, 0x27, 0x09, 0xb0, 0x35, 0xe6, 0x61, 0xe6, 0x61, 0xa4, 0x4e, 0xe6, 0x4e, 0xb1,
+ 0x4a, 0x85, 0x46, 0xb1, 0x4c, 0x85, 0x47, 0x11, 0x4a, 0xd0, 0x18, 0xa2, 0x01, 0xa9, 0x00, 0xa8,
+ 0x91, 0x60, 0xc8, 0xd0, 0xfb, 0xe6, 0x61, 0xea, 0xea, 0xca, 0x10, 0xf4, 0xce, 0x1f, 0x09, 0xf0,
+ 0x07, 0xd0, 0xd8, 0xce, 0x1f, 0x09, 0xd0, 0xca, 0x58, 0x4c, 0x00, 0x20, 0x4c, 0x47, 0x09, 0x02,
+ 0x26, 0x50, 0x52, 0x4f, 0x44, 0x4f, 0x53, 0xa5, 0x60, 0x85, 0x44, 0xa5, 0x61, 0x85, 0x45, 0x6c,
+ 0x48, 0x00, 0x08, 0x1e, 0x24, 0x3f, 0x45, 0x47, 0x76, 0xf4, 0xd7, 0xd1, 0xb6, 0x4b, 0xb4, 0xac,
+ 0xa6, 0x2b, 0x18, 0x60, 0x4c, 0xbc, 0x09, 0x20, 0x58, 0xfc, 0xa0, 0x14, 0xb9, 0x58, 0x09, 0x99,
+ 0xb1, 0x05, 0x88, 0x10, 0xf7, 0x4c, 0x55, 0x09, 0xd5, 0xce, 0xc1, 0xc2, 0xcc, 0xc5, 0xa0, 0xd4,
+ 0xcf, 0xa0, 0xcc, 0xcf, 0xc1, 0xc4, 0xa0, 0xd0, 0xd2, 0xcf, 0xc4, 0xcf, 0xd3, 0xa5, 0x53, 0x29,
+ 0x03, 0x2a, 0x05, 0x2b, 0xaa, 0xbd, 0x80, 0xc0, 0xa9, 0x2c, 0xa2, 0x11, 0xca, 0xd0, 0xfd, 0xe9,
+ 0x01, 0xd0, 0xf7, 0xa6, 0x2b, 0x60, 0xa5, 0x46, 0x29, 0x07, 0xc9, 0x04, 0x29, 0x03, 0x08, 0x0a,
+ 0x28, 0x2a, 0x85, 0x3d, 0xa5, 0x47, 0x4a, 0xa5, 0x46, 0x6a, 0x4a, 0x4a, 0x85, 0x41, 0x0a, 0x85,
+ 0x51, 0xa5, 0x45, 0x85, 0x27, 0xa6, 0x2b, 0xbd, 0x89, 0xc0, 0x20, 0xbc, 0x09, 0xe6, 0x27, 0xe6,
+ 0x3d, 0xe6, 0x3d, 0xb0, 0x03, 0x20, 0xbc, 0x09, 0xbc, 0x88, 0xc0, 0x60, 0xa5, 0x40, 0x0a, 0x85,
+ 0x53, 0xa9, 0x00, 0x85, 0x54, 0xa5, 0x53, 0x85, 0x50, 0x38, 0xe5, 0x51, 0xf0, 0x14, 0xb0, 0x04,
+ 0xe6, 0x53, 0x90, 0x02, 0xc6, 0x53, 0x38, 0x20, 0x6d, 0x09, 0xa5, 0x50, 0x18, 0x20, 0x6f, 0x09,
+ 0xd0, 0xe3, 0xa0, 0x7f, 0x84, 0x52, 0x08, 0x28, 0x38, 0xc6, 0x52, 0xf0, 0xce, 0x18, 0x08, 0x88,
+ 0xf0, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+void fs_prodos::enumerate(floppy_enumerator &fe, uint32_t form_factor, const std::vector<uint32_t> &variants) const
+{
+ bool all = form_factor == floppy_image::FF_UNKNOWN;
+
+ if(all || (form_factor == floppy_image::FF_35 && has_variant(variants, floppy_image::DSDD)))
+ fe.add(this, FLOPPY_APPLE_GCR_FORMAT, 819200, "prodos_800k", 800, "Apple ProDOS 800K");
+ if(all || (form_factor == floppy_image::FF_35 && has_variant(variants, floppy_image::SSDD)))
+ fe.add(this, FLOPPY_APPLE_GCR_FORMAT, 409600, "prodos_400k", 400, "Apple ProDOS 400K");
+}
+
+void fs_prodos::floppy_instantiate(u32 key, std::vector<u8> &image) const
+{
+ if(key == 800) {
+ copy(image, 0x000, boot, 512);
+ w8 (image, 0x402, 0x03);
+ w8 (image, 0x404, 0xf8);
+ wstr(image, 0x405, "UNTITLED");
+ w32b(image, 0x416, 0x642a250d);
+ w16b(image, 0x41a, 0x80ff);
+ w32b(image, 0x41c, 0x642a250d);
+ w32b(image, 0x420, 0x0500c327);
+ w32b(image, 0x424, 0x0d000006);
+ w32b(image, 0x428, 0x00400600);
+ w32b(image, 0x600, 0x02000400);
+ w32b(image, 0x800, 0x03000500);
+ w8 (image, 0xa00, 0x04);
+ w8 (image, 0xc00, 0x01);
+ fill(image, 0xc01, 0xff, 199);
+ }
+}
+
+const filesystem_manager_type FS_PRODOS = &filesystem_manager_creator<fs_prodos>;;
diff --git a/src/lib/formats/fs_prodos.h b/src/lib/formats/fs_prodos.h
new file mode 100644
index 00000000000..5c9dfb3f082
--- /dev/null
+++ b/src/lib/formats/fs_prodos.h
@@ -0,0 +1,26 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// Creation of Apple ProDOS floppy images
+
+#ifndef MAME_FORMATS_FS_PRODOS_H
+#define MAME_FORMATS_FS_PRODOS_H
+
+#pragma once
+
+#include "fsmgr.h"
+
+class fs_prodos : public filesystem_manager_t {
+public:
+ fs_prodos() : filesystem_manager_t() {}
+
+ virtual void enumerate(floppy_enumerator &fe, uint32_t form_factor, const std::vector<uint32_t> &variants) const override;
+ virtual void floppy_instantiate(u32 key, std::vector<u8> &image) const override;
+
+private:
+ static const u8 boot[512];
+};
+
+extern const filesystem_manager_type FS_PRODOS;
+
+#endif
diff --git a/src/lib/formats/fs_unformatted.cpp b/src/lib/formats/fs_unformatted.cpp
new file mode 100644
index 00000000000..0ce556fbab3
--- /dev/null
+++ b/src/lib/formats/fs_unformatted.cpp
@@ -0,0 +1,99 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// Creation of unformatted floppy images
+
+#include "emu.h"
+#include "fs_unformatted.h"
+
+void fs_unformatted::enumerate(floppy_enumerator &fe, uint32_t form_factor, const std::vector<uint32_t> &variants) const
+{
+ bool all = form_factor == floppy_image::FF_UNKNOWN;
+ u32 best_8 =
+ form_factor == floppy_image::FF_8 ?
+ has_variant(variants, floppy_image::DSDD) ? FSI_8_DSDD :
+ has_variant(variants, floppy_image::DSSD) ? FSI_8_DSSD : FSI_8_SSSD
+ : FSI_NONE;
+
+ u32 best_525 =
+ form_factor == floppy_image::FF_525 ?
+ has_variant(variants, floppy_image::DSHD) ? FSI_525_DSHD :
+ has_variant(variants, floppy_image::DSQD) ? FSI_525_DSQD :
+ has_variant(variants, floppy_image::DSDD) ? FSI_525_DSDD :
+ has_variant(variants, floppy_image::SSQD) ? FSI_525_SSQD :
+ has_variant(variants, floppy_image::SSDD) ? FSI_525_SSDD : FSI_525_SSSD
+ : FSI_NONE;
+
+ u32 best_35 =
+ form_factor == floppy_image::FF_35 ?
+ has_variant(variants, floppy_image::DSDD) ? FSI_35_DSDD : FSI_35_SSDD
+ : FSI_NONE;
+
+ u32 best_3 =
+ form_factor == floppy_image::FF_3 ?
+ has_variant(variants, floppy_image::DSDD) ? FSI_3_DSDD : FSI_3_SSDD
+ : FSI_NONE;
+
+ if(all || best_8 == FSI_8_DSDD)
+ fe.add_raw(this, "u8dsdd", FSI_8_DSDD, "Unformatted 8\" double-sided double-density");
+ if(all || best_8 == FSI_8_DSSD)
+ fe.add_raw(this, "u8dssd", FSI_8_DSSD, "Unformatted 8\" double-sided single-density");
+ if(all || best_8 == FSI_8_SSSD)
+ fe.add_raw(this, "u8sssd", FSI_8_SSSD, "Unformatted 8\" single-sided single-density");
+
+ if(all || best_525 == FSI_525_DSHD)
+ fe.add_raw(this, "u525dshd", FSI_525_DSHD, "Unformatted 5\"25 double-sided high-density");
+ if(all || best_525 == FSI_525_DSQD)
+ fe.add_raw(this, "u525dsqd", FSI_525_DSQD, "Unformatted 5\"25 double-sided quad-density");
+ if(all || best_525 == FSI_525_DSDD)
+ fe.add_raw(this, "u525dsdd", FSI_525_DSDD, "Unformatted 5\"25 double-sided double-density");
+ if(all)
+ fe.add_raw(this, "u525dssd", FSI_525_DSSD, "Unformatted 5\"25 double-sided single-density");
+ if(all || best_525 == FSI_525_SSQD)
+ fe.add_raw(this, "u525ssqd", FSI_525_SSQD, "Unformatted 5\"25 single-sided quad-density");
+ if(all || best_525 == FSI_525_SSDD)
+ fe.add_raw(this, "u525ssdd", FSI_525_SSDD, "Unformatted 5\"25 single-sided double-density");
+ if(all || best_525 == FSI_525_SSSD)
+ fe.add_raw(this, "u525sssd", FSI_525_SSSD, "Unformatted 5\"25 single-sided single-density");
+
+ if(all || has_variant(variants, floppy_image::DSED))
+ fe.add_raw(this, "u35dsed", FSI_35_DSED, "Unformatted 3\"5 double-sided extra-density");
+ if(all || has_variant(variants, floppy_image::DSHD))
+ fe.add_raw(this, "u35dshd", FSI_35_DSHD, "Unformatted 3\"5 double-sided high-density");
+ if(all || best_35 == FSI_35_DSDD)
+ fe.add_raw(this, "u35dsdd", FSI_35_DSDD, "Unformatted 3\"5 double-sided double-density");
+ if(all || best_35 == FSI_35_SSDD)
+ fe.add_raw(this, "u35ssdd", FSI_35_SSDD, "Unformatted 3\"5 single-sided double-density");
+
+ if(all || best_3 == FSI_3_DSDD)
+ fe.add_raw(this, "u3dsdd", FSI_35_DSDD, "Unformatted 3\" double-sided double-density");
+ if(all || best_3 == FSI_3_SSDD)
+ fe.add_raw(this, "u3ssdd", FSI_35_SSDD, "Unformatted 3\" single-sided double-density");
+}
+
+void fs_unformatted::floppy_instantiate_raw(u32 key, floppy_image *image) const
+{
+ switch(key) {
+ case FSI_8_DSDD: image->set_form_variant(floppy_image::FF_8, floppy_image::DSDD); break;
+ case FSI_8_DSSD: image->set_form_variant(floppy_image::FF_8, floppy_image::DSSD); break;
+ case FSI_8_SSSD: image->set_form_variant(floppy_image::FF_8, floppy_image::SSSD); break;
+
+ case FSI_525_DSHD: image->set_form_variant(floppy_image::FF_525, floppy_image::DSHD); break;
+ case FSI_525_DSQD: image->set_form_variant(floppy_image::FF_525, floppy_image::DSQD); break;
+ case FSI_525_DSDD: image->set_form_variant(floppy_image::FF_525, floppy_image::DSDD); break;
+ case FSI_525_DSSD: image->set_form_variant(floppy_image::FF_525, floppy_image::DSSD); break;
+ case FSI_525_SSQD: image->set_form_variant(floppy_image::FF_525, floppy_image::SSQD); break;
+ case FSI_525_SSDD: image->set_form_variant(floppy_image::FF_525, floppy_image::SSDD); break;
+ case FSI_525_SSSD: image->set_form_variant(floppy_image::FF_525, floppy_image::SSSD); break;
+
+ case FSI_35_DSED: image->set_form_variant(floppy_image::FF_35, floppy_image::DSED); break;
+ case FSI_35_DSHD: image->set_form_variant(floppy_image::FF_35, floppy_image::DSHD); break;
+ case FSI_35_DSDD: image->set_form_variant(floppy_image::FF_35, floppy_image::DSDD); break;
+ case FSI_35_SSDD: image->set_form_variant(floppy_image::FF_35, floppy_image::SSDD); break;
+
+ case FSI_3_DSDD: image->set_form_variant(floppy_image::FF_3, floppy_image::DSDD); break;
+ case FSI_3_SSDD: image->set_form_variant(floppy_image::FF_3, floppy_image::SSDD); break;
+ }
+}
+
+const filesystem_manager_type FS_UNFORMATTED = &filesystem_manager_creator<fs_unformatted>;
diff --git a/src/lib/formats/fs_unformatted.h b/src/lib/formats/fs_unformatted.h
new file mode 100644
index 00000000000..5bcaaf1e34e
--- /dev/null
+++ b/src/lib/formats/fs_unformatted.h
@@ -0,0 +1,48 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// Creation of unformatted floppy images
+
+#ifndef MAME_FORMATS_FS_UNFORMATTED_H
+#define MAME_FORMATS_FS_UNFORMATTED_H
+
+#pragma once
+
+#include "fsmgr.h"
+
+class fs_unformatted : public filesystem_manager_t {
+public:
+ fs_unformatted() : filesystem_manager_t() {}
+
+ virtual void enumerate(floppy_enumerator &fe, uint32_t form_factor, const std::vector<uint32_t> &variants) const override;
+ virtual void floppy_instantiate_raw(u32 key, floppy_image *image) const override;
+
+private:
+ enum {
+ FSI_NONE,
+
+ FSI_8_SSSD,
+ FSI_8_DSSD,
+ FSI_8_DSDD,
+
+ FSI_525_SSSD,
+ FSI_525_SSDD,
+ FSI_525_SSQD,
+ FSI_525_DSSD,
+ FSI_525_DSDD,
+ FSI_525_DSQD,
+ FSI_525_DSHD,
+
+ FSI_35_SSDD,
+ FSI_35_DSDD,
+ FSI_35_DSHD,
+ FSI_35_DSED,
+
+ FSI_3_DSDD,
+ FSI_3_SSDD,
+ };
+};
+
+extern const filesystem_manager_type FS_UNFORMATTED;
+
+#endif
diff --git a/src/lib/formats/fsmgr.cpp b/src/lib/formats/fsmgr.cpp
new file mode 100644
index 00000000000..706de6a855b
--- /dev/null
+++ b/src/lib/formats/fsmgr.cpp
@@ -0,0 +1,81 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// Filesystem management code for floppy and hd images
+
+// Currently limited to floppies and creation of preformatted images
+
+#include "emu.h"
+#include "fsmgr.h"
+
+void filesystem_manager_t::enumerate(floppy_enumerator &fe, uint32_t form_factor, const std::vector<uint32_t> &variants) const
+{
+}
+
+void filesystem_manager_t::floppy_instantiate(u32 key, std::vector<u8> &image) const
+{
+ fprintf(stderr, "filesystem_manager_t::floppy_instantiate called while unsupported\n");
+ abort();
+}
+
+void filesystem_manager_t::floppy_instantiate_raw(u32 key, floppy_image *image) const
+{
+ fprintf(stderr, "filesystem_manager_t::floppy_instantiate_raw called while unsupported\n");
+ abort();
+}
+
+bool filesystem_manager_t::has_variant(const std::vector<uint32_t> &variants, uint32_t variant)
+{
+ for(uint32_t v : variants)
+ if(variant == v)
+ return true;
+ return false;
+}
+
+void filesystem_manager_t::copy(std::vector<u8> &image, u32 offset, const u8 *src, u32 size)
+{
+ memcpy(image.data() + offset, src, size);
+}
+
+void filesystem_manager_t::fill(std::vector<u8> &image, u32 offset, u8 data, u32 size)
+{
+ memset(image.data() + offset, data, size);
+}
+
+void filesystem_manager_t::wstr(std::vector<u8> &image, u32 offset, const char *str)
+{
+ memcpy(image.data() + offset, str, strlen(str)+1);
+}
+
+void filesystem_manager_t::w8(std::vector<u8> &image, u32 offset, u8 data)
+{
+ image[offset] = data;
+}
+
+void filesystem_manager_t::w16b(std::vector<u8> &image, u32 offset, u16 data)
+{
+ image[offset ] = data >> 8;
+ image[offset+1] = data;
+}
+
+void filesystem_manager_t::w32b(std::vector<u8> &image, u32 offset, u32 data)
+{
+ image[offset ] = data >> 24;
+ image[offset+1] = data >> 16;
+ image[offset+2] = data >> 8;
+ image[offset+3] = data;
+}
+
+void filesystem_manager_t::w16l(std::vector<u8> &image, u32 offset, u16 data)
+{
+ image[offset ] = data;
+ image[offset+1] = data >> 8;
+}
+
+void filesystem_manager_t::w32l(std::vector<u8> &image, u32 offset, u32 data)
+{
+ image[offset ] = data;
+ image[offset+1] = data >> 8;
+ image[offset+2] = data >> 16;
+ image[offset+3] = data >> 24;
+}
diff --git a/src/lib/formats/fsmgr.h b/src/lib/formats/fsmgr.h
new file mode 100644
index 00000000000..0c69cef2e60
--- /dev/null
+++ b/src/lib/formats/fsmgr.h
@@ -0,0 +1,57 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// Filesystem management code for floppy and hd images
+
+// Currently limited to floppies and creation of preformatted images
+
+#ifndef MAME_FORMATS_FSMGR_H
+#define MAME_FORMATS_FSMGR_H
+
+#pragma once
+
+#include "flopimg.h"
+
+class filesystem_manager_t {
+public:
+ struct floppy_enumerator {
+ virtual ~floppy_enumerator() = default;
+
+ virtual void add(const filesystem_manager_t *manager, floppy_format_type type, u32 image_size, const char *name, u32 key, const char *description) = 0;
+ virtual void add_raw(const filesystem_manager_t *manager, const char *name, u32 key, const char *description) = 0;
+ };
+
+ virtual void enumerate(floppy_enumerator &fe, uint32_t form_factor, const std::vector<uint32_t> &variants) const;
+
+ // Floppy image initialization
+ virtual void floppy_instantiate(u32 key, std::vector<u8> &image) const;
+
+ // Floppy image initialization for add_raw
+ virtual void floppy_instantiate_raw(u32 key, floppy_image *image) const;
+
+protected:
+ filesystem_manager_t() = default;
+
+ static bool has_variant(const std::vector<uint32_t> &variants, uint32_t variant);
+
+ static void copy(std::vector<u8> &image, u32 offset, const u8 *src, u32 size);
+ static void fill(std::vector<u8> &image, u32 offset, u8 data, u32 size);
+ static void wstr(std::vector<u8> &image, u32 offset, const char *str);
+ static void w8(std::vector<u8> &image, u32 offset, u8 data);
+ static void w16b(std::vector<u8> &image, u32 offset, u16 data);
+ static void w32b(std::vector<u8> &image, u32 offset, u32 data);
+ static void w16l(std::vector<u8> &image, u32 offset, u16 data);
+ static void w32l(std::vector<u8> &image, u32 offset, u32 data);
+};
+
+
+typedef filesystem_manager_t *(*filesystem_manager_type)();
+
+// this template function creates a stub which constructs a filesystem manager
+template<class _FormatClass>
+filesystem_manager_t *filesystem_manager_creator()
+{
+ return new _FormatClass();
+}
+
+#endif