From f9495b98565a7751bac083ab37181c486ef825a1 Mon Sep 17 00:00:00 2001 From: couriersud Date: Thu, 21 May 2015 12:53:42 +0200 Subject: [PATCH] Removed netlist_input_t and net_output_t. Instead introduced netlist_logic_t and netlist_analog_t. Afterwards refactored proxies. This enabled more flexible connection parsing. In addition, connections between two inputs are now parked and retried after all connections were made. The netlist code now correctly parses TTL_7400_DIP(XU1) RES(R1, RES_K(1)) CAP(C1, CAP_U(1)) NET_C(XU1.1, XU1.2, R1.2, C1.2) NET_C(XU1.3, XU1.4, XU1.5, R1.1) NET_C(XU1.6, C1.1) NET_C(ttllow, XU1.9, XU1.10, XU1.12, XU1.13) This failed before. (nw) --- src/emu/netlist/analog/nld_ms_sor_mat.h | 6 +- src/emu/netlist/analog/nld_solver.c | 7 +- src/emu/netlist/devices/nld_4020.c | 2 +- src/emu/netlist/devices/nld_74107.c | 2 +- src/emu/netlist/devices/nld_74175.c | 2 +- src/emu/netlist/devices/nld_7474.c | 2 +- src/emu/netlist/devices/nld_7493.c | 2 +- src/emu/netlist/devices/nld_9310.c | 2 +- src/emu/netlist/devices/nld_9316.c | 2 +- src/emu/netlist/devices/nld_system.c | 9 +- src/emu/netlist/devices/nld_system.h | 111 +++++++--------- src/emu/netlist/nl_base.c | 84 +++++------- src/emu/netlist/nl_base.h | 107 +++++++++------- src/emu/netlist/nl_factory.h | 5 - src/emu/netlist/nl_setup.c | 163 ++++++++++++++++-------- src/emu/netlist/nl_setup.h | 11 +- src/emu/netlist/nl_util.h | 7 + src/tools/nltool.c | 3 +- 18 files changed, 280 insertions(+), 247 deletions(-) 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 } };