fix power switch, kb beep and fdd sounds

This commit is contained in:
kara1001000 2015-10-09 22:55:17 +03:00
parent 8c3375affa
commit b39b4399ee
15 changed files with 202 additions and 81 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -18,7 +18,7 @@
*/
// Show step operation
#define TRACE_STEP 1
#define TRACE_STEP 0
#define FLOPSND_TAG "floppysound"
@ -1070,71 +1070,100 @@ void ui_menu_control_floppy_image::handle()
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_loaded = false;
}
void floppy_sound_device::register_for_save_states()
{
save_item(NAME(m_sampleend_motor));
save_item(NAME(m_is525));
save_item(NAME(m_sampleindex_motor_start));
save_item(NAME(m_sampleindex_motor_loop));
save_item(NAME(m_sampleindex_motor_end));
save_item(NAME(m_samplesize_motor_start));
save_item(NAME(m_samplesize_motor_loop));
save_item(NAME(m_samplesize_motor_end));
save_item(NAME(m_samplepos_motor));
save_item(NAME(m_motor_mintime));
save_item(NAME(m_motor_time));
save_item(NAME(m_motor));
save_item(NAME(m_sampleend_step));
save_item(NAME(m_samplestart_step));
save_item(NAME(m_motor_playback_state));
save_item(NAME(m_motor_on));
save_item(NAME(m_step_samples));
save_item(NAME(m_sampleindex_step1));
save_item(NAME(m_samplesize_step));
save_item(NAME(m_samplepos_step));
save_item(NAME(m_step_mintime));
save_item(NAME(m_step_time));
save_item(NAME(m_step_playback_state));
}
void floppy_sound_device::device_start()
{
// Sample playback phases
m_motor_playback_state = 0; // 0 == currently not playing, 1 == playing startup sample, 2 == playing the loop, 3 == playing loop for the last time, 4 == playing the spin down sample
m_step_playback_state = 0; // 0 == currently not playing, > 0 = playing one of the step samples from start to end
m_motor_on = false;
m_is525 = strstr(tag(), "525") != NULL;
if (m_is525)
{
m_sampleindex_motor_start = 2;
m_sampleindex_motor_loop = 3;
m_sampleindex_motor_end = 4;
m_step_samples = 5;
m_sampleindex_step1 = 5;
}
else
{
m_sampleindex_motor_start = 0;
m_sampleindex_motor_loop = 0;
m_sampleindex_motor_end = 0;
m_step_samples = 1;
m_sampleindex_step1 = 1;
}
m_samplepos_motor = 0;
m_samplepos_step = 0;
m_samplesize_motor_start = 0;
m_samplesize_motor_loop = 0;
m_samplesize_motor_end = 0;
for (int i = 0; i < MAX_STEP_SAMPLES; ++i) m_samplesize_step[i] = 0;
// 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());
// If we don't have all samples, don't allocate a stream or access sample data.
if (m_loaded)
{
m_sound = machine().sound().stream_alloc(*this, 0, 1, clock()); // per-floppy stream
// 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
// Get the sample lengths from the sample_t
m_samplesize_motor_start = m_sample[m_sampleindex_motor_start].data.size();
m_samplesize_motor_loop = m_sample[m_sampleindex_motor_loop].data.size();
m_samplesize_motor_end = m_sample[m_sampleindex_motor_end].data.size();
for (int i = 0; i < m_step_samples; ++i) m_samplesize_step[i] = m_sample[m_sampleindex_step1 + i].data.size();
}
// 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;
register_for_save_states();
}
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;
if (!m_loaded) return;
m_sound->update(); // required
if ((!m_motor_playback_state || m_motor_playback_state > 2) && state) // motor was either off or already spinning down
{
m_samplepos_motor = 0;
m_motor_playback_state = 1; // (re)start the motor sound
}
else if (m_motor_playback_state == 2 && !state) m_motor_playback_state = 3; // go to spin down sound when loop is finished
m_motor_on = state;
}
/*
Activate the step sound.
*/
// Activate the step sound.
void floppy_sound_device::step()
{
if (!m_loaded) return;
m_sound->update(); // required
m_step_time = m_step_mintime;
m_samplepos_step = m_samplestart_step;
if (m_step_playback_state == 0)
{
m_step_playback_state = machine().rand() % m_step_samples + 1; // play one of the floppy drive step samples
m_samplepos_step = 0; // restart step sound
}
}
//-------------------------------------------------
@ -1148,39 +1177,71 @@ void floppy_sound_device::sound_stream_update(sound_stream &stream, stream_sampl
// 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)
{
out = 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--;
// make sure we are spinning the motor if stepping is going on!
if (m_motor_playback_state == 0 && m_step_playback_state > 0)
{
m_samplepos_motor = 0;
m_motor_playback_state = 2;
}
// Motor sound
if (m_motor_playback_state > 0)
{
switch (m_motor_playback_state)
{
case 1:
out = m_sample[m_sampleindex_motor_start].data[m_samplepos_motor++];
if (m_samplepos_motor >= m_samplesize_motor_start)
{
m_samplepos_motor = 0;
m_motor_playback_state = 2; // move to looping sound
}
break;
case 2:
out = m_sample[m_sampleindex_motor_loop].data[m_samplepos_motor++];
if (m_samplepos_motor >= m_samplesize_motor_loop)
{
m_samplepos_motor = 0; // continue loop, unless...
if (!m_motor_on) m_motor_playback_state = 4; // motor was turned off already (during spin-up maybe) -> spin down
}
break;
case 3:
out = m_sample[m_sampleindex_motor_loop].data[m_samplepos_motor++];
if (m_samplepos_motor >= m_samplesize_motor_loop)
{
m_samplepos_motor = 0;
m_motor_playback_state = 4; // move to spin down sound
}
break;
case 4:
out = m_sample[m_sampleindex_motor_end].data[m_samplepos_motor++];
if (m_samplepos_motor >= m_samplesize_motor_end)
{
m_samplepos_motor = 0;
m_motor_playback_state = !m_motor_on ? 0 : 1; // stop or restart motor sound
}
break;
}
}
// Stepper sound
if (m_step_time > 0)
if (m_step_playback_state > 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;
// Count down the samples
m_step_time--;
// Mix it into the stream value
out += m_sample[m_sampleindex_step1 + m_step_playback_state - 1].data[m_samplepos_step++];
if (m_samplepos_step >= m_samplesize_step[m_step_playback_state - 1])
{
m_samplepos_step = 0;
m_step_playback_state = 0;
}
}
// Write to the stream buffer
*(samplebuffer++) = out;
}
@ -1191,6 +1252,14 @@ static const char *const floppy_sample_names[] =
"*floppy",
"floppy_35_motor",
"floppy_35_step",
"floppy_525_motor_start",
"floppy_525_motor_loop",
"floppy_525_motor_end",
"floppy_525_step1",
"floppy_525_step2",
"floppy_525_step3",
"floppy_525_step4",
"floppy_525_step5",
0
};
@ -1200,7 +1269,7 @@ 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)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, FLOPSPK, 0.5)
MACHINE_CONFIG_END
machine_config_constructor floppy_image_device::device_mconfig_additions() const

