diff options
author | 2021-03-04 10:49:33 +0100 | |
---|---|---|
committer | 2021-03-05 10:17:20 +0100 | |
commit | 92326e47afea2dd65ec6b5ec842454fc74f046cc (patch) | |
tree | 515de40cefa3c48bf30869f9031fbf78e4ba45d4 | |
parent | f7011c21e11e988ec26d095f48b9070760c72bc3 (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)
-rw-r--r-- | scripts/src/formats.lua | 21 | ||||
-rw-r--r-- | scripts/target/mame/mess.lua | 6 | ||||
-rw-r--r-- | src/devices/imagedev/floppy.cpp | 122 | ||||
-rw-r--r-- | src/devices/imagedev/floppy.h | 46 | ||||
-rwxr-xr-x | src/devices/machine/applefdintf.cpp | 3 | ||||
-rw-r--r-- | src/frontend/mame/ui/filecreate.cpp | 55 | ||||
-rw-r--r-- | src/frontend/mame/ui/filecreate.h | 19 | ||||
-rw-r--r-- | src/frontend/mame/ui/floppycntrl.cpp | 22 | ||||
-rw-r--r-- | src/frontend/mame/ui/floppycntrl.h | 3 | ||||
-rw-r--r-- | src/lib/formats/all.cpp | 9 | ||||
-rw-r--r-- | src/lib/formats/all.h | 2 | ||||
-rw-r--r-- | src/lib/formats/fs_prodos.cpp | 76 | ||||
-rw-r--r-- | src/lib/formats/fs_prodos.h | 26 | ||||
-rw-r--r-- | src/lib/formats/fs_unformatted.cpp | 99 | ||||
-rw-r--r-- | src/lib/formats/fs_unformatted.h | 48 | ||||
-rw-r--r-- | src/lib/formats/fsmgr.cpp | 81 | ||||
-rw-r--r-- | src/lib/formats/fsmgr.h | 57 | ||||
-rw-r--r-- | src/mame/includes/mac.h | 2 | ||||
-rw-r--r-- | src/tools/floptool.cpp | 234 |
19 files changed, 918 insertions, 13 deletions
diff --git a/scripts/src/formats.lua b/scripts/src/formats.lua index 6bb3862a226..9e5b4bf0504 100644 --- a/scripts/src/formats.lua +++ b/scripts/src/formats.lua @@ -69,6 +69,11 @@ project "formats" MAME_DIR .. "src/lib/formats/dfi_dsk.cpp", MAME_DIR .. "src/lib/formats/dfi_dsk.h", MAME_DIR .. "src/lib/formats/fdi_dsk.cpp", + + MAME_DIR .. "src/lib/formats/fsmgr.h", + MAME_DIR .. "src/lib/formats/fsmgr.cpp", + MAME_DIR .. "src/lib/formats/fs_unformatted.h", + MAME_DIR .. "src/lib/formats/fs_unformatted.cpp", } -------------------------------------------------- @@ -1598,10 +1603,10 @@ end -------------------------------------------------- -- ---@src/lib/formats/rc759_dsk.h,FORMATS["RC759_DSK"] = true +--@src/lib/formats/rc759_dsk.h,FORMATS["RC759"] = true -------------------------------------------------- -if opt_tool(FORMATS, "RC759_DSK") then +if (FORMATS["APRIDISK"]~=null or _OPTIONS["with-tools"]) then files { MAME_DIR.. "src/lib/formats/rc759_dsk.cpp", MAME_DIR.. "src/lib/formats/rc759_dsk.h", @@ -2052,4 +2057,16 @@ if opt_tool(FORMATS, "ZX81_P") then } end +-------------------------------------------------- +-- +--@src/lib/formats/fs_prodos.h,FORMATS["FS_PRODOS"] = true +-------------------------------------------------- + +if opt_tool(FORMATS, "FS_PRODOS") then + files { + MAME_DIR.. "src/lib/formats/fs_prodos.cpp", + MAME_DIR.. "src/lib/formats/fs_prodos.h", + } +end + end diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 190cfdd5410..88a13968032 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -981,6 +981,7 @@ BUSES["X68K"] = true BUSES["Z29_KBD"] = true BUSES["Z88"] = true BUSES["ZORRO"] = true +BUSES["THOMSON"] = true -------------------------------------------------- -- specify used file formats @@ -1111,7 +1112,7 @@ FORMATS["PPG_DSK"] = true FORMATS["PRIMOPTP"] = true FORMATS["PYLDIN_DSK"] = true FORMATS["QL_DSK"] = true -FORMATS["RC759_DSK"] = true +FORMATS["RC759"] = true FORMATS["RK_CAS"] = true FORMATS["RX50_DSK"] = true FORMATS["SC3000_BIT"] = true @@ -1150,6 +1151,7 @@ FORMATS["X07_CAS"] = true FORMATS["X1_TAP"] = true FORMATS["XDF_DSK"] = true FORMATS["ZX81_P"] = true +FORMATS["FS_PRODOS"] = true -------------------------------------------------- -- this is the list of driver libraries that @@ -3928,8 +3930,6 @@ files { MAME_DIR .. "src/mame/drivers/thomson.cpp", MAME_DIR .. "src/mame/includes/thomson.h", MAME_DIR .. "src/mame/machine/thomson.cpp", - MAME_DIR .. "src/mame/machine/thomflop.cpp", - MAME_DIR .. "src/mame/machine/thomflop.h", MAME_DIR .. "src/mame/video/thomson.cpp", } 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); } //------------------------------------------------- diff --git a/src/devices/imagedev/floppy.h b/src/devices/imagedev/floppy.h index 3c221945f9a..b6bee52a775 100644 --- a/src/devices/imagedev/floppy.h +++ b/src/devices/imagedev/floppy.h @@ -12,6 +12,7 @@ #pragma once #include "formats/flopimg.h" +#include "formats/fsmgr.h" #include "sound/samples.h" #include "softlist_dev.h" @@ -26,12 +27,14 @@ public: format_registration(); void add(floppy_format_type format); + void add(filesystem_manager_type fs); void add_fm_containers(); void add_mfm_containers(); void add_pc_formats(); std::vector<floppy_format_type> m_formats; + std::vector<filesystem_manager_type> m_fs; }; class floppy_image_device : public device_t, @@ -45,15 +48,45 @@ public: typedef delegate<void (floppy_image_device *, int)> wpt_cb; typedef delegate<void (floppy_image_device *, int)> led_cb; + struct fs_info { + const filesystem_manager_t *m_manager; + floppy_format_type m_type; + u32 m_image_size; + const char *m_name; + u32 m_key; + const char *m_description; + + fs_info(const filesystem_manager_t *manager, floppy_format_type type, u32 image_size, const char *name, u32 key, const char *description) : + m_manager(manager), + m_type(type), + m_image_size(image_size), + m_name(name), + m_key(key), + m_description(description) + {} + + fs_info(const filesystem_manager_t *manager, const char *name, u32 key, const char *description) : + m_manager(manager), + m_type(nullptr), + m_image_size(0), + m_name(name), + m_key(key), + m_description(description) + {} + }; + // construction/destruction virtual ~floppy_image_device(); void set_formats(std::function<void (format_registration &fr)> formats); floppy_image_format_t *get_formats() const; + const std::vector<fs_info> &get_fs() const { return m_fs; } floppy_image_format_t *get_load_format() const; floppy_image_format_t *identify(std::string filename); void set_rpm(float rpm); + void init_fs(const fs_info *fs); + // image-level overrides virtual image_init_result call_load() override; virtual void call_unload() override; @@ -120,6 +153,14 @@ public: void enable_sound(bool doit) { m_make_sound = doit; } protected: + struct fs_enum : public filesystem_manager_t::floppy_enumerator { + floppy_image_device *m_fid; + fs_enum(floppy_image_device *fid) : filesystem_manager_t::floppy_enumerator(), m_fid(fid) {}; + + virtual void add(const filesystem_manager_t *manager, floppy_format_type type, u32 image_size, const char *name, u32 key, const char *description) override; + virtual void add_raw(const filesystem_manager_t *manager, const char *name, u32 key, const char *description) override; + }; + floppy_image_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides @@ -137,12 +178,15 @@ protected: void init_floppy_load(bool write_supported); + std::function<void (format_registration &fr)> format_registration_cb; floppy_image_format_t *input_format; floppy_image_format_t *output_format; std::vector<uint32_t> variants; std::unique_ptr<floppy_image> image; char extension_list[256]; floppy_image_format_t *fif_list; + std::vector<fs_info> m_fs; + std::vector<std::unique_ptr<filesystem_manager_t>> m_fs_managers; emu_timer *index_timer; /* Physical characteristics, filled by setup_characteristics */ @@ -197,6 +241,8 @@ protected: wpt_cb cur_wpt_cb; led_cb cur_led_cb; + void register_formats(); + void check_led(); uint32_t find_position(attotime &base, const attotime &when); int find_index(uint32_t position, const std::vector<uint32_t> &buf) const; diff --git a/src/devices/machine/applefdintf.cpp b/src/devices/machine/applefdintf.cpp index ca2eb4b8748..2dc9fcec319 100755 --- a/src/devices/machine/applefdintf.cpp +++ b/src/devices/machine/applefdintf.cpp @@ -6,6 +6,7 @@ #include "formats/ap2_dsk.h" #include "formats/ap_dsk35.h" #include "formats/pc_dsk.h" +#include "formats/fs_prodos.h" void applefdintf_device::formats_525_13(format_registration &fr) { @@ -30,6 +31,8 @@ void applefdintf_device::formats_35(format_registration &fr) fr.add(FLOPPY_WOZ_FORMAT); fr.add(FLOPPY_APPLE_GCR_FORMAT); fr.add(FLOPPY_APPLE_2MG_FORMAT); + + fr.add(FS_PRODOS); } void applefdintf_device::floppies_525(device_slot_interface &device) diff --git a/src/frontend/mame/ui/filecreate.cpp b/src/frontend/mame/ui/filecreate.cpp index 181c4a985ab..25a1eb55c08 100644 --- a/src/frontend/mame/ui/filecreate.cpp +++ b/src/frontend/mame/ui/filecreate.cpp @@ -291,4 +291,59 @@ void menu_select_format::handle() } +/*************************************************************************** +SELECT FORMAT MENU +***************************************************************************/ + +//------------------------------------------------- +// ctor +//------------------------------------------------- + +menu_select_floppy_init::menu_select_floppy_init(mame_ui_manager &mui, render_container &container, const std::vector<floppy_image_device::fs_info> &fs, int *result) + : menu(mui, container), + m_fs(fs), + m_result(result) + +{ +} + + +//------------------------------------------------- +// dtor +//------------------------------------------------- + +menu_select_floppy_init::~menu_select_floppy_init() +{ +} + + +//------------------------------------------------- +// populate +//------------------------------------------------- + +void menu_select_floppy_init::populate(float &customtop, float &custombottom) +{ + item_append(_("Select initial contents"), FLAG_DISABLE, nullptr); + int id = 0; + for (const auto &fmt : m_fs) + item_append(fmt.m_description, fmt.m_name, 0, (void *)(uintptr_t)(id++)); +} + + +//------------------------------------------------- +// handle +//------------------------------------------------- + +void menu_select_floppy_init::handle() +{ + // process the menu + const event *event = process(0); + if (event != nullptr && event->iptkey == IPT_UI_SELECT) + { + *m_result = int(uintptr_t(event->itemref)); + stack_pop(); + } +} + + } // namespace ui diff --git a/src/frontend/mame/ui/filecreate.h b/src/frontend/mame/ui/filecreate.h index a97b4f53ef5..5d9dc597b0d 100644 --- a/src/frontend/mame/ui/filecreate.h +++ b/src/frontend/mame/ui/filecreate.h @@ -14,6 +14,7 @@ #pragma once #include "ui/menu.h" +#include "imagedev/floppy.h" class floppy_image_format_t; @@ -77,6 +78,24 @@ private: int * m_result; }; +// ======================> menu_select_floppy_init + +class menu_select_floppy_init : public menu +{ +public: + menu_select_floppy_init(mame_ui_manager &mui, render_container &container, + const std::vector<floppy_image_device::fs_info> &fs, int *result); + virtual ~menu_select_floppy_init() override; + +private: + virtual void populate(float &customtop, float &custombottom) override; + virtual void handle() override; + + // internal state + const std::vector<floppy_image_device::fs_info> &m_fs; + int * m_result; +}; + } // namespace ui diff --git a/src/frontend/mame/ui/floppycntrl.cpp b/src/frontend/mame/ui/floppycntrl.cpp index 0c4e2f3c834..4d6239ded4a 100644 --- a/src/frontend/mame/ui/floppycntrl.cpp +++ b/src/frontend/mame/ui/floppycntrl.cpp @@ -26,6 +26,7 @@ menu_control_floppy_image::menu_control_floppy_image(mame_ui_manager &mui, rende fd(dynamic_cast<floppy_image_device &>(image)), input_format(nullptr), output_format(nullptr), + create_fs(nullptr), input_filename(), output_filename() { @@ -48,6 +49,8 @@ void menu_control_floppy_image::do_load_create() machine().popmessage("Error: %s", fd.error()); return; } + if (create_fs) + fd.init_fs(create_fs); } else { image_init_result err = fd.load(input_filename); if ((err == image_init_result::PASS) && (output_filename.compare("") != 0)) @@ -122,8 +125,27 @@ void menu_control_floppy_image::handle() m_state = START_FILE; handle(); } else { + const auto &fs = fd.get_fs(); output_filename = util::zippath_combine(m_current_directory, m_current_file); output_format = format_array[m_submenu_result.i]; + if(fs.size() == 1) { + create_fs = &fs[0]; + do_load_create(); + stack_pop(); + } else { + m_submenu_result.i = -1; + menu::stack_push<menu_select_floppy_init>(ui(), container(), fs, &m_submenu_result.i); + m_state = SELECT_INIT; + } + } + break; + + case SELECT_INIT: + if(m_submenu_result.i == -1) { + m_state = START_FILE; + handle(); + } else { + create_fs = &fd.get_fs()[m_submenu_result.i]; do_load_create(); stack_pop(); } diff --git a/src/frontend/mame/ui/floppycntrl.h b/src/frontend/mame/ui/floppycntrl.h index d48f8a88a53..a0ad007be2e 100644 --- a/src/frontend/mame/ui/floppycntrl.h +++ b/src/frontend/mame/ui/floppycntrl.h @@ -27,11 +27,12 @@ public: virtual ~menu_control_floppy_image() override; private: - enum { SELECT_FORMAT = LAST_ID, SELECT_MEDIA, SELECT_RW }; + enum { SELECT_FORMAT = LAST_ID, SELECT_MEDIA, SELECT_INIT, SELECT_RW }; floppy_image_device &fd; std::unique_ptr<floppy_image_format_t * []> format_array; floppy_image_format_t *input_format, *output_format; + const floppy_image_device::fs_info *create_fs; std::string input_filename, output_filename; virtual void handle() override; 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 diff --git a/src/mame/includes/mac.h b/src/mame/includes/mac.h index cddb4f2aef9..0a8b2f3bf25 100644 --- a/src/mame/includes/mac.h +++ b/src/mame/includes/mac.h @@ -33,7 +33,7 @@ #include "emupal.h" #include "screen.h" -#define NEW_SWIM 0 +#define NEW_SWIM 1 #define MAC_SCREEN_NAME "screen" #define MAC_539X_1_TAG "539x_1" diff --git a/src/tools/floptool.cpp b/src/tools/floptool.cpp index 021ee80390b..bfd049def95 100644 --- a/src/tools/floptool.cpp +++ b/src/tools/floptool.cpp @@ -22,16 +22,131 @@ #include "corestr.h" #include "osdcomm.h" +using u8 = uint8_t; +using u16 = uint16_t; +using u32 = uint32_t; + #include "formats/all.h" +struct fs_info { + const filesystem_manager_t *m_manager; + floppy_format_type m_type; + u32 m_image_size; + const char *m_name; + u32 m_key; + const char *m_description; + + fs_info(const filesystem_manager_t *manager, floppy_format_type type, u32 image_size, const char *name, u32 key, const char *description) : + m_manager(manager), + m_type(type), + m_image_size(image_size), + m_name(name), + m_key(key), + m_description(description) + {} + + fs_info(const filesystem_manager_t *manager, const char *name, u32 key, const char *description) : + m_manager(manager), + m_type(nullptr), + m_image_size(0), + m_name(name), + m_key(key), + m_description(description) + {} +}; + +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 }); +} + std::map<std::string, std::vector<floppy_image_format_t *>> formats_by_category; std::map<std::string, floppy_image_format_t *> formats_by_key; +std::map<std::string, std::vector<fs_info>> fs_by_category; +std::map<std::string, fs_info> fs_by_key; + +static std::vector<uint32_t> variants; + +struct enumerator; + +struct fs_enum : public filesystem_manager_t::floppy_enumerator { + enumerator *m_en; + fs_enum(enumerator *en) : filesystem_manager_t::floppy_enumerator(), m_en(en) {}; + + void reg(const fs_info &fsi) const; + virtual void add(const filesystem_manager_t *manager, floppy_format_type type, u32 image_size, const char *name, u32 key, const char *description) override; + virtual void add_raw(const filesystem_manager_t *manager, const char *name, u32 key, const char *description) override; +}; + struct enumerator : public mame_formats_enumerator { + fs_enum fse; + + enumerator() : mame_formats_enumerator(), fse(this) {} + virtual ~enumerator() = default; virtual void add(const cassette_image::Format *const *formats) {} std::vector<floppy_image_format_t *> *cf = nullptr; + std::vector<fs_info> *cfs = nullptr; virtual void category(const char *name) { auto i = formats_by_category.find(name); if(i != formats_by_category.end()) { @@ -39,6 +154,7 @@ struct enumerator : public mame_formats_enumerator { exit(1); } cf = &formats_by_category[name]; + cfs = &fs_by_category[name]; } virtual void add(floppy_format_type format) { @@ -46,7 +162,7 @@ struct enumerator : public mame_formats_enumerator { std::string key = f->name(); auto i = formats_by_key.find(key); if(i != formats_by_key.end()) { - fprintf(stderr, "Collision on key %s between \"%s\" and \"%s\".\n", + fprintf(stderr, "Collision on format key %s between \"%s\" and \"%s\".\n", key.c_str(), i->second->description(), f->description()); @@ -55,8 +171,40 @@ struct enumerator : public mame_formats_enumerator { cf->push_back(f); formats_by_key[key] = f; } + + virtual void add(filesystem_manager_type fs) { + auto ff = fs(); + ff->enumerate(fse, floppy_image::FF_UNKNOWN, variants); + } }; +void fs_enum::reg(const fs_info &fsi) const +{ + std::string key = fsi.m_name; + auto i = fs_by_key.find(key); + if(i != fs_by_key.end()) { + fprintf(stderr, "Collision on fs key %s between \"%s\" and \"%s\".\n", + key.c_str(), + i->second.m_description, + fsi.m_description); + exit(1); + } + m_en->cfs->push_back(fsi); + fs_by_key.emplace(key, fsi); +} + +void fs_enum::add(const filesystem_manager_t *manager, floppy_format_type type, u32 image_size, const char *name, u32 key, const char *description) +{ + fs_info fsi(manager, type, image_size, name, key, description); + reg(fsi); +} + +void fs_enum::add_raw(const filesystem_manager_t *manager, const char *name, u32 key, const char *description) +{ + fs_info fsi(manager, name, key, description); + reg(fsi); +} + void CLIB_DECL ATTR_PRINTF(1,2) logerror(const char *format, ...) { va_list arg; @@ -65,7 +213,6 @@ void CLIB_DECL ATTR_PRINTF(1,2) logerror(const char *format, ...) va_end(arg); } -static std::vector<uint32_t> variants; static void init_formats() { @@ -97,11 +244,21 @@ static floppy_image_format_t *find_format_by_identify(io_generic *image) return best_fif; } +static const fs_info *find_fs_by_name(const char *name) +{ + auto i = fs_by_key.find(name); + if(i == fs_by_key.end()) + return nullptr; + return &i->second; +} + + static void display_usage() { fprintf(stderr, "Usage: \n"); fprintf(stderr, " floptool.exe identify <inputfile> [<inputfile> ...]\n"); fprintf(stderr, " floptool.exe convert [input_format|auto] output_format <inputfile> <outputfile>\n"); + fprintf(stderr, " floptool.exe create output_format filesystem <outputfile>\n"); } static void display_formats() @@ -112,6 +269,11 @@ static void display_formats() if(sz > sk) sk = sz; } + for(const auto &e : fs_by_key) { + int sz = e.first.size(); + if(sz > sk) + sk = sz; + } fprintf(stderr, "Supported formats:\n\n"); for(const auto &e : formats_by_category) @@ -120,6 +282,15 @@ static void display_formats() for(floppy_image_format_t *fif : e.second) fprintf(stderr, " %-*s - %s [%s]\n", sk, fif->name(), fif->description(), fif->extensions()); } + + fprintf(stderr, "\n\n"); + fprintf(stderr, "Supported filesystems:\n\n"); + for(const auto &e : fs_by_category) + if(!e.second.empty()) { + fprintf(stderr, "%s:\n", e.first.c_str()); + for(const fs_info &fs : e.second) + fprintf(stderr, " %-*s - %s\n", sk, fs.m_name, fs.m_description); + } } static void display_full_usage() @@ -240,6 +411,63 @@ static int convert(int argc, char *argv[]) return 0; } +static int create(int argc, char *argv[]) +{ + if (argc!=5) { + fprintf(stderr, "Incorrect number of arguments.\n\n"); + display_usage(); + return 1; + } + + auto dest_format = find_format_by_name(argv[2]); + if(!dest_format) { + fprintf(stderr, "Error: Format '%s' unknown\n", argv[3]); + return 1; + } + + auto source_fs = find_fs_by_name(argv[3]); + if(!source_fs) { + fprintf(stderr, "Error: Filesystem '%s' unknown\n", argv[2]); + return 1; + } + + floppy_image image(84, 2, floppy_image::FF_UNKNOWN); + + if(source_fs->m_type) { + std::vector<u8> img(source_fs->m_image_size); + source_fs->m_manager->floppy_instantiate(source_fs->m_key, img); + auto iog = ram_open(img); + auto source_format = source_fs->m_type(); + source_format->load(iog, floppy_image::FF_UNKNOWN, variants, &image); + delete source_format; + delete iog; + + } else + source_fs->m_manager->floppy_instantiate_raw(source_fs->m_key, &image); + + char msg[4096]; + sprintf(msg, "Error opening %s for writing", argv[4]); + auto f = fopen(argv[4], "wb"); + if (!f) { + perror(msg); + return 1; + } + + io_generic dest_io; + dest_io.file = f; + dest_io.procs = &stdio_ioprocs_noclose; + dest_io.filler = 0xff; + + if(!dest_format->save(&dest_io, variants, &image)) { + fprintf(stderr, "Error: writing output file as '%s' failed\n", dest_format->name()); + return 1; + } + + fclose((FILE *)dest_io.file); + + return 0; +} + int CLIB_DECL main(int argc, char *argv[]) { init_formats(); @@ -253,6 +481,8 @@ int CLIB_DECL main(int argc, char *argv[]) return identify(argc, argv); else if (!core_stricmp("convert", argv[1])) return convert(argc, argv); + else if (!core_stricmp("create", argv[1])) + return create(argc, argv); else { fprintf(stderr, "Unknown command '%s'\n\n", argv[1]); display_usage(); |