summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/netlist/devices/nld_system.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/netlist/devices/nld_system.c')
-rw-r--r--src/emu/netlist/devices/nld_system.c135
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()