View File

@ -265,9 +265,13 @@ DECLARE_FLOPPY_IMAGE_DEVICE(alps_3255190x, "floppy_5_25")
extern const device_type FLOPPYSOUND;
/*
Floppy drive sound
*/
#define MAX_STEP_SAMPLES 5
class floppy_sound_device : public samples_device
{
public:
@ -286,21 +290,26 @@ private:
sound_stream* m_sound;
bool m_loaded;
bool m_is525; // true if this is a 5.25" floppy drive
int m_sampleend_motor;
int m_sampleindex_motor_start;
int m_sampleindex_motor_loop;
int m_sampleindex_motor_end;
int m_samplesize_motor_start;
int m_samplesize_motor_loop;
int m_samplesize_motor_end;
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_motor_playback_state;
bool m_motor_on;
int m_sampleend_step;
int m_samplestart_step;
int m_step_samples;
int m_sampleindex_step1;
int m_samplesize_step[MAX_STEP_SAMPLES];
int m_samplepos_step;
int m_step_mintime;
int m_step_time;
int m_step_playback_state;
};
class floppy_connector: public device_t,
public device_slot_interface
{
@ -318,7 +327,7 @@ protected:
private:
const floppy_format_type *formats;
bool m_enable_sound;
bool m_enable_sound;
};

View File

@ -491,7 +491,9 @@ static MACHINE_CONFIG_START( mm1, mm1_state )
MCFG_UPD765_INTRQ_CALLBACK(INPUTLINE(I8085A_TAG, I8085_RST55_LINE))
MCFG_UPD765_DRQ_CALLBACK(DEVWRITELINE(I8237_TAG, am9517a_device, dreq3_w))
MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", mm1_floppies, "525qd", mm1_state::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", mm1_floppies, "525qd", mm1_state::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_UPD7201_ADD(UPD7201_TAG, XTAL_6_144MHz/2, 0, 0, 0, 0)
MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE(RS232_A_TAG, rs232_port_device, write_txd))

