summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Lord-Nightmare <Lord-Nightmare@users.noreply.github.com>2020-10-22 00:46:30 -0400
committer Lord-Nightmare <Lord-Nightmare@users.noreply.github.com>2020-10-22 00:46:58 -0400
commit0e466c241bb91696d98bd46889cf606a07899b8c (patch)
tree294baf58149cf2a3c221b5f58a1bc987111ec138
parent433eb54a0a7cc0c3f445cd30822684e302da1999 (diff)
Add DAC filtering to Midway "Sounds Good" hardware, and add notes/mirroring regarding the undumped memory mapper PAL. [Lord Nightmare]
-rw-r--r--src/devices/sound/flt_biquad.cpp26
-rw-r--r--src/mame/audio/midway.cpp56
-rw-r--r--src/mame/audio/midway.h6
3 files changed, 68 insertions, 20 deletions
diff --git a/src/devices/sound/flt_biquad.cpp b/src/devices/sound/flt_biquad.cpp
index a0416bfafb1..c625b28c6df 100644
--- a/src/devices/sound/flt_biquad.cpp
+++ b/src/devices/sound/flt_biquad.cpp
@@ -143,6 +143,11 @@ filter_biquad_device& filter_biquad_device::opamp_sk_lowpass_setup(double r1, do
* NOTE: vRef is not definable when setting up the filter.
* If the analog effects caused by vRef are important to the operation of the specific filter
* in question, a netlist implementation may work better under those circumstances.
+ * NOTE2: a variant of this circuit has the c1 capacitor left off. if so, set c1 to 0
+ * which will form a controllable gain 1st order version of the circuit.
+ * NOTE3: There is a well known 'proper' 1st order version of this circuit where r2 is
+ * a dead short, and c1 is also ommitted as in NOTE2. Set both r2 to 0 and c1 to 0 to
+ * emulate a circuit of this type.
*
* .--------+---------.
* | | |
@@ -160,14 +165,13 @@ filter_biquad_device& filter_biquad_device::opamp_sk_lowpass_setup(double r1, do
*/
filter_biquad_device& filter_biquad_device::opamp_mfb_lowpass_setup(double r1, double r2, double r3, double c1, double c2)
{
- if ((r1 == 0) || (r2 == 0) || (r3 == 0) || (c2 == 0))
+ if ((r1 == 0) || ((r2 == 0) && (c1 != 0)) || (r3 == 0) || (c2 == 0))
{
- fatalerror("filter_biquad_device::opamp_mfb_lowpass_setup() - only c1 can be 0; parameters were: r1: %f, r2: %f, r3: %f, c1: %f, c2: %f", r1, r2, r3, c1, c2); /* Filter can not be setup. Undefined results. */
+ fatalerror("filter_biquad_device::opamp_mfb_lowpass_setup() - only c1 can be 0 (and if c1 is 0, r2 can also be 0); parameters were: r1: %f, r2: %f, r3: %f, c1: %f, c2: %f", r1, r2, r3, c1, c2); /* Filter can not be setup. Undefined results. */
}
-
double const gain = -r3 / r1;
double fc, q = (M_SQRT2 / 2.0);
- if (c1 == 0) // set C1 to 0 to run this filter in a degraded single pole mode where C1 was left off the filter entirely. Certain Williams boards seem to have omitted C1, presumably by accident.
+ if ((r2 != 0) && (c1 == 0)) // set C1 to 0 to run this filter in single pole mode where C1 was left off the filter entirely. Certain Williams boards seem to have omitted C1, presumably by accident.
{
fc = (r1 * r3) / (2 * M_PI * ((r1 * r2) + (r1 * r3) + (r2 * r3)) * r3 * c2);
#ifdef FLT_BIQUAD_DEBUG_SETUP
@@ -175,12 +179,20 @@ filter_biquad_device& filter_biquad_device::opamp_mfb_lowpass_setup(double r1, d
#endif
return setup(biquad_type::LOWPASS1P, fc, q, gain);
}
- else
+ else if ((r2 == 0) && (c1 == 0)) // proper first order case, set both C1 to 0 and R2 to 0 for the first order
+ {
+ fc = 1.0 / (2 * M_PI * r3 * c2);
+#ifdef FLT_BIQUAD_DEBUG_SETUP
+ logerror("filter_biquad_device::opamp_mfb_lowpass_setup() in 1st order mode yields: fc = %f, Q = %f(ignored), gain = %f\n", fc, q, gain);
+#endif
+ return setup(biquad_type::LOWPASS1P, fc, q, gain);
+ }
+ else // common case, (r2 != 0) && (c1 != 0)
{
fc = 1.0 / (2 * M_PI * sqrt(r2 * r3 * c1 * c2));
q = sqrt(r2 * r3 * c1 * c2) / ((r3 * c2) + (r2 * c2) + ((r2 * c2) * -gain));
#ifdef FLT_BIQUAD_DEBUG_SETUP
- logerror("filter_biquad_device::opamp_mfb_lowpass_setup() yields: fc = %f, Q = %f, gain = %f\n", fc, q, gain);
+ logerror("filter_biquad_device::opamp_mfb_lowpass_setup() in 2nd order mode yields: fc = %f, Q = %f, gain = %f\n", fc, q, gain);
#endif
return setup(biquad_type::LOWPASS, fc, q, gain);
}
@@ -226,7 +238,7 @@ filter_biquad_device& filter_biquad_device::opamp_mfb_bandpass_setup(double r1,
r_in = 1.0 / (1.0/r1 + 1.0/r2);
}
- double const fc = 1.0 / (2 * M_PI * sqrt(r_in * r3 * c1 * c2));
+ double const fc = 1.0 / (2 * M_PI * sqrt(r_in * r3 * c1 * c2)); // technically this is the center frequency of the bandpass
double const q = sqrt(r3 / r_in * c1 * c2) / (c1 + c2);
gain *= -r3 / r_in * c2 / (c1 + c2);
#ifdef FLT_BIQUAD_DEBUG_SETUP
diff --git a/src/mame/audio/midway.cpp b/src/mame/audio/midway.cpp
index 6a1b9972ff4..075a7beadc9 100644
--- a/src/mame/audio/midway.cpp
+++ b/src/mame/audio/midway.cpp
@@ -470,13 +470,14 @@ void midway_ssio_device::device_timer(emu_timer &timer, device_timer_id id, int
//-------------------------------------------------
midway_sounds_good_device::midway_sounds_good_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, MIDWAY_SOUNDS_GOOD, tag, owner, clock),
- device_mixer_interface(mconfig, *this),
- m_cpu(*this, "cpu"),
- m_pia(*this, "pia"),
- m_dac(*this, "dac"),
- m_status(0),
- m_dacval(0)
+ : device_t(mconfig, MIDWAY_SOUNDS_GOOD, tag, owner, clock)
+ , device_mixer_interface(mconfig, *this)
+ , m_cpu(*this, "cpu")
+ , m_pia(*this, "pia")
+ , m_dac(*this, "dac")
+ , m_dac_filter(*this, "dac_filter%u", 0U)
+ , m_status(0)
+ , m_dacval(0)
{
}
@@ -555,14 +556,36 @@ WRITE_LINE_MEMBER(midway_sounds_good_device::irq_w)
// audio CPU map
//-------------------------------------------------
-// address map determined by PAL; not verified
+// address map determined by PAL20L10 @U15; not dumped/verified yet
+//Address map (x = ignored; * = selects address within this range)
+//68k address map known for certain:
+//a23 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 (a0 via UDS/LDS)
+//x x x x x * * * ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? RW PAL@
+//BEGIN 68k map guesses (until we have a pal dump):
+//x x x x x 0 [a] [b] * * * * * * * * * * * * * * * -> R ROM U7, U17
+//x x x x x 0 [c] [d] * * * * * * * * * * * * * * * -> R ROM U8, U18
+//x x x x x 1 1 0 x x x x x x x x x x x x 0 *e* *f* 1 RW PIA U9 (e goes to PIA RS0, f goes to PIA RS1, D8-D15 go to PIA D0-D7)
+//x x x x x 1 1 1 x x x x * * * * * * * * * * * ? RW RAM U6, U16
+//The ROMTYPE PAL line, is pulled low if JW1 is present, and this presumably controls [a] [b] [c] [d] as such:
+//When ROMTYPE is HIGH/JW1 absent, 27256 roms: (JW3 should be present, JW2 absent)
+//x x x x x 0 0? 0 * * * * * * * * * * * * * * * -> R ROM U7, U17
+//x x x x x 0 0? 1 * * * * * * * * * * * * * * * -> R ROM U8, U18
+//When ROMTYPE is LOW/JW1 present, 27512 roms: (JW3 should be absent, JW2 present)
+//x x x x x 0 0 * * * * * * * * * * * * * * * * -> R ROM U7, U17
+//x x x x x 0 1 * * * * * * * * * * * * * * * * -> R ROM U8, U18
+//JW2 and JW3 are mutually exclusive, and control whether 68k a16 connects to the EPROM pin 1 line (JW2 present), or whether it is tied high (JW3 present).
+//EPROM pin 1 is A15 on 27512, and VPP(usually an active high enable) on 27256
+//END guesses
+
+
+
void midway_sounds_good_device::soundsgood_map(address_map &map)
{
map.unmap_value_high();
map.global_mask(0x7ffff);
map(0x000000, 0x03ffff).rom();
- map(0x060000, 0x060007).rw("pia", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt)).umask16(0xff00);
- map(0x070000, 0x070fff).ram();
+ map(0x060000, 0x060007).mirror(0x00fff0).rw(m_pia, FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt)).umask16(0xff00); // RS0 connects to A2, RS1 connects to A1, hence the "alt" functions are used.
+ map(0x070000, 0x070fff).mirror(0x00f000).ram();
}
@@ -581,7 +604,18 @@ void midway_sounds_good_device::device_add_mconfig(machine_config &config)
m_pia->irqa_handler().set(FUNC(midway_sounds_good_device::irq_w));
m_pia->irqb_handler().set(FUNC(midway_sounds_good_device::irq_w));
- AD7533(config, m_dac, 0).add_route(ALL_OUTPUTS, *this, 1.0); /// ad7533jn.u10
+ AD7533(config, m_dac, 0); /// ad7533jn.u10
+
+ //LM359 @U2.2, 2nd order MFB low-pass (fc = 5404.717733, Q = 0.625210, gain = -1.000000)
+ FILTER_BIQUAD(config, m_dac_filter[2]).opamp_mfb_lowpass_setup(RES_K(150), RES_K(82), RES_K(150), CAP_P(470), CAP_P(150)); // R115, R109, R108, C112, C111
+ m_dac_filter[2]->add_route(ALL_OUTPUTS, *this, 1.0);
+ //LM359 @U3.2, 2nd order MFB low-pass (fc = 5310.690763, Q = 1.608630, gain = -1.000000)
+ FILTER_BIQUAD(config, m_dac_filter[1]).opamp_mfb_lowpass_setup(RES_K(33), RES_K(18), RES_K(33), CAP_P(5600), CAP_P(270)); // R113, R117, R116, C115, C118
+ m_dac_filter[1]->add_route(ALL_OUTPUTS, m_dac_filter[2], 1.0);
+ //LM359 @U3.1, 1st order MFB low-pass (fc = 4912.189602, Q = 0.707107(ignored), gain = -1.000000)
+ FILTER_BIQUAD(config, m_dac_filter[0]).opamp_mfb_lowpass_setup(RES_K(120), RES_K(0), RES_K(120), CAP_P(0), CAP_P(270)); // R112, <short>, R111, <nonexistent>, C113
+ m_dac_filter[0]->add_route(ALL_OUTPUTS, m_dac_filter[1], 1.0);
+ m_dac->add_route(ALL_OUTPUTS, m_dac_filter[0], 1.0);
}
diff --git a/src/mame/audio/midway.h b/src/mame/audio/midway.h
index ea813eaf1af..59135e72d35 100644
--- a/src/mame/audio/midway.h
+++ b/src/mame/audio/midway.h
@@ -18,10 +18,11 @@
#include "cpu/m6800/m6800.h"
#include "cpu/m6809/m6809.h"
#include "machine/6821pia.h"
-#include "sound/tms5220.h"
#include "sound/ay8910.h"
#include "sound/dac.h"
+#include "sound/flt_biquad.h"
#include "sound/hc55516.h"
+#include "sound/tms5220.h"
//**************************************************************************
@@ -148,7 +149,8 @@ private:
// devices
required_device<m68000_device> m_cpu;
required_device<pia6821_device> m_pia;
- required_device<dac_word_interface> m_dac;
+ required_device<ad7533_device> m_dac;
+ required_device_array<filter_biquad_device, 3> m_dac_filter;
// internal state
uint8_t m_status;