summaryrefslogtreecommitdiffstats
path: root/src/devices/imagedev/floppy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/imagedev/floppy.cpp')
-rw-r--r--src/devices/imagedev/floppy.cpp122
1 files changed, 118 insertions, 4 deletions
diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp
index eb622f66d85..cad19d80b8b 100644
--- a/src/devices/imagedev/floppy.cpp
+++ b/src/devices/imagedev/floppy.cpp
@@ -20,6 +20,8 @@
#include "formats/dsk_dsk.h"
#include "formats/pc_dsk.h"
+#include "formats/fs_unformatted.h"
+
#include "speaker.h"
#include "formats/imageutl.h"
#include "zippath.h"
@@ -139,6 +141,8 @@ format_registration::format_registration()
{
add(FLOPPY_MFI_FORMAT); // Our generic format
add(FLOPPY_DFI_FORMAT); // Flux format, dying
+
+ add(FS_UNFORMATTED);
}
void format_registration::add_fm_containers()
@@ -170,6 +174,11 @@ void format_registration::add(floppy_format_type format)
m_formats.push_back(format);
}
+void format_registration::add(filesystem_manager_type fs)
+{
+ m_fs.push_back(fs);
+}
+
void floppy_image_device::default_fm_floppy_formats(format_registration &fr)
{
fr.add_fm_containers();
@@ -299,11 +308,21 @@ void floppy_image_device::setup_led_cb(led_cb cb)
cur_led_cb = cb;
}
-void floppy_image_device::set_formats(std::function<void (format_registration &fr)> formats)
+void floppy_image_device::fs_enum::add(const filesystem_manager_t *manager, floppy_format_type type, u32 image_size, const char *name, u32 key, const char *description)
+{
+ m_fid->m_fs.emplace_back(fs_info(manager, type, image_size, name, key, description));
+}
+
+void floppy_image_device::fs_enum::add_raw(const filesystem_manager_t *manager, const char *name, u32 key, const char *description)
+{
+ m_fid->m_fs.emplace_back(fs_info(manager, name, key, description));
+}
+
+void floppy_image_device::register_formats()
{
format_registration fr;
- if(formats)
- formats(fr);
+ if(format_registration_cb)
+ format_registration_cb(fr);
extension_list[0] = '\0';
fif_list = nullptr;
@@ -320,6 +339,19 @@ void floppy_image_device::set_formats(std::function<void (format_registration &f
image_specify_extension( extension_list, 256, fif->extensions() );
}
+
+ fs_enum fse(this);
+ for(filesystem_manager_type fmt : fr.m_fs)
+ {
+ auto ff = fmt();
+ ff->enumerate(fse, form_factor, variants);
+ m_fs_managers.push_back(std::unique_ptr<filesystem_manager_t>(ff));
+ }
+}
+
+void floppy_image_device::set_formats(std::function<void (format_registration &fr)> formats)
+{
+ format_registration_cb = formats;
}
floppy_image_format_t *floppy_image_device::get_formats() const
@@ -400,6 +432,7 @@ void floppy_image_device::device_start()
phases = 0;
setup_characteristics();
+ register_formats();
if (m_make_sound) m_sound_out = subdevice<floppy_sound_device>(FLOPSND_TAG);
@@ -611,6 +644,87 @@ image_init_result floppy_image_device::call_create(int format_type, util::option
return image_init_result::PASS;
}
+// Should that go into ioprocs? Should ioprocs be turned into something C++?
+
+struct iofile_ram {
+ std::vector<u8> *data;
+ int64_t pos;
+};
+
+static void ram_closeproc(void *file)
+{
+ auto f = (iofile_ram *)file;
+ delete f;
+}
+
+static int ram_seekproc(void *file, int64_t offset, int whence)
+{
+ auto f = (iofile_ram *)file;
+ switch(whence) {
+ case SEEK_SET: f->pos = offset; break;
+ case SEEK_CUR: f->pos += offset; break;
+ case SEEK_END: f->pos = f->data->size() + offset; break;
+ }
+
+ f->pos = std::clamp(f->pos, int64_t(0), int64_t(f->data->size()));
+ return 0;
+}
+
+static size_t ram_readproc(void *file, void *buffer, size_t length)
+{
+ auto f = (iofile_ram *)file;
+ size_t l = std::min(length, f->data->size() - f->pos);
+ memcpy(buffer, f->data->data() + f->pos, l);
+ return l;
+}
+
+static size_t ram_writeproc(void *file, const void *buffer, size_t length)
+{
+ auto f = (iofile_ram *)file;
+ size_t l = std::min(length, f->data->size() - f->pos);
+ memcpy(f->data->data() + f->pos, buffer, l);
+ return l;
+}
+
+static uint64_t ram_filesizeproc(void *file)
+{
+ auto f = (iofile_ram *)file;
+ return f->data->size();
+}
+
+
+static const io_procs iop_ram = {
+ ram_closeproc,
+ ram_seekproc,
+ ram_readproc,
+ ram_writeproc,
+ ram_filesizeproc
+};
+
+static io_generic *ram_open(std::vector<u8> &data)
+{
+ iofile_ram *f = new iofile_ram;
+ f->data = &data;
+ f->pos = 0;
+ return new io_generic({ &iop_ram, f });
+}
+
+void floppy_image_device::init_fs(const fs_info *fs)
+{
+ if (fs->m_type)
+ {
+ std::vector<u8> img(fs->m_image_size);
+ fs->m_manager->floppy_instantiate(fs->m_key, img);
+ auto iog = ram_open(img);
+ auto source_format = fs->m_type();
+ source_format->load(iog, floppy_image::FF_UNKNOWN, variants, image.get());
+ delete source_format;
+ delete iog;
+
+ } else
+ fs->m_manager->floppy_instantiate_raw(fs->m_key, image.get());
+}
+
/* write protect, active high
phase 1 can force it to 1 for drive detection
on the rare drives that actually use phases.
@@ -2293,7 +2407,7 @@ void teac_fd_30a::setup_characteristics()
sides = 1;
set_rpm(300);
- variants.push_back(floppy_image::SSSD);
+ variants.push_back(floppy_image::SSDD);
}
//-------------------------------------------------