summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/imagedev
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/imagedev')
-rw-r--r--src/emu/imagedev/floppy.c168
-rw-r--r--src/emu/imagedev/floppy.h53
2 files changed, 218 insertions, 3 deletions
diff --git a/src/emu/imagedev/floppy.c b/src/emu/imagedev/floppy.c
index c4a61514b89..f2c3773bc3e 100644
--- a/src/emu/imagedev/floppy.c
+++ b/src/emu/imagedev/floppy.c
@@ -18,7 +18,9 @@
*/
// Show step operation
-#define TRACE_STEP 0
+#define TRACE_STEP 1
+
+#define FLOPSND_TAG "floppysound"
// device type definition
const device_type FLOPPY_CONNECTOR = &device_creator<floppy_connector>;
@@ -123,7 +125,8 @@ const floppy_format_type floppy_image_device::default_floppy_formats[] = {
floppy_connector::floppy_connector(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, FLOPPY_CONNECTOR, "Floppy drive connector abstraction", tag, owner, clock, "floppy_connector", __FILE__),
- device_slot_interface(mconfig, *this)
+ device_slot_interface(mconfig, *this),
+ m_enable_sound(false)
{
}
@@ -144,7 +147,10 @@ void floppy_connector::device_config_complete()
{
floppy_image_device *dev = dynamic_cast<floppy_image_device *>(get_card_device());
if(dev)
+ {
dev->set_formats(formats);
+ dev->enable_sound(m_enable_sound);
+ }
}
floppy_image_device *floppy_connector::get_device()
@@ -161,7 +167,8 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t
device_image_interface(mconfig, *this),
device_slot_card_interface(mconfig, *this),
image(NULL),
- fif_list(NULL)
+ fif_list(NULL),
+ m_make_sound(false)
{
extension_list[0] = '\0';
m_err = IMAGE_ERROR_INVALIDIMAGE;
@@ -304,12 +311,20 @@ void floppy_image_device::device_start()
setup_characteristics();
+ if (m_make_sound) m_sound_out = subdevice<floppy_sound_device>(FLOPSND_TAG);
+
save_item(NAME(cyl));
save_item(NAME(subcyl));
}
void floppy_image_device::device_reset()
{
+ if (m_make_sound)
+ {
+ // Have we loaded all samples? Otherwise mute the floppy.
+ m_make_sound = m_sound_out->samples_loaded();
+ }
+
revolution_start_time = attotime::never;
revolution_count = 0;
mon = 1;
@@ -358,6 +373,7 @@ floppy_image_format_t *floppy_image_device::identify(std::string filename)
bool floppy_image_device::call_load()
{
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;
@@ -490,6 +506,8 @@ void floppy_image_device::mon_w(int state)
cur_ready_cb(this, ready);
}
}
+
+ if (m_make_sound) m_sound_out->motor(state==0);
}
attotime floppy_image_device::time_next_index()
@@ -581,6 +599,8 @@ void floppy_image_device::stp_w(int state)
}
}
subcyl = 0;
+ // Do we want a stepper sound?
+ if (m_make_sound) m_sound_out->step(state==0);
}
}
@@ -1032,6 +1052,148 @@ void ui_menu_control_floppy_image::handle()
}
}
+//===================================================================
+// Floppy sound
+//
+// In order to enable floppy sound you must add the line
+// MCFG_FLOPPY_DRIVE_SOUND(true)
+// after MCFG_FLOPPY_DRIVE_ADD
+// and you must put audio samples (44100Hz, mono) with names as
+// shown in floppy_sample_names into the directory samples/floppy
+// Sound will be disabled when these samples are missing.
+//
+// MZ, Aug 2015
+//===================================================================
+
+floppy_sound_device::floppy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : samples_device(mconfig, FLOPPYSOUND, "Floppy sound", tag, owner, clock, "flopsnd", __FILE__)
+{
+ m_motor = false;
+ m_step = false;
+ m_loaded = false;
+}
+
+void floppy_sound_device::device_start()
+{
+ // Read audio samples. The samples are stored in the list m_samples.
+ m_loaded = load_samples();
+
+ // The per-floppy stream. If we don't have all samples, don't allocate a stream.
+ if (m_loaded) m_sound = machine().sound().stream_alloc(*this, 0, 1, clock());
+
+ // Of course, we can read the length from the sample_t, but we want to
+ // be able to fine-tune it, for instance, choose different start and end points
+ m_samplestart_motor = 0;
+ m_sampleend_motor = 8820; // 200ms
+ m_samplestart_step = 0;
+ m_sampleend_step = 2205; // 50ms
+
+ // Mintime says how long the sound persists after the initiating signal
+ // is cleared (important for short step pulses)
+ m_motor_mintime = 8820;
+ m_step_mintime = 1500;
+
+ // Number of updates until the sample stops
+ m_motor_time = 0;
+ m_step_time = 0;
+
+ // Initialize position
+ m_samplepos_step = m_samplestart_step;
+ m_samplepos_motor = m_samplestart_motor;
+}
+
+void floppy_sound_device::motor(bool state)
+{
+ m_sound->update();
+ // We do not reset the motor sample on state==true because we don't want
+ // the sound to "jump"
+ if (state==true) m_motor_time = m_motor_mintime;
+ m_motor = state;
+}
+
+void floppy_sound_device::step(bool state)
+{
+ m_sound->update(); // required
+ if (state==true)
+ {
+ m_step_time = m_step_mintime;
+ m_samplepos_step = m_samplestart_step;
+ }
+ m_step = state;
+}
+
+//-------------------------------------------------
+// sound_stream_update - update the sound stream
+//-------------------------------------------------
+
+void floppy_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+{
+ // We are using only one stream, unlike the parent class
+ // Also, there is no need for interpolation, as we only expect
+ // one sample rate of 44100 for all samples
+
+ INT16 out = 0;
+
+ stream_sample_t *samplebuffer = outputs[0];
+ sample_t& motor_sample = m_sample[0];
+ sample_t& step_sample = m_sample[1];
+
+ while (samples-- > 0)
+ {
+ // Motor sound
+ if (m_motor_time > 0)
+ {
+ if (m_samplepos_motor < m_sampleend_motor)
+ // Stream value
+ out = motor_sample.data[m_samplepos_motor++];
+ else
+ m_samplepos_motor = m_samplestart_motor;
+
+ // When the motor is turned off, count down the samples
+ if (!m_motor) m_motor_time--;
+ }
+
+ // Stepper sound
+ if (m_step_time > 0)
+ {
+ if (m_samplepos_step < m_sampleend_step)
+ // Mix it into the stream value
+ out = out + step_sample.data[m_samplepos_step++];
+ else
+ m_samplepos_step = m_samplestart_step;
+
+ // When the step is turned off, count down the samples
+ if (!m_step) m_step_time--;
+ }
+ // Write to the stream buffer
+ *(samplebuffer++) = out;
+ }
+}
+
+static const char *const floppy_sample_names[] =
+{
+ "*floppy",
+ "flop_35_motor",
+ "flop_35_step",
+ 0
+};
+
+#define FLOPSPK "flopsndout"
+
+MACHINE_CONFIG_FRAGMENT( floppy_img )
+ MCFG_SPEAKER_STANDARD_MONO(FLOPSPK)
+ MCFG_SOUND_ADD(FLOPSND_TAG, FLOPPYSOUND, 44100)
+ MCFG_SAMPLES_NAMES(floppy_sample_names)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, FLOPSPK, 0.75)
+MACHINE_CONFIG_END
+
+machine_config_constructor floppy_image_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( floppy_img );
+}
+
+const device_type FLOPPYSOUND = &device_creator<floppy_sound_device>;
+
//**************************************************************************
// GENERIC FLOPPY DRIVE DEFINITIONS
diff --git a/src/emu/imagedev/floppy.h b/src/emu/imagedev/floppy.h
index 5b230ae9e49..7084f7e4e08 100644
--- a/src/emu/imagedev/floppy.h
+++ b/src/emu/imagedev/floppy.h
@@ -20,12 +20,16 @@
#include "formats/cqm_dsk.h"
#include "formats/dsk_dsk.h"
#include "ui/imgcntrl.h"
+#include "sound/samples.h"
#define MCFG_FLOPPY_DRIVE_ADD(_tag, _slot_intf, _def_slot, _formats) \
MCFG_DEVICE_ADD(_tag, FLOPPY_CONNECTOR, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
static_cast<floppy_connector *>(device)->set_formats(_formats);
+#define MCFG_FLOPPY_DRIVE_SOUND(_doit) \
+ static_cast<floppy_connector *>(device)->enable_sound(_doit);
+
#define DECLARE_FLOPPY_FORMATS(_name) \
static const floppy_format_type _name []
@@ -44,6 +48,7 @@
FLOPPY_DSK_FORMAT, \
NULL };
+class floppy_sound_device;
/***************************************************************************
TYPE DEFINITIONS
@@ -129,6 +134,9 @@ public:
static const floppy_format_type default_floppy_formats[];
+ // Enable sound
+ void enable_sound(bool doit) { m_make_sound = doit; }
+
protected:
// device-level overrides
virtual void device_config_complete();
@@ -136,6 +144,8 @@ protected:
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+ virtual machine_config_constructor device_mconfig_additions() const;
+
virtual void setup_characteristics() = 0;
floppy_image_format_t *input_format;
@@ -187,6 +197,10 @@ protected:
void write_zone(UINT32 *buf, int &cells, int &index, UINT32 spos, UINT32 epos, UINT32 mg);
void commit_image();
attotime get_next_index_time(std::vector<UINT32> &buf, int index, int delta, attotime base);
+
+ // Sound
+ bool m_make_sound;
+ floppy_sound_device* m_sound_out;
};
class ui_menu_control_floppy_image : public ui_menu_control_device_image {
@@ -249,6 +263,43 @@ DECLARE_FLOPPY_IMAGE_DEVICE(teac_fd_55f, "floppy_5_25")
DECLARE_FLOPPY_IMAGE_DEVICE(teac_fd_55g, "floppy_5_25")
DECLARE_FLOPPY_IMAGE_DEVICE(alps_3255190x, "floppy_5_25")
+extern const device_type FLOPPYSOUND;
+
+/*
+ Floppy drive sound
+*/
+class floppy_sound_device : public samples_device
+{
+public:
+ floppy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ void motor(bool on);
+ void step(bool on);
+ bool samples_loaded() { return m_loaded; }
+
+protected:
+ void device_start();
+
+private:
+ // device_sound_interface overrides
+ void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
+
+ sound_stream* m_sound;
+ bool m_loaded;
+
+ int m_sampleend_motor;
+ int m_samplepos_motor;
+ int m_samplestart_motor;
+ int m_motor_mintime; // min time for the samples; sound persists for that time
+ int m_motor_time;
+ bool m_motor;
+
+ int m_sampleend_step;
+ int m_samplestart_step;
+ int m_samplepos_step;
+ int m_step_mintime;
+ int m_step_time;
+ bool m_step;
+};
class floppy_connector: public device_t,
public device_slot_interface
@@ -259,6 +310,7 @@ public:
void set_formats(const floppy_format_type *formats);
floppy_image_device *get_device();
+ void enable_sound(bool doit) { m_enable_sound = doit; }
protected:
virtual void device_start();
@@ -266,6 +318,7 @@ protected:
private:
const floppy_format_type *formats;
+ bool m_enable_sound;
};