summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/mm5837.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/mm5837.h')
-rw-r--r--src/devices/sound/mm5837.h185
1 files changed, 167 insertions, 18 deletions
diff --git a/src/devices/sound/mm5837.h b/src/devices/sound/mm5837.h
index 543f92be033..169965ef1d5 100644
--- a/src/devices/sound/mm5837.h
+++ b/src/devices/sound/mm5837.h
@@ -1,5 +1,5 @@
-// license: GPL-2.0+
-// copyright-holders: Dirk Best
+// license:BSD-3-Clause
+// copyright-holders:Dirk Best
/***************************************************************************
National Semiconductor MM5837
@@ -12,6 +12,76 @@
OUTPUT 3 | | 7 N/C
VSS 4 |_______| 8 N/C
+
+ Couriersud , 16.02.2020
+
+ The following measurements were taken on Saturday, 15.02.2020 using
+ a MM5837. These deviate significantly from the measurements cited
+ below from 'mims circuit scrapbook'. I assume mims has noted down the
+ frequencies measured on the output pin and has not taken the effort to
+ convert them to the internal frequency.
+
+ Some simple math shows that the internal frequency used to drive the
+ lfsr (2^17-1 length) is 4 times the frequency measured at pin 3.
+ The lfsr produces 32768 l-h transitions during one lfsr cycle. This can
+ either be derived using some debug code or stochastic analysis.
+
+ The frequencies measured are also in the order of the 100kHz the
+ S2688 datasheet (MM5837 replacement) states.
+
+ The "sweet spot" of 32768Hz was measured at 12.91 supply voltage.
+
+ V Fpin3 Fint T
+ 7.2 1 4 32768.0
+ 7.4 26 104 1260.3
+ 7.5 110 440 297.9
+ 7.6 205 820 159.8
+ 7.7 370 1,480 88.6
+ 8.0 950 3,800 34.5
+ 8.5 2,900 11,600 11.3
+ 9.0 5,570 22,280 5.9
+ 9.5 8,300 33,200 3.9
+ 10.0 11,300 45,200 2.9
+ 10.5 14,800 59,200 2.2
+ 11.0 18,100 72,400 1.8
+ 11.5 22,050 88,200 1.5
+ 12.0 25,800 103,200 1.3
+ 12.5 29,750 119,000 1.1
+ 12.91 32,768 131,072 1.0
+ 13.0 33,670 134,680 1.0
+ 13.5 37,800 151,200 0.9
+ 14.0 41,900 167,600 0.8
+ 14.5 46,050 184,200 0.7
+ 15.0 49,700 198,800 0.7
+ 15.5 52,450 209,800 0.6
+ 16.0 53,800 215,200 0.6
+ 16.5 53,900 215,600 0.6
+ 17.0 53,000 212,000 0.6
+ 17.5 51,500 206,000 0.6
+ 18.0 49,000 196,000 0.7
+ 18.5 45,900 183,600 0.7
+ 19.0 42,500 170,000 0.8
+ 19.5 39,200 156,800 0.8
+ 20.0 36,000 144,000 0.9
+ 20.5 32,900 131,600 1.0
+ 21.0 29,600 118,400 1.1
+ 21.5 26,700 106,800 1.2
+ 22.0 24,200 96,800 1.4
+ 22.5 21,450 85,800 1.5
+ 23.0 18,800 75,200 1.7
+ 23.5 16,650 66,600 2.0
+ 24.0 13,900 55,600 2.4
+ 24.5 11,950 47,800 2.7
+
+ Output levels (VGG tied to VDD), RL 22k to VDD
+ These were measured using my 30 year old Hameg.
+
+ Vsupply Vmin Vmax
+ 20 6.0 18.0
+ 15 4.0 13.5
+ 12 3.0 10.5
+ 10 2.5 9.0
+
***************************************************************************/
#ifndef MAME_SOUND_MM5837_H
@@ -24,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:
@@ -31,34 +161,53 @@ 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:
// device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+
+ TIMER_CALLBACK_MEMBER(update_clock_output);
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 };
+ // 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
+};
- // callbacks
- devcb_write_line m_output_cb;
- // voltage (as positive number)
- int m_vdd;
+// ======================> mm5837_stream_device
- // output timer
- emu_timer *m_timer;
+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);
- // state
- uint32_t m_shift;
+ // configuration
+ void set_vdd(double voltage) { m_vdd = voltage; }
+
+protected:
+ // device-level overrides
+ virtual void device_start() override ATTR_COLD;
+
+ // sound stream update overrides
+ virtual void sound_stream_update(sound_stream &stream) override;
+
+private:
+ sound_stream *m_stream; // sound stream
+ double m_vdd; // configured voltage
+ mm5837_source m_source; // noise source
};
-// device type definition
+
+// device type definitions
DECLARE_DEVICE_TYPE(MM5837, mm5837_device)
+DECLARE_DEVICE_TYPE(MM5837_STREAM, mm5837_stream_device)
+
#endif // MAME_SOUND_MM5837_H