floppy: Do specific UI handling [O. Galibert]

This commit is contained in:
Olivier Galibert 2012-01-23 21:49:30 +00:00
parent 2cad56dabb
commit afb7d8fb6a
11 changed files with 583 additions and 52 deletions

View File

@ -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;

View File

@ -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__ */

View File

@ -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"

View File

@ -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<floppy_connector>;
const device_type FLOPPY_35_DD = &device_creator<floppy_35_dd>;
const device_type FLOPPY_35_DD_NOSD = &device_creator<floppy_35_dd_nosd>;
const device_type FLOPPY_35_HD = &device_creator<floppy_35_hd>;
const device_type FLOPPY_35_ED = &device_creator<floppy_35_ed>;
const device_type FLOPPY_525_DD = &device_creator<floppy_525_dd>;
@ -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<floppy_image_device *>(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<floppy_image_device *>(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<floppy_image_device *>(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<floppy_image_device *>(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;
}

View File

@ -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;

View File

@ -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; i<total_usable; i++) {
const floppy_image_format_t *fmt = formats[i];
if(i && i == ext_match)
item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL);
item_append(fmt->description(), 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
***************************************************************************/

View File

@ -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__ */

View File

@ -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)

View File

@ -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--);

View File

@ -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,

View File

@ -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;
}