diff options
Diffstat (limited to 'src/emu/netlist/devices/nld_system.c')
-rw-r--r-- | src/emu/netlist/devices/nld_system.c | 135 |
1 files changed, 124 insertions, 11 deletions
diff --git a/src/emu/netlist/devices/nld_system.c b/src/emu/netlist/devices/nld_system.c index b7a5cf6c71e..c4ecbaba454 100644 --- a/src/emu/netlist/devices/nld_system.c +++ b/src/emu/netlist/devices/nld_system.c @@ -5,8 +5,10 @@ * */ +#include <solver/nld_solver.h> #include "nld_system.h" -#include "../analog/nld_solver.h" + +NETLIB_NAMESPACE_DEVICES_START() // ---------------------------------------------------------------------------------------- // netlistparams @@ -42,7 +44,7 @@ NETLIB_START(clock) register_param("FREQ", m_freq, 7159000.0 * 5.0); m_inc = netlist_time::from_hz(m_freq.Value()*2); - connect(m_feedback, m_Q); + connect_late(m_feedback, m_Q); } NETLIB_RESET(clock) @@ -73,7 +75,7 @@ NETLIB_START(extclock) register_param("OFFSET", m_offset, 0.0); m_inc[0] = netlist_time::from_hz(m_freq.Value()*2); - connect(m_feedback, m_Q); + connect_late(m_feedback, m_Q); { netlist_time base = netlist_time::from_hz(m_freq.Value()*2); pstring_list_t pat(m_pattern.Value(),","); @@ -129,22 +131,34 @@ NETLIB_UPDATE(extclock) // logic_input // ---------------------------------------------------------------------------------------- -NETLIB_START(ttl_input) +NETLIB_START(logic_input) { + /* make sure we get the family first */ + register_param("FAMILY", m_FAMILY, ".model FAMILY(TYPE=TTL)"); + set_logic_family(logic_family_desc_t::from_model(m_FAMILY.Value())); + register_output("Q", m_Q); register_param("IN", m_IN, 0); } -NETLIB_RESET(ttl_input) +NETLIB_RESET(logic_input) +{ +} + +NETLIB_STOP(logic_input) { + if (m_logic_family != NULL) + if (!m_logic_family->m_is_static) + pfree(m_logic_family); } -NETLIB_UPDATE(ttl_input) + +NETLIB_UPDATE(logic_input) { OUTLOGIC(m_Q, m_IN.Value() & 1, netlist_time::from_nsec(1)); } -NETLIB_UPDATE_PARAM(ttl_input) +NETLIB_UPDATE_PARAM(logic_input) { update(); } @@ -177,7 +191,7 @@ NETLIB_UPDATE_PARAM(analog_input) // nld_d_to_a_proxy // ---------------------------------------------------------------------------------------- -ATTR_COLD void nld_d_to_a_proxy::start() +void nld_d_to_a_proxy::start() { nld_base_d_to_a_proxy::start(); @@ -188,14 +202,18 @@ ATTR_COLD void nld_d_to_a_proxy::start() register_output("_Q", m_Q); register_subalias("Q", m_RV.m_P); - connect(m_RV.m_N, m_Q); - m_Q.initial(0.0); + connect_direct(m_RV.m_N, m_Q); + + save(NLNAME(m_last_state)); } -ATTR_COLD void nld_d_to_a_proxy::reset() +void nld_d_to_a_proxy::reset() { + m_Q.initial(0.0); + m_last_state = -1; m_RV.do_reset(); m_is_timestep = m_RV.m_P.net().as_analog().solver()->is_timestep(); + m_RV.set(NL_FCONST(1.0) / logic_family().m_R_low, logic_family().m_low_V, 0.0); } ATTR_HOT void nld_d_to_a_proxy::update() @@ -269,3 +287,98 @@ NETLIB_UPDATE_PARAM(res_sw) { // nothing, not intended to be called } + +/* ----------------------------------------------------------------------------- + * nld_function + * ----------------------------------------------------------------------------- */ + +NETLIB_START(function) +{ + register_param("N", m_N, 2); + register_param("FUNC", m_func, ""); + register_output("Q", m_Q); + + for (int i=0; i < m_N; i++) + register_input(pstring::sprintf("A%d", i), m_I[i]); + + pstring_list_t cmds(m_func.Value(), " "); + m_precompiled.clear(); + + for (std::size_t i=0; i < cmds.size(); i++) + { + pstring cmd = cmds[i]; + rpn_inst rc; + if (cmd == "+") + rc.m_cmd = ADD; + else if (cmd == "-") + rc.m_cmd = SUB; + else if (cmd == "*") + rc.m_cmd = MULT; + else if (cmd == "/") + rc.m_cmd = DIV; + else if (cmd == "/") + rc.m_cmd = DIV; + else if (cmd.startsWith("A")) + { + rc.m_cmd = PUSH_INPUT; + rc.m_param = cmd.substr(1).as_long(); + } + else + { + bool err = false; + rc.m_cmd = PUSH_CONST; + rc.m_param = cmd.as_double(&err); + if (err) + netlist().error("nld_function: unknown/misformatted token <%s> in <%s>", cmd.cstr(), m_func.Value().cstr()); + } + m_precompiled.add(rc); + } + +} + +NETLIB_RESET(function) +{ + m_Q.initial(0.0); +} + +NETLIB_UPDATE(function) +{ + //nl_double val = INPANALOG(m_I[0]) * INPANALOG(m_I[1]) * 0.2; + //OUTANALOG(m_Q, val); + nl_double stack[20]; + unsigned ptr = 0; + unsigned e = m_precompiled.size(); + for (unsigned i = 0; i<e; i++) + { + rpn_inst &rc = m_precompiled[i]; + switch (rc.m_cmd) + { + case ADD: + ptr--; + stack[ptr-1] = stack[ptr] + stack[ptr-1]; + break; + case MULT: + ptr--; + stack[ptr-1] = stack[ptr] * stack[ptr-1]; + break; + case SUB: + ptr--; + stack[ptr-1] = stack[ptr-1] - stack[ptr]; + break; + case DIV: + ptr--; + stack[ptr-1] = stack[ptr-1] / stack[ptr]; + break; + case PUSH_INPUT: + stack[ptr++] = INPANALOG(m_I[(int) rc.m_param]); + break; + case PUSH_CONST: + stack[ptr++] = rc.m_param; + break; + } + } + OUTANALOG(m_Q, stack[ptr-1]); +} + + +NETLIB_NAMESPACE_DEVICES_END() |