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.
This commit is contained in:
couriersud 2015-06-20 19:16:53 +02:00
parent ff2bb580ce
commit 00150aec1c
14 changed files with 808 additions and 98 deletions

View File

@ -28,7 +28,7 @@
netlist_mame_analog_input_t::static_set_name(*device, _name); netlist_mame_analog_input_t::static_set_name(*device, _name);
#define MCFG_NETLIST_ANALOG_MULT_OFFSET(_mult, _offset) \ #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) \ #define MCFG_NETLIST_ANALOG_OUTPUT(_basetag, _tag, _IN, _class, _member, _class_tag) \
MCFG_DEVICE_ADD(_basetag ":" _tag, NETLIST_ANALOG_OUTPUT, 0) \ MCFG_DEVICE_ADD(_basetag ":" _tag, NETLIST_ANALOG_OUTPUT, 0) \
@ -425,16 +425,9 @@ public:
inline void write(const UINT32 val) inline void write(const UINT32 val)
{ {
if (is_sound_device()) const UINT32 v = (val >> m_shift) & m_mask;
{ if (v != m_param->Value())
update_to_current_time(); synchronize(0, v);
m_param->setTo((val >> m_shift) & m_mask);
}
else
{
// FIXME: use device timer ....
m_param->setTo((val >> m_shift) & m_mask);
}
} }
inline DECLARE_INPUT_CHANGED_MEMBER(input_changed) { write(newval); } inline DECLARE_INPUT_CHANGED_MEMBER(input_changed) { write(newval); }
@ -447,6 +440,12 @@ public:
protected: protected:
// device-level overrides // device-level overrides
virtual void device_start(); 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: private:
netlist::param_int_t *m_param; netlist::param_int_t *m_param;
@ -575,7 +574,7 @@ public:
ATTR_COLD void reset() ATTR_COLD void reset()
{ {
m_cur = 0; m_cur = 0.0;
m_last_pos = 0; m_last_pos = 0;
m_last_buffer = netlist::netlist_time::zero; m_last_buffer = netlist::netlist_time::zero;
} }
@ -587,21 +586,29 @@ public:
netlist().error("sound %s: exceeded BUFSIZE\n", name().cstr()); netlist().error("sound %s: exceeded BUFSIZE\n", name().cstr());
while (m_last_pos < pos ) 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() 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()); 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) ATTR_HOT void buffer_reset(netlist::netlist_time upto)
{ {
m_last_pos = 0; m_last_pos = 0;
m_last_buffer = upto; m_last_buffer = upto;
m_cur = 0.0;
} }
netlist::param_int_t m_channel; netlist::param_int_t m_channel;
@ -612,7 +619,7 @@ public:
private: private:
netlist::analog_input_t m_in; netlist::analog_input_t m_in;
stream_sample_t m_cur; double m_cur;
int m_last_pos; int m_last_pos;
netlist::netlist_time m_last_buffer; netlist::netlist_time m_last_buffer;
}; };
@ -677,7 +684,7 @@ public:
{ {
if (m_buffer[i] == NULL) if (m_buffer[i] == NULL)
break; // stop, called outside of stream_update 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_param[i]->setTo(v * m_param_mult[i].Value() + m_param_offset[i].Value());
} }
m_pos++; m_pos++;

View File

@ -68,7 +68,8 @@
#ifdef RES_R #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 #endif
#define RES_R(res) ((double)(res)) #define RES_R(res) ((double)(res))

View File

@ -35,6 +35,9 @@
#define TT_LINE(_x) \ #define TT_LINE(_x) \
ttd->m_desc.add(_x); ttd->m_desc.add(_x);
#define TT_FAMILY(_x) \
ttd->m_family = netlist::logic_family_desc_t::from_model(_x);
#define TRUTHTABLE_END() \ #define TRUTHTABLE_END() \
setup.factory().register_device(ttd); \ setup.factory().register_device(ttd); \
} }
@ -294,9 +297,17 @@ class netlist_base_factory_truthtable_t : public base_factory_t
public: public:
netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname, netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname,
const pstring &def_param) 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; pstring_list_t m_desc;
const logic_family_desc_t * m_family;
}; };
@ -313,6 +324,7 @@ public:
{ {
typedef nld_truthtable_t<m_NI, m_NO, has_state> tt_type; typedef nld_truthtable_t<m_NI, m_NO, has_state> tt_type;
device_t *r = palloc(tt_type, &m_ttbl, m_desc); device_t *r = palloc(tt_type, &m_ttbl, m_desc);
r->set_logic_family(m_family);
//r->init(setup, name); //r->init(setup, name);
return r; return r;
} }

View File