View File

@ -36,6 +36,19 @@ const rom_entry *mm1_keyboard_t::device_rom_region() const
return ROM_NAME( mm1_keyboard );
}
//-------------------------------------------------
// sampled sounds from MM1 keyboard beeper
//-------------------------------------------------
static const char *const mm1_kb_sample_names[] =
{
"*MM1_keyboard",
"beep", // beep at 2.6 kHz
"power_switch", // not actually on the keyboard, but close enough :)
0
};
bool mm1_keyboard_t::first_time = true;
//-------------------------------------------------
// MACHINE_DRIVER( mm1_keyboard )
@ -43,8 +56,10 @@ const rom_entry *mm1_keyboard_t::device_rom_region() const
static MACHINE_CONFIG_FRAGMENT( mm1_keyboard )
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MCFG_SOUND_ADD("keyboard_and_chassis_sounds", SAMPLES, 0)
MCFG_SAMPLES_CHANNELS(2)
MCFG_SAMPLES_NAMES(mm1_kb_sample_names)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.7)
MACHINE_CONFIG_END
@ -193,7 +208,7 @@ ioport_constructor mm1_keyboard_t::device_input_ports() const
mm1_keyboard_t::mm1_keyboard_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, MM1_KEYBOARD, "MikroMikko 1 keyboard", tag, owner, clock, "mm1kb", __FILE__),
m_write_kbst(*this),
m_speaker(*this, "speaker"),
m_samples(*this, "keyboard_and_chassis_sounds"),
m_rom(*this, "keyboard"),
m_y0(*this, "Y0"),
m_y1(*this, "Y1"),
@ -212,6 +227,10 @@ mm1_keyboard_t::mm1_keyboard_t(const machine_config &mconfig, const char *tag, d
{
}
enum
{
SCAN_TIMER,
};
//-------------------------------------------------
// device_start - device-specific startup
@ -223,15 +242,22 @@ void mm1_keyboard_t::device_start()
m_write_kbst.resolve_safe();
// allocate timers
m_scan_timer = timer_alloc();
m_scan_timer = timer_alloc(SCAN_TIMER);
m_scan_timer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock()));
// add notification request for system shut down (to play back the power switch sound once more)
machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(mm1_keyboard_t::shut_down_mm1), this));
// state saving
save_item(NAME(m_sense));
save_item(NAME(m_drive));
save_item(NAME(m_data));
}
void mm1_keyboard_t::shut_down_mm1()
{
m_samples->start(1, 1); // pretty useless this, as far as there is no way to delay the shut down process...
}
//-------------------------------------------------
// device_timer - handler timer events
@ -239,6 +265,7 @@ void mm1_keyboard_t::device_start()
void mm1_keyboard_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
// handle scan timer
UINT8 data = 0xff;
switch (m_drive)

View File

@ -12,7 +12,7 @@
#define __MM1_KEYBOARD__
#include "emu.h"
#include "sound/speaker.h"
#include "sound/samples.h"
@ -46,7 +46,20 @@ public:
DECLARE_READ8_MEMBER( read ) { return m_data; }
DECLARE_WRITE_LINE_MEMBER( bell_w ) { m_speaker->level_w(state); }
DECLARE_WRITE_LINE_MEMBER( bell_w )
{
if (state == 1)
{
if (first_time)
{
m_samples->start(1, 1); // power switch
first_time = false;
}
if (!m_samples->playing(0)) m_samples->start(0, 0); // beep; during boot, the second beep is in real HW very short (just before floppy seeks) but that's NYI
}
else if (m_samples->playing(0)) m_samples->stop(0); // happens only once during boot, no effect on output
}
void shut_down_mm1();
protected:
// device-level overrides
@ -56,7 +69,7 @@ protected:
private:
devcb_write_line m_write_kbst;
required_device<speaker_sound_device> m_speaker;
required_device<samples_device> m_samples;
required_memory_region m_rom;
required_ioport m_y0;
required_ioport m_y1;
@ -74,7 +87,8 @@ private:
int m_drive;
UINT8 m_data;
emu_timer *m_scan_timer;
static bool first_time; // for power switch sound
emu_timer *m_scan_timer; // scan timer
};