/********************************************************************* *********************************************************************/ #include "emu.h" #include "floppy.h" #include "formats/imageutl.h" // device type definition const device_type FLOPPY = &device_creator; //------------------------------------------------- // 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(static_config()); if (intf != NULL) *static_cast(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; m_extension_list[0] = '\0'; m_fif_list = 0; for(int cnt=0; m_formats[cnt]; cnt++) { // allocate a new format floppy_image_format_t *fif = m_formats[cnt](); format = global_alloc_clear(image_device_format); format->m_index = cnt; format->m_name = fif->name(); format->m_description = fif->description(); format->m_extensions = fif->extensions(); format->m_optspec = ""; image_specify_extension( m_extension_list, 256, fif->extensions() ); // and append it to the list *formatptr = format; formatptr = &format->m_next; } // set brief and instance name update_names(); } void floppy_image_device::setup_load_cb(load_cb cb) { cur_load_cb = cb; } void floppy_image_device::setup_unload_cb(unload_cb cb) { cur_unload_cb = cb; } void floppy_image_device::setup_index_pulse_cb(index_pulse_cb cb) { cur_index_pulse_cb = cb; } 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)); floppy_image_format_t *format = m_image->identify(&best); m_dskchg = 0; if (format) { format->load(m_image); if (m_load_func) return m_load_func(*this); if (!cur_load_cb.isnull()) return cur_load_cb(this); return IMAGE_INIT_PASS; } else { return IMAGE_INIT_FAIL; } } void floppy_image_device::call_unload() { m_dskchg = 0; if (m_image) global_free(m_image); if (m_unload_func) m_unload_func(*this); if (!cur_unload_cb.isnull()) cur_unload_cb(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); if (!cur_index_pulse_cb.isnull()) cur_index_pulse_cb(this, 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; } } } }