summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/netlist/analog/nld_solver.c70
-rw-r--r--src/emu/netlist/analog/nld_solver.h10
-rw-r--r--src/emu/netlist/devices/nld_74123.c31
-rw-r--r--src/emu/netlist/devices/nld_74123.h8
-rw-r--r--src/emu/netlist/nl_base.c2
-rw-r--r--src/emu/netlist/nl_base.h2
6 files changed, 98 insertions, 25 deletions
diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c
index 8248b75ec9c..7ede33a2664 100644
--- a/src/emu/netlist/analog/nld_solver.c
+++ b/src/emu/netlist/analog/nld_solver.c
@@ -18,6 +18,19 @@
#define SOLVER_VERBOSE_OUT(x) do {} while (0)
//#define SOLVER_VERBOSE_OUT(x) printf x
+ATTR_COLD netlist_matrix_solver_t::netlist_matrix_solver_t()
+: m_owner(NULL)
+{
+}
+
+ATTR_COLD netlist_matrix_solver_t::~netlist_matrix_solver_t()
+{
+#if NEW_INPUT
+ for (int i = 0; i < m_inps.count(); i++)
+ delete m_inps[i];
+#endif
+}
+
ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &aowner)
{
m_owner = &aowner;
@@ -66,10 +79,24 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets, NETLI
NL_VERBOSE_OUT(("Added terminal\n"));
break;
case netlist_terminal_t::INPUT:
- if (!m_inps.contains(p))
- m_inps.add(p);
- NL_VERBOSE_OUT(("Added input\n"));
- break;
+ {
+#if NEW_INPUT
+ // FIXME: multiple outputs per net ...
+ netlist_analog_output_t *m = new netlist_analog_output_t();
+ m->init_object(*this, this->name() + "." + pstring::sprintf("m%d", m_inps.count()));
+ //register_output("m", *m);
+ m_inps.add(m);
+ m->m_proxied_net = &p->net();
+ m->net().register_con(*p);
+ // FIXME: repeated
+ m->net().rebuild_list();
+#else
+ if (!m_inps.contains(p))
+ m_inps.add(p)
+#endif
+ NL_VERBOSE_OUT(("Added input\n"));
+ }
+ break;
default:
owner().netlist().error("unhandled element found\n");
break;
@@ -81,6 +108,18 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets, NETLI
ATTR_HOT void netlist_matrix_solver_t::update_inputs()
{
+
+#if NEW_INPUT
+ // avoid recursive calls. Inputs are updated outside this call
+ for (netlist_analog_output_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
+ if ((*p)->m_proxied_net->m_last_Analog != (*p)->m_proxied_net->m_cur_Analog)
+ (*p)->set_Q((*p)->m_proxied_net->m_cur_Analog);
+ for (netlist_analog_output_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
+ {
+ if ((*p)->m_proxied_net->m_last_Analog != (*p)->m_proxied_net->m_cur_Analog)
+ (*p)->m_proxied_net->m_last_Analog = (*p)->m_proxied_net->m_cur_Analog;
+ }
+#else
for (netlist_core_terminal_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
{
if ((*p)->net().m_last_Analog != (*p)->net().m_cur_Analog)
@@ -93,6 +132,7 @@ ATTR_HOT void netlist_matrix_solver_t::update_inputs()
if ((*p)->net().m_last_Analog != (*p)->net().m_cur_Analog)
(*p)->net().m_last_Analog = (*p)->net().m_cur_Analog;
}
+#endif
}
@@ -156,14 +196,15 @@ ATTR_HOT bool netlist_matrix_solver_t::solve()
netlist_time now = owner().netlist().time();
netlist_time delta = now - m_last_step;
- if (delta < netlist_time::from_nsec(1)) // always update capacitors
- delta = netlist_time::from_nsec(1);
- {
- NL_VERBOSE_OUT(("Step!\n"));
- /* update all terminals for new time step */
- m_last_step = now;
- step(delta);
- }
+ // We are already up to date. Avoid oscillations.
+ if (delta < netlist_time::from_nsec(1))
+ return true;
+
+ NL_VERBOSE_OUT(("Step!\n"));
+ /* update all terminals for new time step */
+ m_last_step = now;
+ //printf("usecs: %f\n", delta.as_double()*1000000.0);
+ step(delta);
if (is_dynamic())
{
@@ -832,11 +873,12 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
ms->m_params.m_nr_loops = m_nr_loops.Value();
ms->m_params.m_nt_sync_delay = m_sync_delay.Value();
- ms->setup(groups[i], *this);
register_sub(*ms, pstring::sprintf("Solver %d",m_mat_solvers.count()));
- m_mat_solvers.add(ms);
+ ms->setup(groups[i], *this);
+
+ m_mat_solvers.add(ms);
netlist().log("Solver %s", ms->name().cstr());
netlist().log(" # %d ==> %d nets %s", i, groups[i].count(), (*(*groups[i].first())->m_core_terms.first())->name().cstr());
diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h
index 0a2c1788a46..5d592cbd0f5 100644
--- a/src/emu/netlist/analog/nld_solver.h
+++ b/src/emu/netlist/analog/nld_solver.h
@@ -9,6 +9,8 @@
#include "../nl_setup.h"
#include "../nl_base.h"
+#define NEW_INPUT (1)
+
// ----------------------------------------------------------------------------------------
// Macros
// ----------------------------------------------------------------------------------------
@@ -40,8 +42,8 @@ public:
typedef netlist_list_t<netlist_matrix_solver_t *> list_t;
typedef netlist_core_device_t::list_t dev_list_t;
- netlist_matrix_solver_t() : m_owner(NULL) {}
- virtual ~netlist_matrix_solver_t() {}
+ ATTR_COLD netlist_matrix_solver_t();
+ ATTR_COLD virtual ~netlist_matrix_solver_t();
ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner);
@@ -75,7 +77,11 @@ protected:
netlist_net_t::list_t m_nets;
dev_list_t m_dynamic;
+#if NEW_INPUT
+ netlist_list_t<netlist_analog_output_t *> m_inps;
+#else
netlist_core_terminal_t::list_t m_inps;
+#endif
dev_list_t m_steps;
netlist_time m_last_step;
diff --git a/src/emu/netlist/devices/nld_74123.c b/src/emu/netlist/devices/nld_74123.c
index 5a40f51987a..aef93f6ab06 100644
--- a/src/emu/netlist/devices/nld_74123.c
+++ b/src/emu/netlist/devices/nld_74123.c
@@ -6,7 +6,7 @@
#include "nld_74123.h"
#define R_OFF (1E20)
-#define R_ON (1)
+#define R_ON (m_RI.Value())
NETLIB_START(74123)
{
@@ -27,20 +27,36 @@ NETLIB_START(74123)
register_subalias("C", m_RN.m_N);
register_subalias("RC", m_RN.m_P);
+ register_param("K", m_K, 0.4);
+ register_param("RI", m_RI, 400.0); // around 250 for HC series, 400 on LS/TTL, estimated from datasheets
+
connect(m_RN.m_P, m_RP.m_N);
connect(m_CV, m_RN.m_P);
save(NAME(m_last_trig));
save(NAME(m_state));
+ save(NAME(m_KP));
+
+ m_KP = 1.0 / (1.0 + exp(m_K.Value()));
}
NETLIB_UPDATE(74123)
{
- // FIXME: CLR!
-
const netlist_sig_t m_trig = (INPLOGIC(m_A) ^ 1) & INPLOGIC(m_B) & INPLOGIC(m_CLRQ);
- if (!m_last_trig && m_trig)
+ if (!INPLOGIC(m_CLRQ))
+ {
+ OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(10));
+ OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(10));
+ /* quick charge until trigger */
+ /* FIXME: SGS datasheet shows quick charge to 5V,
+ * though schematics indicate quick charge to Vhigh only.
+ */
+ m_RP.set_R(R_ON);
+ m_RN.set_R(R_OFF);
+ m_state = 2; //charging (quick)
+ }
+ else if (!m_last_trig && m_trig)
{
// FIXME: Timing!
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(10));
@@ -54,7 +70,8 @@ NETLIB_UPDATE(74123)
if (m_state == 1)
{
- if (INPANALOG(m_CV) < 1.3)
+ const double vLow = m_KP * TERMANALOG(m_RP.m_P);
+ if (INPANALOG(m_CV) < vLow)
{
m_RN.set_R(R_OFF);
m_state = 2; // charging
@@ -62,8 +79,10 @@ NETLIB_UPDATE(74123)
}
else if (m_state == 2)
{
- if (INPANALOG(m_CV) > 3.7)
+ const double vHigh = TERMANALOG(m_RP.m_P) * (1.0 - m_KP);
+ if (INPANALOG(m_CV) > vHigh)
{
+ m_RP.set_R(R_OFF);
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(10));
OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(10));
m_state = 0; // waiting
diff --git a/src/emu/netlist/devices/nld_74123.h b/src/emu/netlist/devices/nld_74123.h
index 67a313d9846..6a81b9bac7c 100644
--- a/src/emu/netlist/devices/nld_74123.h
+++ b/src/emu/netlist/devices/nld_74123.h
@@ -3,7 +3,7 @@
/*
* nld_74123.h
*
- * 74123: PRECISION TIMERS
+ * 74123: Dual Retriggerable One-Shot with Clear and Complementary Outputs
*
* +--------------+
* A1 |1 ++ 16| VCC
@@ -43,8 +43,12 @@ public:
netlist_analog_input_t m_CV;
- netlist_sig_t m_last_trig;
+ netlist_sig_t m_last_trig;
UINT8 m_state;
+ double m_KP;
+
+ netlist_param_double_t m_K;
+ netlist_param_double_t m_RI;
);
diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c
index a64fb784a9e..b274bde868b 100644
--- a/src/emu/netlist/nl_base.c
+++ b/src/emu/netlist/nl_base.c
@@ -841,7 +841,7 @@ ATTR_HOT void netlist_analog_output_t::set_Q(const double newQ)
if (newQ != net().m_new_Analog)
{
net().m_new_Analog = newQ;
- net().push_to_queue(NLTIME_FROM_NS(0));
+ net().push_to_queue(NLTIME_FROM_NS(1));
}
}
diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h
index 1664d98b54e..cd820bf1c27 100644
--- a/src/emu/netlist/nl_base.h
+++ b/src/emu/netlist/nl_base.h
@@ -723,6 +723,8 @@ public:
ATTR_HOT void set_Q(const double newQ);
+ netlist_net_t *m_proxied_net; // only for proxy nets in analog input logic
+
};
// ----------------------------------------------------------------------------------------