diff --git a/src/emu/netlist/analog/nld_ms_sor_mat.h b/src/emu/netlist/analog/nld_ms_sor_mat.h index 9f5cd01e315..52bbe8e5743 100644 --- a/src/emu/netlist/analog/nld_ms_sor_mat.h +++ b/src/emu/netlist/analog/nld_ms_sor_mat.h @@ -29,9 +29,9 @@ public: , m_gs_fail(0) , m_gs_total(0) { - const char *p = osd_getenv("NETLIST_STATS"); - if (p != NULL) - m_log_stats = (bool) atoi(p); + pstring p = nl_util::environment("NETLIST_STATS"); + if (p != "") + m_log_stats = (bool) p.as_long(); else m_log_stats = false; } diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c index c0c1f9964d7..4b734f30fa8 100644 --- a/src/emu/netlist/analog/nld_solver.c +++ b/src/emu/netlist/analog/nld_solver.c @@ -173,7 +173,6 @@ ATTR_HOT void netlist_matrix_solver_t::update_inputs() } - ATTR_HOT void netlist_matrix_solver_t::update_dynamic() { /* update all non-linear devices */ @@ -465,9 +464,9 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() } // Override log statistics - const char *p = osd_getenv("NL_STATS"); - if (p != NULL) - m_params.m_log_stats = (bool) atoi(p); + pstring p = nl_util::environment("NL_STATS"); + if (p != "") + m_params.m_log_stats = (bool) p.as_long(); else m_params.m_log_stats = (bool) m_log_stats.Value(); diff --git a/src/emu/netlist/devices/nld_4020.c b/src/emu/netlist/devices/nld_4020.c index 01c253694ca..f0e160de8d3 100644 --- a/src/emu/netlist/devices/nld_4020.c +++ b/src/emu/netlist/devices/nld_4020.c @@ -58,7 +58,7 @@ NETLIB_START(4020_sub) NETLIB_RESET(4020_sub) { - m_IP.set_state(netlist_input_t::STATE_INP_HL); + m_IP.set_state(netlist_logic_t::STATE_INP_HL); m_cnt = 0; } diff --git a/src/emu/netlist/devices/nld_74107.c b/src/emu/netlist/devices/nld_74107.c index ec46b642eb1..cd0238de829 100644 --- a/src/emu/netlist/devices/nld_74107.c +++ b/src/emu/netlist/devices/nld_74107.c @@ -20,7 +20,7 @@ NETLIB_START(74107Asub) NETLIB_RESET(74107Asub) { - m_clk.set_state(netlist_input_t::STATE_INP_HL); + m_clk.set_state(netlist_logic_t::STATE_INP_HL); m_Q.initial(0); m_QQ.initial(1); diff --git a/src/emu/netlist/devices/nld_74175.c b/src/emu/netlist/devices/nld_74175.c index f66818883c2..a10268bdfda 100644 --- a/src/emu/netlist/devices/nld_74175.c +++ b/src/emu/netlist/devices/nld_74175.c @@ -29,7 +29,7 @@ NETLIB_START(74175_sub) NETLIB_RESET(74175_sub) { - m_CLK.set_state(netlist_input_t::STATE_INP_LH); + m_CLK.set_state(netlist_logic_t::STATE_INP_LH); m_clrq = 0; m_data = 0xFF; } diff --git a/src/emu/netlist/devices/nld_7474.c b/src/emu/netlist/devices/nld_7474.c index 1075a3a6288..1aeb628030f 100644 --- a/src/emu/netlist/devices/nld_7474.c +++ b/src/emu/netlist/devices/nld_7474.c @@ -83,7 +83,7 @@ NETLIB_START(7474sub) NETLIB_RESET(7474sub) { - m_CLK.set_state(netlist_input_t::STATE_INP_LH); + m_CLK.set_state(netlist_logic_t::STATE_INP_LH); m_nextD = 0; /* FIXME: required by pong doubles - need a mechanism to set this from netlist */ diff --git a/src/emu/netlist/devices/nld_7493.c b/src/emu/netlist/devices/nld_7493.c index 902486f09b6..7f5be72fd6a 100644 --- a/src/emu/netlist/devices/nld_7493.c +++ b/src/emu/netlist/devices/nld_7493.c @@ -48,7 +48,7 @@ NETLIB_START(7493ff) NETLIB_RESET(7493ff) { m_reset = 1; - m_I.set_state(netlist_input_t::STATE_INP_HL); + m_I.set_state(netlist_logic_t::STATE_INP_HL); } NETLIB_UPDATE(7493ff) diff --git a/src/emu/netlist/devices/nld_9310.c b/src/emu/netlist/devices/nld_9310.c index f4387f53b05..42787be9157 100644 --- a/src/emu/netlist/devices/nld_9310.c +++ b/src/emu/netlist/devices/nld_9310.c @@ -81,7 +81,7 @@ NETLIB_START(9310_sub) NETLIB_RESET(9310_sub) { - m_CLK.set_state(netlist_input_t::STATE_INP_LH); + m_CLK.set_state(netlist_logic_t::STATE_INP_LH); m_cnt = 0; m_loadq = 1; m_ent = 1; diff --git a/src/emu/netlist/devices/nld_9316.c b/src/emu/netlist/devices/nld_9316.c index b22a6984eac..ce5b05cfbf0 100644 --- a/src/emu/netlist/devices/nld_9316.c +++ b/src/emu/netlist/devices/nld_9316.c @@ -81,7 +81,7 @@ NETLIB_START(9316_sub) NETLIB_RESET(9316_sub) { - m_CLK.set_state(netlist_input_t::STATE_INP_LH); + m_CLK.set_state(netlist_logic_t::STATE_INP_LH); m_cnt = 0; m_loadq = 1; m_ent = 1; diff --git a/src/emu/netlist/devices/nld_system.c b/src/emu/netlist/devices/nld_system.c index e2e07ff821a..6a22a633eba 100644 --- a/src/emu/netlist/devices/nld_system.c +++ b/src/emu/netlist/devices/nld_system.c @@ -198,19 +198,14 @@ ATTR_COLD void nld_d_to_a_proxy::reset() m_is_timestep = m_RV.m_P.net().as_analog().solver()->is_timestep(); } -ATTR_COLD netlist_core_terminal_t &nld_d_to_a_proxy::out() -{ - return m_RV.m_P; -} - ATTR_HOT ATTR_ALIGN void nld_d_to_a_proxy::update() { const int state = INPLOGIC(m_I); if (state != m_last_state) { m_last_state = state; - const nl_double R = state ? m_logic_family->m_R_high : m_logic_family->m_R_low; - const nl_double V = state ? m_logic_family->m_high_V : m_logic_family->m_low_V; + const nl_double R = state ? logic_family().m_R_high : logic_family().m_R_low; + const nl_double V = state ? logic_family().m_high_V : logic_family().m_low_V; // We only need to update the net first if this is a time stepping net if (m_is_timestep) diff --git a/src/emu/netlist/devices/nld_system.h b/src/emu/netlist/devices/nld_system.h index 67164f7123a..1392c6aa12e 100644 --- a/src/emu/netlist/devices/nld_system.h +++ b/src/emu/netlist/devices/nld_system.h @@ -256,19 +256,49 @@ private: UINT8 m_last_state; }; - // ----------------------------------------------------------------------------- -// netdev_a_to_d +// nld_base_proxy // ----------------------------------------------------------------------------- -class nld_a_to_d_proxy : public netlist_device_t +class nld_base_proxy : public netlist_device_t +{ +public: + ATTR_COLD nld_base_proxy(netlist_logic_t &inout_proxied, netlist_core_terminal_t &proxy_inout) + : netlist_device_t() + { + m_logic_family = inout_proxied.logic_family(); + m_term_proxied = &inout_proxied; + m_proxy_term = &proxy_inout; + } + + ATTR_COLD virtual ~nld_base_proxy() {} + + ATTR_COLD netlist_logic_t &term_proxied() const { return *m_term_proxied; } + ATTR_COLD netlist_core_terminal_t &proxy_term() const { return *m_proxy_term; } + +protected: + + ATTR_COLD virtual const netlist_logic_family_desc_t &logic_family() const + { + return *m_logic_family; + } + +private: + const netlist_logic_family_desc_t *m_logic_family; + netlist_logic_t *m_term_proxied; + netlist_core_terminal_t *m_proxy_term; +}; + +// ----------------------------------------------------------------------------- +// nld_a_to_d_proxy +// ----------------------------------------------------------------------------- + +class nld_a_to_d_proxy : public nld_base_proxy { public: ATTR_COLD nld_a_to_d_proxy(netlist_logic_input_t &in_proxied) - : netlist_device_t() + : nld_base_proxy(in_proxied, m_I) { - nl_assert(in_proxied.family() == LOGIC); - m_logic_family = in_proxied.logic_family(); } ATTR_COLD virtual ~nld_a_to_d_proxy() {} @@ -289,34 +319,32 @@ protected: ATTR_HOT ATTR_ALIGN void update() { - if (m_I.Q_Analog() > m_logic_family->m_high_thresh_V) + if (m_I.Q_Analog() > logic_family().m_high_thresh_V) OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(1)); - else if (m_I.Q_Analog() < m_logic_family->m_low_thresh_V) + else if (m_I.Q_Analog() < logic_family().m_low_thresh_V) OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(1)); - //else - // OUTLOGIC(m_Q, m_Q.net().last_Q(), NLTIME_FROM_NS(1)); + else + { + // do nothing + } } private: - const netlist_logic_family_desc_t *m_logic_family; }; // ----------------------------------------------------------------------------- // nld_base_d_to_a_proxy // ----------------------------------------------------------------------------- -class nld_base_d_to_a_proxy : public netlist_device_t +class nld_base_d_to_a_proxy : public nld_base_proxy { public: - ATTR_COLD nld_base_d_to_a_proxy(netlist_logic_output_t &out_proxied) - : netlist_device_t() + ATTR_COLD nld_base_d_to_a_proxy(netlist_logic_output_t &out_proxied, netlist_core_terminal_t &proxy_out) + : nld_base_proxy(out_proxied, proxy_out) { - nl_assert(out_proxied.family() == LOGIC); - m_logic_family = out_proxied.logic_family(); } ATTR_COLD virtual ~nld_base_d_to_a_proxy() {} - ATTR_COLD virtual netlist_core_terminal_t &out() = 0; ATTR_COLD virtual netlist_logic_input_t &in() { return m_I; } protected: @@ -325,60 +353,16 @@ protected: register_input("I", m_I); } - ATTR_COLD virtual const netlist_logic_family_desc_t *logic_family() - { - return m_logic_family; - } - - const netlist_logic_family_desc_t *m_logic_family; - netlist_logic_input_t m_I; private: }; -#if 0 -class nld_d_to_a_proxy : public nld_base_d_to_a_proxy -{ -public: - ATTR_COLD nld_d_to_a_proxy(netlist_output_t &out_proxied) - : nld_base_d_to_a_proxy(out_proxied) - { - } - - ATTR_COLD virtual ~nld_d_to_a_proxy() {} - -protected: - ATTR_COLD void start() - { - nld_base_d_to_a_proxy::start(); - register_output("Q", m_Q); - } - - ATTR_COLD void reset() - { - //m_Q.initial(0); - } - - ATTR_COLD virtual netlist_core_terminal_t &out() - { - return m_Q; - } - - ATTR_HOT ATTR_ALIGN void update() - { - OUTANALOG(m_Q, INPLOGIC(m_I) ? m_logic_family->m_high_V : m_logic_family->m_low_V, NLTIME_FROM_NS(1)); - } - -private: - netlist_analog_output_t m_Q; -}; -#else class nld_d_to_a_proxy : public nld_base_d_to_a_proxy { public: ATTR_COLD nld_d_to_a_proxy(netlist_logic_output_t &out_proxied) - : nld_base_d_to_a_proxy(out_proxied) + : nld_base_d_to_a_proxy(out_proxied, m_RV.m_P) , m_RV(TWOTERM) , m_last_state(-1) , m_is_timestep(false) @@ -392,8 +376,6 @@ protected: ATTR_COLD virtual void reset(); - ATTR_COLD virtual netlist_core_terminal_t &out(); - ATTR_HOT ATTR_ALIGN void update(); private: @@ -402,6 +384,5 @@ private: int m_last_state; bool m_is_timestep; }; -#endif #endif /* NLD_SYSTEM_H_ */ diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index e4d09780399..e61cb65a09c 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -11,8 +11,6 @@ #include "pstring.h" #include "nl_util.h" -#include // FIXME: only included for atof - const netlist_time netlist_time::zero = netlist_time::from_raw(0); class netlist_logic_family_ttl_t : public netlist_logic_family_desc_t @@ -161,7 +159,6 @@ ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev, netlist_base_t::netlist_base_t() : netlist_object_t(NETLIST, GENERIC), m_stop(netlist_time::zero), - // FIXME:: Use a parameter to set this on a schematics per schematics basis m_time(netlist_time::zero), m_queue(*this), m_use_deactivate(0), @@ -429,7 +426,7 @@ ATTR_COLD void netlist_core_device_t::stop_dev() ATTR_HOT ATTR_ALIGN netlist_sig_t netlist_core_device_t::INPLOGIC_PASSIVE(netlist_logic_input_t &inp) { - if (inp.state() != netlist_input_t::STATE_INP_PASSIVE) + if (inp.state() != netlist_logic_t::STATE_INP_PASSIVE) return inp.Q(); else { @@ -476,7 +473,7 @@ ATTR_COLD void netlist_device_t::init(netlist_base_t &anetlist, const pstring &n ATTR_COLD void netlist_device_t::register_sub(const pstring &name, netlist_device_t &dev) { dev.init(netlist(), this->name() + "." + name); - // FIXME: subdevices always first inherit the logic family of the parent + // subdevices always first inherit the logic family of the parent dev.set_logic_family(this->logic_family()); dev.start_dev(); } @@ -505,7 +502,7 @@ ATTR_COLD void netlist_device_t::register_output(const pstring &name, netlist_lo setup().register_object(*this, name, port); } -ATTR_COLD void netlist_device_t::register_output(const pstring &name, netlist_output_t &port) +ATTR_COLD void netlist_device_t::register_output(const pstring &name, netlist_analog_output_t &port) { //port.set_logic_family(this->logic_family()); setup().register_object(*this, name, port); @@ -518,7 +515,7 @@ ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_log m_terminals.add(inp.name()); } -ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_input_t &inp) +ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_analog_input_t &inp) { //inp.set_logic_family(this->logic_family()); setup().register_object(*this, name, inp); @@ -527,7 +524,9 @@ ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_inp ATTR_COLD void netlist_device_t::connect(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2) { - setup().connect(t1, t2); + /* FIXME: These should really first be collected like NET_C connects */ + if (!setup().connect(t1, t2)) + netlist().error("Error connecting %s to %s\n", t1.name().cstr(), t2.name().cstr()); } @@ -614,7 +613,7 @@ ATTR_HOT void netlist_net_t::dec_active(netlist_core_terminal_t &term) railterminal().netdev().dec_active(); } -ATTR_COLD void netlist_net_t::register_railterminal(netlist_output_t &mr) +ATTR_COLD void netlist_net_t::register_railterminal(netlist_core_terminal_t &mr) { nl_assert(m_railterminal == NULL); m_railterminal = &mr; @@ -626,7 +625,7 @@ ATTR_COLD void netlist_net_t::rebuild_list() m_list_active.clear(); for (int i=0; i < m_core_terms.count(); i++) - if (m_core_terms[i]->state() != netlist_input_t::STATE_INP_PASSIVE) + if (m_core_terms[i]->state() != netlist_logic_t::STATE_INP_PASSIVE) m_list_active.add(*m_core_terms[i]); } @@ -663,31 +662,11 @@ ATTR_HOT /*ATTR_ALIGN*/ inline void netlist_net_t::update_devs() netlist_core_terminal_t *p = m_list_active.first(); -#if 0 - switch (m_active) - { - case 2: - p->update_dev(mask); - p = m_list_active.next(p); - case 1: - p->update_dev(mask); - break; - default: - while (p != NULL) - { - p->update_dev(mask); - p = m_list_active.next(p); - } - break; - } -#else while (p != NULL) { p->update_dev(mask); p = m_list_active.next(p); } -#endif - } ATTR_COLD void netlist_net_t::reset() @@ -710,7 +689,7 @@ ATTR_COLD void netlist_net_t::reset() m_core_terms[i]->do_reset(); for (int i=0; i < m_core_terms.count(); i++) - if (m_core_terms[i]->state() != netlist_input_t::STATE_INP_PASSIVE) + if (m_core_terms[i]->state() != netlist_logic_t::STATE_INP_PASSIVE) m_active++; } @@ -720,7 +699,7 @@ ATTR_COLD void netlist_net_t::register_con(netlist_core_terminal_t &terminal) m_core_terms.add(&terminal); - if (terminal.state() != netlist_input_t::STATE_INP_PASSIVE) + if (terminal.state() != netlist_logic_t::STATE_INP_PASSIVE) m_active++; } @@ -909,51 +888,50 @@ ATTR_COLD void netlist_terminal_t::save_register() // net_output_t // ---------------------------------------------------------------------------------------- -netlist_output_t::netlist_output_t(const type_t atype, const family_t afamily) - : netlist_core_terminal_t(atype, afamily) -{ - set_state(STATE_OUT); -} - -ATTR_COLD netlist_output_t::~netlist_output_t() -{ -} - - -ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const pstring &aname) -{ - netlist_core_terminal_t::init_object(dev, aname); - net().init_object(dev.netlist(), aname + ".net"); - net().register_railterminal(*this); -} - // ---------------------------------------------------------------------------------------- // netlist_logic_output_t // ---------------------------------------------------------------------------------------- ATTR_COLD netlist_logic_output_t::netlist_logic_output_t() - : netlist_output_t(OUTPUT, LOGIC), netlist_logic_family_t(), m_proxy(NULL) + : netlist_logic_t(OUTPUT) { + set_state(STATE_OUT); this->set_net(m_my_net); } +ATTR_COLD void netlist_logic_output_t::init_object(netlist_core_device_t &dev, const pstring &aname) +{ + netlist_core_terminal_t::init_object(dev, aname); + net().init_object(dev.netlist(), aname + ".net"); + net().register_railterminal(*this); +} + ATTR_COLD void netlist_logic_output_t::initial(const netlist_sig_t val) { net().as_logic().initial(val); } + // ---------------------------------------------------------------------------------------- // netlist_analog_output_t // ---------------------------------------------------------------------------------------- ATTR_COLD netlist_analog_output_t::netlist_analog_output_t() - : netlist_output_t(OUTPUT, ANALOG), m_proxied_net(NULL) + : netlist_analog_t(OUTPUT), m_proxied_net(NULL) { this->set_net(m_my_net); + set_state(STATE_OUT); net().as_analog().m_cur_Analog = 0.98; } +ATTR_COLD void netlist_analog_output_t::init_object(netlist_core_device_t &dev, const pstring &aname) +{ + netlist_core_terminal_t::init_object(dev, aname); + net().init_object(dev.netlist(), aname + ".net"); + net().register_railterminal(*this); +} + ATTR_COLD void netlist_analog_output_t::initial(const nl_double val) { // FIXME: Really necessary? @@ -1039,7 +1017,7 @@ ATTR_COLD nl_double netlist_param_model_t::model_value(const pstring &entity, co } if (factor != NL_FCONST(1.0)) tmp = tmp.left(tmp.len() - 1); - return (nl_double) atof(tmp.cstr()) * factor; + return tmp.as_double() * factor; } else { diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h index cbf68933717..82307015bbb 100644 --- a/src/emu/netlist/nl_base.h +++ b/src/emu/netlist/nl_base.h @@ -263,7 +263,6 @@ ATTR_COLD virtual const netlist_logic_family_desc_t *default_logic_family() class netlist_net_t; class netlist_analog_net_t; class netlist_logic_net_t; -class netlist_output_t; class netlist_logic_output_t; class netlist_param_t; class netlist_setup_t; @@ -273,7 +272,7 @@ class NETLIB_NAME(gnd); class NETLIB_NAME(solver); class NETLIB_NAME(mainclock); class NETLIB_NAME(netlistparams); -class NETLIB_NAME(base_d_to_a_proxy); +class NETLIB_NAME(base_proxy); // ----------------------------------------------------------------------------- // netlist_output_family_t @@ -530,27 +529,39 @@ private: // netlist_input_t // ----------------------------------------------------------------------------- -class netlist_input_t : public netlist_core_terminal_t +class netlist_logic_t : public netlist_core_terminal_t, public netlist_logic_family_t { public: - ATTR_COLD netlist_input_t(const type_t atype, const family_t afamily) - : netlist_core_terminal_t(atype, afamily) + ATTR_COLD netlist_logic_t(const type_t atype) + : netlist_core_terminal_t(atype, LOGIC), netlist_logic_family_t(), + m_proxy(NULL) { - set_state(STATE_INP_ACTIVE); } - ATTR_HOT inline void inactivate(); - ATTR_HOT inline void activate(); + ATTR_COLD bool has_proxy() const { return (m_proxy != NULL); } + ATTR_COLD nld_base_proxy *get_proxy() const { return m_proxy; } + ATTR_COLD void set_proxy(nld_base_proxy *proxy) { m_proxy = proxy; } protected: - ATTR_COLD virtual void reset() + +private: + nld_base_proxy *m_proxy; +}; + +class netlist_analog_t : public netlist_core_terminal_t +{ +public: + + + ATTR_COLD netlist_analog_t(const type_t atype) + : netlist_core_terminal_t(atype, ANALOG) { - //netlist_core_terminal_t::reset(); - set_state(STATE_INP_ACTIVE); } +protected: + private: }; @@ -558,33 +569,53 @@ private: // netlist_logic_input_t // ----------------------------------------------------------------------------- -class netlist_logic_input_t : public netlist_input_t, public netlist_logic_family_t +class netlist_logic_input_t : public netlist_logic_t { public: ATTR_COLD netlist_logic_input_t() - : netlist_input_t(INPUT, LOGIC), netlist_logic_family_t() + : netlist_logic_t(INPUT) { + set_state(STATE_INP_ACTIVE); } ATTR_HOT inline netlist_sig_t Q() const; ATTR_HOT inline netlist_sig_t last_Q() const; + ATTR_HOT inline void inactivate(); + ATTR_HOT inline void activate(); ATTR_HOT inline void activate_hl(); ATTR_HOT inline void activate_lh(); +protected: + ATTR_COLD virtual void reset() + { + //netlist_core_terminal_t::reset(); + set_state(STATE_INP_ACTIVE); + } + }; // ----------------------------------------------------------------------------- // netlist_analog_input_t // ----------------------------------------------------------------------------- -class netlist_analog_input_t : public netlist_input_t +class netlist_analog_input_t : public netlist_analog_t { public: ATTR_COLD netlist_analog_input_t() - : netlist_input_t(INPUT, ANALOG) { } + : netlist_analog_t(INPUT) + { + set_state(STATE_INP_ACTIVE); + } ATTR_HOT inline nl_double Q_Analog() const; + +protected: + ATTR_COLD virtual void reset() + { + //netlist_core_terminal_t::reset(); + set_state(STATE_INP_ACTIVE); + } }; //#define INPVAL(_x) (_x).Q() @@ -607,7 +638,7 @@ public: ATTR_COLD void register_con(netlist_core_terminal_t &terminal); ATTR_COLD void merge_net(netlist_net_t *othernet); - ATTR_COLD void register_railterminal(netlist_output_t &mr); + ATTR_COLD void register_railterminal(netlist_core_terminal_t &mr); ATTR_HOT inline netlist_logic_net_t & RESTRICT as_logic(); ATTR_HOT inline const netlist_logic_net_t & RESTRICT as_logic() const; @@ -621,7 +652,7 @@ public: ATTR_HOT inline void set_time(const netlist_time &ntime) { m_time = ntime; } ATTR_HOT inline bool isRailNet() const { return !(m_railterminal == NULL); } - ATTR_HOT inline const netlist_core_terminal_t & RESTRICT railterminal() const { return *m_railterminal; } + ATTR_HOT inline netlist_core_terminal_t & railterminal() const { return *m_railterminal; } ATTR_HOT inline void push_to_queue(const netlist_time &delay); ATTR_HOT inline void reschedule_in_queue(const netlist_time &delay); @@ -783,13 +814,12 @@ public: // net_output_t // ----------------------------------------------------------------------------- -class netlist_output_t : public netlist_core_terminal_t +class netlist_logic_output_t : public netlist_logic_t { - NETLIST_PREVENT_COPYING(netlist_output_t) + NETLIST_PREVENT_COPYING(netlist_logic_output_t) public: - ATTR_COLD netlist_output_t(const type_t atype, const family_t afamily); - ATTR_COLD virtual ~netlist_output_t(); + ATTR_COLD netlist_logic_output_t(); ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname); ATTR_COLD virtual void reset() @@ -797,17 +827,6 @@ public: set_state(STATE_OUT); } -private: -}; - - -class netlist_logic_output_t : public netlist_output_t, public netlist_logic_family_t -{ - NETLIST_PREVENT_COPYING(netlist_logic_output_t) -public: - - ATTR_COLD netlist_logic_output_t(); - ATTR_COLD void initial(const netlist_sig_t val); ATTR_HOT inline void set_Q(const netlist_sig_t newQ, const netlist_time &delay) @@ -815,22 +834,23 @@ public: net().as_logic().set_Q(newQ, delay); } - ATTR_COLD bool has_proxy() const { return (m_proxy != NULL); } - ATTR_COLD nld_base_d_to_a_proxy *get_proxy() const { return m_proxy; } - ATTR_COLD void set_proxy(nld_base_d_to_a_proxy *proxy) { m_proxy = proxy; } - private: netlist_logic_net_t m_my_net; - nld_base_d_to_a_proxy *m_proxy; }; -class netlist_analog_output_t : public netlist_output_t +class netlist_analog_output_t : public netlist_analog_t { NETLIST_PREVENT_COPYING(netlist_analog_output_t) public: ATTR_COLD netlist_analog_output_t(); + ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname); + ATTR_COLD virtual void reset() + { + set_state(STATE_OUT); + } + ATTR_COLD void initial(const nl_double val); ATTR_HOT inline void set_Q(const nl_double newQ); @@ -993,7 +1013,7 @@ public: ATTR_HOT inline netlist_sig_t INPLOGIC(const netlist_logic_input_t &inp) const { - nl_assert(inp.state() != netlist_input_t::STATE_INP_PASSIVE); + nl_assert(inp.state() != netlist_logic_t::STATE_INP_PASSIVE); return inp.Q(); } @@ -1062,9 +1082,9 @@ public: ATTR_COLD void register_sub(const pstring &name, netlist_device_t &dev); ATTR_COLD void register_subalias(const pstring &name, netlist_core_terminal_t &term); ATTR_COLD void register_terminal(const pstring &name, netlist_terminal_t &port); - ATTR_COLD void register_output(const pstring &name, netlist_output_t &out); + ATTR_COLD void register_output(const pstring &name, netlist_analog_output_t &out); ATTR_COLD void register_output(const pstring &name, netlist_logic_output_t &out); - ATTR_COLD void register_input(const pstring &name, netlist_input_t &in); + ATTR_COLD void register_input(const pstring &name, netlist_analog_input_t &in); ATTR_COLD void register_input(const pstring &name, netlist_logic_input_t &in); ATTR_COLD void connect(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2); @@ -1167,7 +1187,6 @@ public: template _C *get_first_device() { - //FIXME: for (netlist_device_t * const *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry)) { _C *dev = dynamic_cast<_C *>(*entry); @@ -1296,7 +1315,7 @@ ATTR_HOT inline const netlist_analog_net_t & RESTRICT netlist_net_t::as_analog() } -ATTR_HOT inline void netlist_input_t::inactivate() +ATTR_HOT inline void netlist_logic_input_t::inactivate() { if (EXPECTED(!is_state(STATE_INP_PASSIVE))) { @@ -1305,7 +1324,7 @@ ATTR_HOT inline void netlist_input_t::inactivate() } } -ATTR_HOT inline void netlist_input_t::activate() +ATTR_HOT inline void netlist_logic_input_t::activate() { if (is_state(STATE_INP_PASSIVE)) { diff --git a/src/emu/netlist/nl_factory.h b/src/emu/netlist/nl_factory.h index 3ad4613f499..421bdfefdad 100644 --- a/src/emu/netlist/nl_factory.h +++ b/src/emu/netlist/nl_factory.h @@ -12,11 +12,6 @@ #include "nl_config.h" #include "plists.h" #include "nl_base.h" -#if 0 -#include "nl_time.h" -#include "nl_util.h" -#include "pstate.h" -#endif #include "pstring.h" // ----------------------------------------------------------------------------- diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c index 8fe226a2159..06bc5fb2eb0 100644 --- a/src/emu/netlist/nl_setup.c +++ b/src/emu/netlist/nl_setup.c @@ -15,9 +15,6 @@ #include "analog/nld_solver.h" #include "analog/nld_twoterm.h" -//FIXME: we need a nl_getenv -#include - static NETLIST_START(base) TTL_INPUT(ttlhigh, 1) TTL_INPUT(ttllow, 0) @@ -193,7 +190,14 @@ void netlist_setup_t::register_object(netlist_device_t &dev, const pstring &name { netlist_core_terminal_t &term = dynamic_cast(obj); if (obj.isType(netlist_terminal_t::OUTPUT)) - dynamic_cast(term).init_object(dev, dev.name() + "." + name); + { + if (obj.isFamily(netlist_terminal_t::LOGIC)) + dynamic_cast(term).init_object(dev, dev.name() + "." + name); + else if (obj.isFamily(netlist_terminal_t::ANALOG)) + dynamic_cast(term).init_object(dev, dev.name() + "." + name); + else + netlist().error("Error adding %s %s to terminal list, neither LOGIC nor ANALOG\n", objtype_as_astr(term).cstr(), term.name().cstr()); + } else term.init_object(dev, dev.name() + "." + name); @@ -389,23 +393,24 @@ netlist_param_t *netlist_setup_t::find_param(const pstring ¶m_in, bool requi return ret; } -nld_base_d_to_a_proxy *netlist_setup_t::get_d_a_proxy(netlist_output_t &out) +// FIXME avoid dynamic cast here +nld_base_proxy *netlist_setup_t::get_d_a_proxy(netlist_core_terminal_t &out) { nl_assert(out.isFamily(netlist_terminal_t::LOGIC)); //printf("proxy for %s\n", out.name().cstr());; netlist_logic_output_t &out_cast = dynamic_cast(out); - nld_base_d_to_a_proxy *proxy = out_cast.get_proxy(); + nld_base_proxy *proxy = out_cast.get_proxy(); if (proxy == NULL) { // create a new one ... - proxy = out_cast.logic_family()->create_d_a_proxy(out_cast); + nld_base_d_to_a_proxy *new_proxy = out_cast.logic_family()->create_d_a_proxy(out_cast); pstring x = pstring::sprintf("proxy_da_%s_%d", out.name().cstr(), m_proxy_cnt); m_proxy_cnt++; - register_dev(proxy, x); - proxy->start_dev(); + register_dev(new_proxy, x); + new_proxy->start_dev(); #if 1 /* connect all existing terminals to new net */ @@ -414,23 +419,25 @@ nld_base_d_to_a_proxy *netlist_setup_t::get_d_a_proxy(netlist_output_t &out) { netlist_core_terminal_t *p = out.net().m_core_terms[i]; p->clear_net(); // de-link from all nets ... - connect(proxy->out(), *p); + if (!connect(new_proxy->proxy_term(), *p)) + netlist().error("Error connecting %s to %s\n", new_proxy->proxy_term().name().cstr(), (*p).name().cstr()); } out.net().m_core_terms.clear(); // clear the list #endif - out.net().register_con(proxy->in()); - out_cast.set_proxy(proxy); - + out.net().register_con(new_proxy->in()); + out_cast.set_proxy(new_proxy); + proxy = new_proxy; } return proxy; } -void netlist_setup_t::connect_input_output(netlist_input_t &in, netlist_output_t &out) +void netlist_setup_t::connect_input_output(netlist_core_terminal_t &in, netlist_core_terminal_t &out) { if (out.isFamily(netlist_terminal_t::ANALOG) && in.isFamily(netlist_terminal_t::LOGIC)) { netlist_logic_input_t &incast = dynamic_cast(in); nld_a_to_d_proxy *proxy = nl_alloc(nld_a_to_d_proxy, incast); + incast.set_proxy(proxy); pstring x = pstring::sprintf("proxy_ad_%s_%d", in.name().cstr(), m_proxy_cnt); m_proxy_cnt++; @@ -443,9 +450,9 @@ void netlist_setup_t::connect_input_output(netlist_input_t &in, netlist_output_t } else if (out.isFamily(netlist_terminal_t::LOGIC) && in.isFamily(netlist_terminal_t::ANALOG)) { - nld_base_d_to_a_proxy *proxy = get_d_a_proxy(out); + nld_base_proxy *proxy = get_d_a_proxy(out); - connect_terminals(proxy->out(), in); + connect_terminals(proxy->proxy_term(), in); //proxy->out().net().register_con(in); } else @@ -457,7 +464,8 @@ void netlist_setup_t::connect_input_output(netlist_input_t &in, netlist_output_t } } -void netlist_setup_t::connect_terminal_input(netlist_terminal_t &term, netlist_input_t &inp) + +void netlist_setup_t::connect_terminal_input(netlist_terminal_t &term, netlist_core_terminal_t &inp) { if (inp.isFamily(netlist_terminal_t::ANALOG)) { @@ -468,6 +476,7 @@ void netlist_setup_t::connect_terminal_input(netlist_terminal_t &term, netlist_i netlist_logic_input_t &incast = dynamic_cast(inp); NL_VERBOSE_OUT(("connect_terminal_input: connecting proxy\n")); nld_a_to_d_proxy *proxy = nl_alloc(nld_a_to_d_proxy, incast); + incast.set_proxy(proxy); pstring x = pstring::sprintf("proxy_ad_%s_%d", inp.name().cstr(), m_proxy_cnt); m_proxy_cnt++; @@ -488,7 +497,7 @@ void netlist_setup_t::connect_terminal_input(netlist_terminal_t &term, netlist_i } } -void netlist_setup_t::connect_terminal_output(netlist_terminal_t &in, netlist_output_t &out) +void netlist_setup_t::connect_terminal_output(netlist_terminal_t &in, netlist_core_terminal_t &out) { if (out.isFamily(netlist_terminal_t::ANALOG)) { @@ -502,9 +511,9 @@ void netlist_setup_t::connect_terminal_output(netlist_terminal_t &in, netlist_ou else if (out.isFamily(netlist_terminal_t::LOGIC)) { NL_VERBOSE_OUT(("connect_terminal_output: connecting proxy\n")); - nld_base_d_to_a_proxy *proxy = get_d_a_proxy(out); + nld_base_proxy *proxy = get_d_a_proxy(out); - connect_terminals(proxy->out(), in); + connect_terminals(proxy->proxy_term(), in); } else { @@ -547,55 +556,92 @@ void netlist_setup_t::connect_terminals(netlist_core_terminal_t &t1, netlist_cor static netlist_core_terminal_t &resolve_proxy(netlist_core_terminal_t &term) { - if (term.isType(netlist_core_terminal_t::OUTPUT) && term.isFamily(netlist_core_terminal_t::LOGIC)) + if (term.isFamily(netlist_core_terminal_t::LOGIC)) { - netlist_logic_output_t &out = dynamic_cast(term); + netlist_logic_t &out = dynamic_cast(term); if (out.has_proxy()) - return out.get_proxy()->out(); + return out.get_proxy()->proxy_term(); } return term; } -void netlist_setup_t::connect(netlist_core_terminal_t &t1_in, netlist_core_terminal_t &t2_in) +bool netlist_setup_t::connect_input_input(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2) +{ + bool ret = false; + if (t1.has_net()) + { + for (int i=0; iisType(netlist_core_terminal_t::TERMINAL) + || t1.net().m_core_terms[i]->isType(netlist_core_terminal_t::OUTPUT)) + ret = connect(t2, *t1.net().m_core_terms[i]); + if (ret) + break; + } + } + if (!ret && t2.has_net()) + { + for (int i=0; iisType(netlist_core_terminal_t::TERMINAL) + || t2.net().m_core_terms[i]->isType(netlist_core_terminal_t::OUTPUT)) + ret = connect(t1, *t2.net().m_core_terms[i]); + if (ret) + break; + } + } + return ret; +} + + + +bool netlist_setup_t::connect(netlist_core_terminal_t &t1_in, netlist_core_terminal_t &t2_in) { NL_VERBOSE_OUT(("Connecting %s to %s\n", t1_in.name().cstr(), t2_in.name().cstr())); netlist_core_terminal_t &t1 = resolve_proxy(t1_in); netlist_core_terminal_t &t2 = resolve_proxy(t2_in); + bool ret = true; if (t1.isType(netlist_core_terminal_t::OUTPUT) && t2.isType(netlist_core_terminal_t::INPUT)) { if (t2.has_net() && t2.net().isRailNet()) netlist().error("Input %s already connected\n", t2.name().cstr()); - connect_input_output(dynamic_cast(t2), dynamic_cast(t1)); + connect_input_output(t2, t1); } else if (t1.isType(netlist_core_terminal_t::INPUT) && t2.isType(netlist_core_terminal_t::OUTPUT)) { if (t1.has_net() && t1.net().isRailNet()) netlist().error("Input %s already connected\n", t1.name().cstr()); - connect_input_output(dynamic_cast(t1), dynamic_cast(t2)); + connect_input_output(t1, t2); } else if (t1.isType(netlist_core_terminal_t::OUTPUT) && t2.isType(netlist_core_terminal_t::TERMINAL)) { - connect_terminal_output(dynamic_cast(t2), dynamic_cast(t1)); + connect_terminal_output(dynamic_cast(t2), t1); } else if (t1.isType(netlist_core_terminal_t::TERMINAL) && t2.isType(netlist_core_terminal_t::OUTPUT)) { - connect_terminal_output(dynamic_cast(t1), dynamic_cast(t2)); + connect_terminal_output(dynamic_cast(t1), t2); } else if (t1.isType(netlist_core_terminal_t::INPUT) && t2.isType(netlist_core_terminal_t::TERMINAL)) { - connect_terminal_input(dynamic_cast(t2), dynamic_cast(t1)); + connect_terminal_input(dynamic_cast(t2), t1); } else if (t1.isType(netlist_core_terminal_t::TERMINAL) && t2.isType(netlist_core_terminal_t::INPUT)) { - connect_terminal_input(dynamic_cast(t1), dynamic_cast(t2)); + connect_terminal_input(dynamic_cast(t1), t2); } else if (t1.isType(netlist_core_terminal_t::TERMINAL) && t2.isType(netlist_core_terminal_t::TERMINAL)) { connect_terminals(dynamic_cast(t1), dynamic_cast(t2)); } + else if (t1.isType(netlist_core_terminal_t::INPUT) && t2.isType(netlist_core_terminal_t::INPUT)) + { + ret = connect_input_input(t1, t2); + } else - netlist().error("Connecting %s to %s not supported!\n", t1.name().cstr(), t2.name().cstr()); + ret = false; + //netlist().error("Connecting %s to %s not supported!\n", t1.name().cstr(), t2.name().cstr()); + return ret; } void netlist_setup_t::resolve_inputs() @@ -604,23 +650,40 @@ void netlist_setup_t::resolve_inputs() netlist().log("Resolving inputs ..."); - for (const link_t *entry = m_links.first(); entry != NULL; entry = m_links.next(entry)) + /* Netlist can directly connect input to input. + * We therefore first park connecting inputs and retry + * after all other terminals were connected. + */ + int tries = 100; + while (m_links.count() > 0 && tries > 0) // FIXME: convert into constant { - const pstring t1s = entry->e1; - const pstring t2s = entry->e2; - netlist_core_terminal_t *t1 = find_terminal(t1s); - netlist_core_terminal_t *t2 = find_terminal(t2s); + int li = 0; + while (li < m_links.count()) + { + const pstring t1s = m_links[li].e1; + const pstring t2s = m_links[li].e2; + netlist_core_terminal_t *t1 = find_terminal(t1s); + netlist_core_terminal_t *t2 = find_terminal(t2s); - connect(*t1, *t2); + if (connect(*t1, *t2)) + { + printf("%s and %s connected\n", t1s.cstr(), t2s.cstr()); + m_links.remove_at(li); + } + else + { + printf("%s and %s failed\n", t1s.cstr(), t2s.cstr()); + li++; + } + } + tries--; } - - //netlist().log("printing outputs ..."); - /* print all outputs */ - for (int i = 0; i < m_terminals.count(); i++) + if (tries == 0) { - ATTR_UNUSED netlist_output_t *out = dynamic_cast(m_terminals[i]); - //if (out != NULL) - //VERBOSE_OUT(("%s %d\n", out->netdev()->name(), *out->Q_ptr())); + for (int i = 0; i < m_links.count(); i++ ) + netlist().warning("Error connecting %s to %s\n", m_links[i].e1.cstr(), m_links[i].e2.cstr()); + + netlist().error("Error connecting -- bailing out\n"); } netlist().log("deleting empty nets ..."); @@ -637,12 +700,7 @@ void netlist_setup_t::resolve_inputs() } else { -#if 0 - for (netlist_core_terminal_t *p = (*pn)->m_list.first(); p != NULL; p = (*pn)->m_list.next(p)) - (*pn)->m_registered.add(p); -#else (*pn)->rebuild_list(); -#endif } } @@ -698,11 +756,12 @@ void netlist_setup_t::resolve_inputs() void netlist_setup_t::start_devices() { - //FIXME: we need a nl_getenv - if (getenv("NL_LOGS")) + pstring env = nl_util::environment("NL_LOGS"); + + if (env != "") { NL_VERBOSE_OUT(("Creating dynamic logs ...\n")); - nl_util::pstring_list ll = nl_util::split(getenv("NL_LOGS"), ":"); + nl_util::pstring_list ll = nl_util::split(env, ":"); for (int i=0; i < ll.count(); i++) { NL_VERBOSE_OUT(("%d: <%s>\n",i, ll[i].cstr())); diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h index 8deddf08dee..d58893ca6af 100644 --- a/src/emu/netlist/nl_setup.h +++ b/src/emu/netlist/nl_setup.h @@ -129,7 +129,7 @@ public: void register_param(const pstring ¶m, const double value); void register_object(netlist_device_t &dev, const pstring &name, netlist_object_t &obj); - void connect(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2); + bool connect(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2); netlist_core_terminal_t *find_terminal(const pstring &outname_in, bool required = true); netlist_core_terminal_t *find_terminal(const pstring &outname_in, netlist_object_t::type_t atype, bool required = true); @@ -175,15 +175,16 @@ private: void connect_terminals(netlist_core_terminal_t &in, netlist_core_terminal_t &out); - void connect_input_output(netlist_input_t &in, netlist_output_t &out); - void connect_terminal_output(netlist_terminal_t &in, netlist_output_t &out); - void connect_terminal_input(netlist_terminal_t &term, netlist_input_t &inp); + void connect_input_output(netlist_core_terminal_t &in, netlist_core_terminal_t &out); + void connect_terminal_output(netlist_terminal_t &in, netlist_core_terminal_t &out); + void connect_terminal_input(netlist_terminal_t &term, netlist_core_terminal_t &inp); + bool connect_input_input(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2); // helpers pstring objtype_as_astr(netlist_object_t &in) const; const pstring resolve_alias(const pstring &name) const; - nld_base_d_to_a_proxy *get_d_a_proxy(netlist_output_t &out); + nld_base_proxy *get_d_a_proxy(netlist_core_terminal_t &out); }; #endif /* NLSETUP_H_ */ diff --git a/src/emu/netlist/nl_util.h b/src/emu/netlist/nl_util.h index 4fb6f82e9e0..ff5511b7f90 100644 --- a/src/emu/netlist/nl_util.h +++ b/src/emu/netlist/nl_util.h @@ -45,6 +45,13 @@ public: } return temp; } + static const pstring environment(const pstring &var, const pstring &default_val = "") + { + if (getenv(var.cstr()) == NULL) + return default_val; + else + return pstring(getenv(var.cstr())); + } }; class nl_math diff --git a/src/tools/nltool.c b/src/tools/nltool.c index 37a784cb353..317f3b285fa 100644 --- a/src/tools/nltool.c +++ b/src/tools/nltool.c @@ -85,8 +85,7 @@ struct options_entry oplist[] = { "logs;l", "", OPTION_STRING, "colon separated list of terminals to log" }, { "file;f", "-", OPTION_STRING, "file to process (default is stdin)" }, { "cmd;c", "run", OPTION_STRING, "run|convert|listdevices" }, - { "listdevices;ld", "", OPTION_BOOLEAN, "list all devices available for use" }, - { "verbose;v", "0", OPTION_BOOLEAN, "list all devices available for use" }, + { "verbose;v", "0", OPTION_BOOLEAN, "be verbose - this produces lots of output" }, { "help;h", "0", OPTION_BOOLEAN, "display help" }, { NULL, NULL, 0, NULL } };