@ -46,7 +46,7 @@ fatalerror_e::fatalerror_e(const char *format, va_list ap)
class logic_family_ttl_t : public logic_family_desc_t class logic_family_ttl_t : public logic_family_desc_t
{ {
public: public:
logic_family_ttl_t() logic_family_ttl_t() : logic_family_desc_t()
{ {
m_low_thresh_V = 0.8; m_low_thresh_V = 0.8;
m_high_thresh_V = 2.0; m_high_thresh_V = 2.0;
@ -55,6 +55,7 @@ public:
m_high_V = 4.0; m_high_V = 4.0;
m_R_low = 1.0; m_R_low = 1.0;
m_R_high = 130.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 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 class logic_family_cd4000_t : public logic_family_desc_t
{ {
public: public:
logic_family_cd4000_t() logic_family_cd4000_t() : logic_family_desc_t()
{ {
m_low_thresh_V = 0.8; m_low_thresh_V = 0.8;
m_high_thresh_V = 2.0; 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 - these depend on sinked/sourced current. Values should be suitable for typical applications.
m_low_V = 0.1; m_low_V = 0.05;
m_high_V = 4.0; m_high_V = 4.95;
m_R_low = 1.0; m_R_low = 10.0;
m_R_high = 130.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 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_TTL = logic_family_ttl_t();
const logic_family_desc_t &netlist_family_CD4000 = logic_family_cd4000_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 // 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) 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); init_object(anetlist, name);
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF) #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 ATTR_COLD nl_double param_model_t::model_value(const pstring &entity, const nl_double defval) const
{ {
pstring tmp = this->Value(); return setup_t::model_value(this->Value(), entity, defval);
// .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;
}
} }
} } // namespace
NETLIB_NAMESPACE_DEVICES_START() NETLIB_NAMESPACE_DEVICES_START()

View File

@ -304,6 +304,7 @@ namespace netlist
class setup_t; class setup_t;
class netlist_t; class netlist_t;
class core_device_t; class core_device_t;
class param_model_t;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// netlist_output_family_t // netlist_output_family_t
@ -312,6 +313,7 @@ namespace netlist
class logic_family_desc_t class logic_family_desc_t
{ {
public: public:
logic_family_desc_t() : m_is_static(false) {}
virtual ~logic_family_desc_t() {} virtual ~logic_family_desc_t() {}
virtual devices::nld_base_d_to_a_proxy *create_d_a_proxy(logic_output_t *proxied) const = 0; 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_high_V;
nl_double m_R_low; nl_double m_R_low;
nl_double m_R_high; nl_double m_R_high;
bool m_is_static;
static const logic_family_desc_t *from_model(const pstring &model);
}; };
class logic_family_t class logic_family_t
@ -986,6 +992,7 @@ namespace netlist
/* these should be cached! */ /* these should be cached! */
ATTR_COLD nl_double model_value(const pstring &entity, const nl_double defval = 0.0) const; 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; ATTR_COLD const pstring model_type() const;
private: private:

View File

@ -847,6 +847,64 @@ void setup_t::print_stats() const
#endif #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 // Sources
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------

View File

@ -190,6 +190,11 @@ namespace netlist
void print_stats() const; 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: protected:
private: private:

View File

@ -266,12 +266,12 @@ void matrix_solver_t::solve_base(C *p)
ATTR_HOT nl_double matrix_solver_t::solve() ATTR_HOT nl_double matrix_solver_t::solve()
{ {
netlist_time now = netlist().time(); const netlist_time now = netlist().time();
netlist_time delta = now - m_last_step; const netlist_time delta = now - m_last_step;
// We are already up to date. Avoid oscillations. // We are already up to date. Avoid oscillations.
// FIXME: Make this a parameter! // FIXME: Make this a parameter!
if (delta < netlist_time::from_nsec(1)) if (delta < netlist_time::from_nsec(1)) // 20000
return -1.0; return -1.0;
/* update all terminals for new time step */ /* 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 else
{ {
//typedef matrix_solver_SOR_t<m_N,_storage_N> solver_GS; typedef matrix_solver_SOR_t<m_N,_storage_N> solver_GS;
typedef matrix_solver_GMRES_t<m_N,_storage_N> solver_GS; //typedef matrix_solver_GMRES_t<m_N,_storage_N> solver_GS;
return palloc(solver_GS, &m_params, size); return palloc(solver_GS, &m_params, size);
} }
} }

View File

@ -19,6 +19,8 @@ irem_audio_device::irem_audio_device(const machine_config &mconfig, const char *
device_sound_interface(mconfig, *this), device_sound_interface(mconfig, *this),
m_port1(0), m_port1(0),
m_port2(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<msm5205_device>("msm1"); m_adpcm1 = machine().device<msm5205_device>("msm1");
m_adpcm2 = machine().device<msm5205_device>("msm2"); m_adpcm2 = machine().device<msm5205_device>("msm2");
m_ay1 = machine().device<ay8910_device>("ay1"); m_ay_45L = machine().device<ay8910_device>("ay_45l");
m_ay2 = machine().device<ay8910_device>("ay2"); m_ay_45M = machine().device<ay8910_device>("ay_45m");
m_audio_BD = machine().device<netlist_mame_logic_input_t>("snd_nl:ibd");
m_audio_SD = machine().device<netlist_mame_logic_input_t>("snd_nl:isd");
m_audio_OH = machine().device<netlist_mame_logic_input_t>("snd_nl:ioh");
m_audio_CH = machine().device<netlist_mame_logic_input_t>("snd_nl:ich");
m_audio_SINH = machine().device<netlist_mame_logic_input_t>("snd_nl:sinh");
save_item(NAME(m_port1)); save_item(NAME(m_port1));
save_item(NAME(m_port2)); save_item(NAME(m_port2));
@ -90,17 +98,17 @@ WRITE8_MEMBER( irem_audio_device::m6803_port2_w )
{ {
/* PSG 0 or 1? */ /* PSG 0 or 1? */
if (m_port2 & 0x08) 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) if (m_port2 & 0x10)
m_ay2->address_w(space, 0, m_port1); m_ay_45L->address_w(space, 0, m_port1);
} }
else else
{ {
/* PSG 0 or 1? */ /* PSG 0 or 1? */
if (m_port2 & 0x08) 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) if (m_port2 & 0x10)
m_ay2->data_w(space, 0, m_port1); m_ay_45L->data_w(space, 0, m_port1);
} }
} }
m_port2 = data; m_port2 = data;
@ -118,15 +126,20 @@ READ8_MEMBER( irem_audio_device::m6803_port1_r )
{ {
/* PSG 0 or 1? */ /* PSG 0 or 1? */
if (m_port2 & 0x08) if (m_port2 & 0x08)
return m_ay1->data_r(space, 0); return m_ay_45M->data_r(space, 0);
if (m_port2 & 0x10) if (m_port2 & 0x10)
return m_ay2->data_r(space, 0); return m_ay_45L->data_r(space, 0);
return 0xff; return 0xff;
} }
READ8_MEMBER( irem_audio_device::m6803_port2_r ) READ8_MEMBER( irem_audio_device::m6803_port2_r )
{ {
/*
* Pin21, 6803 (Port 21) tied with 4.7k to +5V
*
*/
printf("port2 read\n");
return 0; 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 */ /* bits 2-4 select MSM5205 clock & 3b/4b playback mode */
m_adpcm1->playmode_w((data >> 2) & 7); 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 20 IOA1 ==> SD
* 45L 19 IOA2 ==> OH * 45L 19 IOA2 ==> OH
* 45L 18 IOA3 ==> CH * 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 #ifdef MAME_DEBUG
if (data & 0x0f) popmessage("analog sound %x",data&0x0f); if (data & 0x0f) popmessage("analog sound %x",data&0x0f);
#endif #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) AM_RANGE(M6801_PORT2, M6801_PORT2) AM_DEVREADWRITE("irem_audio", irem_audio_device, m6803_port2_r, m6803_port2_w)
ADDRESS_MAP_END 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("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_OUTPUT_TYPE(AY8910_RESISTOR_OUTPUT)
MCFG_AY8910_RES_LOADS(470, 0, 0) 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_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(ALL_OUTPUTS, "mono", 0.80) 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_SOUND_ADD("ay_45l", AY8910, XTAL_3_579545MHz/4) /* verified on pcb */
MCFG_AY8910_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT | AY8910_DISCRETE_OUTPUT) MCFG_AY8910_OUTPUT_TYPE(AY8910_RESISTOR_OUTPUT)
MCFG_AY8910_RES_LOADS(470, 0, 0) MCFG_AY8910_RES_LOADS(2000.0, 2000.0, 2000.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(ALL_OUTPUTS, "mono", 0.80) 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_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_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_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_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_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_END
MACHINE_CONFIG_FRAGMENT( m52_sound_c_audio ) 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("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_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT | AY8910_DISCRETE_OUTPUT)
MCFG_AY8910_RES_LOADS(470, 0, 0) MCFG_AY8910_RES_LOADS(470, 0, 0)
MCFG_AY8910_PORT_A_READ_CB(READ8(driver_device, soundlatch_byte_r)) 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_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_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT | AY8910_DISCRETE_OUTPUT)
MCFG_AY8910_RES_LOADS(470, 0, 0) 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_ROUTE_EX(0, "filtermix", 1.0, 1)
MCFG_SOUND_ADD("msm1", MSM5205, XTAL_384kHz) /* verified on pcb */ MCFG_SOUND_ADD("msm1", MSM5205, XTAL_384kHz) /* verified on pcb */

View File

@ -2,6 +2,7 @@
// copyright-holders:Couriersud // copyright-holders:Couriersud
#include "sound/ay8910.h" #include "sound/ay8910.h"
#include "sound/msm5205.h" #include "sound/msm5205.h"
#include "machine/netlist.h"
class irem_audio_device : public device_t, class irem_audio_device : public device_t,
public device_sound_interface public device_sound_interface
@ -15,14 +16,16 @@ public:
DECLARE_WRITE8_MEMBER( m6803_port2_w ); DECLARE_WRITE8_MEMBER( m6803_port2_w );
DECLARE_READ8_MEMBER( m6803_port1_r ); DECLARE_READ8_MEMBER( m6803_port1_r );
DECLARE_READ8_MEMBER( m6803_port2_r ); DECLARE_READ8_MEMBER( m6803_port2_r );
DECLARE_WRITE8_MEMBER( ay8910_0_portb_w ); DECLARE_WRITE8_MEMBER( ay8910_45M_portb_w );
DECLARE_WRITE8_MEMBER( ay8910_1_porta_w ); DECLARE_WRITE8_MEMBER( ay8910_45L_porta_w );
DECLARE_WRITE8_MEMBER( sound_irq_ack_w ); DECLARE_WRITE8_MEMBER( sound_irq_ack_w );
DECLARE_WRITE8_MEMBER( m52_adpcm_w ); DECLARE_WRITE8_MEMBER( m52_adpcm_w );
DECLARE_WRITE8_MEMBER( m62_adpcm_w ); DECLARE_WRITE8_MEMBER( m62_adpcm_w );
void adpcm_int(int st); void adpcm_int(int st);
netlist_mame_logic_input_t * m_audio_SINH;
protected: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete(); virtual void device_config_complete();
@ -36,10 +39,18 @@ private:
UINT8 m_port1; UINT8 m_port1;
UINT8 m_port2; UINT8 m_port2;
ay8910_device *m_ay1; /* FIXME: using required / optional device would be better */
ay8910_device *m_ay2; // required_device<ay8910_device> m_ay_45L;
// required_device<ay8910_device> m_ay_45M;
ay8910_device *m_ay_45L;
ay8910_device *m_ay_45M;
msm5205_device *m_adpcm1; msm5205_device *m_adpcm1;
msm5205_device *m_adpcm2; 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 ); MACHINE_CONFIG_EXTERN( m52_sound_c_audio );

427
src/mame/audio/nl_kidniki.c Normal file
View File

@ -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()

View File

@ -71,7 +71,6 @@ other supported games as well.
#include "emu.h" #include "emu.h"
#include "cpu/z80/z80.h" #include "cpu/z80/z80.h"
#include "audio/irem.h"
#include "includes/iremipt.h" #include "includes/iremipt.h"
#include "includes/m62.h" #include "includes/m62.h"

View File

@ -1,5 +1,8 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:smf, David Haywood // copyright-holders:smf, David Haywood
#include "audio/irem.h"
class m62_state : public driver_device class m62_state : public driver_device
{ {
public: public:
@ -11,7 +14,9 @@ public:
m_scrollram(*this, "scrollram"), m_scrollram(*this, "scrollram"),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"), m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette") { } m_palette(*this, "palette"),
m_audio(*this, "irem_audio")
{ }
/* memory pointers */ /* memory pointers */
required_shared_ptr<UINT8> m_spriteram; required_shared_ptr<UINT8> m_spriteram;
@ -119,4 +124,5 @@ public:
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode; required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette; required_device<palette_device> m_palette;
required_device<irem_audio_device> m_audio;
}; };

View File

@ -292,7 +292,7 @@ void m62_state::register_savestate( )
WRITE8_MEMBER(m62_state::m62_flipscreen_w) WRITE8_MEMBER(m62_state::m62_flipscreen_w)
{ {
/* screen flip is handled both by software and hardware */ /* screen flip is handled both by software and hardware */
data ^= ~ioport("DSW2")->read() & 1; data ^= ((~ioport("DSW2")->read()) & 1);
m_flipscreen = data & 0x01; m_flipscreen = data & 0x01;
if (m_flipscreen) 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(), 0, data & 2);
coin_counter_w(machine(), 1, data & 4); 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) WRITE8_MEMBER(m62_state::m62_hscroll_low_w)