mirror of
https://github.com/holub/mame
synced 2025-07-02 00:29:37 +03:00
mm5837: unify implementations
* create base mm5837_source device to provide raw output * mm5837_device is based on it * mm5837_stream_device generates a sound stream from it * frequency calculation now computed instead of table-based
This commit is contained in:
parent
7e2d6aa41e
commit
dfa1168970
@ -12,22 +12,16 @@
|
||||
#include "mm5837.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// CONSTEXPR DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
constexpr int mm5837_device::m_frequency[];
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(MM5837, mm5837_device, "mm5837", "MM5837 Digital Noise Source")
|
||||
DEFINE_DEVICE_TYPE(MM5837_STREAM, mm5837_stream_device, "mm5837", "MM5837 Digital Noise Stream")
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
// MM5837 DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -37,12 +31,12 @@ DEFINE_DEVICE_TYPE(MM5837, mm5837_device, "mm5837", "MM5837 Digital Noise Source
|
||||
mm5837_device::mm5837_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, MM5837, tag, owner, clock),
|
||||
m_output_cb(*this),
|
||||
m_vdd(0),
|
||||
m_timer(nullptr),
|
||||
m_shift(0)
|
||||
m_vdd(-12)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
@ -56,36 +50,70 @@ void mm5837_device::device_start()
|
||||
m_timer = timer_alloc(0);
|
||||
|
||||
// register for save states
|
||||
save_item(NAME(m_shift));
|
||||
save_item(NAME(m_source.m_shift));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void mm5837_device::device_reset()
|
||||
{
|
||||
// initialize with something
|
||||
m_shift = 123456;
|
||||
m_source.reset();
|
||||
|
||||
if (m_vdd < 16)
|
||||
m_timer->adjust(attotime::zero, 0, attotime::from_hz(m_frequency[m_vdd]));
|
||||
m_timer->adjust(attotime::zero, 0, attotime::from_hz(mm5837_source::frequency(m_vdd)));
|
||||
else
|
||||
throw emu_fatalerror("%s: Invalid voltage: %d\n", tag(), m_vdd);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - handle timer callbacks
|
||||
//-------------------------------------------------
|
||||
|
||||
void mm5837_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
int tap_14 = BIT(m_shift, 13);
|
||||
int tap_17 = BIT(m_shift, 16);
|
||||
int zero = (m_shift == 0) ? 1 : 0;
|
||||
|
||||
m_shift <<= 1;
|
||||
m_shift |= tap_14 ^ tap_17 ^ zero;
|
||||
|
||||
m_output_cb(BIT(m_shift, 16));
|
||||
m_output_cb(m_source.clock());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MM5837 STREAM DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// mm5837_stream_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
mm5837_stream_device::mm5837_stream_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, MM5837_STREAM, tag, owner, clock),
|
||||
device_sound_interface(mconfig, *this),
|
||||
m_stream(nullptr),
|
||||
m_vdd(-12)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void mm5837_stream_device::device_start()
|
||||
{
|
||||
m_stream = stream_alloc(0, 1, mm5837_source::frequency(m_vdd));
|
||||
save_item(NAME(m_source.m_shift));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - fill the sound buffer
|
||||
//-------------------------------------------------
|
||||
|
||||
void mm5837_stream_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
|
||||
{
|
||||
for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++)
|
||||
outputs[0].put(sampindex, m_source.clock() ? 1.0 : 0.0);
|
||||
}
|
||||
|
@ -94,6 +94,66 @@
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> mm5837_source
|
||||
|
||||
class mm5837_source
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
mm5837_source() :
|
||||
m_shift(0x1ffff)
|
||||
{
|
||||
}
|
||||
|
||||
// reset to base state
|
||||
void reset()
|
||||
{
|
||||
m_shift = 0x1ffff;
|
||||
}
|
||||
|
||||
// clock one time and return the shift value
|
||||
u8 clock()
|
||||
{
|
||||
int tap_14 = BIT(m_shift, 13);
|
||||
int tap_17 = BIT(m_shift, 16);
|
||||
int zero = (m_shift == 0) ? 1 : 0;
|
||||
|
||||
m_shift <<= 1;
|
||||
m_shift |= tap_14 ^ tap_17 ^ zero;
|
||||
|
||||
return BIT(m_shift, 16);
|
||||
}
|
||||
|
||||
// taken from the book 'mims circuit scrapbook, vol. 1'
|
||||
static u32 frequency(double vdd)
|
||||
{
|
||||
// Vdd should be negative -6.2..-15V
|
||||
if (vdd > -6.2 || vdd < -15)
|
||||
throw emu_fatalerror("mm5837 frequency should be -6.2V .. -15V");
|
||||
|
||||
// curve fitting done in excel from this table:
|
||||
// { 0, 0, 0, 0, 0, 0, 1, 2267, 8731, 16382, 23531, 32564, 38347, 40010, 37800, 33173 }
|
||||
double result = 191.98*vdd*vdd*vdd + 5448.4*vdd*vdd + 43388*vdd + 105347;
|
||||
|
||||
// datasheet claims frequency range 24-56kHz at Vdd=-14V, but also lists
|
||||
// maximum cycle times as ranging from 1.1-2.4s; since the 17-bit shift
|
||||
// register cycles after 131072 clocks, we would expect the actual cycle
|
||||
// times to be 2.34-5.46s at the 24-56kHz frequency range, so I'm presuming
|
||||
// that it ticks 2x per "clock", effectively running at 2x the frequency
|
||||
result *= 2;
|
||||
|
||||
// make sure the result isn't TOO crazy
|
||||
result = std::max(result, 100.0);
|
||||
return u32(result);
|
||||
}
|
||||
|
||||
// leave this public for easy saving
|
||||
u32 m_shift;
|
||||
};
|
||||
|
||||
|
||||
// ======================> mm5837_device
|
||||
|
||||
class mm5837_device : public device_t
|
||||
{
|
||||
public:
|
||||
@ -101,7 +161,7 @@ public:
|
||||
mm5837_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
|
||||
// configuration
|
||||
void set_vdd_voltage(int voltage) { m_vdd = voltage; }
|
||||
void set_vdd(double voltage) { m_vdd = voltage; }
|
||||
auto output_callback() { return m_output_cb.bind(); }
|
||||
|
||||
protected:
|
||||
@ -111,24 +171,42 @@ protected:
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
private:
|
||||
// taken from the book 'mims circuit scrapbook, vol. 1'
|
||||
// this is the frequency the chip runs at when given a vdd voltage of -0 to -15
|
||||
static constexpr int m_frequency[16] = { 0, 0, 0, 0, 0, 0, 1, 2267, 8731, 16382, 23531, 32564, 38347, 40010, 37800, 33173 };
|
||||
|
||||
// callbacks
|
||||
devcb_write_line m_output_cb;
|
||||
|
||||
// voltage (as positive number)
|
||||
int m_vdd;
|
||||
|
||||
// output timer
|
||||
emu_timer *m_timer;
|
||||
|
||||
// state
|
||||
uint32_t m_shift;
|
||||
// internal state
|
||||
devcb_write_line m_output_cb; // output callback
|
||||
emu_timer *m_timer; // output timer
|
||||
double m_vdd; // configured voltage
|
||||
mm5837_source m_source; // noise source
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
||||
// ======================> mm5837_stream_device
|
||||
|
||||
class mm5837_stream_device : public device_t, public device_sound_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
mm5837_stream_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// configuration
|
||||
void set_vdd(double voltage) { m_vdd = voltage; }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
|
||||
|
||||
private:
|
||||
sound_stream *m_stream; // sound stream
|
||||
double m_vdd; // configured voltage
|
||||
mm5837_source m_source; // noise source
|
||||
};
|
||||
|
||||
|
||||
// device type definitions
|
||||
DECLARE_DEVICE_TYPE(MM5837, mm5837_device)
|
||||
DECLARE_DEVICE_TYPE(MM5837_STREAM, mm5837_stream_device)
|
||||
|
||||
|
||||
#endif // MAME_SOUND_MM5837_H
|
||||
|
@ -55,6 +55,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "sound/mm5837.h"
|
||||
#include "audio/sente6vb.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/clock.h"
|
||||
@ -66,53 +67,6 @@
|
||||
DEFINE_DEVICE_TYPE(SENTE6VB, sente6vb_device, "sente6vb", "Bally Sente 6VB Audio Board")
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Trivial sound device to spew
|
||||
* a MM5837 noise stream to CEM3394
|
||||
* inputs
|
||||
*
|
||||
*************************************/
|
||||
|
||||
DECLARE_DEVICE_TYPE(MM5837_NOISE_SOURCE, mm5837_noise_source)
|
||||
|
||||
class mm5837_noise_source : public device_t, public device_sound_interface
|
||||
{
|
||||
public:
|
||||
mm5837_noise_source(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, MM5837_NOISE_SOURCE, tag, owner, clock),
|
||||
device_sound_interface(mconfig, *this),
|
||||
m_stream(nullptr),
|
||||
m_noise_state(0x1ffff)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override
|
||||
{
|
||||
m_stream = stream_alloc(0, 1, clock());
|
||||
save_item(NAME(m_noise_state));
|
||||
}
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override
|
||||
{
|
||||
for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++)
|
||||
{
|
||||
outputs[0].put(sampindex, BIT(m_noise_state, 0) ? 1.0 : 0.0);
|
||||
m_noise_state = (m_noise_state >> 1) | ((BIT(m_noise_state, 0) ^ BIT(m_noise_state, 3)) << 16);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
sound_stream *m_stream; // sound stream
|
||||
u32 m_noise_state; // noise state
|
||||
};
|
||||
|
||||
DEFINE_DEVICE_TYPE(MM5837_NOISE_SOURCE, mm5837_noise_source, "mm5837noise", "MM5837")
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -172,7 +126,9 @@ void sente6vb_device::device_add_mconfig(machine_config &config)
|
||||
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
mm5837_noise_source &noise(MM5837_NOISE_SOURCE(config, "noise", 100000));
|
||||
mm5837_stream_device &noise(MM5837_STREAM(config, "noise", 0));
|
||||
// noise.set_vdd(-6.5); // seems too low -- possible the mapping in mm5837 is wrong
|
||||
noise.set_vdd(-8.0);
|
||||
|
||||
for (auto &cem_device : m_cem_device)
|
||||
{
|
||||
@ -180,7 +136,7 @@ void sente6vb_device::device_add_mconfig(machine_config &config)
|
||||
cem_device->set_vco_zero_freq(431.894);
|
||||
cem_device->set_filter_zero_freq(1300.0);
|
||||
cem_device->add_route(ALL_OUTPUTS, "mono", 0.90);
|
||||
noise.add_route(0, *cem_device, 1.0);
|
||||
noise.add_route(0, *cem_device, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -554,7 +554,7 @@ void beezer_state::beezer(machine_config &config)
|
||||
// schematics show an input labeled VCO to channel 2, but the source is unknown
|
||||
|
||||
mm5837_device &noise(MM5837(config, "noise"));
|
||||
noise.set_vdd_voltage(12);
|
||||
noise.set_vdd(-12);
|
||||
noise.output_callback().set(FUNC(beezer_state::noise_w));
|
||||
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
|
Loading…
Reference in New Issue
Block a user