diff options
Diffstat (limited to 'src/devices/imagedev/floppy.cpp')
-rw-r--r-- | src/devices/imagedev/floppy.cpp | 122 |
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); } //------------------------------------------------- |