From afb7d8fb6a595531c75d898cbdba6f3cffffcab5 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Mon, 23 Jan 2012 21:49:30 +0000 Subject: [PATCH] floppy: Do specific UI handling [O. Galibert] --- src/emu/diimage.c | 105 ++++++++------ src/emu/diimage.h | 34 ++++- src/emu/emu.h | 3 + src/emu/imagedev/floppy.c | 280 +++++++++++++++++++++++++++++++++++++- src/emu/imagedev/floppy.h | 47 +++++++ src/emu/uiimage.c | 84 +++++++++++- src/emu/uiimage.h | 28 ++++ src/lib/formats/dfi_dsk.c | 2 +- src/lib/formats/flopimg.c | 40 +++++- src/lib/formats/flopimg.h | 6 + src/lib/formats/mfi_dsk.c | 6 +- 11 files changed, 583 insertions(+), 52 deletions(-) diff --git a/src/emu/diimage.c b/src/emu/diimage.c index c063c17977c..f23c4823599 100644 --- a/src/emu/diimage.c +++ b/src/emu/diimage.c @@ -649,6 +649,60 @@ image_error_t device_image_interface::load_image_by_path(UINT32 open_flags, cons return err; } +int device_image_interface::reopen_for_write(const char *path) +{ + if(m_file) + core_fclose(m_file); + + file_error filerr = FILERR_NOT_FOUND; + image_error_t err = IMAGE_ERROR_FILENOTFOUND; + astring revised_path; + + /* attempt to open the file for writing*/ + filerr = zippath_fopen(path, OPEN_FLAG_READ|OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, m_file, revised_path); + + /* did the open succeed? */ + switch(filerr) + { + case FILERR_NONE: + /* success! */ + m_readonly = 0; + m_created = 1; + err = IMAGE_ERROR_SUCCESS; + break; + + case FILERR_NOT_FOUND: + case FILERR_ACCESS_DENIED: + /* file not found (or otherwise cannot open); continue */ + err = IMAGE_ERROR_FILENOTFOUND; + break; + + case FILERR_OUT_OF_MEMORY: + /* out of memory */ + err = IMAGE_ERROR_OUTOFMEMORY; + break; + + case FILERR_ALREADY_OPEN: + /* this shouldn't happen */ + err = IMAGE_ERROR_ALREADYOPEN; + break; + + case FILERR_FAILURE: + case FILERR_TOO_MANY_FILES: + case FILERR_INVALID_DATA: + default: + /* other errors */ + err = IMAGE_ERROR_INTERNAL; + break; + } + + /* if successful, set the file name */ + if (filerr == FILERR_NONE) + set_image_filename(revised_path); + + return err; +} + /*------------------------------------------------- determine_open_plan - determines which open flags to use, and in what order @@ -1040,35 +1094,6 @@ void device_image_interface::update_names() for ui-level image selection -------------------------------------------------*/ -class ui_menu_control_device_image : public ui_menu { -public: - ui_menu_control_device_image(running_machine &machine, render_container *container, device_image_interface *image); - virtual ~ui_menu_control_device_image(); - virtual void populate(); - virtual void handle(); - -private: - enum { - START_FILE, START_OTHER_PART, START_SOFTLIST, SELECT_PARTLIST, SELECT_ONE_PART, SELECT_OTHER_PART, SELECT_FILE, CREATE_FILE, CREATE_CONFIRM, DO_CREATE, SELECT_SOFTLIST - }; - int state; - - device_image_interface *image; - astring current_directory; - astring current_file; - int submenu_result; - bool create_confirmed; - bool softlist_done; - const software_list *swl; - const software_info *swi; - const software_part *swp; - const software_list_config *slc; - astring software_info_name; - - void test_create(bool &can_create, bool &need_confirm); - void load_software_part(); -}; - ui_menu *device_image_interface::get_selection_menu(running_machine &machine, render_container *container) { return auto_alloc_clear(machine, ui_menu_control_device_image(machine, container, this)); @@ -1128,8 +1153,6 @@ void ui_menu_control_device_image::test_create(bool &can_create, bool &need_conf /* does a file or a directory exist at the path */ entry = osd_stat(path); file_type = (entry != NULL) ? entry->type : ENTTYPE_NONE; - if (entry != NULL) - free(entry); switch(file_type) { @@ -1165,7 +1188,13 @@ void ui_menu_control_device_image::load_software_part() astring temp_name(swi->shortname); temp_name.cat(":"); temp_name.cat(swp->name); - image->load(temp_name.cstr()); + hook_load(temp_name, true); +} + +void ui_menu_control_device_image::hook_load(astring name, bool softlist) +{ + image->load(name); + ui_menu::stack_pop(machine()); } void ui_menu_control_device_image::populate() @@ -1249,7 +1278,6 @@ void ui_menu_control_device_image::handle() switch(submenu_result) { case ui_menu_software_parts::T_ENTRY: { load_software_part(); - ui_menu::stack_pop(machine()); break; } @@ -1273,8 +1301,7 @@ void ui_menu_control_device_image::handle() break; case ui_menu_file_selector::R_FILE: - image->load(current_file); - ui_menu::stack_pop(machine()); + hook_load(current_file, false); break; case ui_menu_file_selector::R_CREATE: @@ -1301,12 +1328,8 @@ void ui_menu_control_device_image::handle() ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_confirm_save_as(machine(), container, &create_confirmed))); state = CREATE_CONFIRM; } else { - astring path; - zippath_combine(path, current_directory, current_file); - int err = image->create(path, 0, NULL); - if (err != 0) - popmessage("Error: %s", image->error()); - ui_menu::stack_pop(machine()); + state = DO_CREATE; + handle(); } } else { state = START_FILE; diff --git a/src/emu/diimage.h b/src/emu/diimage.h index f07cf88977d..583b058f607 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -182,7 +182,7 @@ public: virtual const char *file_extensions() const = 0; virtual const option_guide *create_option_guide() const = 0; - virtual class ui_menu *get_selection_menu(running_machine &machine, class render_container *container); + virtual ui_menu *get_selection_menu(running_machine &machine, class render_container *container); const image_device_format *device_get_indexed_creatable_format(int index); const image_device_format *device_get_named_creatable_format(const char *format_name); @@ -249,6 +249,8 @@ public: void unload(); bool create(const char *path, const image_device_format *create_format, option_resolution *create_args); bool load_software(char *swlist, char *swname, rom_entry *entry); + int reopen_for_write(const char *path); + protected: bool load_internal(const char *path, bool is_create, int create_format, option_resolution *create_args); void determine_open_plan(int is_create, UINT32 *open_plan); @@ -322,5 +324,35 @@ protected: bool m_is_loading; }; +class ui_menu_control_device_image : public ui_menu { +public: + ui_menu_control_device_image(running_machine &machine, render_container *container, device_image_interface *image); + virtual ~ui_menu_control_device_image(); + virtual void populate(); + virtual void handle(); + +protected: + enum { + START_FILE, START_OTHER_PART, START_SOFTLIST, SELECT_PARTLIST, SELECT_ONE_PART, SELECT_OTHER_PART, SELECT_FILE, CREATE_FILE, CREATE_CONFIRM, DO_CREATE, SELECT_SOFTLIST, + LAST_ID + }; + int state; + + device_image_interface *image; + astring current_directory; + astring current_file; + int submenu_result; + bool create_confirmed; + bool softlist_done; + const class software_list *swl; + const class software_info *swi; + const class software_part *swp; + const class software_list_config *slc; + astring software_info_name; + + void test_create(bool &can_create, bool &need_confirm); + void load_software_part(); + virtual void hook_load(astring filename, bool softlist); +}; #endif /* __DIIMAGE_H__ */ diff --git a/src/emu/emu.h b/src/emu/emu.h index 2086a03952a..2051f54af89 100644 --- a/src/emu/emu.h +++ b/src/emu/emu.h @@ -88,6 +88,9 @@ typedef device_t * (*machine_config_constructor)(machine_config &config, device_ #include "ioport.h" #include "output.h" +// diimage requires uimenu +#include "uimenu.h" + // devices and callbacks #include "device.h" #include "distate.h" diff --git a/src/emu/imagedev/floppy.c b/src/emu/imagedev/floppy.c index d95460550c6..2e4d9593a62 100644 --- a/src/emu/imagedev/floppy.c +++ b/src/emu/imagedev/floppy.c @@ -5,12 +5,15 @@ *********************************************************************/ #include "emu.h" +#include "zippath.h" #include "floppy.h" #include "formats/imageutl.h" +#include "uiimage.h" // device type definition const device_type FLOPPY_CONNECTOR = &device_creator; const device_type FLOPPY_35_DD = &device_creator; +const device_type FLOPPY_35_DD_NOSD = &device_creator; const device_type FLOPPY_35_HD = &device_creator; const device_type FLOPPY_35_ED = &device_creator; const device_type FLOPPY_525_DD = &device_creator; @@ -115,6 +118,16 @@ void floppy_image_device::set_formats(const floppy_format_type *formats) update_names(); } +floppy_image_format_t *floppy_image_device::get_formats() const +{ + return fif_list; +} + +floppy_image_format_t *floppy_image_device::get_load_format() const +{ + return input_format; +} + void floppy_image_device::device_config_complete() { update_names(); @@ -129,6 +142,24 @@ void floppy_image_device::set_rpm(float _rpm) rev_time = attotime::from_double(60/rpm); } +void floppy_image_device::setup_write(floppy_image_format_t *_output_format) +{ + output_format = _output_format; + commit_image(); +} + +void floppy_image_device::commit_image() +{ + image_dirty = false; + if(!output_format) + return; + io_generic io; + // Do _not_ remove this cast otherwise the pointer will be incorrect when used by the ioprocs. + io.file = (device_image_interface *)this; + io.procs = &image_ioprocs; + io.filler = 0xff; + output_format->save(&io, image); +} //------------------------------------------------- // device_start - device-specific startup @@ -151,6 +182,7 @@ void floppy_image_device::device_start() stp = 1; dskchg = 0; index_timer = timer_alloc(0); + image_dirty = false; } void floppy_image_device::device_reset() @@ -165,6 +197,30 @@ void floppy_image_device::device_timer(emu_timer &timer, device_timer_id id, int index_resync(); } +floppy_image_format_t *floppy_image_device::identify(astring filename) const +{ + FILE *fd; + fd = fopen(filename.cstr(), "r"); + if(!fd) + return 0; + + io_generic io; + io.file = fd; + io.procs = &stdio_ioprocs_noclose; + io.filler = 0xff; + int best = 0; + floppy_image_format_t *best_format = 0; + for(floppy_image_format_t *format = fif_list; format; format = format->next) { + int score = format->identify(&io, form_factor); + if(score > best) { + best = score; + best_format = format; + } + } + fclose(fd); + return best_format; +} + bool floppy_image_device::call_load() { io_generic io; @@ -192,6 +248,8 @@ bool floppy_image_device::call_load() revolution_count = 0; index_resync(); + image_dirty = false; + output_format = 0; if (!cur_load_cb.isnull()) return cur_load_cb(this); @@ -203,6 +261,8 @@ void floppy_image_device::call_unload() dskchg = 0; if (image) { + if(image_dirty) + commit_image(); global_free(image); image = 0; } @@ -210,6 +270,13 @@ void floppy_image_device::call_unload() cur_unload_cb(this); } +bool floppy_image_device::call_create(int format_type, option_resolution *format_options) +{ + image = global_alloc(floppy_image(tracks, sides, form_factor)); + output_format = 0; + return IMAGE_INIT_PASS; +} + /* motor on, active low */ void floppy_image_device::mon_w(int state) { @@ -227,6 +294,8 @@ void floppy_image_device::mon_w(int state) /* on -> off */ else { + if(image_dirty) + commit_image(); revolution_start_time = attotime::never; index_timer->adjust(attotime::zero); } @@ -377,6 +446,8 @@ attotime floppy_image_device::get_next_transition(attotime from_when) void floppy_image_device::write_flux(attotime start, attotime end, int transition_count, const attotime *transitions) { + image_dirty = true; + attotime base; int start_pos = find_position(base, start); int end_pos = find_position(base, end); @@ -395,7 +466,7 @@ void floppy_image_device::write_flux(attotime start, attotime end, int transitio index = 0; image->set_track_size(cyl, ss, 1); buf = image->get_buffer(cyl, ss); - buf[cells++] = floppy_image::MG_N | 200000000; + buf[cells++] = floppy_image::MG_N; } if(index && (buf[index] & floppy_image::TIME_MASK) == start_pos) @@ -408,8 +479,10 @@ void floppy_image_device::write_flux(attotime start, attotime end, int transitio UINT32 pos = start_pos; int ti = 0; while(pos != end_pos) { - if(image->get_track_size(cyl, ss) < cells+10) + if(image->get_track_size(cyl, ss) < cells+10) { image->set_track_size(cyl, ss, cells+200); + buf = image->get_buffer(cyl, ss); + } UINT32 next_pos; if(ti != transition_count) next_pos = trans_pos[ti++]; @@ -530,6 +603,152 @@ void floppy_image_device::write_zone(UINT32 *buf, int &cells, int &index, UINT32 } } +ui_menu *floppy_image_device::get_selection_menu(running_machine &machine, render_container *container) +{ + return auto_alloc_clear(machine, ui_menu_control_floppy_image(machine, container, this)); +} + +ui_menu_control_floppy_image::ui_menu_control_floppy_image(running_machine &machine, render_container *container, device_image_interface *_image) : ui_menu_control_device_image(machine, container, _image) +{ + floppy_image_device *fd = static_cast(image); + const floppy_image_format_t *fif_list = fd->get_formats(); + int fcnt = 0; + for(const floppy_image_format_t *i = fif_list; i; i = i->next) + fcnt++; + + format_array = global_alloc_array(floppy_image_format_t *, fcnt); + input_format = output_format = 0; + input_filename = output_filename = ""; +} + +ui_menu_control_floppy_image::~ui_menu_control_floppy_image() +{ + global_free(format_array); +} + +void ui_menu_control_floppy_image::do_load_create() +{ + floppy_image_device *fd = static_cast(image); + if(input_filename == "") { + int err = fd->create(output_filename, 0, NULL); + if (err != 0) { + popmessage("Error: %s", fd->error()); + return; + } + fd->setup_write(output_format); + } else { + int err = fd->load(input_filename); + if(!err && output_filename != "") + err = fd->reopen_for_write(output_filename); + if(err != 0) { + popmessage("Error: %s", fd->error()); + return; + } + if(output_format) + fd->setup_write(output_format); + } +} + +void ui_menu_control_floppy_image::hook_load(astring filename, bool softlist) +{ + input_filename = filename; + input_format = static_cast(image)->identify(filename); + if(!input_format) { + popmessage("Error: %s\n", image->error()); + ui_menu::stack_pop(machine()); + return; + } + + bool can_in_place = input_format->supports_save(); + if(can_in_place) { + file_error filerr = FILERR_NOT_FOUND; + astring tmp_path; + core_file *tmp_file; + /* attempt to open the file for writing but *without* create */ + filerr = zippath_fopen(filename, OPEN_FLAG_READ|OPEN_FLAG_WRITE, tmp_file, tmp_path); + if(!filerr) + core_fclose(tmp_file); + else + can_in_place = false; + } + submenu_result = -1; + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_select_rw(machine(), container, can_in_place, &submenu_result))); + state = SELECT_RW; +} + +void ui_menu_control_floppy_image::handle() +{ + floppy_image_device *fd = static_cast(image); + switch(state) { + case DO_CREATE: { + floppy_image_format_t *fif_list = fd->get_formats(); + int ext_match = 0, total_usable = 0; + for(floppy_image_format_t *i = fif_list; i; i = i->next) { + if(!i->supports_save()) + continue; + if(i->extension_matches(current_file)) + format_array[total_usable++] = i; + } + ext_match = total_usable; + for(floppy_image_format_t *i = fif_list; i; i = i->next) { + if(!i->supports_save()) + continue; + if(!i->extension_matches(current_file)) + format_array[total_usable++] = i; + } + submenu_result = -1; + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_select_format(machine(), container, format_array, ext_match, total_usable, &submenu_result))); + + state = SELECT_FORMAT; + break; + } + + case SELECT_FORMAT: + if(submenu_result == -1) { + state = START_FILE; + handle(); + } else { + zippath_combine(output_filename, current_directory, current_file); + output_format = format_array[submenu_result]; + do_load_create(); + ui_menu::stack_pop(machine()); + } + break; + + case SELECT_RW: + switch(submenu_result) { + case ui_menu_select_rw::READONLY: + do_load_create(); + ui_menu::stack_pop(machine()); + break; + + case ui_menu_select_rw::READWRITE: + output_format = input_format; + do_load_create(); + ui_menu::stack_pop(machine()); + break; + + case ui_menu_select_rw::WRITE_DIFF: + popmessage("Sorry, diffs are not supported yet\n"); + ui_menu::stack_pop(machine()); + break; + + case ui_menu_select_rw::WRITE_OTHER: + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_file_create(machine(), container, image, current_directory, current_file))); + state = CREATE_FILE; + break; + + case -1: + ui_menu::stack_pop(machine()); + break; + } + break; + + default: + ui_menu_control_device_image::handle(); + } +} + floppy_35_dd::floppy_35_dd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : floppy_image_device(mconfig, FLOPPY_35_DD, "3.5\" double density floppy drive", tag, owner, clock) { @@ -547,6 +766,38 @@ void floppy_35_dd::setup_characteristics() set_rpm(300); } +void floppy_35_dd::handled_variants(UINT32 *variants, int &var_count) const +{ + var_count = 0; + variants[var_count++] = floppy_image::SSSD; + variants[var_count++] = floppy_image::SSDD; + variants[var_count++] = floppy_image::DSDD; +} + +floppy_35_dd_nosd::floppy_35_dd_nosd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + floppy_image_device(mconfig, FLOPPY_35_DD_NOSD, "3.5\" double density floppy drive", tag, owner, clock) +{ +} + +floppy_35_dd_nosd::~floppy_35_dd_nosd() +{ +} + +void floppy_35_dd_nosd::setup_characteristics() +{ + form_factor = floppy_image::FF_35; + tracks = 84; + sides = 2; + set_rpm(300); +} + +void floppy_35_dd_nosd::handled_variants(UINT32 *variants, int &var_count) const +{ + var_count = 0; + variants[var_count++] = floppy_image::SSSD; + variants[var_count++] = floppy_image::SSDD; +} + floppy_35_hd::floppy_35_hd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : floppy_image_device(mconfig, FLOPPY_35_HD, "3.5\" high density floppy drive", tag, owner, clock) { @@ -564,6 +815,15 @@ void floppy_35_hd::setup_characteristics() set_rpm(300); } +void floppy_35_hd::handled_variants(UINT32 *variants, int &var_count) const +{ + var_count = 0; + variants[var_count++] = floppy_image::SSSD; + variants[var_count++] = floppy_image::SSDD; + variants[var_count++] = floppy_image::DSDD; + variants[var_count++] = floppy_image::DSHD; +} + floppy_35_ed::floppy_35_ed(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : floppy_image_device(mconfig, FLOPPY_35_ED, "3.5\" extended density floppy drive", tag, owner, clock) { @@ -581,6 +841,15 @@ void floppy_35_ed::setup_characteristics() set_rpm(300); } +void floppy_35_ed::handled_variants(UINT32 *variants, int &var_count) const +{ + var_count = 0; + variants[var_count++] = floppy_image::SSSD; + variants[var_count++] = floppy_image::SSDD; + variants[var_count++] = floppy_image::DSDD; + variants[var_count++] = floppy_image::DSHD; + variants[var_count++] = floppy_image::DSED; +} floppy_525_dd::floppy_525_dd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : floppy_image_device(mconfig, FLOPPY_525_DD, "5.25\" double density floppy drive", tag, owner, clock) @@ -598,3 +867,10 @@ void floppy_525_dd::setup_characteristics() sides = 1; set_rpm(300); } + +void floppy_525_dd::handled_variants(UINT32 *variants, int &var_count) const +{ + var_count = 0; + variants[var_count++] = floppy_image::SSSD; + variants[var_count++] = floppy_image::SSDD; +} diff --git a/src/emu/imagedev/floppy.h b/src/emu/imagedev/floppy.h index 67157c592fa..508a71166eb 100644 --- a/src/emu/imagedev/floppy.h +++ b/src/emu/imagedev/floppy.h @@ -32,12 +32,18 @@ public: floppy_image_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); virtual ~floppy_image_device(); + virtual void handled_variants(UINT32 *variants, int &var_count) const = 0; + void set_formats(const floppy_format_type *formats); + floppy_image_format_t *get_formats() const; + floppy_image_format_t *get_load_format() const; + floppy_image_format_t *identify(astring filename) const; void set_rpm(float rpm); // image-level overrides virtual bool call_load(); virtual void call_unload(); + virtual bool call_create(int format_type, option_resolution *format_options); virtual void call_display_info() {} virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry) { return load_software(swlist, swname, start_entry); } @@ -50,6 +56,7 @@ public: virtual bool is_reset_on_load() const { return false; } virtual const char *file_extensions() const { return extension_list; } virtual const option_guide *create_option_guide() const { return NULL; } + void setup_write(floppy_image_format_t *output_format); void setup_load_cb(load_cb cb); void setup_unload_cb(unload_cb cb); @@ -79,6 +86,8 @@ public: UINT32 get_form_factor() const; UINT32 get_variant() const; + virtual ui_menu *get_selection_menu(running_machine &machine, class render_container *container); + protected: // device-level overrides virtual void device_config_complete(); @@ -89,6 +98,8 @@ protected: virtual void setup_characteristics() = 0; image_device_format format; + floppy_image_format_t *input_format; + floppy_image_format_t *output_format; floppy_image *image; char extension_list[256]; floppy_image_format_t *fif_list; @@ -119,6 +130,8 @@ protected: UINT32 revolution_count; int cyl; + bool image_dirty; + load_cb cur_load_cb; unload_cb cur_unload_cb; index_pulse_cb cur_index_pulse_cb; @@ -126,12 +139,42 @@ protected: UINT32 find_position(attotime &base, attotime when); int find_index(UINT32 position, const UINT32 *buf, int buf_size); void write_zone(UINT32 *buf, int &cells, int &index, UINT32 spos, UINT32 epos, UINT32 mg); + void commit_image(); +}; + +class ui_menu_control_floppy_image : public ui_menu_control_device_image { +public: + ui_menu_control_floppy_image(running_machine &machine, render_container *container, device_image_interface *image); + virtual ~ui_menu_control_floppy_image(); + + virtual void handle(); + +protected: + enum { SELECT_FORMAT = LAST_ID, SELECT_MEDIA, SELECT_RW }; + + floppy_image_format_t **format_array; + floppy_image_format_t *input_format, *output_format; + astring input_filename, output_filename; + + void do_load_create(); + virtual void hook_load(astring filename, bool softlist); }; class floppy_35_dd : public floppy_image_device { public: floppy_35_dd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); virtual ~floppy_35_dd(); + virtual void handled_variants(UINT32 *variants, int &var_count) const; + +protected: + virtual void setup_characteristics(); +}; + +class floppy_35_dd_nosd : public floppy_image_device { +public: + floppy_35_dd_nosd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~floppy_35_dd_nosd(); + virtual void handled_variants(UINT32 *variants, int &var_count) const; protected: virtual void setup_characteristics(); @@ -141,6 +184,7 @@ class floppy_35_hd : public floppy_image_device { public: floppy_35_hd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); virtual ~floppy_35_hd(); + virtual void handled_variants(UINT32 *variants, int &var_count) const; protected: virtual void setup_characteristics(); @@ -150,6 +194,7 @@ class floppy_35_ed : public floppy_image_device { public: floppy_35_ed(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); virtual ~floppy_35_ed(); + virtual void handled_variants(UINT32 *variants, int &var_count) const; protected: virtual void setup_characteristics(); @@ -159,6 +204,7 @@ class floppy_525_dd : public floppy_image_device { public: floppy_525_dd(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); virtual ~floppy_525_dd(); + virtual void handled_variants(UINT32 *variants, int &var_count) const; protected: virtual void setup_characteristics(); @@ -186,6 +232,7 @@ private: // device type definition extern const device_type FLOPPY_CONNECTOR; extern const device_type FLOPPY_35_DD; +extern const device_type FLOPPY_35_DD_NOSD; extern const device_type FLOPPY_35_HD; extern const device_type FLOPPY_35_ED; extern const device_type FLOPPY_525_DD; diff --git a/src/emu/uiimage.c b/src/emu/uiimage.c index 56449a43f72..45fec3c3132 100644 --- a/src/emu/uiimage.c +++ b/src/emu/uiimage.c @@ -25,6 +25,7 @@ #include "uiimage.h" #include "zippath.h" #include "unicode.h" +#include "imagedev/floppy.h" #include "imagedev/cassette.h" #include "imagedev/bitbngr.h" @@ -521,9 +522,6 @@ void ui_menu_file_selector::populate() const char *volume_name; const char *path = current_directory; - if(path[0]) - fprintf(stderr, "curdir=%s\n", path); - /* open the directory */ err = zippath_opendir(path, &directory); if (err != FILERR_NONE) @@ -877,6 +875,86 @@ void ui_menu_image_info::handle() process(0); } +/*------------------------------------------------- + ui_menu_select_format - floppy image format + selection menu +-------------------------------------------------*/ + +ui_menu_select_format::ui_menu_select_format(running_machine &machine, render_container *container, + floppy_image_format_t **_formats, int _ext_match, int _total_usable, int *_result) + : ui_menu(machine, container) +{ + formats = _formats; + ext_match = _ext_match; + total_usable = _total_usable; + result = _result; +} + +void ui_menu_select_format::populate() +{ + item_append("Select image format", NULL, MENU_FLAG_DISABLE, NULL); + for(int i=0; idescription(), fmt->name(), 0, (void *)i); + } +} + +ui_menu_select_format::~ui_menu_select_format() +{ +} + +void ui_menu_select_format::handle() +{ + /* process the menu */ + const ui_menu_event *event = process(0); + if (event != NULL && event->iptkey == IPT_UI_SELECT) + { + *result = int(FPTR(event->itemref)); + ui_menu::stack_pop(machine()); + } +} + +/*------------------------------------------------- + ui_menu_select_rw - floppy read/write + selection menu +-------------------------------------------------*/ + +ui_menu_select_rw::ui_menu_select_rw(running_machine &machine, render_container *container, + bool _can_in_place, int *_result) + : ui_menu(machine, container) +{ + can_in_place = _can_in_place; + result = _result; +} + +void ui_menu_select_rw::populate() +{ + item_append("Select access mode", NULL, MENU_FLAG_DISABLE, NULL); + item_append("Read-only", 0, 0, (void *)READONLY); + if(can_in_place) + item_append("Read-write", 0, 0, (void *)READWRITE); + item_append("Read this image, write to another image", 0, 0, (void *)WRITE_OTHER); + item_append("Read this image, write to diff", 0, 0, (void *)WRITE_DIFF); +} + +ui_menu_select_rw::~ui_menu_select_rw() +{ +} + +void ui_menu_select_rw::handle() +{ + /* process the menu */ + const ui_menu_event *event = process(0); + if (event != NULL && event->iptkey == IPT_UI_SELECT) + { + *result = int(FPTR(event->itemref)); + ui_menu::stack_pop(machine()); + } +} + /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/emu/uiimage.h b/src/emu/uiimage.h index 5dd80618cd1..345b22829a4 100644 --- a/src/emu/uiimage.h +++ b/src/emu/uiimage.h @@ -129,4 +129,32 @@ private: void append_entry_menu_item(const file_selector_entry *entry); }; +class ui_menu_select_format : public ui_menu { +public: + ui_menu_select_format(running_machine &machine, render_container *container, + class floppy_image_format_t **formats, int ext_match, int total_usable, int *result); + virtual ~ui_menu_select_format(); + virtual void populate(); + virtual void handle(); + +private: + floppy_image_format_t **formats; + int ext_match, total_usable; + int *result; +}; + +class ui_menu_select_rw : public ui_menu { +public: + enum { READONLY, READWRITE, WRITE_OTHER, WRITE_DIFF }; + ui_menu_select_rw(running_machine &machine, render_container *container, + bool can_in_place, int *result); + virtual ~ui_menu_select_rw(); + virtual void populate(); + virtual void handle(); + +private: + bool can_in_place; + int *result; +}; + #endif /* __UIIMAGE_H__ */ diff --git a/src/lib/formats/dfi_dsk.c b/src/lib/formats/dfi_dsk.c index 18ec4785aa6..5b3a17f7c0f 100644 --- a/src/lib/formats/dfi_dsk.c +++ b/src/lib/formats/dfi_dsk.c @@ -23,7 +23,7 @@ const char *dfi_format::extensions() const bool dfi_format::supports_save() const { - return true; + return false; } int dfi_format::identify(io_generic *io, UINT32 form_factor) diff --git a/src/lib/formats/flopimg.c b/src/lib/formats/flopimg.c index 24a1aa7f0f9..1f59988601d 100644 --- a/src/lib/formats/flopimg.c +++ b/src/lib/formats/flopimg.c @@ -1008,6 +1008,18 @@ void floppy_image::ensure_alloc(int track, int head) } } +const char *floppy_image::get_variant_name(UINT32 form_factor, UINT32 variant) +{ + switch(variant) { + case SSSD: return "Single side, single density"; + case SSDD: return "Single side, double density"; + case DSDD: return "Double side, double density"; + case DSHD: return "Double side, high density"; + case DSED: return "Double side, extended density"; + } + return "Unknown"; +} + floppy_image_format_t::floppy_image_format_t() { next = 0; @@ -1030,6 +1042,27 @@ bool floppy_image_format_t::save(io_generic *, floppy_image *) return false; } +bool floppy_image_format_t::extension_matches(const char *file_name) const +{ + const char *ext = strrchr(file_name, '.'); + if(!ext) + return false; + ext++; + int elen = strlen(ext); + const char *rext = extensions(); + for(;;) { + const char *next = strchr(rext, ','); + int rlen = next ? next - rext : strlen(rext); + if(rlen == elen && !memcmp(ext, rext, rlen)) + return true; + if(next) + rext = next+1; + else + break; + } + return false; +} + bool floppy_image_format_t::type_no_data(int type) const { return type == CRC_CCITT_START || @@ -2178,6 +2211,11 @@ void floppy_image_format_t::get_geometry_mfm_pc(floppy_image *image, int cell_si { image->get_actual_geometry(track_count, head_count); + if(!track_count) { + sector_count = 0; + return; + } + UINT8 bitstream[500000/8]; UINT8 sectdata[50000]; desc_xs sectors[256]; @@ -2190,7 +2228,7 @@ void floppy_image_format_t::get_geometry_mfm_pc(floppy_image *image, int cell_si // 0-10, not near the end like 70+, no special effects on sync // like 33 - generate_bitstream_from_track(20, 0, cell_size, bitstream, track_size, image); + generate_bitstream_from_track(track_count > 20 ? 20 : 0, 0, cell_size, bitstream, track_size, image); extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); for(sector_count = 44; sector_count > 0 && !sectors[sector_count].data; sector_count--); diff --git a/src/lib/formats/flopimg.h b/src/lib/formats/flopimg.h index 40467798539..5b1bffb3a0e 100644 --- a/src/lib/formats/flopimg.h +++ b/src/lib/formats/flopimg.h @@ -237,6 +237,8 @@ public: floppy_image_format_t *next; void append(floppy_image_format_t *_next); + bool extension_matches(const char *file_name) const; + protected: // Input for convert_to_edge enum { @@ -522,6 +524,8 @@ public: // Variants enum { + SSSD = 0x44535353, // "SSSD", + SSDD = 0x44445353, // "DSSD", DSDD = 0x44445344, // "DSDD", DSHD = 0x44485344, // "DSHD", DSED = 0x44455344, // "DSED", @@ -543,6 +547,8 @@ public: void get_maximal_geometry(int &tracks, int &heads); void get_actual_geometry(int &tracks, int &heads); + static const char *get_variant_name(UINT32 form_factor, UINT32 variant); + private: enum { MAX_FLOPPY_HEADS = 2, diff --git a/src/lib/formats/mfi_dsk.c b/src/lib/formats/mfi_dsk.c index e4849587a17..1bfd2135413 100644 --- a/src/lib/formats/mfi_dsk.c +++ b/src/lib/formats/mfi_dsk.c @@ -95,9 +95,9 @@ int mfi_format::identify(io_generic *io, UINT32 form_factor) io_generic_read(io, &h, 0, sizeof(header)); if(memcmp( h.sign, sign, 16 ) == 0 && - h.cyl_count > 0 && h.cyl_count <= 84 && - h.head_count > 0 && h.head_count <= 2 && - h.form_factor == form_factor) + h.cyl_count <= 160 && + h.head_count <= 2 && + (!form_factor || h.form_factor == form_factor)) return 100; return 0; }