mirror of
https://github.com/holub/mame
synced 2025-06-30 07:58:56 +03:00
Add DAC filtering to Midway "Sounds Good" hardware, and add notes/mirroring regarding the undumped memory mapper PAL. [Lord Nightmare]
This commit is contained in:
parent
433eb54a0a
commit
0e466c241b
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user