From 00150aec1cf3e6b4d00a3fd7b0211baaedc6881b Mon Sep 17 00:00:00 2001 From: couriersud Date: Sat, 20 Jun 2015 19:16:53 +0200 Subject: [PATCH] Analog drums and filtering for Kid Niki et al. [Andrew Gardner, Couriersud] In addition: - Generalized the device family concept. - Truthtable device can now define their own device family model. --- src/emu/machine/netlist.h | 41 ++- src/emu/netlist/analog/nld_twoterm.h | 3 +- src/emu/netlist/devices/nld_truthtable.h | 14 +- src/emu/netlist/nl_base.c | 89 ++--- src/emu/netlist/nl_base.h | 7 + src/emu/netlist/nl_setup.c | 58 +++ src/emu/netlist/nl_setup.h | 5 + src/emu/netlist/solver/nld_solver.c | 10 +- src/mame/audio/irem.c | 218 ++++++++++-- src/mame/audio/irem.h | 19 +- src/mame/audio/nl_kidniki.c | 427 +++++++++++++++++++++++ src/mame/drivers/m62.c | 1 - src/mame/includes/m62.h | 8 +- src/mame/video/m62.c | 6 +- 14 files changed, 808 insertions(+), 98 deletions(-) create mode 100644 src/mame/audio/nl_kidniki.c diff --git a/src/emu/machine/netlist.h b/src/emu/machine/netlist.h index 673b67a2d90..3893807de07 100644 --- a/src/emu/machine/netlist.h +++ b/src/emu/machine/netlist.h @@ -28,7 +28,7 @@ netlist_mame_analog_input_t::static_set_name(*device, _name); #define MCFG_NETLIST_ANALOG_MULT_OFFSET(_mult, _offset) \ - netlist_mame_analog_input_t::static_set_mult_offset(*device, _mult, _offset); + netlist_mame_sub_interface::static_set_mult_offset(*device, _mult, _offset); #define MCFG_NETLIST_ANALOG_OUTPUT(_basetag, _tag, _IN, _class, _member, _class_tag) \ MCFG_DEVICE_ADD(_basetag ":" _tag, NETLIST_ANALOG_OUTPUT, 0) \ @@ -425,16 +425,9 @@ public: inline void write(const UINT32 val) { - if (is_sound_device()) - { - update_to_current_time(); - m_param->setTo((val >> m_shift) & m_mask); - } - else - { - // FIXME: use device timer .... - m_param->setTo((val >> m_shift) & m_mask); - } + const UINT32 v = (val >> m_shift) & m_mask; + if (v != m_param->Value()) + synchronize(0, v); } inline DECLARE_INPUT_CHANGED_MEMBER(input_changed) { write(newval); } @@ -447,6 +440,12 @@ public: protected: // device-level overrides virtual void device_start(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) + { + if (is_sound_device()) + update_to_current_time(); + m_param->setTo(param); + } private: netlist::param_int_t *m_param; @@ -575,7 +574,7 @@ public: ATTR_COLD void reset() { - m_cur = 0; + m_cur = 0.0; m_last_pos = 0; m_last_buffer = netlist::netlist_time::zero; } @@ -587,21 +586,29 @@ public: netlist().error("sound %s: exceeded BUFSIZE\n", name().cstr()); while (m_last_pos < pos ) { - m_buffer[m_last_pos++] = m_cur; + m_buffer[m_last_pos++] = (stream_sample_t) m_cur; } } ATTR_HOT void update() { - nl_double val = INPANALOG(m_in); + nl_double val = INPANALOG(m_in) * m_mult.Value() + m_offset.Value(); sound_update(netlist().time()); - m_cur = (stream_sample_t) (val * m_mult.Value() + m_offset.Value()); + /* ignore spikes */ + if (std::abs(val) < 32767.0) + m_cur = val; + else if (val > 0.0) + m_cur = 32767.0; + else + m_cur = -32767.0; + } ATTR_HOT void buffer_reset(netlist::netlist_time upto) { m_last_pos = 0; m_last_buffer = upto; + m_cur = 0.0; } netlist::param_int_t m_channel; @@ -612,7 +619,7 @@ public: private: netlist::analog_input_t m_in; - stream_sample_t m_cur; + double m_cur; int m_last_pos; netlist::netlist_time m_last_buffer; }; @@ -677,7 +684,7 @@ public: { if (m_buffer[i] == NULL) break; // stop, called outside of stream_update - nl_double v = m_buffer[i][m_pos]; + const nl_double v = m_buffer[i][m_pos]; m_param[i]->setTo(v * m_param_mult[i].Value() + m_param_offset[i].Value()); } m_pos++; diff --git a/src/emu/netlist/analog/nld_twoterm.h b/src/emu/netlist/analog/nld_twoterm.h index cea8731a0e7..6cea4408ff6 100644 --- a/src/emu/netlist/analog/nld_twoterm.h +++ b/src/emu/netlist/analog/nld_twoterm.h @@ -68,7 +68,8 @@ #ifdef RES_R -#warning "Do not include rescap.h in a netlist environment" +// FIXME: avoid compile fails +// #warning "Do not include rescap.h in a netlist environment" #endif #define RES_R(res) ((double)(res)) diff --git a/src/emu/netlist/devices/nld_truthtable.h b/src/emu/netlist/devices/nld_truthtable.h index 2cd80d29a7b..e5edec072ce 100644 --- a/src/emu/netlist/devices/nld_truthtable.h +++ b/src/emu/netlist/devices/nld_truthtable.h @@ -35,6 +35,9 @@ #define TT_LINE(_x) \ ttd->m_desc.add(_x); +#define TT_FAMILY(_x) \ + ttd->m_family = netlist::logic_family_desc_t::from_model(_x); + #define TRUTHTABLE_END() \ setup.factory().register_device(ttd); \ } @@ -294,9 +297,17 @@ class netlist_base_factory_truthtable_t : public base_factory_t public: netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname, const pstring &def_param) - : base_factory_t(name, classname, def_param) + : base_factory_t(name, classname, def_param), m_family(&netlist_family_TTL) {} + + virtual ~netlist_base_factory_truthtable_t() + { + if (!m_family->m_is_static) + pfree(m_family); + } + pstring_list_t m_desc; + const logic_family_desc_t * m_family; }; @@ -313,6 +324,7 @@ public: { typedef nld_truthtable_t tt_type; device_t *r = palloc(tt_type, &m_ttbl, m_desc); + r->set_logic_family(m_family); //r->init(setup, name); return r; } diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index 6a38cfa57bc..588b4e53f35 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -46,7 +46,7 @@ fatalerror_e::fatalerror_e(const char *format, va_list ap) class logic_family_ttl_t : public logic_family_desc_t { public: - logic_family_ttl_t() + logic_family_ttl_t() : logic_family_desc_t() { m_low_thresh_V = 0.8; m_high_thresh_V = 2.0; @@ -55,6 +55,7 @@ public: m_high_V = 4.0; m_R_low = 1.0; m_R_high = 130.0; + m_is_static = true; } virtual devices::nld_base_d_to_a_proxy *create_d_a_proxy(logic_output_t *proxied) const { @@ -66,15 +67,16 @@ public: class logic_family_cd4000_t : public logic_family_desc_t { public: - logic_family_cd4000_t() + logic_family_cd4000_t() : logic_family_desc_t() { m_low_thresh_V = 0.8; m_high_thresh_V = 2.0; // m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications. - m_low_V = 0.1; - m_high_V = 4.0; - m_R_low = 1.0; - m_R_high = 130.0; + m_low_V = 0.05; + m_high_V = 4.95; + m_R_low = 10.0; + m_R_high = 10.0; + m_is_static = true; } virtual devices::nld_base_d_to_a_proxy *create_d_a_proxy(logic_output_t *proxied) const { @@ -85,6 +87,38 @@ public: const logic_family_desc_t &netlist_family_TTL = logic_family_ttl_t(); const logic_family_desc_t &netlist_family_CD4000 = logic_family_cd4000_t(); +class logic_family_std_proxy_t : public logic_family_desc_t +{ +public: + logic_family_std_proxy_t() { } + virtual devices::nld_base_d_to_a_proxy *create_d_a_proxy(logic_output_t *proxied) const + { + return palloc(devices::nld_d_to_a_proxy , proxied); + } +}; + +const logic_family_desc_t *logic_family_desc_t::from_model(const pstring &model) +{ + + if (setup_t::model_value_str(model, "TYPE", "") == "TTL") + return &netlist_family_TTL; + if (setup_t::model_value_str(model, "TYPE", "") == "CD4000") + return &netlist_family_CD4000; + + /* FIXME: Memory leak */ + logic_family_std_proxy_t *ret = palloc(logic_family_std_proxy_t); + + ret->m_low_thresh_V = setup_t::model_value(model, "IVL", 0.8); + ret->m_high_thresh_V = setup_t::model_value(model, "IVH", 2.0); + ret->m_low_V = setup_t::model_value(model, "OVL", 0.1); + ret->m_high_V = setup_t::model_value(model, "OVH", 4.0); + ret->m_R_low = setup_t::model_value(model, "ORL", 1.0); + ret->m_R_high = setup_t::model_value(model, "ORH", 130.0); + + return ret; +} + + // ---------------------------------------------------------------------------------------- // netlist_queue_t // ---------------------------------------------------------------------------------------- @@ -424,7 +458,8 @@ ATTR_COLD core_device_t::core_device_t(const family_t afamily) ATTR_COLD void core_device_t::init(netlist_t &anetlist, const pstring &name) { - set_logic_family(this->default_logic_family()); + if (logic_family() == NULL) + set_logic_family(this->default_logic_family()); init_object(anetlist, name); #if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF) @@ -1055,43 +1090,17 @@ ATTR_COLD const pstring param_model_t::model_type() const } +ATTR_COLD const pstring param_model_t::model_value_str(const pstring &entity, const pstring defval) const +{ + return setup_t::model_value_str(this->Value(), entity, defval); +} + ATTR_COLD nl_double param_model_t::model_value(const pstring &entity, const nl_double defval) const { - pstring tmp = this->Value(); - // .model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon) - int p = tmp.ucase().find(entity.ucase() + "="); - if (p>=0) - { - int pblank = tmp.find(" ", p); - if (pblank < 0) pblank = tmp.len() + 1; - tmp = tmp.substr(p, pblank - p); - int pequal = tmp.find("=", 0); - if (pequal < 0) - netlist().error("parameter %s misformat in model %s temp %s\n", entity.cstr(), Value().cstr(), tmp.cstr()); - tmp = tmp.substr(pequal+1); - nl_double factor = NL_FCONST(1.0); - switch (*(tmp.right(1).cstr())) - { - case 'm': factor = 1e-3; break; - case 'u': factor = 1e-6; break; - case 'n': factor = 1e-9; break; - case 'p': factor = 1e-12; break; - case 'f': factor = 1e-15; break; - case 'a': factor = 1e-18; break; - - } - if (factor != NL_FCONST(1.0)) - tmp = tmp.left(tmp.len() - 1); - return tmp.as_double() * factor; - } - else - { - netlist().log("Entity %s not found in model %s\n", entity.cstr(), tmp.cstr()); - return defval; - } + return setup_t::model_value(this->Value(), entity, defval); } -} +} // namespace NETLIB_NAMESPACE_DEVICES_START() diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h index f2d41b54014..b6347eb5fe8 100644 --- a/src/emu/netlist/nl_base.h +++ b/src/emu/netlist/nl_base.h @@ -304,6 +304,7 @@ namespace netlist class setup_t; class netlist_t; class core_device_t; + class param_model_t; // ----------------------------------------------------------------------------- // netlist_output_family_t @@ -312,6 +313,7 @@ namespace netlist class logic_family_desc_t { public: + logic_family_desc_t() : m_is_static(false) {} virtual ~logic_family_desc_t() {} virtual devices::nld_base_d_to_a_proxy *create_d_a_proxy(logic_output_t *proxied) const = 0; @@ -321,6 +323,10 @@ namespace netlist nl_double m_high_V; nl_double m_R_low; nl_double m_R_high; + + bool m_is_static; + + static const logic_family_desc_t *from_model(const pstring &model); }; class logic_family_t @@ -986,6 +992,7 @@ namespace netlist /* these should be cached! */ ATTR_COLD nl_double model_value(const pstring &entity, const nl_double defval = 0.0) const; + ATTR_COLD const pstring model_value_str(const pstring &entity, const pstring defval = "") const; ATTR_COLD const pstring model_type() const; private: diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c index 6887042d440..68bc5452815 100644 --- a/src/emu/netlist/nl_setup.c +++ b/src/emu/netlist/nl_setup.c @@ -847,6 +847,64 @@ void setup_t::print_stats() const #endif } +// ---------------------------------------------------------------------------------------- +// Static +// ---------------------------------------------------------------------------------------- + +const pstring setup_t::model_value_str(const pstring &model_str, const pstring &entity, const pstring defval) +{ + pstring tmp = model_str; + // .model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon) + int p = tmp.ucase().find(entity.ucase() + "="); + if (p>=0) + { + int pblank = tmp.find(" ", p); + if (pblank < 0) pblank = tmp.len() + 1; + tmp = tmp.substr(p, pblank - p); + int pequal = tmp.find("=", 0); + if (pequal < 0) + fatalerror_e("parameter %s misformat in model %s temp %s\n", entity.cstr(), model_str.cstr(), tmp.cstr()); + tmp = tmp.substr(pequal+1); + return tmp; + } + else + { + //netlist().log("Entity %s not found in model %s\n", entity.cstr(), tmp.cstr()); + return defval; + } +} + +nl_double setup_t::model_value(const pstring &model_str, const pstring &entity, const nl_double defval) +{ + pstring tmp = model_value_str(model_str, entity, "NOTFOUND"); + + nl_double factor = NL_FCONST(1.0); + if (tmp != "NOTFOUND") + { + char numfac = *(tmp.right(1).cstr()); + switch (numfac) + { + case 'm': factor = 1e-3; break; + case 'u': factor = 1e-6; break; + case 'n': factor = 1e-9; break; + case 'p': factor = 1e-12; break; + case 'f': factor = 1e-15; break; + case 'a': factor = 1e-18; break; + default: + if (numfac < '0' || numfac > '9') + fatalerror_e("Unknown number factor <%c> in: %s", numfac, entity.cstr()); + } + if (factor != NL_FCONST(1.0)) + tmp = tmp.left(tmp.len() - 1); + return tmp.as_double() * factor; + } + else + { + //netlist().log("Entity %s not found in model %s\n", entity.cstr(), tmp.cstr()); + return defval; + } +} + // ---------------------------------------------------------------------------------------- // Sources // ---------------------------------------------------------------------------------------- diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h index e837c4d27e2..2c6d341913c 100644 --- a/src/emu/netlist/nl_setup.h +++ b/src/emu/netlist/nl_setup.h @@ -190,6 +190,11 @@ namespace netlist void print_stats() const; + /* static support functions */ + + static const pstring model_value_str(const pstring &model_str, const pstring &entity, const pstring defval); + static nl_double model_value(const pstring &model_str, const pstring &entity, const nl_double defval); + protected: private: diff --git a/src/emu/netlist/solver/nld_solver.c b/src/emu/netlist/solver/nld_solver.c index e8ba510a888..82267608eaa 100644 --- a/src/emu/netlist/solver/nld_solver.c +++ b/src/emu/netlist/solver/nld_solver.c @@ -266,12 +266,12 @@ void matrix_solver_t::solve_base(C *p) ATTR_HOT nl_double matrix_solver_t::solve() { - netlist_time now = netlist().time(); - netlist_time delta = now - m_last_step; + const netlist_time now = netlist().time(); + const netlist_time delta = now - m_last_step; // We are already up to date. Avoid oscillations. // FIXME: Make this a parameter! - if (delta < netlist_time::from_nsec(1)) + if (delta < netlist_time::from_nsec(1)) // 20000 return -1.0; /* update all terminals for new time step */ @@ -428,8 +428,8 @@ matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const int gs_thre } else { - //typedef matrix_solver_SOR_t solver_GS; - typedef matrix_solver_GMRES_t solver_GS; + typedef matrix_solver_SOR_t solver_GS; + //typedef matrix_solver_GMRES_t solver_GS; return palloc(solver_GS, &m_params, size); } } diff --git a/src/mame/audio/irem.c b/src/mame/audio/irem.c index c25305148b4..6a403a184fd 100644 --- a/src/mame/audio/irem.c +++ b/src/mame/audio/irem.c @@ -19,6 +19,8 @@ irem_audio_device::irem_audio_device(const machine_config &mconfig, const char * device_sound_interface(mconfig, *this), m_port1(0), m_port2(0) + //m_ay_45L(*this, "ay_45l"), + //m_ay_45M(*this, "ay_45m") { } @@ -40,8 +42,14 @@ void irem_audio_device::device_start() { m_adpcm1 = machine().device("msm1"); m_adpcm2 = machine().device("msm2"); - m_ay1 = machine().device("ay1"); - m_ay2 = machine().device("ay2"); + m_ay_45L = machine().device("ay_45l"); + m_ay_45M = machine().device("ay_45m"); + + m_audio_BD = machine().device("snd_nl:ibd"); + m_audio_SD = machine().device("snd_nl:isd"); + m_audio_OH = machine().device("snd_nl:ioh"); + m_audio_CH = machine().device("snd_nl:ich"); + m_audio_SINH = machine().device("snd_nl:sinh"); save_item(NAME(m_port1)); save_item(NAME(m_port2)); @@ -90,17 +98,17 @@ WRITE8_MEMBER( irem_audio_device::m6803_port2_w ) { /* PSG 0 or 1? */ if (m_port2 & 0x08) - m_ay1->address_w(space, 0, m_port1); + m_ay_45M->address_w(space, 0, m_port1); if (m_port2 & 0x10) - m_ay2->address_w(space, 0, m_port1); + m_ay_45L->address_w(space, 0, m_port1); } else { /* PSG 0 or 1? */ if (m_port2 & 0x08) - m_ay1->data_w(space, 0, m_port1); + m_ay_45M->data_w(space, 0, m_port1); if (m_port2 & 0x10) - m_ay2->data_w(space, 0, m_port1); + m_ay_45L->data_w(space, 0, m_port1); } } m_port2 = data; @@ -118,15 +126,20 @@ READ8_MEMBER( irem_audio_device::m6803_port1_r ) { /* PSG 0 or 1? */ if (m_port2 & 0x08) - return m_ay1->data_r(space, 0); + return m_ay_45M->data_r(space, 0); if (m_port2 & 0x10) - return m_ay2->data_r(space, 0); + return m_ay_45L->data_r(space, 0); return 0xff; } READ8_MEMBER( irem_audio_device::m6803_port2_r ) { + /* + * Pin21, 6803 (Port 21) tied with 4.7k to +5V + * + */ + printf("port2 read\n"); return 0; } @@ -138,7 +151,7 @@ READ8_MEMBER( irem_audio_device::m6803_port2_r ) * *************************************/ -WRITE8_MEMBER( irem_audio_device::ay8910_0_portb_w ) +WRITE8_MEMBER( irem_audio_device::ay8910_45M_portb_w ) { /* bits 2-4 select MSM5205 clock & 3b/4b playback mode */ m_adpcm1->playmode_w((data >> 2) & 7); @@ -152,15 +165,19 @@ WRITE8_MEMBER( irem_audio_device::ay8910_0_portb_w ) } -WRITE8_MEMBER( irem_audio_device::ay8910_1_porta_w ) +WRITE8_MEMBER( irem_audio_device::ay8910_45L_porta_w ) { /* - * 45L 21 IOA0 ==> 8D + * 45L 21 IOA0 ==> BD * 45L 20 IOA1 ==> SD * 45L 19 IOA2 ==> OH * 45L 18 IOA3 ==> CH * */ + m_audio_BD->write_line(data & 0x01 ? 1: 0); + m_audio_SD->write_line(data & 0x02 ? 1: 0); + m_audio_OH->write_line(data & 0x04 ? 1: 0); + m_audio_CH->write_line(data & 0x08 ? 1: 0); #ifdef MAME_DEBUG if (data & 0x0f) popmessage("analog sound %x",data&0x0f); #endif @@ -362,7 +379,118 @@ static ADDRESS_MAP_START( irem_sound_portmap, AS_IO, 8, driver_device ) AM_RANGE(M6801_PORT2, M6801_PORT2) AM_DEVREADWRITE("irem_audio", irem_audio_device, m6803_port2_r, m6803_port2_w) ADDRESS_MAP_END +/* + * Original recordings: + * + * https://www.youtube.com/watch?v=Hr1wZpwP7R4 + * + * This is not an original recording ("drums added") + * + * https://www.youtube.com/watch?v=aarl0xfBQf0 + * + */ +#define USE_FRONTIERS 1 +#define USE_FIXED_STV 1 +#include "nl_kidniki.c" + +NETLIST_START(kidniki_interface) +#if 0 + SOLVER(Solver, 12000) + PARAM(Solver.ACCURACY, 1e-8) + PARAM(Solver.NR_LOOPS, 300) + PARAM(Solver.GS_LOOPS, 2) +#else + SOLVER(Solver, 12000) + PARAM(Solver.ACCURACY, 1e-8) + PARAM(Solver.NR_LOOPS, 300) + PARAM(Solver.GS_LOOPS, 2) + PARAM(Solver.GS_THRESHOLD, 99) +#endif + //PARAM(Solver.GS_THRESHOLD, 99) // Force Gaussian elimination here + PARAM(Solver.SOR_FACTOR, 1.05) + //FIXME proper models! + NET_MODEL(".model 2SC945 NPN(Is=2.04f Xti=3 Eg=1.11 Vaf=6 Bf=400 Ikf=20m Xtb=1.5 Br=3.377 Rc=1 Cjc=1p Mjc=.3333 Vjc=.75 Fc=.5 Cje=25p Mje=.3333 Vje=.75 Tr=450n Tf=20n Itf=0 Vtf=0 Xtf=0 VCEO=45V ICrating=150M MFG=Toshiba)") + NET_MODEL(".model 1S1588 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)") + + LOCAL_SOURCE(kidniki_schematics) + + /* + * Workaround: The simplified opamp model does not correctly + * model the internals of the inputs. + */ + + ANALOG_INPUT(VWORKAROUND, 2.061) + RES(RWORKAROUND, RES_K(27)) + NET_C(VWORKAROUND.Q, RWORKAROUND.1) + NET_C(XU1.6, RWORKAROUND.2) + + ANALOG_INPUT(I_V5, 5) + //ANALOG_INPUT(I_V0, 0) + ALIAS(I_V0.Q, GND) + + /* AY 8910 internal resistors */ + + RES(R_AY45L_A, 1000) + RES(R_AY45L_B, 1000) + RES(R_AY45L_C, 1000) + + RES(R_AY45M_A, 1000) + RES(R_AY45M_B, 1000) + RES(R_AY45M_C, 1000) + + NET_C(I_V5, R_AY45L_A.1, R_AY45L_B.1, R_AY45L_C.1, R_AY45M_A.1, R_AY45M_B.1, R_AY45M_C.1) + NET_C(R_AY45L_A.2, R_AY45L_B.2, R_AY45M_A.2, R_AY45M_B.2, R_AY45M_C.2) + + ALIAS(I_SOUNDIC0, R_AY45L_C.2) + ALIAS(I_SOUND0, R_AY45L_A.2) + + /* On M62 boards with pcb pictures available + * D6 is missing, although the pcb print exists. + * We are replacing this with a 10m Resistor. + */ + TTL_INPUT(SINH, 1) +#if 0 + DIODE(D6, "1N914") + NET_C(D6.K, SINH) + ALIAS(I_SINH0, D6.A) +#else + RES(SINH_DUMMY, RES_M(10)) + NET_C(SINH_DUMMY.1, SINH) + ALIAS(I_SINH0, SINH_DUMMY.2) +#endif + + TTL_INPUT(I_SD0, 1) + //CLOCK(I_SD0, 5) + TTL_INPUT(I_BD0, 1) + //CLOCK(I_BD0, 5) + TTL_INPUT(I_CH0, 1) + //CLOCK(I_CH0, 2.2 ) + TTL_INPUT(I_OH0, 1) + //CLOCK(I_OH0, 1.0) + ANALOG_INPUT(I_MSM2K0, 0) + ANALOG_INPUT(I_MSM3K0, 0) + + INCLUDE(kidniki_schematics) + + CAP(C26, CAP_U(1)) + RES(R25, 560) + RES(R26, RES_K(47)) + CAP(C29, CAP_U(0.01)) + + NET_C(RV1.2, C26.1) + NET_C(C26.2, R25.1) + NET_C(R25.2, R26.1, C29.1) + NET_C(R26.2, C29.2, GND) + + #if (USE_FRONTIERS) + OPTIMIZE_FRONTIER(C63.2, RES_K(27), RES_K(1)) + OPTIMIZE_FRONTIER(R31.2, RES_K(5.1), 50) + OPTIMIZE_FRONTIER(R29.2, RES_K(2.7), 50) + OPTIMIZE_FRONTIER(R87.2, RES_K(68), 50) + #endif + +NETLIST_END() /************************************* * @@ -381,27 +509,63 @@ static MACHINE_CONFIG_FRAGMENT( irem_audio_base ) MCFG_SOUND_ADD("irem_audio", IREM_AUDIO, 0) - MCFG_SOUND_ADD("ay1", AY8910, XTAL_3_579545MHz/4) /* verified on pcb */ - MCFG_AY8910_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT | AY8910_DISCRETE_OUTPUT) - MCFG_AY8910_RES_LOADS(470, 0, 0) + MCFG_SOUND_ADD("ay_45m", AY8910, XTAL_3_579545MHz/4) /* verified on pcb */ + MCFG_AY8910_OUTPUT_TYPE(AY8910_RESISTOR_OUTPUT) + MCFG_AY8910_RES_LOADS(2000.0, 2000.0, 2000.0) MCFG_AY8910_PORT_A_READ_CB(READ8(driver_device, soundlatch_byte_r)) - MCFG_AY8910_PORT_B_WRITE_CB(DEVWRITE8("irem_audio", irem_audio_device, ay8910_0_portb_w)) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) + MCFG_AY8910_PORT_B_WRITE_CB(DEVWRITE8("irem_audio", irem_audio_device, ay8910_45M_portb_w)) + MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 0) + MCFG_SOUND_ROUTE_EX(1, "snd_nl", 1.0, 1) + MCFG_SOUND_ROUTE_EX(2, "snd_nl", 1.0, 2) - MCFG_SOUND_ADD("ay2", AY8910, XTAL_3_579545MHz/4) /* verified on pcb */ - MCFG_AY8910_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT | AY8910_DISCRETE_OUTPUT) - MCFG_AY8910_RES_LOADS(470, 0, 0) - MCFG_AY8910_PORT_A_WRITE_CB(DEVWRITE8("irem_audio", irem_audio_device, ay8910_1_porta_w)) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) + MCFG_SOUND_ADD("ay_45l", AY8910, XTAL_3_579545MHz/4) /* verified on pcb */ + MCFG_AY8910_OUTPUT_TYPE(AY8910_RESISTOR_OUTPUT) + MCFG_AY8910_RES_LOADS(2000.0, 2000.0, 2000.0) + MCFG_AY8910_PORT_A_WRITE_CB(DEVWRITE8("irem_audio", irem_audio_device, ay8910_45L_porta_w)) + MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 3) + MCFG_SOUND_ROUTE_EX(1, "snd_nl", 1.0, 4) + MCFG_SOUND_ROUTE_EX(2, "snd_nl", 1.0, 5) MCFG_SOUND_ADD("msm1", MSM5205, XTAL_384kHz) /* verified on pcb */ MCFG_MSM5205_VCLK_CB(DEVWRITELINE("irem_audio", irem_audio_device, adpcm_int)) /* interrupt function */ MCFG_MSM5205_PRESCALER_SELECTOR(MSM5205_S96_4B) /* default to 4KHz, but can be changed at run time */ - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) + MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 6) MCFG_SOUND_ADD("msm2", MSM5205, XTAL_384kHz) /* verified on pcb */ MCFG_MSM5205_PRESCALER_SELECTOR(MSM5205_SEX_4B) /* default to 4KHz, but can be changed at run time, slave */ - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) + MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 7) + + /* NETLIST configuration using internal AY8910 resistor values */ + + MCFG_SOUND_ADD("snd_nl", NETLIST_SOUND, 48000) + MCFG_NETLIST_SETUP(kidniki_interface) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) + + MCFG_NETLIST_LOGIC_INPUT("snd_nl", "ibd", "I_BD0.IN", 0, 1) + MCFG_NETLIST_LOGIC_INPUT("snd_nl", "isd", "I_SD0.IN", 0, 1) + MCFG_NETLIST_LOGIC_INPUT("snd_nl", "ich", "I_CH0.IN", 0, 1) + MCFG_NETLIST_LOGIC_INPUT("snd_nl", "ioh", "I_OH0.IN", 0, 1) + MCFG_NETLIST_LOGIC_INPUT("snd_nl", "sinh", "SINH.IN", 0, 1) + + MCFG_NETLIST_STREAM_INPUT("snd_nl", 0, "R_AY45M_A.R") + MCFG_NETLIST_STREAM_INPUT("snd_nl", 1, "R_AY45M_B.R") + MCFG_NETLIST_STREAM_INPUT("snd_nl", 2, "R_AY45M_C.R") + + MCFG_NETLIST_STREAM_INPUT("snd_nl", 3, "R_AY45L_A.R") + MCFG_NETLIST_STREAM_INPUT("snd_nl", 4, "R_AY45L_B.R") + MCFG_NETLIST_STREAM_INPUT("snd_nl", 5, "R_AY45L_C.R") + + + MCFG_NETLIST_STREAM_INPUT("snd_nl", 6, "I_MSM2K0.IN") + MCFG_NETLIST_ANALOG_MULT_OFFSET(5.0/65535.0, 2.5) + MCFG_NETLIST_STREAM_INPUT("snd_nl", 7, "I_MSM3K0.IN") + MCFG_NETLIST_ANALOG_MULT_OFFSET(5.0/65535.0, 2.5) + + //MCFG_NETLIST_STREAM_OUTPUT("snd_nl", 0, "RV1.1") + //MCFG_NETLIST_ANALOG_MULT_OFFSET(30000.0, -35000.0) + MCFG_NETLIST_STREAM_OUTPUT("snd_nl", 0, "R26.1") + MCFG_NETLIST_ANALOG_MULT_OFFSET(30000.0 * 10.0, 0.0) + MACHINE_CONFIG_END MACHINE_CONFIG_FRAGMENT( m52_sound_c_audio ) @@ -416,17 +580,17 @@ MACHINE_CONFIG_FRAGMENT( m52_sound_c_audio ) MCFG_SOUND_ADD("irem_audio", IREM_AUDIO, 0) - MCFG_SOUND_ADD("ay1", AY8910, XTAL_3_579545MHz/4) /* verified on pcb */ + MCFG_SOUND_ADD("ay_45m", AY8910, XTAL_3_579545MHz/4) /* verified on pcb */ MCFG_AY8910_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT | AY8910_DISCRETE_OUTPUT) MCFG_AY8910_RES_LOADS(470, 0, 0) MCFG_AY8910_PORT_A_READ_CB(READ8(driver_device, soundlatch_byte_r)) - MCFG_AY8910_PORT_B_WRITE_CB(DEVWRITE8("irem_audio", irem_audio_device, ay8910_0_portb_w)) + MCFG_AY8910_PORT_B_WRITE_CB(DEVWRITE8("irem_audio", irem_audio_device, ay8910_45M_portb_w)) MCFG_SOUND_ROUTE_EX(0, "filtermix", 1.0, 0) - MCFG_SOUND_ADD("ay2", AY8910, XTAL_3_579545MHz/4) /* verified on pcb */ + MCFG_SOUND_ADD("ay_45l", AY8910, XTAL_3_579545MHz/4) /* verified on pcb */ MCFG_AY8910_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT | AY8910_DISCRETE_OUTPUT) MCFG_AY8910_RES_LOADS(470, 0, 0) - MCFG_AY8910_PORT_A_WRITE_CB(DEVWRITE8("irem_audio", irem_audio_device, ay8910_1_porta_w)) + MCFG_AY8910_PORT_A_WRITE_CB(DEVWRITE8("irem_audio", irem_audio_device, ay8910_45L_porta_w)) MCFG_SOUND_ROUTE_EX(0, "filtermix", 1.0, 1) MCFG_SOUND_ADD("msm1", MSM5205, XTAL_384kHz) /* verified on pcb */ diff --git a/src/mame/audio/irem.h b/src/mame/audio/irem.h index 863fc992c6d..aa59e4e5c63 100644 --- a/src/mame/audio/irem.h +++ b/src/mame/audio/irem.h @@ -2,6 +2,7 @@ // copyright-holders:Couriersud #include "sound/ay8910.h" #include "sound/msm5205.h" +#include "machine/netlist.h" class irem_audio_device : public device_t, public device_sound_interface @@ -15,14 +16,16 @@ public: DECLARE_WRITE8_MEMBER( m6803_port2_w ); DECLARE_READ8_MEMBER( m6803_port1_r ); DECLARE_READ8_MEMBER( m6803_port2_r ); - DECLARE_WRITE8_MEMBER( ay8910_0_portb_w ); - DECLARE_WRITE8_MEMBER( ay8910_1_porta_w ); + DECLARE_WRITE8_MEMBER( ay8910_45M_portb_w ); + DECLARE_WRITE8_MEMBER( ay8910_45L_porta_w ); DECLARE_WRITE8_MEMBER( sound_irq_ack_w ); DECLARE_WRITE8_MEMBER( m52_adpcm_w ); DECLARE_WRITE8_MEMBER( m62_adpcm_w ); void adpcm_int(int st); + netlist_mame_logic_input_t * m_audio_SINH; + protected: // device-level overrides virtual void device_config_complete(); @@ -36,10 +39,18 @@ private: UINT8 m_port1; UINT8 m_port2; - ay8910_device *m_ay1; - ay8910_device *m_ay2; + /* FIXME: using required / optional device would be better */ + // required_device m_ay_45L; + // required_device m_ay_45M; + ay8910_device *m_ay_45L; + ay8910_device *m_ay_45M; msm5205_device *m_adpcm1; msm5205_device *m_adpcm2; + + netlist_mame_logic_input_t * m_audio_BD; + netlist_mame_logic_input_t * m_audio_SD; + netlist_mame_logic_input_t * m_audio_OH; + netlist_mame_logic_input_t * m_audio_CH; }; MACHINE_CONFIG_EXTERN( m52_sound_c_audio ); diff --git a/src/mame/audio/nl_kidniki.c b/src/mame/audio/nl_kidniki.c new file mode 100644 index 00000000000..57abca3176b --- /dev/null +++ b/src/mame/audio/nl_kidniki.c @@ -0,0 +1,427 @@ + +#include "netlist/devices/net_lib.h" + +#ifndef USE_FRONTIERS +#define USE_FRONTIERS 0 +#endif + +#ifndef USE_FIXED_STV +#define USE_FIXED_STV 0 +#endif + +NETLIST_EXTERNAL(LM324_DIP) +NETLIST_EXTERNAL(LM358_DIP) + +#ifndef __PLIB_PREPROCESSOR__ +#define MC14584B_GATE(_name) \ + NET_REGISTER_DEV_X(MC14584B_GATE, _name) +#endif + +NETLIST_START(kidniki_lib) + TRUTHTABLE_START(MC14584B_GATE, 1, 1, 0, "A,B") + TT_HEAD(" A | Q ") + TT_LINE(" 0 | 1 |100") + TT_LINE(" 1 | 0 |100") + TT_FAMILY(".model MC14584B FAMILY(IVL=2.1 IVH=2.7 OVL=0.05 OVH=4.95 ORL=10.0 ORH 10.0)") + TRUTHTABLE_END() +NETLIST_END() + +NETLIST_START(MC14584B_DIP) + MC14584B_GATE(s1) + MC14584B_GATE(s2) + MC14584B_GATE(s3) + MC14584B_GATE(s4) + MC14584B_GATE(s5) + MC14584B_GATE(s6) + + ALIAS( 1, s1.A) + ALIAS( 2, s1.Q) + ALIAS( 3, s2.A) + ALIAS( 4, s2.Q) + ALIAS( 5, s3.A) + ALIAS( 6, s3.Q) + + ALIAS( 8, s4.Q) + ALIAS( 9, s4.A) + ALIAS(10, s5.Q) + ALIAS(11, s5.A) + ALIAS(12, s6.Q) + ALIAS(13, s6.A) +NETLIST_END() + +NETLIST_START(kidniki_schematics) + // EESCHEMA NETLIST VERSION 1.1 (SPICE FORMAT) CREATION DATE: SAT 06 JUN 2015 01:06:26 PM CEST + // TO EXCLUDE A COMPONENT FROM THE SPICE NETLIST ADD [SPICE_NETLIST_ENABLED] USER FIELD SET TO: N + // TO REORDER THE COMPONENT SPICE NODE SEQUENCE ADD [SPICE_NODE_SEQUENCE] USER FIELD AND DEFINE SEQUENCE: 2,1,0 + // SHEET NAME:/ + // IGNORED O_AUDIO0: O_AUDIO0 49 0 + // .END + + LOCAL_SOURCE(kidniki_lib) + + INCLUDE(kidniki_lib) + + CAP(C200, CAP_N(100)) + CAP(C28, CAP_U(1)) + CAP(C31, CAP_N(470)) + CAP(C32, CAP_N(3.3)) + CAP(C33, CAP_U(1)) + CAP(C34, CAP_N(1)) + CAP(C35, CAP_N(1)) + CAP(C36, CAP_N(6.5)) + CAP(C37, CAP_N(22)) + CAP(C38, CAP_N(1)) + CAP(C39, CAP_N(1)) + CAP(C40, CAP_P(12)) + CAP(C41, CAP_U(1)) + CAP(C42, CAP_N(1.2)) + CAP(C43, CAP_N(1.2)) + CAP(C44, CAP_U(1)) + CAP(C45, CAP_N(22)) + CAP(C47, CAP_U(1)) + CAP(C48, CAP_N(470)) + CAP(C49, CAP_N(3.3)) + CAP(C50, CAP_N(22)) + CAP(C51, CAP_N(22)) + CAP(C52, CAP_N(27)) + CAP(C53, CAP_N(27)) + CAP(C56, CAP_N(6.8)) + CAP(C57, CAP_N(6.8)) + CAP(C59, CAP_N(6.8)) + CAP(C60, CAP_N(22)) + CAP(C61, CAP_N(22)) + CAP(C62, CAP_N(6.8)) + CAP(C63, CAP_N(1)) + CAP(C64, CAP_N(68)) + CAP(C65, CAP_N(68)) + CAP(C66, CAP_N(68)) + CAP(C67, CAP_N(15)) + CAP(C68, CAP_N(15)) + CAP(C69, CAP_N(10)) + CAP(C70, CAP_N(22)) + CAP(C72, CAP_N(12)) + CAP(C73, CAP_N(10)) + CAP(C76, CAP_N(68)) + CAP(C77, CAP_N(12)) + + DIODE(D3, "1S1588") + DIODE(D4, "1S1588") + DIODE(D5, "1S1588") + + POT(RV1, RES_K(50)) + + QBJT_EB(Q10, "2SC945") + QBJT_EB(Q3, "2SC945") + QBJT_EB(Q4, "2SC945") + QBJT_EB(Q5, "2SC945") + QBJT_EB(Q6, "2SC945") + QBJT_EB(Q7, "2SC945") + QBJT_EB(Q9, "2SC945") + + SUBMODEL(LM324_DIP,XU1) + SUBMODEL(LM358_DIP,XU2) + + SUBMODEL(MC14584B_DIP, XU3) + + RES(R100, RES_K(560)) + RES(R101, RES_K(150)) + RES(R102, RES_K(150)) + RES(R103, RES_K(470)) + RES(R104, RES_K(22)) + RES(R105, RES_K(470)) + RES(R106, RES_K(150)) + RES(R107, RES_K(150)) + RES(R108, RES_K(560)) + RES(R119, RES_K(22)) + RES(R200, RES_K(100)) + RES(R201, RES_K(100)) + RES(R27, RES_K(6.8)) + RES(R28, RES_K(150)) + RES(R29, RES_K(2.7)) + RES(R30, RES_K(10)) + RES(R31, RES_K(5.1)) + RES(R32, RES_K(4.7)) + RES(R34, RES_K(100)) + RES(R35, RES_K(100)) + RES(R36, RES_K(100)) + RES(R37, RES_K(47)) + RES(R38, 820) + RES(R39, RES_K(22)) + RES(R40, RES_K(10)) + RES(R41, RES_K(10)) + RES(R42, RES_K(150)) + RES(R43, 470) + RES(R44, RES_K(100)) + RES(R45, RES_K(1)) + RES(R46, RES_K(12)) + RES(R48, 470) + RES(R48_2, RES_K(100)) + RES(R49, RES_K(10)) + RES(R50, RES_K(2.2)) + RES(R51, RES_K(150)) + RES(R52, RES_K(100)) + RES(R53, RES_K(100)) + RES(R54, RES_K(680)) + RES(R55, RES_K(510)) + RES(R57, 560) + RES(R58, RES_K(39)) + RES(R59, 560) + RES(R60, RES_K(39)) + RES(R61, RES_K(100)) + RES(R62, RES_K(100)) + RES(R63, RES_K(1)) + RES(R65, RES_K(1)) + RES(R65_1, RES_K(27)) + RES(R66, RES_M(1)) + RES(R67, RES_K(100)) + RES(R68, RES_K(100)) + RES(R69, RES_K(1)) + RES(R70, RES_K(10)) + RES(R71, RES_K(100)) + RES(R72, RES_K(100)) + RES(R73, RES_K(10)) + RES(R74, RES_K(10)) + RES(R75, RES_K(10)) + RES(R76, RES_K(10)) + RES(R81, 220) + RES(R82, RES_M(2.2)) + RES(R83, RES_K(12)) + RES(R84, RES_K(1)) + RES(R85, RES_M(2.2)) + RES(R86, RES_K(10)) + RES(R87, RES_K(68)) + RES(R89, RES_K(22)) + RES(R90, RES_K(390)) + RES(R91, RES_K(100)) + RES(R92, RES_K(22)) + RES(R93, RES_K(1)) + RES(R94, RES_K(22)) + RES(R95, RES_K(330)) + RES(R96, RES_K(150)) + RES(R97, RES_K(150)) + RES(R98, RES_K(650)) + + #if USE_FIXED_STV + ANALOG_INPUT(STV, 2) + #else + RES(R78, RES_K(3.3)) + RES(R77, RES_K(2.2)) + CAP(C58, CAP_U(47)) + #endif + + NET_C(R95.1, XU3.2, R96.2) + NET_C(R95.2, XU3.1, C69.1) + NET_C(XU3.3, R103.2, C73.1) + NET_C(XU3.4, R103.1, R102.2) + NET_C(XU3.5, R105.2, C72.1) + NET_C(XU3.6, R105.1, R106.2) + #if USE_FIXED_STV + //FIXME: We should have a NET_C_REMOVE + NET_C(/*XU3.7,*/ C69.2, C73.2, C72.2, C77.2, C67.2, C68.2, R65.2, R38.2, XU1.11, R54.2, Q4.E, R63.2, C47.2, R72.2, R67.2, R71.2, R68.2, C48.2, R46.2, C28.1, C32.1, R43.2, XU2.4, C56.1, C52.1,/* R77.2, C58.1, */ R48.2, R93.2, R94.2, R119.2, R104.2, R53.2, R34.2, R81.2, R92.2, R89.2, C33.1, R37.2, R36.1, R91.1, I_V0.Q, RV1.3) + #else + NET_C(/*XU3.7,*/ C69.2, C73.2, C72.2, C77.2, C67.2, C68.2, R65.2, R38.2, XU1.11, R54.2, Q4.E, R63.2, C47.2, R72.2, R67.2, R71.2, R68.2, C48.2, R46.2, C28.1, C32.1, R43.2, XU2.4, C56.1, C52.1, R77.2, C58.1, R48.2, R93.2, R94.2, R119.2, R104.2, R53.2, R34.2, R81.2, R92.2, R89.2, C33.1, R37.2, R36.1, R91.1, I_V0.Q, RV1.3) + #endif + NET_C(XU3.8, R108.1, R107.2) + NET_C(XU3.9, R108.2, C77.1) + NET_C(XU3.10, R100.1, R101.2) + NET_C(XU3.11, R100.2, C67.1) + NET_C(XU3.12, R98.1, R97.2) + NET_C(XU3.13, R98.2, C68.1) + #if USE_FIXED_STV + NET_C(/*XU3.14,*/ XU1.4, R66.1, R70.1, Q6.C, Q5.C, XU2.8, /* R78.1, */ R86.1, R83.1, Q3.C, I_V5.Q) + #else + NET_C(/*XU3.14,*/ XU1.4, R66.1, R70.1, Q6.C, Q5.C, XU2.8, R78.1, R86.1, R83.1, Q3.C, I_V5.Q) + #endif + NET_C(R96.1, R102.1, R106.1, R107.1, R101.1, R97.1, R65.1, C63.2) + NET_C(C63.1, R65_1.2) + NET_C(R65_1.1, R44.2, C38.2, C40.2, XU1.6) + #if USE_FIXED_STV + NET_C(R30.1, R41.1, R40.1, STV, R76.2, /* R78.2, R77.1, C58.2*/ STV) + #else + NET_C(R30.1, R41.1, R40.1, R76.2, R78.2, R77.1, C58.2) + #endif + NET_C(R30.2, XU1.5) + NET_C(R44.1, C39.1, C40.1, R48_2.2) + NET_C(C38.1, C39.2, R38.1) + NET_C(XU1.1, XU1.2, R39.1, R32.2) + NET_C(XU1.3, C34.1, R41.2) + NET_C(XU1.7, R45.2) + NET_C(XU1.8, XU1.9, R31.2, C36.2) + NET_C(XU1.10, R42.1, C32.2) + NET_C(XU1.12, C49.1, C31.1, R40.2, C61.1, C60.1) + NET_C(XU1.13, R27.1, R28.2) + NET_C(XU1.14, R28.1, R29.2, I_SINH0) + NET_C(R48_2.1, C45.2, R54.1) + NET_C(C45.1, R55.1, Q7.B) + NET_C(R55.2, R90.2, C33.2, R37.1, Q3.E) + NET_C(R45.1, C44.2) + NET_C(C44.1, R66.2, Q4.B) + NET_C(Q4.C, C42.1, C43.1, R46.1, C35.2, D4.K, D5.K) + NET_C(R70.2, R69.2, Q7.C) + NET_C(R63.1, Q7.E) + NET_C(R69.1, C49.2) + NET_C(C42.2, R58.1, D5.A) + NET_C(R58.2, R57.1, C47.1) + NET_C(R57.2, Q6.E) + NET_C(Q6.B, R61.1) + NET_C(C50.1, R67.1, R61.2) + NET_C(C50.2, R72.1, I_OH0.Q) + NET_C(C51.1, R68.1, R62.2) + NET_C(C51.2, R71.1, I_CH0.Q) + NET_C(R62.1, Q5.B) + NET_C(Q5.E, R59.2) + NET_C(R60.1, C43.2, D4.A) + NET_C(R60.2, R59.1, C48.1) + NET_C(C35.1, C34.2, R39.2) + NET_C(R32.1, C31.2) + NET_C(R27.2, C28.2) + NET_C(R29.1, R31.1, R50.2, R49.1, RV1.1) + NET_C(R42.2, R51.1, C36.1) + NET_C(R51.2, C41.1) + NET_C(C41.2, R43.1, I_SOUNDIC0) + NET_C(XU2.1, XU2.2, R73.1) + NET_C(XU2.3, R76.1, C200.2) + NET_C(XU2.5, C56.2, R75.1) + NET_C(XU2.6, XU2.7, R50.1, C53.2) + NET_C(R75.2, R74.1, C53.1) + NET_C(R74.2, C52.2, R73.2) + NET_C(R49.2, R48.1, I_SOUND0) + NET_C(Q9.E, R81.1) + NET_C(Q9.C, R84.2, R83.2, R82.1, C59.1) + NET_C(Q9.B, R82.2, C62.1) + NET_C(Q10.E, R93.1) + NET_C(Q10.C, R87.2, R86.2, R85.1, C76.1) + NET_C(Q10.B, R85.2, C64.1) + NET_C(R84.1, C61.2) + NET_C(C60.2, R87.1) + NET_C(C64.2, C65.1, R94.1, D3.K) + NET_C(C65.2, C66.1, R119.1) + NET_C(C66.2, C76.2, R104.1) + NET_C(R53.1, R52.2, C37.1) + NET_C(R34.1, C37.2, I_BD0.Q) + NET_C(R52.1, D3.A) + NET_C(R92.1, C62.2, C57.1) + NET_C(R89.1, C57.2, C59.2, R90.1) + NET_C(Q3.B, R35.1) + NET_C(R35.2, R36.2, C70.1) + NET_C(R91.2, C70.2, I_SD0.Q) + NET_C(I_MSM3K0.Q, R200.2) + NET_C(I_MSM2K0.Q, R201.2) + NET_C(R200.1, R201.1, C200.1) +NETLIST_END() + +NETLIST_START(opamp) + + /* Opamp model from + * + * http://www.ecircuitcenter.com/Circuits/opmodel1/opmodel1.htm + * + * Bandwidth 1Mhz + * + */ + + /* Terminal definitions for calling netlists */ + + ALIAS(PLUS, G1.IP) // Positive input + ALIAS(MINUS, G1.IN) // Negative input + ALIAS(OUT, EBUF.OP) // Opamp output ... + + ALIAS(GND, EBUF.ON) // GND terminal + ALIAS(VCC, DUMMY.I) // VCC terminal + DUMMY_INPUT(DUMMY) + + /* The opamp model */ + + VCCS(G1) + PARAM(G1.RI, RES_K(1000)) +#if 1 + PARAM(G1.G, 100) // typical OP-AMP amplification 100 * 1000 = 100000 + RES(RP1, 1000) + CAP(CP1, 1.59e-5) // <== change to 1.59e-3 for 10Khz bandwidth +#else + PARAM(G1.G, 1) // typical OP-AMP amplification 100 * 1000 = 100000 + RES(RP1, 100000) + CAP(CP1, 1.59e-7) // <== change to 1.59e-3 for 10Khz bandwidth +#endif + VCVS(EBUF) + PARAM(EBUF.RO, 50) + PARAM(EBUF.G, 1) + +// PARAM(EBUF.RI, 1e20) +// NET_C(EBUF.ON, GND) + + NET_C(G1.ON, GND) + NET_C(RP1.2, GND) + NET_C(CP1.2, GND) + NET_C(EBUF.IN, GND) + + NET_C(RP1.1, G1.OP) + NET_C(CP1.1, RP1.1) + + DIODE(DP,"1N914") + DIODE(DN,"1N914") + + NET_C(DP.K, VCC) +#if 1 + NET_C(DP.A, DN.K, RP1.1) +#else + RES(RDP, 1000) + RES(RDN, 1000) + NET_C(RDP.1, DP.A) + NET_C(RDN.1, DN.K) + NET_C(RDP.2, RDN.2, RP1.1) +#endif + NET_C(DN.A, GND) + + NET_C(EBUF.IP, RP1.1) + +NETLIST_END() + +NETLIST_START(LM324_DIP) + SUBMODEL(opamp, op1) + SUBMODEL(opamp, op2) + SUBMODEL(opamp, op3) + SUBMODEL(opamp, op4) + + ALIAS( 1, op1.OUT) + ALIAS( 2, op1.MINUS) + ALIAS( 3, op1.PLUS) + + ALIAS( 7, op2.OUT) + ALIAS( 6, op2.MINUS) + ALIAS( 5, op2.PLUS) + + ALIAS( 8, op3.OUT) + ALIAS( 9, op3.MINUS) + ALIAS(10, op3.PLUS) + + ALIAS(14, op4.OUT) + ALIAS(13, op4.MINUS) + ALIAS(12, op4.PLUS) + + NET_C(op1.GND, op2.GND, op3.GND, op4.GND) + NET_C(op1.VCC, op2.VCC, op3.VCC, op4.VCC) + + ALIAS(11, op1.GND) + ALIAS( 4, op1.VCC) +NETLIST_END() + +NETLIST_START(LM358_DIP) + SUBMODEL(opamp, op1) + SUBMODEL(opamp, op2) + + ALIAS( 1, op1.OUT) + ALIAS( 2, op1.MINUS) + ALIAS( 3, op1.PLUS) + + ALIAS( 7, op2.OUT) + ALIAS( 6, op2.MINUS) + ALIAS( 5, op2.PLUS) + + + NET_C(op1.GND, op2.GND) + NET_C(op1.VCC, op2.VCC) + + ALIAS( 4, op1.GND) + ALIAS( 8, op1.VCC) +NETLIST_END() diff --git a/src/mame/drivers/m62.c b/src/mame/drivers/m62.c index 00c5fbfbc44..7e2b313aecd 100644 --- a/src/mame/drivers/m62.c +++ b/src/mame/drivers/m62.c @@ -71,7 +71,6 @@ other supported games as well. #include "emu.h" #include "cpu/z80/z80.h" -#include "audio/irem.h" #include "includes/iremipt.h" #include "includes/m62.h" diff --git a/src/mame/includes/m62.h b/src/mame/includes/m62.h index 9a508876b61..5b48f4bfaef 100644 --- a/src/mame/includes/m62.h +++ b/src/mame/includes/m62.h @@ -1,5 +1,8 @@ // license:BSD-3-Clause // copyright-holders:smf, David Haywood + +#include "audio/irem.h" + class m62_state : public driver_device { public: @@ -11,7 +14,9 @@ public: m_scrollram(*this, "scrollram"), m_maincpu(*this, "maincpu"), m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette") { } + m_palette(*this, "palette"), + m_audio(*this, "irem_audio") + { } /* memory pointers */ required_shared_ptr m_spriteram; @@ -119,4 +124,5 @@ public: required_device m_maincpu; required_device m_gfxdecode; required_device m_palette; + required_device m_audio; }; diff --git a/src/mame/video/m62.c b/src/mame/video/m62.c index 87b994a0cd1..3f309a9ffb3 100644 --- a/src/mame/video/m62.c +++ b/src/mame/video/m62.c @@ -292,7 +292,7 @@ void m62_state::register_savestate( ) WRITE8_MEMBER(m62_state::m62_flipscreen_w) { /* screen flip is handled both by software and hardware */ - data ^= ~ioport("DSW2")->read() & 1; + data ^= ((~ioport("DSW2")->read()) & 1); m_flipscreen = data & 0x01; if (m_flipscreen) @@ -302,6 +302,10 @@ WRITE8_MEMBER(m62_state::m62_flipscreen_w) coin_counter_w(machine(), 0, data & 2); coin_counter_w(machine(), 1, data & 4); + + /* Sound inhibit ... connected to D6 which is not present on any board */ + if (m_audio->m_audio_SINH != NULL) + m_audio->m_audio_SINH->write((data >> 3) & 1); } WRITE8_MEMBER(m62_state::m62_hscroll_low_w)