mirror of
https://github.com/holub/mame
synced 2025-06-29 07:34:45 +03:00
Netlist:
- code cleanup - logs on demand ... NL_LOGS=EBUF.OP:4V ./mame64 -np 4 pongf No recompile or dealing with roms
This commit is contained in:
parent
0a61ffafc2
commit
2fa537b49f
9
.gitattributes
vendored
9
.gitattributes
vendored
@ -2139,15 +2139,23 @@ src/emu/netlist/devices/nld_7427.h svneol=native#text/plain
|
|||||||
src/emu/netlist/devices/nld_7430.h svneol=native#text/plain
|
src/emu/netlist/devices/nld_7430.h svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_7474.c svneol=native#text/plain
|
src/emu/netlist/devices/nld_7474.c svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_7474.h svneol=native#text/plain
|
src/emu/netlist/devices/nld_7474.h svneol=native#text/plain
|
||||||
|
src/emu/netlist/devices/nld_7483.c svneol=native#text/plain
|
||||||
|
src/emu/netlist/devices/nld_7483.h svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_7486.c svneol=native#text/plain
|
src/emu/netlist/devices/nld_7486.c svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_7486.h svneol=native#text/plain
|
src/emu/netlist/devices/nld_7486.h svneol=native#text/plain
|
||||||
|
src/emu/netlist/devices/nld_7490.c svneol=native#text/plain
|
||||||
|
src/emu/netlist/devices/nld_7490.h svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_7493.c svneol=native#text/plain
|
src/emu/netlist/devices/nld_7493.c svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_7493.h svneol=native#text/plain
|
src/emu/netlist/devices/nld_7493.h svneol=native#text/plain
|
||||||
|
src/emu/netlist/devices/nld_9316.c svneol=native#text/plain
|
||||||
|
src/emu/netlist/devices/nld_9316.h svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_NE555.c svneol=native#text/plain
|
src/emu/netlist/devices/nld_NE555.c svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_NE555.h svneol=native#text/plain
|
src/emu/netlist/devices/nld_NE555.h svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_log.c svneol=native#text/plain
|
src/emu/netlist/devices/nld_log.c svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_log.h svneol=native#text/plain
|
src/emu/netlist/devices/nld_log.h svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_signal.h svneol=native#text/plain
|
src/emu/netlist/devices/nld_signal.h svneol=native#text/plain
|
||||||
|
src/emu/netlist/devices/nld_solver.c svneol=native#text/plain
|
||||||
|
src/emu/netlist/devices/nld_solver.h svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_system.c svneol=native#text/plain
|
src/emu/netlist/devices/nld_system.c svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_system.h svneol=native#text/plain
|
src/emu/netlist/devices/nld_system.h svneol=native#text/plain
|
||||||
src/emu/netlist/devices/nld_twoterm.c svneol=native#text/plain
|
src/emu/netlist/devices/nld_twoterm.c svneol=native#text/plain
|
||||||
@ -2162,6 +2170,7 @@ src/emu/netlist/nl_parser.h svneol=native#text/plain
|
|||||||
src/emu/netlist/nl_setup.c svneol=native#text/plain
|
src/emu/netlist/nl_setup.c svneol=native#text/plain
|
||||||
src/emu/netlist/nl_setup.h svneol=native#text/plain
|
src/emu/netlist/nl_setup.h svneol=native#text/plain
|
||||||
src/emu/netlist/nl_time.h svneol=native#text/plain
|
src/emu/netlist/nl_time.h svneol=native#text/plain
|
||||||
|
src/emu/netlist/nl_util.h svneol=native#text/plain
|
||||||
src/emu/netlist/pstring.c svneol=native#text/plain
|
src/emu/netlist/pstring.c svneol=native#text/plain
|
||||||
src/emu/netlist/pstring.h svneol=native#text/plain
|
src/emu/netlist/pstring.h svneol=native#text/plain
|
||||||
src/emu/network.c svneol=native#text/plain
|
src/emu/network.c svneol=native#text/plain
|
||||||
|
@ -50,24 +50,6 @@
|
|||||||
#include "net_lib.h"
|
#include "net_lib.h"
|
||||||
#include "nld_system.h"
|
#include "nld_system.h"
|
||||||
|
|
||||||
NETLIB_START(logic_input)
|
|
||||||
{
|
|
||||||
register_output("Q", m_Q);
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_UPDATE(logic_input)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_START(analog_input)
|
|
||||||
{
|
|
||||||
register_output("Q", m_Q);
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_UPDATE(analog_input)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_START(nicMultiSwitch)
|
NETLIB_START(nicMultiSwitch)
|
||||||
{
|
{
|
||||||
static const char *sIN[8] = { "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8" };
|
static const char *sIN[8] = { "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8" };
|
||||||
@ -418,97 +400,8 @@ NETLIB_UPDATE(nic7450)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NETLIB_START(nic7483)
|
|
||||||
{
|
|
||||||
m_lastr = 0;
|
|
||||||
|
|
||||||
register_input("A1", m_A1);
|
|
||||||
register_input("A2", m_A2);
|
|
||||||
register_input("A3", m_A3);
|
|
||||||
register_input("A4", m_A4);
|
|
||||||
register_input("B1", m_B1);
|
|
||||||
register_input("B2", m_B2);
|
|
||||||
register_input("B3", m_B3);
|
|
||||||
register_input("B4", m_B4);
|
|
||||||
register_input("CI", m_CI);
|
|
||||||
|
|
||||||
register_output("SA", m_SA);
|
|
||||||
register_output("SB", m_SB);
|
|
||||||
register_output("SC", m_SC);
|
|
||||||
register_output("SD", m_SD);
|
|
||||||
register_output("CO", m_CO);
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_UPDATE(nic7483)
|
|
||||||
{
|
|
||||||
UINT8 a = (INPLOGIC(m_A1) << 0) | (INPLOGIC(m_A2) << 1) | (INPLOGIC(m_A3) << 2) | (INPLOGIC(m_A4) << 3);
|
|
||||||
UINT8 b = (INPLOGIC(m_B1) << 0) | (INPLOGIC(m_B2) << 1) | (INPLOGIC(m_B3) << 2) | (INPLOGIC(m_B4) << 3);
|
|
||||||
|
|
||||||
UINT8 r = a + b + INPLOGIC(m_CI);
|
|
||||||
|
|
||||||
if (r != m_lastr)
|
|
||||||
{
|
|
||||||
m_lastr = r;
|
|
||||||
OUTLOGIC(m_SA, (r >> 0) & 1, NLTIME_FROM_NS(23));
|
|
||||||
OUTLOGIC(m_SB, (r >> 1) & 1, NLTIME_FROM_NS(23));
|
|
||||||
OUTLOGIC(m_SC, (r >> 2) & 1, NLTIME_FROM_NS(23));
|
|
||||||
OUTLOGIC(m_SD, (r >> 3) & 1, NLTIME_FROM_NS(23));
|
|
||||||
OUTLOGIC(m_CO, (r >> 4) & 1, NLTIME_FROM_NS(23));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_START(nic7490)
|
|
||||||
{
|
|
||||||
m_cnt = 0;
|
|
||||||
|
|
||||||
register_input("CLK", m_clk);
|
|
||||||
register_input("R1", m_R1);
|
|
||||||
register_input("R2", m_R2);
|
|
||||||
register_input("R91", m_R91);
|
|
||||||
register_input("R92", m_R92);
|
|
||||||
|
|
||||||
register_output("QA", m_Q[0]);
|
|
||||||
register_output("QB", m_Q[1]);
|
|
||||||
register_output("QC", m_Q[2]);
|
|
||||||
register_output("QD", m_Q[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_UPDATE(nic7490)
|
|
||||||
{
|
|
||||||
if (INPLOGIC(m_R91) & INPLOGIC(m_R92))
|
|
||||||
{
|
|
||||||
m_cnt = 9;
|
|
||||||
update_outputs();
|
|
||||||
}
|
|
||||||
else if (INPLOGIC(m_R1) & INPLOGIC(m_R2))
|
|
||||||
{
|
|
||||||
m_cnt = 0;
|
|
||||||
update_outputs();
|
|
||||||
}
|
|
||||||
else if (INP_HL(m_clk))
|
|
||||||
{
|
|
||||||
m_cnt++;
|
|
||||||
if (m_cnt >= 10)
|
|
||||||
m_cnt = 0;
|
|
||||||
update_outputs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
NETLIB_FUNC_VOID(nic7490, update_outputs)
|
|
||||||
{
|
|
||||||
OUTLOGIC(m_QA, (m_cnt >> 0) & 1, NLTIME_FROM_NS(18));
|
|
||||||
OUTLOGIC(m_QB, (m_cnt >> 1) & 1, NLTIME_FROM_NS(36));
|
|
||||||
OUTLOGIC(m_QC, (m_cnt >> 2) & 1, NLTIME_FROM_NS(54));
|
|
||||||
OUTLOGIC(m_QD, (m_cnt >> 3) & 1, NLTIME_FROM_NS(72));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
NETLIB_FUNC_VOID(nic7490, update_outputs, (void))
|
|
||||||
{
|
|
||||||
const netlist_time delay[4] = { NLTIME_FROM_NS(18), NLTIME_FROM_NS(36), NLTIME_FROM_NS(54), NLTIME_FROM_NS(72) };
|
|
||||||
for (int i=0; i<4; i++)
|
|
||||||
OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NETLIB_START(nic74107Asub)
|
NETLIB_START(nic74107Asub)
|
||||||
{
|
{
|
||||||
@ -626,141 +519,6 @@ NETLIB_UPDATE(nic74153)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NETLIB_START(nic9316)
|
|
||||||
{
|
|
||||||
register_sub(sub, "sub");
|
|
||||||
|
|
||||||
register_subalias("CLK", sub.m_clk);
|
|
||||||
|
|
||||||
register_input("ENP", m_ENP);
|
|
||||||
register_input("ENT", m_ENT);
|
|
||||||
register_input("CLRQ", m_CLRQ);
|
|
||||||
register_input("LOADQ", m_LOADQ);
|
|
||||||
|
|
||||||
register_subalias("A", sub.m_A);
|
|
||||||
register_subalias("B", sub.m_B);
|
|
||||||
register_subalias("C", sub.m_C);
|
|
||||||
register_subalias("D", sub.m_D);
|
|
||||||
|
|
||||||
register_subalias("QA", sub.m_QA);
|
|
||||||
register_subalias("QB", sub.m_QB);
|
|
||||||
register_subalias("QC", sub.m_QC);
|
|
||||||
register_subalias("QD", sub.m_QD);
|
|
||||||
register_subalias("RC", sub.m_RC);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_START(nic9316_sub)
|
|
||||||
{
|
|
||||||
m_cnt = 0;
|
|
||||||
m_loadq = 1;
|
|
||||||
m_ent = 1;
|
|
||||||
|
|
||||||
register_input("CLK", m_clk, netlist_input_t::STATE_INP_LH);
|
|
||||||
|
|
||||||
register_input("A", m_A, netlist_input_t::STATE_INP_PASSIVE);
|
|
||||||
register_input("B", m_B, netlist_input_t::STATE_INP_PASSIVE);
|
|
||||||
register_input("C", m_C, netlist_input_t::STATE_INP_PASSIVE);
|
|
||||||
register_input("D", m_D, netlist_input_t::STATE_INP_PASSIVE);
|
|
||||||
|
|
||||||
register_output("QA", m_QA);
|
|
||||||
register_output("QB", m_QB);
|
|
||||||
register_output("QC", m_QC);
|
|
||||||
register_output("QD", m_QD);
|
|
||||||
register_output("RC", m_RC);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_UPDATE(nic9316_sub)
|
|
||||||
{
|
|
||||||
if (m_loadq)
|
|
||||||
{
|
|
||||||
m_cnt = ( m_cnt + 1) & 0x0f;
|
|
||||||
update_outputs();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_cnt = (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
|
|
||||||
update_outputs_all();
|
|
||||||
}
|
|
||||||
OUTLOGIC(m_RC, m_ent & (m_cnt == 0x0f), NLTIME_FROM_NS(20));
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_UPDATE(nic9316)
|
|
||||||
{
|
|
||||||
sub.m_loadq = INPLOGIC(m_LOADQ);
|
|
||||||
sub.m_ent = INPLOGIC(m_ENT);
|
|
||||||
const netlist_sig_t clrq = INPLOGIC(m_CLRQ);
|
|
||||||
|
|
||||||
if ((!sub.m_loadq || (sub.m_ent & INPLOGIC(m_ENP))) & clrq)
|
|
||||||
{
|
|
||||||
sub.m_clk.activate_lh();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sub.m_clk.inactivate();
|
|
||||||
if (!clrq & (sub.m_cnt>0))
|
|
||||||
{
|
|
||||||
sub.m_cnt = 0;
|
|
||||||
sub.update_outputs();
|
|
||||||
OUTLOGIC(sub.m_RC, 0, NLTIME_FROM_NS(20));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == 0x0f), NLTIME_FROM_NS(20));
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_FUNC_VOID(nic9316_sub, update_outputs_all, (void))
|
|
||||||
{
|
|
||||||
const netlist_time out_delay = NLTIME_FROM_NS(20);
|
|
||||||
OUTLOGIC(m_QA, (m_cnt >> 0) & 1, out_delay);
|
|
||||||
OUTLOGIC(m_QB, (m_cnt >> 1) & 1, out_delay);
|
|
||||||
OUTLOGIC(m_QC, (m_cnt >> 2) & 1, out_delay);
|
|
||||||
OUTLOGIC(m_QD, (m_cnt >> 3) & 1, out_delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_FUNC_VOID(nic9316_sub, update_outputs, (void))
|
|
||||||
{
|
|
||||||
const netlist_time out_delay = NLTIME_FROM_NS(20);
|
|
||||||
#if 0
|
|
||||||
OUTLOGIC(m_QA, (m_cnt >> 0) & 1, out_delay);
|
|
||||||
OUTLOGIC(m_QB, (m_cnt >> 1) & 1, out_delay);
|
|
||||||
OUTLOGIC(m_QC, (m_cnt >> 2) & 1, out_delay);
|
|
||||||
OUTLOGIC(m_QD, (m_cnt >> 3) & 1, out_delay);
|
|
||||||
#else
|
|
||||||
if ((m_cnt & 1) == 1)
|
|
||||||
OUTLOGIC(m_QA, 1, out_delay);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OUTLOGIC(m_QA, 0, out_delay);
|
|
||||||
switch (m_cnt)
|
|
||||||
{
|
|
||||||
case 0x00:
|
|
||||||
OUTLOGIC(m_QB, 0, out_delay);
|
|
||||||
OUTLOGIC(m_QC, 0, out_delay);
|
|
||||||
OUTLOGIC(m_QD, 0, out_delay);
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
case 0x06:
|
|
||||||
case 0x0A:
|
|
||||||
case 0x0E:
|
|
||||||
OUTLOGIC(m_QB, 1, out_delay);
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
case 0x0C:
|
|
||||||
OUTLOGIC(m_QB, 0, out_delay);
|
|
||||||
OUTLOGIC(m_QC, 1, out_delay);
|
|
||||||
break;
|
|
||||||
case 0x08:
|
|
||||||
OUTLOGIC(m_QB, 0, out_delay);
|
|
||||||
OUTLOGIC(m_QC, 0, out_delay);
|
|
||||||
OUTLOGIC(m_QD, 1, out_delay);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define xstr(s) # s
|
#define xstr(s) # s
|
||||||
#define ENTRY1(_nic, _name) m_list.add(new net_device_t_factory< _nic >( # _name, xstr(_nic) ));
|
#define ENTRY1(_nic, _name) m_list.add(new net_device_t_factory< _nic >( # _name, xstr(_nic) ));
|
||||||
@ -795,6 +553,7 @@ void netlist_factory::initialize()
|
|||||||
ENTRY(logic_input, NETDEV_LOGIC_INPUT)
|
ENTRY(logic_input, NETDEV_LOGIC_INPUT)
|
||||||
ENTRY(analog_input, NETDEV_ANALOG_INPUT)
|
ENTRY(analog_input, NETDEV_ANALOG_INPUT)
|
||||||
ENTRY(log, NETDEV_LOG)
|
ENTRY(log, NETDEV_LOG)
|
||||||
|
ENTRY(logD, NETDEV_LOGD)
|
||||||
ENTRY(clock, NETDEV_CLOCK)
|
ENTRY(clock, NETDEV_CLOCK)
|
||||||
ENTRY(mainclock, NETDEV_MAINCLOCK)
|
ENTRY(mainclock, NETDEV_MAINCLOCK)
|
||||||
ENTRY(solver, NETDEV_SOLVER)
|
ENTRY(solver, NETDEV_SOLVER)
|
||||||
|
@ -64,26 +64,24 @@
|
|||||||
#include "nld_7427.h"
|
#include "nld_7427.h"
|
||||||
#include "nld_7430.h"
|
#include "nld_7430.h"
|
||||||
#include "nld_7474.h"
|
#include "nld_7474.h"
|
||||||
|
#include "nld_7483.h"
|
||||||
#include "nld_7486.h"
|
#include "nld_7486.h"
|
||||||
|
#include "nld_7490.h"
|
||||||
#include "nld_7493.h"
|
#include "nld_7493.h"
|
||||||
|
#include "nld_9316.h"
|
||||||
|
|
||||||
#include "nld_NE555.h"
|
#include "nld_NE555.h"
|
||||||
|
|
||||||
#include "nld_log.h"
|
#include "nld_log.h"
|
||||||
|
|
||||||
|
#include "nld_solver.h"
|
||||||
|
|
||||||
// this is a bad hack
|
// this is a bad hack
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// Special chips
|
// Special chips
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#define NETDEV_LOGIC_INPUT(_name) \
|
|
||||||
NET_REGISTER_DEV(logic_input, _name)
|
|
||||||
#define NETDEV_ANALOG_INPUT(_name) \
|
|
||||||
NET_REGISTER_DEV(analog_input, _name)
|
|
||||||
#define NETDEV_CALLBACK(_name, _IN) \
|
|
||||||
NET_REGISTER_DEV(analog_callback, _name) \
|
|
||||||
NET_CONNECT(_name, IN, _IN)
|
|
||||||
#define NETDEV_SWITCH2(_name, _i1, _i2) \
|
#define NETDEV_SWITCH2(_name, _i1, _i2) \
|
||||||
NET_REGISTER_DEV(nicMultiSwitch, _name) \
|
NET_REGISTER_DEV(nicMultiSwitch, _name) \
|
||||||
NET_CONNECT(_name, i1, _i1) \
|
NET_CONNECT(_name, i1, _i1) \
|
||||||
@ -120,26 +118,6 @@
|
|||||||
NET_CONNECT(_name, BIQ, _BIQ) \
|
NET_CONNECT(_name, BIQ, _BIQ) \
|
||||||
NET_CONNECT(_name, RBIQ, _RBIQ)
|
NET_CONNECT(_name, RBIQ, _RBIQ)
|
||||||
|
|
||||||
#define TTL_7483(_name, _A1, _A2, _A3, _A4, _B1, _B2, _B3, _B4, _CI) \
|
|
||||||
NET_REGISTER_DEV(nic7483, _name) \
|
|
||||||
NET_CONNECT(_name, A1, _A1) \
|
|
||||||
NET_CONNECT(_name, A2, _A2) \
|
|
||||||
NET_CONNECT(_name, A3, _A3) \
|
|
||||||
NET_CONNECT(_name, A4, _A4) \
|
|
||||||
NET_CONNECT(_name, B1, _B1) \
|
|
||||||
NET_CONNECT(_name, B2, _B2) \
|
|
||||||
NET_CONNECT(_name, B3, _B3) \
|
|
||||||
NET_CONNECT(_name, B4, _B4) \
|
|
||||||
NET_CONNECT(_name, CI, _CI)
|
|
||||||
|
|
||||||
#define TTL_7490(_name, _CLK, _R1, _R2, _R91, _R92) \
|
|
||||||
NET_REGISTER_DEV(nic7490, _name) \
|
|
||||||
NET_CONNECT(_name, CLK, _CLK) \
|
|
||||||
NET_CONNECT(_name, R1, _R1) \
|
|
||||||
NET_CONNECT(_name, R2, _R2) \
|
|
||||||
NET_CONNECT(_name, R91, _R91) \
|
|
||||||
NET_CONNECT(_name, R92, _R92)
|
|
||||||
|
|
||||||
#define TTL_74107A(_name, _CLK, _J, _K, _CLRQ) \
|
#define TTL_74107A(_name, _CLK, _J, _K, _CLRQ) \
|
||||||
NET_REGISTER_DEV(nic74107A, _name) \
|
NET_REGISTER_DEV(nic74107A, _name) \
|
||||||
NET_CONNECT(_name, CLK, _CLK) \
|
NET_CONNECT(_name, CLK, _CLK) \
|
||||||
@ -160,18 +138,6 @@
|
|||||||
NET_CONNECT(_name, B, _B) \
|
NET_CONNECT(_name, B, _B) \
|
||||||
NET_CONNECT(_name, GA, _GA)
|
NET_CONNECT(_name, GA, _GA)
|
||||||
|
|
||||||
#define TTL_9316(_name, _CLK, _ENP, _ENT, _CLRQ, _LOADQ, _A, _B, _C, _D) \
|
|
||||||
NET_REGISTER_DEV(nic9316, _name) \
|
|
||||||
NET_CONNECT(_name, CLK, _CLK) \
|
|
||||||
NET_CONNECT(_name, ENP, _ENP) \
|
|
||||||
NET_CONNECT(_name, ENT, _ENT) \
|
|
||||||
NET_CONNECT(_name, CLRQ, _CLRQ) \
|
|
||||||
NET_CONNECT(_name, LOADQ,_LOADQ) \
|
|
||||||
NET_CONNECT(_name, A, _A) \
|
|
||||||
NET_CONNECT(_name, B, _B) \
|
|
||||||
NET_CONNECT(_name, C, _C) \
|
|
||||||
NET_CONNECT(_name, D, _D)
|
|
||||||
|
|
||||||
#define NE555N_MSTABLE(_name, _TRIG, _CV) \
|
#define NE555N_MSTABLE(_name, _TRIG, _CV) \
|
||||||
NET_REGISTER_DEV(nicNE555N_MSTABLE, _name) \
|
NET_REGISTER_DEV(nicNE555N_MSTABLE, _name) \
|
||||||
NET_CONNECT(_name, TRIG, _TRIG) \
|
NET_CONNECT(_name, TRIG, _TRIG) \
|
||||||
@ -183,18 +149,6 @@
|
|||||||
NET_CONNECT(_name, I2, _I2) \
|
NET_CONNECT(_name, I2, _I2) \
|
||||||
NET_CONNECT(_name, I3, _I3)
|
NET_CONNECT(_name, I3, _I3)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
|
||||||
// Special support devices ...
|
|
||||||
// ----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
NETLIB_DEVICE(logic_input,
|
|
||||||
netlist_ttl_output_t m_Q;
|
|
||||||
);
|
|
||||||
|
|
||||||
NETLIB_DEVICE(analog_input,
|
|
||||||
netlist_analog_output_t m_Q;
|
|
||||||
);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// Special devices ...
|
// Special devices ...
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
@ -308,73 +262,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
NETLIB_DEVICE(nic7490,
|
|
||||||
ATTR_HOT void update_outputs();
|
|
||||||
|
|
||||||
netlist_ttl_input_t m_R1;
|
|
||||||
netlist_ttl_input_t m_R2;
|
|
||||||
netlist_ttl_input_t m_R91;
|
|
||||||
netlist_ttl_input_t m_R92;
|
|
||||||
netlist_ttl_input_t m_clk;
|
|
||||||
|
|
||||||
UINT8 m_cnt;
|
|
||||||
|
|
||||||
netlist_ttl_output_t m_Q[4];
|
|
||||||
);
|
|
||||||
|
|
||||||
/* ripple-carry counter on low-high clock transition */
|
/* ripple-carry counter on low-high clock transition */
|
||||||
|
|
||||||
NETLIB_SUBDEVICE(nic9316_sub,
|
|
||||||
ATTR_HOT void update_outputs_all();
|
|
||||||
ATTR_HOT void update_outputs();
|
|
||||||
|
|
||||||
netlist_ttl_input_t m_clk;
|
|
||||||
|
|
||||||
netlist_ttl_input_t m_A;
|
|
||||||
netlist_ttl_input_t m_B;
|
|
||||||
netlist_ttl_input_t m_C;
|
|
||||||
netlist_ttl_input_t m_D;
|
|
||||||
|
|
||||||
UINT8 m_cnt;
|
|
||||||
netlist_sig_t m_loadq;
|
|
||||||
netlist_sig_t m_ent;
|
|
||||||
|
|
||||||
netlist_ttl_output_t m_QA;
|
|
||||||
netlist_ttl_output_t m_QB;
|
|
||||||
netlist_ttl_output_t m_QC;
|
|
||||||
netlist_ttl_output_t m_QD;
|
|
||||||
netlist_ttl_output_t m_RC;
|
|
||||||
);
|
|
||||||
|
|
||||||
NETLIB_DEVICE(nic9316,
|
|
||||||
NETLIB_NAME(nic9316_sub) sub;
|
|
||||||
netlist_ttl_input_t m_ENP;
|
|
||||||
netlist_ttl_input_t m_ENT;
|
|
||||||
netlist_ttl_input_t m_CLRQ;
|
|
||||||
netlist_ttl_input_t m_LOADQ;
|
|
||||||
);
|
|
||||||
|
|
||||||
NETLIB_DEVICE(nic7483,
|
|
||||||
netlist_ttl_input_t m_CI;
|
|
||||||
netlist_ttl_input_t m_A1;
|
|
||||||
netlist_ttl_input_t m_A2;
|
|
||||||
netlist_ttl_input_t m_A3;
|
|
||||||
netlist_ttl_input_t m_A4;
|
|
||||||
netlist_ttl_input_t m_B1;
|
|
||||||
netlist_ttl_input_t m_B2;
|
|
||||||
netlist_ttl_input_t m_B3;
|
|
||||||
netlist_ttl_input_t m_B4;
|
|
||||||
netlist_ttl_input_t m_clk;
|
|
||||||
|
|
||||||
UINT8 m_lastr;
|
|
||||||
|
|
||||||
netlist_ttl_output_t m_SA;
|
|
||||||
netlist_ttl_output_t m_SB;
|
|
||||||
netlist_ttl_output_t m_SC;
|
|
||||||
netlist_ttl_output_t m_SD;
|
|
||||||
netlist_ttl_output_t m_CO;
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
/* one half of a nic74153 */
|
/* one half of a nic74153 */
|
||||||
|
|
||||||
|
46
src/emu/netlist/devices/nld_7483.c
Normal file
46
src/emu/netlist/devices/nld_7483.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* nld_7483.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nld_7483.h"
|
||||||
|
|
||||||
|
NETLIB_START(nic7483)
|
||||||
|
{
|
||||||
|
m_lastr = 0;
|
||||||
|
|
||||||
|
register_input("A1", m_A1);
|
||||||
|
register_input("A2", m_A2);
|
||||||
|
register_input("A3", m_A3);
|
||||||
|
register_input("A4", m_A4);
|
||||||
|
register_input("B1", m_B1);
|
||||||
|
register_input("B2", m_B2);
|
||||||
|
register_input("B3", m_B3);
|
||||||
|
register_input("B4", m_B4);
|
||||||
|
register_input("C0", m_C0);
|
||||||
|
|
||||||
|
register_output("SA", m_SA);
|
||||||
|
register_output("SB", m_SB);
|
||||||
|
register_output("SC", m_SC);
|
||||||
|
register_output("SD", m_SD);
|
||||||
|
register_output("C4", m_C4);
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_UPDATE(nic7483)
|
||||||
|
{
|
||||||
|
UINT8 a = (INPLOGIC(m_A1) << 0) | (INPLOGIC(m_A2) << 1) | (INPLOGIC(m_A3) << 2) | (INPLOGIC(m_A4) << 3);
|
||||||
|
UINT8 b = (INPLOGIC(m_B1) << 0) | (INPLOGIC(m_B2) << 1) | (INPLOGIC(m_B3) << 2) | (INPLOGIC(m_B4) << 3);
|
||||||
|
|
||||||
|
UINT8 r = a + b + INPLOGIC(m_C0);
|
||||||
|
|
||||||
|
if (r != m_lastr)
|
||||||
|
{
|
||||||
|
m_lastr = r;
|
||||||
|
OUTLOGIC(m_SA, (r >> 0) & 1, NLTIME_FROM_NS(23));
|
||||||
|
OUTLOGIC(m_SB, (r >> 1) & 1, NLTIME_FROM_NS(23));
|
||||||
|
OUTLOGIC(m_SC, (r >> 2) & 1, NLTIME_FROM_NS(23));
|
||||||
|
OUTLOGIC(m_SD, (r >> 3) & 1, NLTIME_FROM_NS(23));
|
||||||
|
OUTLOGIC(m_C4, (r >> 4) & 1, NLTIME_FROM_NS(23));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
65
src/emu/netlist/devices/nld_7483.h
Normal file
65
src/emu/netlist/devices/nld_7483.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// license:GPL-2.0+
|
||||||
|
// copyright-holders:Couriersud
|
||||||
|
/*
|
||||||
|
* nld_7483.h
|
||||||
|
*
|
||||||
|
* DM7483: 4-Bit Binary Adder with Fast Carry
|
||||||
|
*
|
||||||
|
* +--------------+
|
||||||
|
* A4 |1 ++ 16| B4
|
||||||
|
* Ʃ3 |2 15| Ʃ3
|
||||||
|
* A3 |3 14| C4
|
||||||
|
* B3 |4 7483 13| C0
|
||||||
|
* VCC |5 12| GND
|
||||||
|
* Ʃ3 |6 11| B1
|
||||||
|
* B2 |7 10| A1
|
||||||
|
* A2 |8 9| Ʃ3
|
||||||
|
* +--------------+
|
||||||
|
*
|
||||||
|
* Ʃ = (A + B + C) & 0x0f
|
||||||
|
*
|
||||||
|
* C4 = (A + B + C) > 15 ? 1 : 0
|
||||||
|
*
|
||||||
|
* Naming conventions follow Fairchild Semiconductor datasheet
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NLD_7483_H_
|
||||||
|
#define NLD_7483_H_
|
||||||
|
|
||||||
|
#include "../nl_base.h"
|
||||||
|
|
||||||
|
#define TTL_7483(_name, _A1, _A2, _A3, _A4, _B1, _B2, _B3, _B4, _CI) \
|
||||||
|
NET_REGISTER_DEV(nic7483, _name) \
|
||||||
|
NET_CONNECT(_name, A1, _A1) \
|
||||||
|
NET_CONNECT(_name, A2, _A2) \
|
||||||
|
NET_CONNECT(_name, A3, _A3) \
|
||||||
|
NET_CONNECT(_name, A4, _A4) \
|
||||||
|
NET_CONNECT(_name, B1, _B1) \
|
||||||
|
NET_CONNECT(_name, B2, _B2) \
|
||||||
|
NET_CONNECT(_name, B3, _B3) \
|
||||||
|
NET_CONNECT(_name, B4, _B4) \
|
||||||
|
NET_CONNECT(_name, C0, _CI)
|
||||||
|
|
||||||
|
NETLIB_DEVICE(nic7483,
|
||||||
|
netlist_ttl_input_t m_C0;
|
||||||
|
netlist_ttl_input_t m_A1;
|
||||||
|
netlist_ttl_input_t m_A2;
|
||||||
|
netlist_ttl_input_t m_A3;
|
||||||
|
netlist_ttl_input_t m_A4;
|
||||||
|
netlist_ttl_input_t m_B1;
|
||||||
|
netlist_ttl_input_t m_B2;
|
||||||
|
netlist_ttl_input_t m_B3;
|
||||||
|
netlist_ttl_input_t m_B4;
|
||||||
|
|
||||||
|
UINT8 m_lastr;
|
||||||
|
|
||||||
|
netlist_ttl_output_t m_SA;
|
||||||
|
netlist_ttl_output_t m_SB;
|
||||||
|
netlist_ttl_output_t m_SC;
|
||||||
|
netlist_ttl_output_t m_SD;
|
||||||
|
netlist_ttl_output_t m_C4;
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif /* NLD_7483_H_ */
|
59
src/emu/netlist/devices/nld_7490.c
Normal file
59
src/emu/netlist/devices/nld_7490.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* nld_7490.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nld_7490.h"
|
||||||
|
|
||||||
|
NETLIB_START(nic7490)
|
||||||
|
{
|
||||||
|
m_cnt = 0;
|
||||||
|
|
||||||
|
register_input("CLK", m_clk);
|
||||||
|
register_input("R1", m_R1);
|
||||||
|
register_input("R2", m_R2);
|
||||||
|
register_input("R91", m_R91);
|
||||||
|
register_input("R92", m_R92);
|
||||||
|
|
||||||
|
register_output("QA", m_Q[0]);
|
||||||
|
register_output("QB", m_Q[1]);
|
||||||
|
register_output("QC", m_Q[2]);
|
||||||
|
register_output("QD", m_Q[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_UPDATE(nic7490)
|
||||||
|
{
|
||||||
|
if (INPLOGIC(m_R91) & INPLOGIC(m_R92))
|
||||||
|
{
|
||||||
|
m_cnt = 9;
|
||||||
|
update_outputs();
|
||||||
|
}
|
||||||
|
else if (INPLOGIC(m_R1) & INPLOGIC(m_R2))
|
||||||
|
{
|
||||||
|
m_cnt = 0;
|
||||||
|
update_outputs();
|
||||||
|
}
|
||||||
|
else if (INP_HL(m_clk))
|
||||||
|
{
|
||||||
|
m_cnt++;
|
||||||
|
if (m_cnt >= 10)
|
||||||
|
m_cnt = 0;
|
||||||
|
update_outputs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
NETLIB_FUNC_VOID(nic7490, update_outputs)
|
||||||
|
{
|
||||||
|
OUTLOGIC(m_QA, (m_cnt >> 0) & 1, NLTIME_FROM_NS(18));
|
||||||
|
OUTLOGIC(m_QB, (m_cnt >> 1) & 1, NLTIME_FROM_NS(36));
|
||||||
|
OUTLOGIC(m_QC, (m_cnt >> 2) & 1, NLTIME_FROM_NS(54));
|
||||||
|
OUTLOGIC(m_QD, (m_cnt >> 3) & 1, NLTIME_FROM_NS(72));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
NETLIB_FUNC_VOID(nic7490, update_outputs, (void))
|
||||||
|
{
|
||||||
|
const netlist_time delay[4] = { NLTIME_FROM_NS(18), NLTIME_FROM_NS(36), NLTIME_FROM_NS(54), NLTIME_FROM_NS(72) };
|
||||||
|
for (int i=0; i<4; i++)
|
||||||
|
OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
|
||||||
|
}
|
||||||
|
#endif
|
83
src/emu/netlist/devices/nld_7490.h
Normal file
83
src/emu/netlist/devices/nld_7490.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// license:GPL-2.0+
|
||||||
|
// copyright-holders:Couriersud
|
||||||
|
/*
|
||||||
|
* nld_7490.h
|
||||||
|
*
|
||||||
|
* DM7490: Decade Counters
|
||||||
|
*
|
||||||
|
* +--------------+
|
||||||
|
* B |1 ++ 14| A
|
||||||
|
* R01 |2 13| NC
|
||||||
|
* R02 |3 12| QA
|
||||||
|
* NC |4 7490 11| QD
|
||||||
|
* VCC |5 10| GND
|
||||||
|
* R91 |6 9| QB
|
||||||
|
* R92 |7 8| QC
|
||||||
|
* +--------------+
|
||||||
|
*
|
||||||
|
* Counter Sequence
|
||||||
|
*
|
||||||
|
* +-------++----+----+----+----+
|
||||||
|
* | COUNT || QD | QC | QB | QA |
|
||||||
|
* +=======++====+====+====+====+
|
||||||
|
* | 0 || 0 | 0 | 0 | 0 |
|
||||||
|
* | 1 || 0 | 0 | 0 | 1 |
|
||||||
|
* | 2 || 0 | 0 | 1 | 0 |
|
||||||
|
* | 3 || 0 | 0 | 1 | 1 |
|
||||||
|
* | 4 || 0 | 1 | 0 | 0 |
|
||||||
|
* | 5 || 0 | 1 | 0 | 1 |
|
||||||
|
* | 6 || 0 | 1 | 1 | 0 |
|
||||||
|
* | 7 || 0 | 1 | 1 | 1 |
|
||||||
|
* | 8 || 1 | 0 | 0 | 0 |
|
||||||
|
* | 9 || 1 | 0 | 0 | 1 |
|
||||||
|
* +-------++----+----+----+----+
|
||||||
|
*
|
||||||
|
* Note A Output QA is connected to input B for BCD count
|
||||||
|
*
|
||||||
|
* Reset Count Function table
|
||||||
|
*
|
||||||
|
* +-----+-----+-----+-----++----+----+----+----+
|
||||||
|
* | R01 | R02 | R91 | R92 || QD | QC | QB | QA |
|
||||||
|
* +=====+=====+=====+=====++====+====+====+====+
|
||||||
|
* | 1 | 1 | 0 | X || 0 | 0 | 0 | 0 |
|
||||||
|
* | 1 | 1 | X | 0 || 0 | 0 | 0 | 0 |
|
||||||
|
* | X | X | 1 | 1 || 1 | 0 | 0 | 1 |
|
||||||
|
* | X | 0 | X | 0 || COUNT |
|
||||||
|
* | 0 | X | 0 | X || COUNT |
|
||||||
|
* | 0 | X | X | 0 || COUNT |
|
||||||
|
* | X | 0 | 0 | X || COUNT |
|
||||||
|
* +-----+-----+-----+-----++----+----+----+----+
|
||||||
|
*
|
||||||
|
* Naming conventions follow National Semiconductor datasheet
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NLD_7490_H_
|
||||||
|
#define NLD_7490_H_
|
||||||
|
|
||||||
|
#include "../nl_base.h"
|
||||||
|
|
||||||
|
#define TTL_7490(_name, _CLK, _R1, _R2, _R91, _R92) \
|
||||||
|
NET_REGISTER_DEV(nic7490, _name) \
|
||||||
|
NET_CONNECT(_name, CLK, _CLK) \
|
||||||
|
NET_CONNECT(_name, R1, _R1) \
|
||||||
|
NET_CONNECT(_name, R2, _R2) \
|
||||||
|
NET_CONNECT(_name, R91, _R91) \
|
||||||
|
NET_CONNECT(_name, R92, _R92)
|
||||||
|
|
||||||
|
|
||||||
|
NETLIB_DEVICE(nic7490,
|
||||||
|
ATTR_HOT void update_outputs();
|
||||||
|
|
||||||
|
netlist_ttl_input_t m_R1;
|
||||||
|
netlist_ttl_input_t m_R2;
|
||||||
|
netlist_ttl_input_t m_R91;
|
||||||
|
netlist_ttl_input_t m_R92;
|
||||||
|
netlist_ttl_input_t m_clk;
|
||||||
|
|
||||||
|
UINT8 m_cnt;
|
||||||
|
|
||||||
|
netlist_ttl_output_t m_Q[4];
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif /* NLD_7490_H_ */
|
@ -3,7 +3,7 @@
|
|||||||
/*
|
/*
|
||||||
* nld_7493.h
|
* nld_7493.h
|
||||||
*
|
*
|
||||||
* DM7493: Quad 2-Input NAND Gates
|
* DM7493: Binary Counters
|
||||||
*
|
*
|
||||||
* +--------------+
|
* +--------------+
|
||||||
* B |1 ++ 14| A
|
* B |1 ++ 14| A
|
||||||
@ -38,10 +38,12 @@
|
|||||||
* | 15 || 1 | 1 | 1 | 1 |
|
* | 15 || 1 | 1 | 1 | 1 |
|
||||||
* +-------++----+----+----+----+
|
* +-------++----+----+----+----+
|
||||||
*
|
*
|
||||||
|
* Note C Output QA is connected to input B
|
||||||
|
*
|
||||||
* Reset Count Function table
|
* Reset Count Function table
|
||||||
*
|
*
|
||||||
* +-----+-----++----+----+----+----+
|
* +-----+-----++----+----+----+----+
|
||||||
* | R01 | R01 || QD | QC | QB | QA |
|
* | R01 | R02 || QD | QC | QB | QA |
|
||||||
* +=====+=====++====+====+====+====+
|
* +=====+=====++====+====+====+====+
|
||||||
* | 1 | 1 || 0 | 0 | 0 | 0 |
|
* | 1 | 1 || 0 | 0 | 0 | 0 |
|
||||||
* | 0 | X || COUNT |
|
* | 0 | X || COUNT |
|
||||||
|
143
src/emu/netlist/devices/nld_9316.c
Normal file
143
src/emu/netlist/devices/nld_9316.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* nld_9316.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nld_9316.h"
|
||||||
|
|
||||||
|
NETLIB_START(nic9316)
|
||||||
|
{
|
||||||
|
register_sub(sub, "sub");
|
||||||
|
|
||||||
|
register_subalias("CLK", sub.m_clk);
|
||||||
|
|
||||||
|
register_input("ENP", m_ENP);
|
||||||
|
register_input("ENT", m_ENT);
|
||||||
|
register_input("CLRQ", m_CLRQ);
|
||||||
|
register_input("LOADQ", m_LOADQ);
|
||||||
|
|
||||||
|
register_subalias("A", sub.m_A);
|
||||||
|
register_subalias("B", sub.m_B);
|
||||||
|
register_subalias("C", sub.m_C);
|
||||||
|
register_subalias("D", sub.m_D);
|
||||||
|
|
||||||
|
register_subalias("QA", sub.m_QA);
|
||||||
|
register_subalias("QB", sub.m_QB);
|
||||||
|
register_subalias("QC", sub.m_QC);
|
||||||
|
register_subalias("QD", sub.m_QD);
|
||||||
|
register_subalias("RC", sub.m_RC);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_START(nic9316_sub)
|
||||||
|
{
|
||||||
|
m_cnt = 0;
|
||||||
|
m_loadq = 1;
|
||||||
|
m_ent = 1;
|
||||||
|
|
||||||
|
register_input("CLK", m_clk, netlist_input_t::STATE_INP_LH);
|
||||||
|
|
||||||
|
register_input("A", m_A, netlist_input_t::STATE_INP_PASSIVE);
|
||||||
|
register_input("B", m_B, netlist_input_t::STATE_INP_PASSIVE);
|
||||||
|
register_input("C", m_C, netlist_input_t::STATE_INP_PASSIVE);
|
||||||
|
register_input("D", m_D, netlist_input_t::STATE_INP_PASSIVE);
|
||||||
|
|
||||||
|
register_output("QA", m_QA);
|
||||||
|
register_output("QB", m_QB);
|
||||||
|
register_output("QC", m_QC);
|
||||||
|
register_output("QD", m_QD);
|
||||||
|
register_output("RC", m_RC);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_UPDATE(nic9316_sub)
|
||||||
|
{
|
||||||
|
if (m_loadq)
|
||||||
|
{
|
||||||
|
m_cnt = ( m_cnt + 1) & 0x0f;
|
||||||
|
update_outputs();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_cnt = (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
|
||||||
|
update_outputs_all();
|
||||||
|
}
|
||||||
|
OUTLOGIC(m_RC, m_ent & (m_cnt == 0x0f), NLTIME_FROM_NS(20));
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_UPDATE(nic9316)
|
||||||
|
{
|
||||||
|
sub.m_loadq = INPLOGIC(m_LOADQ);
|
||||||
|
sub.m_ent = INPLOGIC(m_ENT);
|
||||||
|
const netlist_sig_t clrq = INPLOGIC(m_CLRQ);
|
||||||
|
|
||||||
|
if ((!sub.m_loadq || (sub.m_ent & INPLOGIC(m_ENP))) & clrq)
|
||||||
|
{
|
||||||
|
sub.m_clk.activate_lh();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sub.m_clk.inactivate();
|
||||||
|
if (!clrq & (sub.m_cnt>0))
|
||||||
|
{
|
||||||
|
sub.m_cnt = 0;
|
||||||
|
sub.update_outputs();
|
||||||
|
OUTLOGIC(sub.m_RC, 0, NLTIME_FROM_NS(20));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == 0x0f), NLTIME_FROM_NS(20));
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_FUNC_VOID(nic9316_sub, update_outputs_all, (void))
|
||||||
|
{
|
||||||
|
const netlist_time out_delay = NLTIME_FROM_NS(20);
|
||||||
|
OUTLOGIC(m_QA, (m_cnt >> 0) & 1, out_delay);
|
||||||
|
OUTLOGIC(m_QB, (m_cnt >> 1) & 1, out_delay);
|
||||||
|
OUTLOGIC(m_QC, (m_cnt >> 2) & 1, out_delay);
|
||||||
|
OUTLOGIC(m_QD, (m_cnt >> 3) & 1, out_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_FUNC_VOID(nic9316_sub, update_outputs, (void))
|
||||||
|
{
|
||||||
|
const netlist_time out_delay = NLTIME_FROM_NS(20);
|
||||||
|
#if 0
|
||||||
|
OUTLOGIC(m_QA, (m_cnt >> 0) & 1, out_delay);
|
||||||
|
OUTLOGIC(m_QB, (m_cnt >> 1) & 1, out_delay);
|
||||||
|
OUTLOGIC(m_QC, (m_cnt >> 2) & 1, out_delay);
|
||||||
|
OUTLOGIC(m_QD, (m_cnt >> 3) & 1, out_delay);
|
||||||
|
#else
|
||||||
|
if ((m_cnt & 1) == 1)
|
||||||
|
OUTLOGIC(m_QA, 1, out_delay);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OUTLOGIC(m_QA, 0, out_delay);
|
||||||
|
switch (m_cnt)
|
||||||
|
{
|
||||||
|
case 0x00:
|
||||||
|
OUTLOGIC(m_QB, 0, out_delay);
|
||||||
|
OUTLOGIC(m_QC, 0, out_delay);
|
||||||
|
OUTLOGIC(m_QD, 0, out_delay);
|
||||||
|
break;
|
||||||
|
case 0x02:
|
||||||
|
case 0x06:
|
||||||
|
case 0x0A:
|
||||||
|
case 0x0E:
|
||||||
|
OUTLOGIC(m_QB, 1, out_delay);
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
case 0x0C:
|
||||||
|
OUTLOGIC(m_QB, 0, out_delay);
|
||||||
|
OUTLOGIC(m_QC, 1, out_delay);
|
||||||
|
break;
|
||||||
|
case 0x08:
|
||||||
|
OUTLOGIC(m_QB, 0, out_delay);
|
||||||
|
OUTLOGIC(m_QC, 0, out_delay);
|
||||||
|
OUTLOGIC(m_QD, 1, out_delay);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
96
src/emu/netlist/devices/nld_9316.h
Normal file
96
src/emu/netlist/devices/nld_9316.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// license:GPL-2.0+
|
||||||
|
// copyright-holders:Couriersud
|
||||||
|
/*
|
||||||
|
* nld_9316.h
|
||||||
|
*
|
||||||
|
* DM9316: Synchronous 4-Bit Counters
|
||||||
|
*
|
||||||
|
* +--------------+
|
||||||
|
* CLEAR |1 ++ 16| VCC
|
||||||
|
* CLOCK |2 15| RC (Ripple Carry)
|
||||||
|
* A |3 14| QA
|
||||||
|
* B |4 9316 13| QB
|
||||||
|
* C |5 12| QC
|
||||||
|
* D |6 11| QD
|
||||||
|
* Enable P |7 10| Enable T
|
||||||
|
* GND |8 9| LOAD
|
||||||
|
* +--------------+
|
||||||
|
*
|
||||||
|
* Counter Sequence
|
||||||
|
*
|
||||||
|
* +-------++----+----+----+----+----+
|
||||||
|
* | COUNT || QD | QC | QB | QA | RC |
|
||||||
|
* +=======++====+====+====+====+====+
|
||||||
|
* | 0 || 0 | 0 | 0 | 0 | 0 |
|
||||||
|
* | 1 || 0 | 0 | 0 | 1 | 0 |
|
||||||
|
* | 2 || 0 | 0 | 1 | 0 | 0 |
|
||||||
|
* | 3 || 0 | 0 | 1 | 1 | 0 |
|
||||||
|
* | 4 || 0 | 1 | 0 | 0 | 0 |
|
||||||
|
* | 5 || 0 | 1 | 0 | 1 | 0 |
|
||||||
|
* | 6 || 0 | 1 | 1 | 0 | 0 |
|
||||||
|
* | 7 || 0 | 1 | 1 | 1 | 0 |
|
||||||
|
* | 8 || 1 | 0 | 0 | 0 | 0 |
|
||||||
|
* | 9 || 1 | 0 | 0 | 1 | 0 |
|
||||||
|
* | 10 || 1 | 0 | 1 | 0 | 0 |
|
||||||
|
* | 11 || 1 | 0 | 1 | 1 | 0 |
|
||||||
|
* | 12 || 1 | 1 | 0 | 0 | 0 |
|
||||||
|
* | 13 || 1 | 1 | 0 | 1 | 0 |
|
||||||
|
* | 14 || 1 | 1 | 1 | 0 | 0 |
|
||||||
|
* | 15 || 1 | 1 | 1 | 1 | 1 |
|
||||||
|
* +-------++----+----+----+----+----+
|
||||||
|
*
|
||||||
|
* Reset count function: Please refer to
|
||||||
|
* National Semiconductor datasheet (timing diagramm)
|
||||||
|
*
|
||||||
|
* Naming conventions follow National Semiconductor datasheet
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NLD_9316_H_
|
||||||
|
#define NLD_9316_H_
|
||||||
|
|
||||||
|
#include "../nl_base.h"
|
||||||
|
|
||||||
|
#define TTL_9316(_name, _CLK, _ENP, _ENT, _CLRQ, _LOADQ, _A, _B, _C, _D) \
|
||||||
|
NET_REGISTER_DEV(nic9316, _name) \
|
||||||
|
NET_CONNECT(_name, CLK, _CLK) \
|
||||||
|
NET_CONNECT(_name, ENP, _ENP) \
|
||||||
|
NET_CONNECT(_name, ENT, _ENT) \
|
||||||
|
NET_CONNECT(_name, CLRQ, _CLRQ) \
|
||||||
|
NET_CONNECT(_name, LOADQ,_LOADQ) \
|
||||||
|
NET_CONNECT(_name, A, _A) \
|
||||||
|
NET_CONNECT(_name, B, _B) \
|
||||||
|
NET_CONNECT(_name, C, _C) \
|
||||||
|
NET_CONNECT(_name, D, _D)
|
||||||
|
|
||||||
|
NETLIB_SUBDEVICE(nic9316_sub,
|
||||||
|
ATTR_HOT void update_outputs_all();
|
||||||
|
ATTR_HOT void update_outputs();
|
||||||
|
|
||||||
|
netlist_ttl_input_t m_clk;
|
||||||
|
|
||||||
|
netlist_ttl_input_t m_A;
|
||||||
|
netlist_ttl_input_t m_B;
|
||||||
|
netlist_ttl_input_t m_C;
|
||||||
|
netlist_ttl_input_t m_D;
|
||||||
|
|
||||||
|
UINT8 m_cnt;
|
||||||
|
netlist_sig_t m_loadq;
|
||||||
|
netlist_sig_t m_ent;
|
||||||
|
|
||||||
|
netlist_ttl_output_t m_QA;
|
||||||
|
netlist_ttl_output_t m_QB;
|
||||||
|
netlist_ttl_output_t m_QC;
|
||||||
|
netlist_ttl_output_t m_QD;
|
||||||
|
netlist_ttl_output_t m_RC;
|
||||||
|
);
|
||||||
|
|
||||||
|
NETLIB_DEVICE(nic9316,
|
||||||
|
NETLIB_NAME(nic9316_sub) sub;
|
||||||
|
netlist_ttl_input_t m_ENP;
|
||||||
|
netlist_ttl_input_t m_ENT;
|
||||||
|
netlist_ttl_input_t m_CLRQ;
|
||||||
|
netlist_ttl_input_t m_LOADQ;
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif /* NLD_9316_H_ */
|
@ -24,6 +24,17 @@ NETLIB_NAME(log)::~NETLIB_NAME(log)()
|
|||||||
fclose(m_file);
|
fclose(m_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NETLIB_START(logD)
|
||||||
|
{
|
||||||
|
NETLIB_NAME(log)::start();
|
||||||
|
register_input("I2", m_I2);
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_UPDATE(logD)
|
||||||
|
{
|
||||||
|
fprintf(m_file, "%e %e\n", netlist().time().as_double(), INPANALOG(m_I) - INPANALOG(m_I2));
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Implement wav later, this must be clock triggered device where the input to be written
|
// FIXME: Implement wav later, this must be clock triggered device where the input to be written
|
||||||
// is on a subdevice ...
|
// is on a subdevice ...
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -27,10 +27,19 @@
|
|||||||
NETLIB_DEVICE(log,
|
NETLIB_DEVICE(log,
|
||||||
~NETLIB_NAME(log)();
|
~NETLIB_NAME(log)();
|
||||||
netlist_analog_input_t m_I;
|
netlist_analog_input_t m_I;
|
||||||
private:
|
protected:
|
||||||
FILE *m_file;
|
FILE *m_file;
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#define NETDEV_LOGD(_name, _I, _I2) \
|
||||||
|
NET_REGISTER_DEV(logD, _name) \
|
||||||
|
NET_CONNECT(_name, I, _I) \
|
||||||
|
NET_CONNECT(_name, I2, _I2)
|
||||||
|
|
||||||
|
NETLIB_DEVICE_DERIVED(logD, log,
|
||||||
|
netlist_analog_input_t m_I2;
|
||||||
|
);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
NETLIB_DEVICE(wav,
|
NETLIB_DEVICE(wav,
|
||||||
~NETLIB_NAME(wav)();
|
~NETLIB_NAME(wav)();
|
||||||
|
333
src/emu/netlist/devices/nld_solver.c
Normal file
333
src/emu/netlist/devices/nld_solver.c
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
/*
|
||||||
|
* nld_solver.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nld_solver.h"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
// netlist_matrix_solver
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets)
|
||||||
|
{
|
||||||
|
for (netlist_net_t::list_t::entry_t *pn = nets.first(); pn != NULL; pn = nets.next(pn))
|
||||||
|
{
|
||||||
|
NL_VERBOSE_OUT(("setting up net\n"));
|
||||||
|
|
||||||
|
m_nets.add(pn->object());
|
||||||
|
pn->object()->m_solver = this;
|
||||||
|
|
||||||
|
for (netlist_core_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
|
||||||
|
{
|
||||||
|
switch (p->type())
|
||||||
|
{
|
||||||
|
case netlist_terminal_t::TERMINAL:
|
||||||
|
switch (p->netdev().family())
|
||||||
|
{
|
||||||
|
case netlist_device_t::CAPACITOR:
|
||||||
|
if (!m_steps.contains(&p->netdev()))
|
||||||
|
m_steps.add(&p->netdev());
|
||||||
|
break;
|
||||||
|
case netlist_device_t::DIODE:
|
||||||
|
//case netlist_device_t::VCVS:
|
||||||
|
//case netlist_device_t::BJT_SWITCH:
|
||||||
|
if (!m_dynamic.contains(&p->netdev()))
|
||||||
|
m_dynamic.add(&p->netdev());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pn->object()->m_terms.add(static_cast<netlist_terminal_t *>(p));
|
||||||
|
NL_VERBOSE_OUT(("Added terminal\n"));
|
||||||
|
break;
|
||||||
|
case netlist_terminal_t::INPUT:
|
||||||
|
if (!m_inps.contains(&p->netdev()))
|
||||||
|
m_inps.add(&p->netdev());
|
||||||
|
NL_VERBOSE_OUT(("Added input\n"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fatalerror("unhandled element found\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTR_HOT inline void netlist_matrix_solver_t::step(const netlist_time delta)
|
||||||
|
{
|
||||||
|
const double dd = delta.as_double();
|
||||||
|
for (dev_list_t::entry_t *p = m_steps.first(); p != NULL; p = m_steps.next(p))
|
||||||
|
p->object()->step_time(dd);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTR_HOT inline void netlist_matrix_solver_t::update_inputs()
|
||||||
|
{
|
||||||
|
for (dev_list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p))
|
||||||
|
p->object()->update_dev();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ATTR_HOT inline bool netlist_matrix_solver_t::solve()
|
||||||
|
{
|
||||||
|
bool resched = false;
|
||||||
|
|
||||||
|
/* update all non-linear devices */
|
||||||
|
for (dev_list_t::entry_t *p = m_dynamic.first(); p != NULL; p = m_dynamic.next(p))
|
||||||
|
p->object()->update_terminals();
|
||||||
|
|
||||||
|
for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
|
||||||
|
{
|
||||||
|
netlist_net_t *net = pn->object();
|
||||||
|
|
||||||
|
double gtot = 0;
|
||||||
|
double gabs = 0;
|
||||||
|
double iIdr = 0;
|
||||||
|
const netlist_net_t::terminal_list_t &terms = net->m_terms;
|
||||||
|
#if 1
|
||||||
|
switch (terms.count())
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
const netlist_terminal_t *pt = terms.first()->object();
|
||||||
|
gtot = pt->m_gt;
|
||||||
|
gabs = fabs(pt->m_go);
|
||||||
|
iIdr = pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
const netlist_terminal_t *pt1 = terms[0];
|
||||||
|
const netlist_terminal_t *pt2 = terms[1];
|
||||||
|
gtot = pt1->m_gt + pt2->m_gt;
|
||||||
|
gabs = fabs(pt1->m_go) + fabs(pt2->m_go);
|
||||||
|
iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
|
||||||
|
+ pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
const netlist_terminal_t *pt1 = terms[0];
|
||||||
|
const netlist_terminal_t *pt2 = terms[1];
|
||||||
|
const netlist_terminal_t *pt3 = terms[2];
|
||||||
|
gtot = pt1->m_gt + pt2->m_gt + pt3->m_gt;
|
||||||
|
gabs = fabs(pt1->m_go) + fabs(pt2->m_go) + fabs(pt3->m_go);
|
||||||
|
iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
|
||||||
|
+ pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog()
|
||||||
|
+ pt3->m_Idr + pt3->m_go * pt3->m_otherterm->net().Q_Analog();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
|
||||||
|
{
|
||||||
|
netlist_terminal_t *pt = e->object();
|
||||||
|
gtot += pt->m_gt;
|
||||||
|
gabs += fabs(pt->m_go);
|
||||||
|
iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
|
||||||
|
{
|
||||||
|
netlist_terminal_t *pt = e->object();
|
||||||
|
gtot += pt->m_gt;
|
||||||
|
gabs += fabs(pt->m_go);
|
||||||
|
iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
double new_val;
|
||||||
|
gabs *= m_convergence_factor;
|
||||||
|
if (gabs > gtot)
|
||||||
|
new_val = (net->m_cur.Analog * gabs + iIdr) / (gtot + gabs);
|
||||||
|
else
|
||||||
|
new_val = iIdr / gtot;
|
||||||
|
|
||||||
|
if (fabs(new_val - net->m_cur.Analog) > m_accuracy)
|
||||||
|
resched = true;
|
||||||
|
net->m_cur.Analog = net->m_new.Analog = new_val;
|
||||||
|
|
||||||
|
NL_VERBOSE_OUT(("Info: %d\n", pn->object()->m_num_cons));
|
||||||
|
NL_VERBOSE_OUT(("New: %lld %f %f\n", netlist().time().as_raw(), netlist().time().as_double(), new_val));
|
||||||
|
}
|
||||||
|
return resched;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
// solver
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef netlist_net_t::list_t *net_groups_t;
|
||||||
|
|
||||||
|
static bool already_processed(net_groups_t groups, int &cur_group, netlist_net_t *net)
|
||||||
|
{
|
||||||
|
if (net->isRailNet())
|
||||||
|
return true;
|
||||||
|
for (int i = 0; i <= cur_group; i++)
|
||||||
|
{
|
||||||
|
if (groups[i].contains(net))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void process_net(net_groups_t groups, int &cur_group, netlist_net_t *net)
|
||||||
|
{
|
||||||
|
/* add the net */
|
||||||
|
groups[cur_group].add(net);
|
||||||
|
for (netlist_core_terminal_t *p = net->m_head; p != NULL; p = p->m_update_list_next)
|
||||||
|
{
|
||||||
|
if (p->isType(netlist_terminal_t::TERMINAL))
|
||||||
|
{
|
||||||
|
netlist_terminal_t *pt = static_cast<netlist_terminal_t *>(p);
|
||||||
|
netlist_net_t *nnet = &pt->m_otherterm->net();
|
||||||
|
if (!already_processed(groups, cur_group, nnet))
|
||||||
|
process_net(groups, cur_group, nnet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NETLIB_START(solver)
|
||||||
|
{
|
||||||
|
register_output("Q_sync", m_Q_sync);
|
||||||
|
register_output("Q_step", m_Q_step);
|
||||||
|
//register_input("FB", m_feedback);
|
||||||
|
|
||||||
|
register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_NS(10).as_double());
|
||||||
|
m_nt_sync_delay = m_sync_delay.Value();
|
||||||
|
|
||||||
|
register_param("FREQ", m_freq, 48000.0);
|
||||||
|
m_inc = netlist_time::from_hz(m_freq.Value());
|
||||||
|
|
||||||
|
register_param("ACCURACY", m_accuracy, 1e-3);
|
||||||
|
register_param("CONVERG", m_convergence, 0.3);
|
||||||
|
|
||||||
|
register_link_internal(m_fb_sync, m_Q_sync, netlist_input_t::STATE_INP_ACTIVE);
|
||||||
|
register_link_internal(m_fb_step, m_Q_step, netlist_input_t::STATE_INP_ACTIVE);
|
||||||
|
m_last_step = netlist_time::zero;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_UPDATE_PARAM(solver)
|
||||||
|
{
|
||||||
|
m_inc = netlist_time::from_hz(m_freq.Value());
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_NAME(solver)::~NETLIB_NAME(solver)()
|
||||||
|
{
|
||||||
|
netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first();
|
||||||
|
while (e != NULL)
|
||||||
|
{
|
||||||
|
netlist_matrix_solver_t::list_t::entry_t *en = m_mat_solvers.next(e);
|
||||||
|
delete e->object();
|
||||||
|
e = en;
|
||||||
|
}
|
||||||
|
|
||||||
|
netlist_net_t::list_t::entry_t *p = m_nets.first();
|
||||||
|
while (p != NULL)
|
||||||
|
{
|
||||||
|
netlist_net_t::list_t::entry_t *pn = m_nets.next(p);
|
||||||
|
delete p->object();
|
||||||
|
p = pn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_FUNC_VOID(solver, post_start, ())
|
||||||
|
{
|
||||||
|
netlist_net_t::list_t groups[100];
|
||||||
|
int cur_group = -1;
|
||||||
|
|
||||||
|
NL_VERBOSE_OUT(("post start solver ...\n"));
|
||||||
|
|
||||||
|
// delete empty nets ...
|
||||||
|
for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
|
||||||
|
{
|
||||||
|
if (pn->object()->m_head == NULL)
|
||||||
|
{
|
||||||
|
NL_VERBOSE_OUT(("Deleting net ...\n"));
|
||||||
|
netlist_net_t *to_delete = pn->object();
|
||||||
|
m_nets.remove(to_delete);
|
||||||
|
delete to_delete;
|
||||||
|
pn--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Scanning net groups ...\n");
|
||||||
|
// determine net groups
|
||||||
|
for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
|
||||||
|
{
|
||||||
|
if (!already_processed(groups, cur_group, pn->object()))
|
||||||
|
{
|
||||||
|
cur_group++;
|
||||||
|
process_net(groups, cur_group, pn->object());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup the solvers
|
||||||
|
printf("Found %d net groups in %d nets\n", cur_group + 1, m_nets.count());
|
||||||
|
for (int i = 0; i <= cur_group; i++)
|
||||||
|
{
|
||||||
|
netlist_matrix_solver_t *ms = new netlist_matrix_solver_t;
|
||||||
|
ms->m_accuracy = m_accuracy.Value();
|
||||||
|
ms->m_convergence_factor = m_convergence.Value();
|
||||||
|
ms->setup(groups[i]);
|
||||||
|
m_mat_solvers.add(ms);
|
||||||
|
printf("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr());
|
||||||
|
printf(" has %s elements\n", ms->is_dynamic() ? "dynamic" : "no dynamic");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NETLIB_UPDATE(solver)
|
||||||
|
{
|
||||||
|
//m_Q.setToNoCheck(!m_Q.new_Q(), m_inc );
|
||||||
|
//OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc );
|
||||||
|
|
||||||
|
bool resched = false;
|
||||||
|
int resched_cnt = 0;
|
||||||
|
netlist_time now = netlist().time();
|
||||||
|
netlist_time delta = now - m_last_step;
|
||||||
|
|
||||||
|
if (delta >= m_inc)
|
||||||
|
{
|
||||||
|
NL_VERBOSE_OUT(("Step!\n"));
|
||||||
|
/* update all terminals for new time step */
|
||||||
|
m_last_step = now;
|
||||||
|
for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
|
||||||
|
{
|
||||||
|
e->object()->step(delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool global_resched = false;
|
||||||
|
for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
|
||||||
|
{
|
||||||
|
resched_cnt = (e->object()->is_dynamic() ? 0 : 1);
|
||||||
|
do {
|
||||||
|
resched = e->object()->solve();
|
||||||
|
resched_cnt++;
|
||||||
|
} while ((resched && (resched_cnt < 5)) || (resched_cnt <= 1));
|
||||||
|
global_resched = global_resched || resched;
|
||||||
|
}
|
||||||
|
//if (global_resched)
|
||||||
|
// printf("rescheduled\n");
|
||||||
|
if (global_resched)
|
||||||
|
{
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* update all inputs connected */
|
||||||
|
for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
|
||||||
|
{
|
||||||
|
e->object()->update_inputs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* step circuit */
|
||||||
|
if (!m_Q_step.net().is_queued())
|
||||||
|
m_Q_step.net().push_to_queue(m_inc);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
85
src/emu/netlist/devices/nld_solver.h
Normal file
85
src/emu/netlist/devices/nld_solver.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* nld_solver.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NLD_SOLVER_H_
|
||||||
|
#define NLD_SOLVER_H_
|
||||||
|
|
||||||
|
#include "../nl_setup.h"
|
||||||
|
#include "../nl_base.h"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
// Macros
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define NETDEV_SOLVER(_name) \
|
||||||
|
NET_REGISTER_DEV(solver, _name)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
// solver
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class netlist_matrix_solver_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef netlist_list_t<netlist_matrix_solver_t *> list_t;
|
||||||
|
typedef netlist_core_device_t::list_t dev_list_t;
|
||||||
|
ATTR_COLD void setup(netlist_net_t::list_t &nets);
|
||||||
|
|
||||||
|
// return true if a reschedule is needed ...
|
||||||
|
ATTR_HOT bool solve();
|
||||||
|
ATTR_HOT void step(const netlist_time delta);
|
||||||
|
ATTR_HOT void update_inputs();
|
||||||
|
|
||||||
|
ATTR_HOT inline bool is_dynamic() { return m_dynamic.count() > 0; }
|
||||||
|
|
||||||
|
double m_accuracy;
|
||||||
|
double m_convergence_factor;
|
||||||
|
|
||||||
|
private:
|
||||||
|
netlist_net_t::list_t m_nets;
|
||||||
|
dev_list_t m_dynamic;
|
||||||
|
dev_list_t m_inps;
|
||||||
|
dev_list_t m_steps;
|
||||||
|
};
|
||||||
|
|
||||||
|
NETLIB_DEVICE_WITH_PARAMS(solver,
|
||||||
|
typedef netlist_core_device_t::list_t dev_list_t;
|
||||||
|
|
||||||
|
netlist_ttl_input_t m_fb_sync;
|
||||||
|
netlist_ttl_output_t m_Q_sync;
|
||||||
|
|
||||||
|
netlist_ttl_input_t m_fb_step;
|
||||||
|
netlist_ttl_output_t m_Q_step;
|
||||||
|
|
||||||
|
netlist_param_double_t m_freq;
|
||||||
|
netlist_param_double_t m_sync_delay;
|
||||||
|
netlist_param_double_t m_accuracy;
|
||||||
|
netlist_param_double_t m_convergence;
|
||||||
|
|
||||||
|
netlist_time m_inc;
|
||||||
|
netlist_time m_last_step;
|
||||||
|
netlist_time m_nt_sync_delay;
|
||||||
|
|
||||||
|
netlist_matrix_solver_t::list_t m_mat_solvers;
|
||||||
|
public:
|
||||||
|
|
||||||
|
~NETLIB_NAME(solver)();
|
||||||
|
|
||||||
|
netlist_net_t::list_t m_nets;
|
||||||
|
|
||||||
|
ATTR_HOT inline void schedule();
|
||||||
|
|
||||||
|
ATTR_COLD void post_start();
|
||||||
|
);
|
||||||
|
|
||||||
|
inline void NETLIB_NAME(solver)::schedule()
|
||||||
|
{
|
||||||
|
// FIXME: time should be parameter;
|
||||||
|
if (!m_Q_sync.net().is_queued())
|
||||||
|
m_Q_sync.net().push_to_queue(m_nt_sync_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* NLD_SOLVER_H_ */
|
@ -78,327 +78,27 @@ NETLIB_UPDATE(clock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// netlist_matrix_solver
|
// logic_input
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NETLIB_START(logic_input)
|
||||||
ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets)
|
|
||||||
{
|
{
|
||||||
for (netlist_net_t::list_t::entry_t *pn = nets.first(); pn != NULL; pn = nets.next(pn))
|
register_output("Q", m_Q);
|
||||||
{
|
|
||||||
NL_VERBOSE_OUT(("setting up net\n"));
|
|
||||||
|
|
||||||
m_nets.add(pn->object());
|
|
||||||
pn->object()->m_solver = this;
|
|
||||||
|
|
||||||
for (netlist_core_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
|
|
||||||
{
|
|
||||||
switch (p->type())
|
|
||||||
{
|
|
||||||
case netlist_terminal_t::TERMINAL:
|
|
||||||
switch (p->netdev().family())
|
|
||||||
{
|
|
||||||
case netlist_device_t::CAPACITOR:
|
|
||||||
if (!m_steps.contains(&p->netdev()))
|
|
||||||
m_steps.add(&p->netdev());
|
|
||||||
break;
|
|
||||||
case netlist_device_t::DIODE:
|
|
||||||
//case netlist_device_t::VCVS:
|
|
||||||
//case netlist_device_t::BJT_SWITCH:
|
|
||||||
if (!m_dynamic.contains(&p->netdev()))
|
|
||||||
m_dynamic.add(&p->netdev());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pn->object()->m_terms.add(static_cast<netlist_terminal_t *>(p));
|
|
||||||
NL_VERBOSE_OUT(("Added terminal\n"));
|
|
||||||
break;
|
|
||||||
case netlist_terminal_t::INPUT:
|
|
||||||
if (!m_inps.contains(&p->netdev()))
|
|
||||||
m_inps.add(&p->netdev());
|
|
||||||
NL_VERBOSE_OUT(("Added input\n"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fatalerror("unhandled element found\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTR_HOT inline void netlist_matrix_solver_t::step(const netlist_time delta)
|
NETLIB_UPDATE(logic_input)
|
||||||
{
|
{
|
||||||
const double dd = delta.as_double();
|
|
||||||
for (dev_list_t::entry_t *p = m_steps.first(); p != NULL; p = m_steps.next(p))
|
|
||||||
p->object()->step_time(dd);
|
|
||||||
}
|
|
||||||
|
|
||||||
ATTR_HOT inline void netlist_matrix_solver_t::update_inputs()
|
|
||||||
{
|
|
||||||
for (dev_list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p))
|
|
||||||
p->object()->update_dev();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ATTR_HOT inline bool netlist_matrix_solver_t::solve()
|
|
||||||
{
|
|
||||||
bool resched = false;
|
|
||||||
|
|
||||||
/* update all non-linear devices */
|
|
||||||
for (dev_list_t::entry_t *p = m_dynamic.first(); p != NULL; p = m_dynamic.next(p))
|
|
||||||
p->object()->update_terminals();
|
|
||||||
|
|
||||||
for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
|
|
||||||
{
|
|
||||||
netlist_net_t *net = pn->object();
|
|
||||||
|
|
||||||
double gtot = 0;
|
|
||||||
double gabs = 0;
|
|
||||||
double iIdr = 0;
|
|
||||||
const netlist_net_t::terminal_list_t &terms = net->m_terms;
|
|
||||||
#if 1
|
|
||||||
switch (terms.count())
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
const netlist_terminal_t *pt = terms.first()->object();
|
|
||||||
gtot = pt->m_gt;
|
|
||||||
gabs = fabs(pt->m_go);
|
|
||||||
iIdr = pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
const netlist_terminal_t *pt1 = terms.first()->object();
|
|
||||||
const netlist_terminal_t *pt2 = terms.item(1)->object();
|
|
||||||
gtot = pt1->m_gt + pt2->m_gt;
|
|
||||||
gabs = fabs(pt1->m_go) + fabs(pt2->m_go);
|
|
||||||
iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
|
|
||||||
+ pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
const netlist_terminal_t *pt1 = terms.first()->object();
|
|
||||||
const netlist_terminal_t *pt2 = terms.item(1)->object();
|
|
||||||
const netlist_terminal_t *pt3 = terms.item(2)->object();
|
|
||||||
gtot = pt1->m_gt + pt2->m_gt + pt3->m_gt;
|
|
||||||
gabs = fabs(pt1->m_go) + fabs(pt2->m_go) + fabs(pt3->m_go);
|
|
||||||
iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
|
|
||||||
+ pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog()
|
|
||||||
+ pt3->m_Idr + pt3->m_go * pt3->m_otherterm->net().Q_Analog();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
|
|
||||||
{
|
|
||||||
netlist_terminal_t *pt = e->object();
|
|
||||||
gtot += pt->m_gt;
|
|
||||||
gabs += fabs(pt->m_go);
|
|
||||||
iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
|
|
||||||
{
|
|
||||||
netlist_terminal_t *pt = e->object();
|
|
||||||
gtot += pt->m_gt;
|
|
||||||
gabs += fabs(pt->m_go);
|
|
||||||
iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
double new_val;
|
|
||||||
gabs *= m_convergence_factor;
|
|
||||||
if (gabs > gtot)
|
|
||||||
new_val = (net->m_cur.Analog * gabs + iIdr) / (gtot + gabs);
|
|
||||||
else
|
|
||||||
new_val = iIdr / gtot;
|
|
||||||
|
|
||||||
if (fabs(new_val - net->m_cur.Analog) > m_accuracy)
|
|
||||||
resched = true;
|
|
||||||
net->m_cur.Analog = net->m_new.Analog = new_val;
|
|
||||||
|
|
||||||
NL_VERBOSE_OUT(("Info: %d\n", pn->object()->m_num_cons));
|
|
||||||
NL_VERBOSE_OUT(("New: %lld %f %f\n", netlist().time().as_raw(), netlist().time().as_double(), new_val));
|
|
||||||
}
|
|
||||||
return resched;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// solver
|
// analog_input
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
typedef netlist_net_t::list_t *net_groups_t;
|
NETLIB_START(analog_input)
|
||||||
|
|
||||||
static bool already_processed(net_groups_t groups, int &cur_group, netlist_net_t *net)
|
|
||||||
{
|
{
|
||||||
if (net->isRailNet())
|
register_output("Q", m_Q);
|
||||||
return true;
|
|
||||||
for (int i = 0; i <= cur_group; i++)
|
|
||||||
{
|
|
||||||
if (groups[i].contains(net))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_net(net_groups_t groups, int &cur_group, netlist_net_t *net)
|
NETLIB_UPDATE(analog_input)
|
||||||
{
|
{
|
||||||
/* add the net */
|
|
||||||
groups[cur_group].add(net);
|
|
||||||
for (netlist_core_terminal_t *p = net->m_head; p != NULL; p = p->m_update_list_next)
|
|
||||||
{
|
|
||||||
if (p->isType(netlist_terminal_t::TERMINAL))
|
|
||||||
{
|
|
||||||
netlist_terminal_t *pt = static_cast<netlist_terminal_t *>(p);
|
|
||||||
netlist_net_t *nnet = &pt->m_otherterm->net();
|
|
||||||
if (!already_processed(groups, cur_group, nnet))
|
|
||||||
process_net(groups, cur_group, nnet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NETLIB_START(solver)
|
|
||||||
{
|
|
||||||
register_output("Q_sync", m_Q_sync);
|
|
||||||
register_output("Q_step", m_Q_step);
|
|
||||||
//register_input("FB", m_feedback);
|
|
||||||
|
|
||||||
register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_NS(10).as_double());
|
|
||||||
m_nt_sync_delay = m_sync_delay.Value();
|
|
||||||
|
|
||||||
register_param("FREQ", m_freq, 48000.0);
|
|
||||||
m_inc = netlist_time::from_hz(m_freq.Value());
|
|
||||||
|
|
||||||
register_param("ACCURACY", m_accuracy, 1e-3);
|
|
||||||
register_param("CONVERG", m_convergence, 0.3);
|
|
||||||
|
|
||||||
register_link_internal(m_fb_sync, m_Q_sync, netlist_input_t::STATE_INP_ACTIVE);
|
|
||||||
register_link_internal(m_fb_step, m_Q_step, netlist_input_t::STATE_INP_ACTIVE);
|
|
||||||
m_last_step = netlist_time::zero;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_UPDATE_PARAM(solver)
|
|
||||||
{
|
|
||||||
m_inc = netlist_time::from_hz(m_freq.Value());
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_NAME(solver)::~NETLIB_NAME(solver)()
|
|
||||||
{
|
|
||||||
netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first();
|
|
||||||
while (e != NULL)
|
|
||||||
{
|
|
||||||
netlist_matrix_solver_t::list_t::entry_t *en = m_mat_solvers.next(e);
|
|
||||||
delete e->object();
|
|
||||||
e = en;
|
|
||||||
}
|
|
||||||
|
|
||||||
netlist_net_t::list_t::entry_t *p = m_nets.first();
|
|
||||||
while (p != NULL)
|
|
||||||
{
|
|
||||||
netlist_net_t::list_t::entry_t *pn = m_nets.next(p);
|
|
||||||
delete p->object();
|
|
||||||
p = pn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_FUNC_VOID(solver, post_start, ())
|
|
||||||
{
|
|
||||||
netlist_net_t::list_t groups[100];
|
|
||||||
int cur_group = -1;
|
|
||||||
|
|
||||||
NL_VERBOSE_OUT(("post start solver ...\n"));
|
|
||||||
|
|
||||||
// delete empty nets ...
|
|
||||||
for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
|
|
||||||
{
|
|
||||||
if (pn->object()->m_head == NULL)
|
|
||||||
{
|
|
||||||
NL_VERBOSE_OUT(("Deleting net ...\n"));
|
|
||||||
netlist_net_t *to_delete = pn->object();
|
|
||||||
m_nets.remove(to_delete);
|
|
||||||
delete to_delete;
|
|
||||||
pn--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Scanning net groups ...\n");
|
|
||||||
// determine net groups
|
|
||||||
for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
|
|
||||||
{
|
|
||||||
if (!already_processed(groups, cur_group, pn->object()))
|
|
||||||
{
|
|
||||||
cur_group++;
|
|
||||||
process_net(groups, cur_group, pn->object());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup the solvers
|
|
||||||
printf("Found %d net groups in %d nets\n", cur_group + 1, m_nets.count());
|
|
||||||
for (int i = 0; i <= cur_group; i++)
|
|
||||||
{
|
|
||||||
netlist_matrix_solver_t *ms = new netlist_matrix_solver_t;
|
|
||||||
ms->m_accuracy = m_accuracy.Value();
|
|
||||||
ms->m_convergence_factor = m_convergence.Value();
|
|
||||||
ms->setup(groups[i]);
|
|
||||||
m_mat_solvers.add(ms);
|
|
||||||
printf("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr());
|
|
||||||
printf(" has %s elements\n", ms->is_dynamic() ? "dynamic" : "no dynamic");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
NETLIB_UPDATE(solver)
|
|
||||||
{
|
|
||||||
//m_Q.setToNoCheck(!m_Q.new_Q(), m_inc );
|
|
||||||
//OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc );
|
|
||||||
|
|
||||||
bool resched = false;
|
|
||||||
int resched_cnt = 0;
|
|
||||||
netlist_time now = netlist().time();
|
|
||||||
netlist_time delta = now - m_last_step;
|
|
||||||
|
|
||||||
if (delta >= m_inc)
|
|
||||||
{
|
|
||||||
NL_VERBOSE_OUT(("Step!\n"));
|
|
||||||
/* update all terminals for new time step */
|
|
||||||
m_last_step = now;
|
|
||||||
for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
|
|
||||||
{
|
|
||||||
e->object()->step(delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool global_resched = false;
|
|
||||||
for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
|
|
||||||
{
|
|
||||||
resched_cnt = (e->object()->is_dynamic() ? 0 : 1);
|
|
||||||
do {
|
|
||||||
resched = e->object()->solve();
|
|
||||||
resched_cnt++;
|
|
||||||
} while ((resched && (resched_cnt < 5)) || (resched_cnt <= 1));
|
|
||||||
global_resched = global_resched || resched;
|
|
||||||
}
|
|
||||||
//if (global_resched)
|
|
||||||
// printf("rescheduled\n");
|
|
||||||
if (global_resched)
|
|
||||||
{
|
|
||||||
schedule();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* update all inputs connected */
|
|
||||||
for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
|
|
||||||
{
|
|
||||||
e->object()->update_inputs();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* step circuit */
|
|
||||||
if (!m_Q_step.net().is_queued())
|
|
||||||
m_Q_step.net().push_to_queue(m_inc);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,15 @@
|
|||||||
#define NETDEV_CLOCK(_name) \
|
#define NETDEV_CLOCK(_name) \
|
||||||
NET_REGISTER_DEV(clock, _name)
|
NET_REGISTER_DEV(clock, _name)
|
||||||
|
|
||||||
#define NETDEV_SOLVER(_name) \
|
#define NETDEV_LOGIC_INPUT(_name) \
|
||||||
NET_REGISTER_DEV(solver, _name)
|
NET_REGISTER_DEV(logic_input, _name)
|
||||||
|
|
||||||
// .model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)
|
#define NETDEV_ANALOG_INPUT(_name) \
|
||||||
|
NET_REGISTER_DEV(analog_input, _name)
|
||||||
|
|
||||||
|
#define NETDEV_CALLBACK(_name, _IN) \
|
||||||
|
NET_REGISTER_DEV(analog_callback, _name) \
|
||||||
|
NET_CONNECT(_name, IN, _IN)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// netdev_*_const
|
// netdev_*_const
|
||||||
@ -75,70 +80,6 @@ NETLIB_DEVICE_WITH_PARAMS(clock,
|
|||||||
netlist_time m_inc;
|
netlist_time m_inc;
|
||||||
);
|
);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
|
||||||
// solver
|
|
||||||
// ----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class netlist_matrix_solver_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef netlist_list_t<netlist_matrix_solver_t *> list_t;
|
|
||||||
typedef netlist_core_device_t::list_t dev_list_t;
|
|
||||||
ATTR_COLD void setup(netlist_net_t::list_t &nets);
|
|
||||||
|
|
||||||
// return true if a reschedule is needed ...
|
|
||||||
ATTR_HOT bool solve();
|
|
||||||
ATTR_HOT void step(const netlist_time delta);
|
|
||||||
ATTR_HOT void update_inputs();
|
|
||||||
|
|
||||||
ATTR_HOT inline bool is_dynamic() { return m_dynamic.count() > 0; }
|
|
||||||
|
|
||||||
double m_accuracy;
|
|
||||||
double m_convergence_factor;
|
|
||||||
|
|
||||||
private:
|
|
||||||
netlist_net_t::list_t m_nets;
|
|
||||||
dev_list_t m_dynamic;
|
|
||||||
dev_list_t m_inps;
|
|
||||||
dev_list_t m_steps;
|
|
||||||
};
|
|
||||||
|
|
||||||
NETLIB_DEVICE_WITH_PARAMS(solver,
|
|
||||||
typedef netlist_core_device_t::list_t dev_list_t;
|
|
||||||
|
|
||||||
netlist_ttl_input_t m_fb_sync;
|
|
||||||
netlist_ttl_output_t m_Q_sync;
|
|
||||||
|
|
||||||
netlist_ttl_input_t m_fb_step;
|
|
||||||
netlist_ttl_output_t m_Q_step;
|
|
||||||
|
|
||||||
netlist_param_double_t m_freq;
|
|
||||||
netlist_param_double_t m_sync_delay;
|
|
||||||
netlist_param_double_t m_accuracy;
|
|
||||||
netlist_param_double_t m_convergence;
|
|
||||||
|
|
||||||
netlist_time m_inc;
|
|
||||||
netlist_time m_last_step;
|
|
||||||
netlist_time m_nt_sync_delay;
|
|
||||||
|
|
||||||
netlist_matrix_solver_t::list_t m_mat_solvers;
|
|
||||||
public:
|
|
||||||
|
|
||||||
~NETLIB_NAME(solver)();
|
|
||||||
|
|
||||||
netlist_net_t::list_t m_nets;
|
|
||||||
|
|
||||||
ATTR_HOT inline void schedule();
|
|
||||||
|
|
||||||
ATTR_COLD void post_start();
|
|
||||||
);
|
|
||||||
|
|
||||||
inline void NETLIB_NAME(solver)::schedule()
|
|
||||||
{
|
|
||||||
// FIXME: time should be parameter;
|
|
||||||
if (!m_Q_sync.net().is_queued())
|
|
||||||
m_Q_sync.net().push_to_queue(m_nt_sync_delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// netdev_callback
|
// netdev_callback
|
||||||
@ -168,6 +109,18 @@ private:
|
|||||||
netlist_output_delegate m_callback;
|
netlist_output_delegate m_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
// Special support devices ...
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NETLIB_DEVICE(logic_input,
|
||||||
|
netlist_ttl_output_t m_Q;
|
||||||
|
);
|
||||||
|
|
||||||
|
NETLIB_DEVICE(analog_input,
|
||||||
|
netlist_analog_output_t m_Q;
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* NLD_SYSTEM_H_ */
|
#endif /* NLD_SYSTEM_H_ */
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "nld_twoterm.h"
|
#include "nld_twoterm.h"
|
||||||
#include "nld_system.h"
|
#include "nld_system.h"
|
||||||
|
#include "nld_solver.h"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// nld_twoterm
|
// nld_twoterm
|
||||||
|
@ -24,11 +24,15 @@ NETLISTOBJS+= \
|
|||||||
$(NETLISTOBJ)/nl_parser.o \
|
$(NETLISTOBJ)/nl_parser.o \
|
||||||
$(NETLISTOBJ)/devices/nld_system.o \
|
$(NETLISTOBJ)/devices/nld_system.o \
|
||||||
$(NETLISTOBJ)/devices/nld_twoterm.o \
|
$(NETLISTOBJ)/devices/nld_twoterm.o \
|
||||||
|
$(NETLISTOBJ)/devices/nld_solver.o \
|
||||||
$(NETLISTOBJ)/devices/net_lib.o \
|
$(NETLISTOBJ)/devices/net_lib.o \
|
||||||
$(NETLISTOBJ)/devices/nld_7404.o \
|
$(NETLISTOBJ)/devices/nld_7404.o \
|
||||||
$(NETLISTOBJ)/devices/nld_7474.o \
|
$(NETLISTOBJ)/devices/nld_7474.o \
|
||||||
|
$(NETLISTOBJ)/devices/nld_7483.o \
|
||||||
$(NETLISTOBJ)/devices/nld_7486.o \
|
$(NETLISTOBJ)/devices/nld_7486.o \
|
||||||
|
$(NETLISTOBJ)/devices/nld_7490.o \
|
||||||
$(NETLISTOBJ)/devices/nld_7493.o \
|
$(NETLISTOBJ)/devices/nld_7493.o \
|
||||||
|
$(NETLISTOBJ)/devices/nld_9316.o \
|
||||||
$(NETLISTOBJ)/devices/nld_NE555.o \
|
$(NETLISTOBJ)/devices/nld_NE555.o \
|
||||||
$(NETLISTOBJ)/devices/nld_log.o \
|
$(NETLISTOBJ)/devices/nld_log.o \
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "nl_base.h"
|
#include "nl_base.h"
|
||||||
#include "devices/nld_system.h"
|
#include "devices/nld_system.h"
|
||||||
#include "pstring.h"
|
#include "pstring.h"
|
||||||
|
#include "nl_util.h"
|
||||||
|
|
||||||
const netlist_time netlist_time::zero = netlist_time::from_raw(0);
|
const netlist_time netlist_time::zero = netlist_time::from_raw(0);
|
||||||
|
|
||||||
@ -280,7 +281,7 @@ ATTR_COLD void netlist_device_t::register_sub(netlist_device_t &dev, const pstri
|
|||||||
dev.init(*m_setup, this->name() + "." + name);
|
dev.init(*m_setup, this->name() + "." + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTR_COLD void netlist_device_t::register_subalias(const pstring &name, netlist_core_terminal_t &term)
|
ATTR_COLD void netlist_device_t::register_subalias(const pstring &name, const netlist_core_terminal_t &term)
|
||||||
{
|
{
|
||||||
pstring alias = this->name() + "." + name;
|
pstring alias = this->name() + "." + name;
|
||||||
|
|
||||||
@ -330,14 +331,14 @@ static void init_term(netlist_core_device_t &dev, netlist_core_terminal_t &term,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Revise internal links ...
|
// FIXME: Revise internal links ...
|
||||||
ATTR_COLD void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState)
|
ATTR_COLD void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, const netlist_input_t::state_e aState)
|
||||||
{
|
{
|
||||||
init_term(dev, in, aState);
|
init_term(dev, in, aState);
|
||||||
init_term(dev, out, aState);
|
init_term(dev, out, aState);
|
||||||
m_setup->connect(in, out);
|
m_setup->connect(in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTR_COLD void netlist_device_t::register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState)
|
ATTR_COLD void netlist_device_t::register_link_internal(netlist_input_t &in, netlist_output_t &out, const netlist_input_t::state_e aState)
|
||||||
{
|
{
|
||||||
register_link_internal(*this, in, out, aState);
|
register_link_internal(*this, in, out, aState);
|
||||||
}
|
}
|
||||||
@ -422,7 +423,7 @@ ATTR_COLD void netlist_net_t::register_con(netlist_core_terminal_t &terminal)
|
|||||||
m_active++;
|
m_active++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTR_HOT inline void netlist_net_t::update_dev(const netlist_core_terminal_t *inp, const UINT32 mask)
|
ATTR_HOT inline void netlist_net_t::update_dev(const netlist_core_terminal_t *inp, const UINT32 mask) const
|
||||||
{
|
{
|
||||||
if ((inp->state() & mask) != 0)
|
if ((inp->state() & mask) != 0)
|
||||||
{
|
{
|
||||||
@ -602,7 +603,6 @@ NETLIB_START(mainclock)
|
|||||||
|
|
||||||
register_param("FREQ", m_freq, 7159000.0 * 5);
|
register_param("FREQ", m_freq, 7159000.0 * 5);
|
||||||
m_inc = netlist_time::from_hz(m_freq.Value()*2);
|
m_inc = netlist_time::from_hz(m_freq.Value()*2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NETLIB_UPDATE_PARAM(mainclock)
|
NETLIB_UPDATE_PARAM(mainclock)
|
||||||
|
@ -243,7 +243,8 @@ class netlist_param_t;
|
|||||||
class netlist_setup_t;
|
class netlist_setup_t;
|
||||||
class netlist_base_t;
|
class netlist_base_t;
|
||||||
class netlist_matrix_solver_t;
|
class netlist_matrix_solver_t;
|
||||||
|
class NETLIB_NAME(solver);
|
||||||
|
class NETLIB_NAME(mainclock);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// netlist_object_t
|
// netlist_object_t
|
||||||
@ -339,7 +340,7 @@ public:
|
|||||||
ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate);
|
ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate);
|
||||||
|
|
||||||
ATTR_COLD void set_net(netlist_net_t &anet);
|
ATTR_COLD void set_net(netlist_net_t &anet);
|
||||||
ATTR_COLD inline bool has_net() { return (m_net != NULL); }
|
ATTR_COLD inline bool has_net() const { return (m_net != NULL); }
|
||||||
ATTR_HOT inline const netlist_net_t & RESTRICT net() const { return *m_net;}
|
ATTR_HOT inline const netlist_net_t & RESTRICT net() const { return *m_net;}
|
||||||
ATTR_HOT inline netlist_net_t & RESTRICT net() { return *m_net;}
|
ATTR_HOT inline netlist_net_t & RESTRICT net() { return *m_net;}
|
||||||
|
|
||||||
@ -483,14 +484,9 @@ public:
|
|||||||
typedef netlist_list_t<netlist_net_t *> list_t;
|
typedef netlist_list_t<netlist_net_t *> list_t;
|
||||||
|
|
||||||
friend class NETLIB_NAME(mainclock);
|
friend class NETLIB_NAME(mainclock);
|
||||||
friend class NETLIB_NAME(solver);
|
|
||||||
friend class netlist_matrix_solver_t;
|
friend class netlist_matrix_solver_t;
|
||||||
friend class netlist_output_t;
|
|
||||||
friend class netlist_input_t;
|
|
||||||
friend class netlist_logic_output_t;
|
friend class netlist_logic_output_t;
|
||||||
friend class netlist_analog_output_t;
|
friend class netlist_analog_output_t;
|
||||||
friend class netlist_logic_input_t;
|
|
||||||
friend class netlist_analog_input_t;
|
|
||||||
|
|
||||||
// FIXME: union does not work
|
// FIXME: union does not work
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -511,9 +507,8 @@ public:
|
|||||||
ATTR_HOT inline const netlist_time time() const { return m_time; }
|
ATTR_HOT inline const netlist_time time() const { return m_time; }
|
||||||
ATTR_HOT inline void set_time(const netlist_time ntime) { m_time = ntime; }
|
ATTR_HOT inline void set_time(const netlist_time ntime) { m_time = ntime; }
|
||||||
|
|
||||||
ATTR_HOT inline bool isRailNet() { return !(m_railterminal == NULL); }
|
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 const netlist_core_terminal_t & RESTRICT railterminal() const { return *m_railterminal; }
|
||||||
ATTR_HOT inline const netlist_core_terminal_t & RESTRICT railterminal() { return *m_railterminal; }
|
|
||||||
|
|
||||||
/* Everything below is used by the logic subsystem */
|
/* Everything below is used by the logic subsystem */
|
||||||
|
|
||||||
@ -522,8 +517,23 @@ public:
|
|||||||
|
|
||||||
ATTR_HOT inline const int active_count() const { return m_active; }
|
ATTR_HOT inline const int active_count() const { return m_active; }
|
||||||
|
|
||||||
ATTR_HOT inline const netlist_sig_t last_Q() const { return m_last.Q; }
|
ATTR_HOT inline const netlist_sig_t Q() const
|
||||||
ATTR_HOT inline const netlist_sig_t new_Q() const { return m_new.Q; }
|
{
|
||||||
|
assert(family() == LOGIC);
|
||||||
|
return m_cur.Q;
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTR_HOT inline const netlist_sig_t last_Q() const
|
||||||
|
{
|
||||||
|
assert(family() == LOGIC);
|
||||||
|
return m_last.Q;
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTR_HOT inline const netlist_sig_t new_Q() const
|
||||||
|
{
|
||||||
|
assert(family() == LOGIC);
|
||||||
|
return m_new.Q;
|
||||||
|
}
|
||||||
|
|
||||||
ATTR_HOT inline const double Q_Analog() const
|
ATTR_HOT inline const double Q_Analog() const
|
||||||
{
|
{
|
||||||
@ -544,15 +554,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* prohibit use in device functions
|
|
||||||
* current (pending) state can be inquired using new_Q()
|
|
||||||
*/
|
|
||||||
ATTR_HOT inline const netlist_sig_t Q() const
|
|
||||||
{
|
|
||||||
//assert(object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
|
|
||||||
assert(family() == LOGIC);
|
|
||||||
return m_cur.Q;
|
|
||||||
}
|
|
||||||
|
|
||||||
hybrid_t m_last;
|
hybrid_t m_last;
|
||||||
hybrid_t m_cur;
|
hybrid_t m_cur;
|
||||||
@ -561,7 +562,7 @@ protected:
|
|||||||
UINT32 m_num_cons;
|
UINT32 m_num_cons;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ATTR_HOT void update_dev(const netlist_core_terminal_t *inp, const UINT32 mask);
|
ATTR_HOT void update_dev(const netlist_core_terminal_t *inp, const UINT32 mask) const;
|
||||||
|
|
||||||
netlist_time m_time;
|
netlist_time m_time;
|
||||||
INT32 m_active;
|
INT32 m_active;
|
||||||
@ -575,9 +576,6 @@ private:
|
|||||||
// net_output_t
|
// net_output_t
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class NETLIB_NAME(mainclock);
|
|
||||||
class NETLIB_NAME(solver);
|
|
||||||
|
|
||||||
class netlist_output_t : public netlist_core_terminal_t
|
class netlist_output_t : public netlist_core_terminal_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -860,29 +858,29 @@ public:
|
|||||||
|
|
||||||
ATTR_COLD netlist_setup_t *setup() const { return m_setup; }
|
ATTR_COLD netlist_setup_t *setup() const { return m_setup; }
|
||||||
|
|
||||||
ATTR_COLD bool variable_input_count() { return m_variable_input_count; }
|
// FIXME: Legacy ... this needs to disappear
|
||||||
|
ATTR_COLD bool variable_input_count() const { return m_variable_input_count; }
|
||||||
|
|
||||||
ATTR_COLD void register_sub(netlist_device_t &dev, const pstring &name);
|
ATTR_COLD void register_sub(netlist_device_t &dev, const pstring &name);
|
||||||
ATTR_COLD void register_subalias(const pstring &name, netlist_core_terminal_t &term);
|
ATTR_COLD void register_subalias(const pstring &name, const netlist_core_terminal_t &term);
|
||||||
|
|
||||||
ATTR_COLD void register_terminal(const pstring &name, netlist_terminal_t &port);
|
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_output_t &out);
|
||||||
|
|
||||||
ATTR_COLD void register_input(const pstring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
|
ATTR_COLD void register_input(const pstring &name, netlist_input_t &in, const netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
|
||||||
|
|
||||||
ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState);
|
ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, const netlist_input_t::state_e aState);
|
||||||
ATTR_COLD void register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState);
|
ATTR_COLD void register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, const netlist_input_t::state_e aState);
|
||||||
|
|
||||||
ATTR_HOT virtual void update_terminals() { }
|
|
||||||
|
|
||||||
/* driving logic outputs don't count in here */
|
/* driving logic outputs don't count in here */
|
||||||
netlist_list_t<pstring, 20> m_terminals;
|
netlist_list_t<pstring, 20> m_terminals;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void update() { }
|
ATTR_HOT virtual void update() { }
|
||||||
virtual void start() { }
|
ATTR_HOT virtual void start() { }
|
||||||
|
ATTR_HOT virtual void update_terminals() { }
|
||||||
|
|
||||||
template <class C, class T>
|
template <class C, class T>
|
||||||
ATTR_COLD void register_param(const pstring &sname, C ¶m, const T initialVal)
|
ATTR_COLD void register_param(const pstring &sname, C ¶m, const T initialVal)
|
||||||
@ -915,6 +913,7 @@ public:
|
|||||||
|
|
||||||
ATTR_COLD void set_clock_freq(UINT64 clockfreq);
|
ATTR_COLD void set_clock_freq(UINT64 clockfreq);
|
||||||
|
|
||||||
|
ATTR_HOT inline const queue_t &queue() const { return m_queue; }
|
||||||
ATTR_HOT inline queue_t &queue() { return m_queue; }
|
ATTR_HOT inline queue_t &queue() { return m_queue; }
|
||||||
|
|
||||||
ATTR_HOT inline void push_to_queue(netlist_net_t &out, const netlist_time &attime)
|
ATTR_HOT inline void push_to_queue(netlist_net_t &out, const netlist_time &attime)
|
||||||
@ -922,7 +921,7 @@ public:
|
|||||||
m_queue.push(queue_t::entry_t(attime, out));
|
m_queue.push(queue_t::entry_t(attime, out));
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTR_HOT NETLIB_NAME(solver) *solver() { return m_solver; }
|
ATTR_HOT NETLIB_NAME(solver) *solver() const { return m_solver; }
|
||||||
|
|
||||||
ATTR_HOT void process_queue(INT32 &atime);
|
ATTR_HOT void process_queue(INT32 &atime);
|
||||||
|
|
||||||
@ -961,7 +960,7 @@ private:
|
|||||||
class nld_a_to_d_proxy : public netlist_device_t
|
class nld_a_to_d_proxy : public netlist_device_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nld_a_to_d_proxy(netlist_input_t &in_proxied)
|
ATTR_COLD nld_a_to_d_proxy(netlist_input_t &in_proxied)
|
||||||
: netlist_device_t()
|
: netlist_device_t()
|
||||||
{
|
{
|
||||||
//assert(in_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
|
//assert(in_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
|
||||||
@ -970,13 +969,13 @@ public:
|
|||||||
m_I.m_low_thresh_V = in_proxied.m_low_thresh_V;
|
m_I.m_low_thresh_V = in_proxied.m_low_thresh_V;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~nld_a_to_d_proxy() {}
|
ATTR_COLD virtual ~nld_a_to_d_proxy() {}
|
||||||
|
|
||||||
netlist_analog_input_t m_I;
|
netlist_analog_input_t m_I;
|
||||||
netlist_ttl_output_t m_Q;
|
netlist_ttl_output_t m_Q;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void start()
|
ATTR_COLD void start()
|
||||||
{
|
{
|
||||||
m_I.init_object(*this, "I", netlist_terminal_t::STATE_INP_ACTIVE);
|
m_I.init_object(*this, "I", netlist_terminal_t::STATE_INP_ACTIVE);
|
||||||
|
|
||||||
@ -1003,7 +1002,7 @@ protected:
|
|||||||
class nld_d_to_a_proxy : public netlist_device_t
|
class nld_d_to_a_proxy : public netlist_device_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nld_d_to_a_proxy(netlist_output_t &out_proxied)
|
ATTR_COLD nld_d_to_a_proxy(netlist_output_t &out_proxied)
|
||||||
: netlist_device_t()
|
: netlist_device_t()
|
||||||
{
|
{
|
||||||
//assert(out_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
|
//assert(out_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
|
||||||
@ -1012,13 +1011,13 @@ public:
|
|||||||
m_high_V = out_proxied.m_high_V;
|
m_high_V = out_proxied.m_high_V;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~nld_d_to_a_proxy() {}
|
ATTR_COLD virtual ~nld_d_to_a_proxy() {}
|
||||||
|
|
||||||
netlist_ttl_input_t m_I;
|
netlist_ttl_input_t m_I;
|
||||||
netlist_analog_output_t m_Q;
|
netlist_analog_output_t m_Q;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void start()
|
ATTR_COLD void start()
|
||||||
{
|
{
|
||||||
m_I.init_object(*this, "I", netlist_terminal_t::STATE_INP_ACTIVE);
|
m_I.init_object(*this, "I", netlist_terminal_t::STATE_INP_ACTIVE);
|
||||||
m_Q.init_object(*this, "Q");
|
m_Q.init_object(*this, "Q");
|
||||||
@ -1158,6 +1157,7 @@ ATTR_HOT inline const double netlist_analog_input_t::Q_Analog() const
|
|||||||
return net().Q_Analog();
|
return net().Q_Analog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME: Legacy ... must be removed
|
||||||
ATTR_HOT inline const bool netlist_analog_input_t::is_highz() const
|
ATTR_HOT inline const bool netlist_analog_input_t::is_highz() const
|
||||||
{
|
{
|
||||||
return (net().Q_Analog() == NETLIST_HIGHIMP_V);
|
return (net().Q_Analog() == NETLIST_HIGHIMP_V);
|
||||||
|
@ -66,6 +66,12 @@ typedef delegate<void (const double)> netlist_output_delegate;
|
|||||||
// MACROS
|
// MACROS
|
||||||
//============================================================
|
//============================================================
|
||||||
|
|
||||||
|
// prevent implicit copying
|
||||||
|
#define NETLIST_PREVENT_COPYING(_name) \
|
||||||
|
private: \
|
||||||
|
_name(const _name &); \
|
||||||
|
_name &operator=(const _name &); \
|
||||||
|
|
||||||
#if NL_KEEP_STATISTICS
|
#if NL_KEEP_STATISTICS
|
||||||
#define add_to_stat(v,x) do { v += (x); } while (0)
|
#define add_to_stat(v,x) do { v += (x); } while (0)
|
||||||
#define inc_stat(v) add_to_stat(v, 1)
|
#define inc_stat(v) add_to_stat(v, 1)
|
||||||
|
@ -35,6 +35,28 @@ public:
|
|||||||
m_ptr = m_list;
|
m_ptr = m_list;
|
||||||
m_ptr--;
|
m_ptr--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ATTR_COLD netlist_list_t(const netlist_list_t &rhs)
|
||||||
|
{
|
||||||
|
m_list = new entry_t[m_num_elements];
|
||||||
|
m_ptr = m_list;
|
||||||
|
m_ptr--;
|
||||||
|
for (int i=0; i<rhs.count(); i++)
|
||||||
|
{
|
||||||
|
this->add(rhs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTR_COLD netlist_list_t &operator=(const netlist_list_t &rhs)
|
||||||
|
{
|
||||||
|
for (int i=0; i<rhs.count(); i++)
|
||||||
|
{
|
||||||
|
this->add(rhs[i]);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ATTR_COLD ~netlist_list_t()
|
ATTR_COLD ~netlist_list_t()
|
||||||
{
|
{
|
||||||
delete[] m_list;
|
delete[] m_list;
|
||||||
@ -87,10 +109,14 @@ public:
|
|||||||
ATTR_HOT inline entry_t *first() const { return (m_ptr >= m_list ? &m_list[0] : NULL ); }
|
ATTR_HOT inline entry_t *first() const { return (m_ptr >= m_list ? &m_list[0] : NULL ); }
|
||||||
ATTR_HOT inline entry_t *next(entry_t *lc) const { return (lc < last() ? lc + 1 : NULL ); }
|
ATTR_HOT inline entry_t *next(entry_t *lc) const { return (lc < last() ? lc + 1 : NULL ); }
|
||||||
ATTR_HOT inline entry_t *last() const { return m_ptr; }
|
ATTR_HOT inline entry_t *last() const { return m_ptr; }
|
||||||
ATTR_HOT inline entry_t *item(int i) const { return &m_list[i]; }
|
|
||||||
ATTR_HOT inline int count() const { return m_ptr - m_list + 1; }
|
ATTR_HOT inline int count() const { return m_ptr - m_list + 1; }
|
||||||
ATTR_HOT inline bool empty() const { return (m_ptr < m_list); }
|
ATTR_HOT inline bool empty() const { return (m_ptr < m_list); }
|
||||||
ATTR_HOT inline void reset() { m_ptr = m_list - 1; }
|
ATTR_HOT inline void reset() { m_ptr = m_list - 1; }
|
||||||
|
|
||||||
|
//ATTR_HOT inline entry_t *item(int i) const { return &m_list[i]; }
|
||||||
|
ATTR_HOT inline _ListClass& operator[](const int & index) { return m_list[index].m_obj; }
|
||||||
|
ATTR_HOT inline const _ListClass& operator[](const int & index) const { return m_list[index].m_obj; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
entry_t * m_ptr;
|
entry_t * m_ptr;
|
||||||
entry_t * m_list;
|
entry_t * m_list;
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
#include "nl_base.h"
|
#include "nl_base.h"
|
||||||
#include "nl_setup.h"
|
#include "nl_setup.h"
|
||||||
#include "nl_parser.h"
|
#include "nl_parser.h"
|
||||||
|
#include "nl_util.h"
|
||||||
#include "devices/nld_system.h"
|
#include "devices/nld_system.h"
|
||||||
|
#include "devices/nld_solver.h"
|
||||||
|
|
||||||
static NETLIST_START(base)
|
static NETLIST_START(base)
|
||||||
NETDEV_TTL_CONST(ttlhigh, 1)
|
NETDEV_TTL_CONST(ttlhigh, 1)
|
||||||
@ -139,7 +141,7 @@ pstring netlist_setup_t::objtype_as_astr(netlist_object_t &in)
|
|||||||
fatalerror("Unknown object type %d\n", in.type());
|
fatalerror("Unknown object type %d\n", in.type());
|
||||||
}
|
}
|
||||||
|
|
||||||
void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, netlist_input_t::state_e state)
|
void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, const netlist_input_t::state_e state)
|
||||||
{
|
{
|
||||||
switch (obj.type())
|
switch (obj.type())
|
||||||
{
|
{
|
||||||
@ -248,7 +250,7 @@ const pstring netlist_setup_t::resolve_alias(const pstring &name) const
|
|||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
fatalerror("Device for %s not found\n", name.cstr());
|
fatalerror("Device for %s not found\n", name.cstr());
|
||||||
int c = atoi(ret.substr(p+2,ret.len()-p-3));
|
int c = atoi(ret.substr(p+2,ret.len()-p-3));
|
||||||
temp = dev->name() + "." + dev->m_terminals.item(c)->object();
|
temp = dev->name() + "." + dev->m_terminals[c];
|
||||||
// reresolve ....
|
// reresolve ....
|
||||||
do {
|
do {
|
||||||
ret = temp;
|
ret = temp;
|
||||||
@ -517,6 +519,21 @@ void netlist_setup_t::resolve_inputs(void)
|
|||||||
void netlist_setup_t::start_devices(void)
|
void netlist_setup_t::start_devices(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (getenv("NL_LOGS"))
|
||||||
|
{
|
||||||
|
NL_VERBOSE_OUT(("Creating dynamic logs ...\n"));
|
||||||
|
nl_util::pstring_list ll = nl_util::split(getenv("NL_LOGS"), ":");
|
||||||
|
for (int i=0; i < ll.count(); i++)
|
||||||
|
{
|
||||||
|
printf("%d: <%s>\n",i, ll[i].cstr());
|
||||||
|
netlist_device_t *nc = factory().new_device_by_classname("nld_log", *this);
|
||||||
|
pstring name = "log" + ll[i];
|
||||||
|
register_dev(nc, name);
|
||||||
|
register_link(name + ".I", ll[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NL_VERBOSE_OUT(("Searching for mainclock and solver ...\n"));
|
NL_VERBOSE_OUT(("Searching for mainclock and solver ...\n"));
|
||||||
/* find the main clock ... */
|
/* find the main clock ... */
|
||||||
for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
|
for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
|
||||||
|
41
src/emu/netlist/nl_util.h
Normal file
41
src/emu/netlist/nl_util.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* nl_util.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NL_UTIL_H_
|
||||||
|
#define NL_UTIL_H_
|
||||||
|
|
||||||
|
#include "pstring.h"
|
||||||
|
#include "nl_lists.h"
|
||||||
|
|
||||||
|
class nl_util
|
||||||
|
{
|
||||||
|
// this is purely static
|
||||||
|
private:
|
||||||
|
nl_util() {};
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef netlist_list_t<pstring, 10> pstring_list;
|
||||||
|
|
||||||
|
static pstring_list split(const pstring &str, const pstring &onstr)
|
||||||
|
{
|
||||||
|
pstring_list temp;
|
||||||
|
|
||||||
|
int p = 0;
|
||||||
|
int pn;
|
||||||
|
|
||||||
|
pn = str.find(onstr, p);
|
||||||
|
while (pn>=0)
|
||||||
|
{
|
||||||
|
temp.add(str.substr(p, pn - p));
|
||||||
|
p = pn + onstr.len();
|
||||||
|
pn = str.find(onstr, p);
|
||||||
|
}
|
||||||
|
if (p<str.len())
|
||||||
|
temp.add(str.substr(p));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* NL_UTIL_H_ */
|
Loading…
Reference in New Issue
Block a user