diff options
Diffstat (limited to 'trunk/src/emu/imagedev/floppy.c')
-rw-r--r-- | trunk/src/emu/imagedev/floppy.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/trunk/src/emu/imagedev/floppy.c b/trunk/src/emu/imagedev/floppy.c new file mode 100644 index 00000000000..0041603dff3 --- /dev/null +++ b/trunk/src/emu/imagedev/floppy.c @@ -0,0 +1,216 @@ +/********************************************************************* + + + +*********************************************************************/ + +#include "emu.h" +#include "floppy.h" +#include "formats/imageutl.h" + +// device type definition +const device_type FLOPPY = &device_creator<floppy_image_device>; + +//------------------------------------------------- +// floppy_image_device - constructor +//------------------------------------------------- + +floppy_image_device::floppy_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, FLOPPY, "Floppy drive", tag, owner, clock), + device_image_interface(mconfig, *this), + m_image(NULL) +{ + +} + +//------------------------------------------------- +// floppy_image_device - destructor +//------------------------------------------------- + +floppy_image_device::~floppy_image_device() +{ +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void floppy_image_device::device_config_complete() +{ + // inherit a copy of the static data + const floppy_interface *intf = reinterpret_cast<const floppy_interface *>(static_config()); + if (intf != NULL) + *static_cast<floppy_interface *>(this) = *intf; + + // or initialize to defaults if none provided + else + { + memset(&m_formats, 0, sizeof(m_formats)); + memset(&m_interface, 0, sizeof(m_interface)); + memset(&m_device_displayinfo, 0, sizeof(m_device_displayinfo)); + memset(&m_load_func, 0, sizeof(m_load_func)); + memset(&m_unload_func, 0, sizeof(m_unload_func)); + } + + image_device_format **formatptr; + image_device_format *format; + formatptr = &m_formatlist; + int cnt = 0; + m_extension_list[0] = '\0'; + while (m_formats[cnt].name) + { + // allocate a new format + format = global_alloc_clear(image_device_format); + format->m_index = cnt; + format->m_name = m_formats[cnt].name; + format->m_description = m_formats[cnt].description; + format->m_extensions = m_formats[cnt].extensions; + format->m_optspec = (m_formats[cnt].param_guidelines) ? m_formats[cnt].param_guidelines : ""; + + image_specify_extension( m_extension_list, 256, m_formats[cnt].extensions ); + // and append it to the list + *formatptr = format; + formatptr = &format->m_next; + cnt++; + } + + // set brief and instance name + update_names(); +} + +static TIMER_CALLBACK(floppy_drive_index_callback) +{ + floppy_image_device *image = (floppy_image_device *) ptr; + image->index_func(); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void floppy_image_device::device_start() +{ + // resolve callbacks + m_out_idx_func.resolve(m_out_idx_cb, *this); + + m_idx = 0; + + /* motor off */ + m_mon = 1; + /* set write protect on */ + m_wpt = 0; + + m_rpm = 300.0f; + + m_cyl = 0; + m_ss = 1; + m_stp = 1; + m_dskchg = 0; + m_index_timer = machine().scheduler().timer_alloc(FUNC(floppy_drive_index_callback), (void *)this); +} + +bool floppy_image_device::call_load() +{ + device_image_interface *image = this; + int best; + m_image = global_alloc(floppy_image((void *) image, &image_ioprocs, m_formats)); + const struct floppy_format_def *format = m_image->identify(&best); + m_dskchg = 0; + if (format) { + m_image->load(best); + if (m_load_func) + return m_load_func(*this); + } else { + return IMAGE_INIT_FAIL; + } + return IMAGE_INIT_PASS; +} + +void floppy_image_device::call_unload() +{ + m_dskchg = 0; + + if (m_image) + global_free(m_image); + if (m_unload_func) + m_unload_func(*this); +} + +/* motor on, active low */ +void floppy_image_device::mon_w(int state) +{ + /* force off if there is no attached image */ + if (!exists()) + state = 1; + + /* off -> on */ + if (m_mon && state == 0) + { + m_idx = 0; + index_func(); + } + + /* on -> off */ + else if (m_mon == 0 && state) + m_index_timer->adjust(attotime::zero); + + m_mon = state; +} + +/* index pulses at rpm/60 Hz, and stays high 1/20th of time */ +void floppy_image_device::index_func() +{ + double ms = 1000.0 / (m_rpm / 60.0); + + if (m_idx) + { + m_idx = 0; + m_index_timer->adjust(attotime::from_double(ms*19/20/1000.0)); + } + else + { + m_idx = 1; + m_index_timer->adjust(attotime::from_double(ms/20/1000.0)); + } + + m_out_idx_func(m_idx); +} + +int floppy_image_device::ready_r() +{ + if (exists()) + { + if (m_mon == 0) + { + return 0; + } + } + return 1; +} + +double floppy_image_device::get_pos() +{ + return m_index_timer->elapsed().as_double(); +} + +void floppy_image_device::stp_w(int state) +{ + if ( m_stp != state ) { + m_stp = state; + if ( m_stp == 0 ) { + if ( m_dir ) { + if ( m_cyl ) m_cyl--; + } else { + if ( m_cyl < 83 ) m_cyl++; + } + /* Update disk detection if applicable */ + if (exists()) + { + if (m_dskchg==0) m_dskchg = 1; + } + } + } + +} |