mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
Netlist: implemented something more complex: A generic NE555 model. Period accuracy for astable operation is within 2% of the TI datasheet for astable operation.
Fixed an issue in the object model as well and made the code distinguish between a core terminal and analog terminals. NETDEV_R(RA, 5000) NETDEV_R(RB, 3000) NETDEV_C(C, 0.15e-6) NETDEV_NE555(555) NET_C(V0, 555.GND) NET_C(V5, 555.VCC) NET_C(RA.1, 555.VCC) NET_C(RA.2, 555.DISCH) NET_C(RB.1, 555.DISCH) NET_C(RB.2, 555.TRIG) NET_C(RB.2, 555.THRESH) NET_C(555.TRIG, C.1) NET_C(C.2, V0)
This commit is contained in:
parent
ecac6034c6
commit
7069a5828c
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -2138,6 +2138,8 @@ 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_7486.c svneol=native#text/plain
|
||||
src/emu/netlist/devices/nld_7486.h 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_signal.h 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
|
||||
|
@ -939,11 +939,11 @@ static const net_device_t_base_factory *netregistry[] =
|
||||
ENTRY(7420, TTL_7420_NAND)
|
||||
ENTRY(7425, TTL_7425_NOR)
|
||||
ENTRY(7427, TTL_7427_NOR)
|
||||
ENTRY(nic7430, TTL_7430_NAND)
|
||||
ENTRY(7430, TTL_7430_NAND)
|
||||
ENTRY(nic7450, TTL_7450_ANDORINVERT)
|
||||
ENTRY(nic7486, TTL_7486_XOR)
|
||||
ENTRY(7486, TTL_7486_XOR)
|
||||
ENTRY(nic7448, TTL_7448)
|
||||
ENTRY(nic7474, TTL_7474)
|
||||
ENTRY(7474, TTL_7474)
|
||||
ENTRY(nic7483, TTL_7483)
|
||||
ENTRY(nic7490, TTL_7490)
|
||||
ENTRY(nic7493, TTL_7493)
|
||||
@ -951,7 +951,8 @@ static const net_device_t_base_factory *netregistry[] =
|
||||
ENTRY(nic74107A, TTL_74107A)
|
||||
ENTRY(nic74153, TTL_74153)
|
||||
ENTRY(nic9316, TTL_9316)
|
||||
ENTRY(nicNE555N_MSTABLE, NE555N_MSTABLE)
|
||||
ENTRY(NE555, NETDEV_NE555)
|
||||
ENTRY(nicNE555N_MSTABLE, NE555N_MSTABLE)
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -66,6 +66,8 @@
|
||||
#include "nld_7474.h"
|
||||
#include "nld_7486.h"
|
||||
|
||||
#include "nld_NE555.h"
|
||||
|
||||
// this is a bad hack
|
||||
#define USE_OLD7493 (0)
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "nld_signal.h"
|
||||
|
||||
#define TTL_7430_NAND(_name, _I1, _I2, _I3, _I4, _I5, _I6, _I7, _I8) \
|
||||
NET_REGISTER_DEV(nic7430, _name) \
|
||||
NET_REGISTER_DEV(7430, _name) \
|
||||
NET_CONNECT(_name, A, _I1) \
|
||||
NET_CONNECT(_name, B, _I2) \
|
||||
NET_CONNECT(_name, C, _I3) \
|
||||
@ -51,6 +51,6 @@
|
||||
NET_CONNECT(_name, H, _I8)
|
||||
|
||||
|
||||
NETLIB_SIGNAL(nic7430, 8, 0, 0);
|
||||
NETLIB_SIGNAL(7430, 8, 0, 0);
|
||||
|
||||
#endif /* NLD_7430_H_ */
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "nld_7474.h"
|
||||
|
||||
ATTR_HOT inline void NETLIB_NAME(nic7474sub)::newstate(const UINT8 state)
|
||||
ATTR_HOT inline void NETLIB_NAME(7474sub)::newstate(const UINT8 state)
|
||||
{
|
||||
static const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(40) };
|
||||
//printf("%s %d %d %d\n", "7474", state, Q.Q(), QQ.Q());
|
||||
@ -13,7 +13,7 @@ ATTR_HOT inline void NETLIB_NAME(nic7474sub)::newstate(const UINT8 state)
|
||||
OUTLOGIC(m_QQ, !state, delay[!state]);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(nic7474sub)
|
||||
NETLIB_UPDATE(7474sub)
|
||||
{
|
||||
//if (!INP_LAST(m_clk) & INP(m_clk))
|
||||
{
|
||||
@ -22,7 +22,7 @@ NETLIB_UPDATE(nic7474sub)
|
||||
}
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(nic7474)
|
||||
NETLIB_UPDATE(7474)
|
||||
{
|
||||
if (!INPLOGIC(m_preQ))
|
||||
{
|
||||
@ -44,7 +44,7 @@ NETLIB_UPDATE(nic7474)
|
||||
}
|
||||
}
|
||||
|
||||
NETLIB_START(nic7474)
|
||||
NETLIB_START(7474)
|
||||
{
|
||||
register_sub(sub, "sub");
|
||||
|
||||
@ -58,7 +58,7 @@ NETLIB_START(nic7474)
|
||||
|
||||
}
|
||||
|
||||
NETLIB_START(nic7474sub)
|
||||
NETLIB_START(7474sub)
|
||||
{
|
||||
register_input("CLK", m_clk, netlist_input_t::STATE_INP_LH);
|
||||
|
||||
|
@ -45,13 +45,13 @@
|
||||
#include "nld_signal.h"
|
||||
|
||||
#define TTL_7474(_name, _CLK, _D, _CLRQ, _PREQ) \
|
||||
NET_REGISTER_DEV(nic7474, _name) \
|
||||
NET_REGISTER_DEV(7474, _name) \
|
||||
NET_CONNECT(_name, CLK, _CLK) \
|
||||
NET_CONNECT(_name, D, _D) \
|
||||
NET_CONNECT(_name, CLRQ, _CLRQ) \
|
||||
NET_CONNECT(_name, PREQ, _PREQ)
|
||||
|
||||
NETLIB_SUBDEVICE(nic7474sub,
|
||||
NETLIB_SUBDEVICE(7474sub,
|
||||
netlist_ttl_input_t m_clk;
|
||||
|
||||
UINT8 m_nextD;
|
||||
@ -61,8 +61,8 @@ NETLIB_SUBDEVICE(nic7474sub,
|
||||
ATTR_HOT inline void newstate(const UINT8 state);
|
||||
);
|
||||
|
||||
NETLIB_DEVICE(nic7474,
|
||||
NETLIB_NAME(nic7474sub) sub;
|
||||
NETLIB_DEVICE(7474,
|
||||
NETLIB_NAME(7474sub) sub;
|
||||
|
||||
netlist_ttl_input_t m_D;
|
||||
netlist_ttl_input_t m_clrQ;
|
||||
@ -70,7 +70,4 @@ NETLIB_DEVICE(nic7474,
|
||||
);
|
||||
|
||||
|
||||
|
||||
NETLIB_SIGNAL(7474, 4, 0, 0);
|
||||
|
||||
#endif /* NLD_7474_H_ */
|
||||
|
@ -5,14 +5,14 @@
|
||||
|
||||
#include "nld_7486.h"
|
||||
|
||||
NETLIB_START(nic7486)
|
||||
NETLIB_START(7486)
|
||||
{
|
||||
register_input("A", m_A);
|
||||
register_input("B", m_B);
|
||||
register_output("Q", m_Q);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(nic7486)
|
||||
NETLIB_UPDATE(7486)
|
||||
{
|
||||
static const netlist_time delay[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(22) };
|
||||
UINT8 t = INPLOGIC(m_A) ^ INPLOGIC(m_B);
|
||||
|
@ -35,11 +35,11 @@
|
||||
#include "nld_signal.h"
|
||||
|
||||
#define TTL_7486_XOR(_name, _A, _B) \
|
||||
NET_REGISTER_DEV(nic7486, _name) \
|
||||
NET_REGISTER_DEV(7486, _name) \
|
||||
NET_CONNECT(_name, A, _A) \
|
||||
NET_CONNECT(_name, B, _B)
|
||||
|
||||
NETLIB_DEVICE(nic7486,
|
||||
NETLIB_DEVICE(7486,
|
||||
netlist_ttl_input_t m_A;
|
||||
netlist_ttl_input_t m_B;
|
||||
netlist_ttl_output_t m_Q;
|
||||
|
82
src/emu/netlist/devices/nld_NE555.c
Normal file
82
src/emu/netlist/devices/nld_NE555.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* nld_NE555.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nld_NE555.h"
|
||||
#include "../nl_setup.h"
|
||||
|
||||
#define R_OFF (1E20)
|
||||
#define R_ON (1)
|
||||
|
||||
inline double NETLIB_NAME(NE555)::clamp(const double v, const double a, const double b)
|
||||
{
|
||||
double ret = v;
|
||||
double vcc = TERMANALOG(m_R1.m_P);
|
||||
|
||||
if (ret > vcc - a)
|
||||
ret = vcc - a;
|
||||
if (ret < b)
|
||||
ret = b;
|
||||
return ret;
|
||||
}
|
||||
|
||||
NETLIB_START(NE555)
|
||||
{
|
||||
|
||||
register_sub(m_R1, "R1");
|
||||
register_sub(m_R2, "R2");
|
||||
register_sub(m_R3, "R3");
|
||||
register_sub(m_RDIS, "RDIS");
|
||||
|
||||
register_subalias("GND", m_R3.m_N); // Pin 1
|
||||
register_input("TRIG", m_TRIG); // Pin 2
|
||||
register_output("OUT", m_OUT); // Pin 3
|
||||
register_input("RESET", m_RESET); // Pin 4
|
||||
register_subalias("CONT", m_R1.m_N); // Pin 5
|
||||
register_input("THRESH", m_THRES); // Pin 6
|
||||
register_subalias("DISCH", m_RDIS.m_P); // Pin 7
|
||||
register_subalias("VCC", m_R1.m_P); // Pin 8
|
||||
|
||||
m_R1.set_R(5000);
|
||||
m_R2.set_R(5000);
|
||||
m_R3.set_R(5000);
|
||||
m_RDIS.set_R(R_OFF);
|
||||
|
||||
m_setup->connect(m_R1.m_N, m_R2.m_P);
|
||||
m_setup->connect(m_R2.m_N, m_R3.m_P);
|
||||
m_setup->connect(m_RDIS.m_N, m_R3.m_N);
|
||||
|
||||
m_last_out = false;
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(NE555)
|
||||
{
|
||||
// FIXME: assumes GND is connected to 0V.
|
||||
|
||||
double vt = clamp(TERMANALOG(m_R2.m_P), 0.7, 1.4);
|
||||
bool bthresh = (INPANALOG(m_THRES) > vt);
|
||||
bool btrig = (INPANALOG(m_TRIG) > clamp(TERMANALOG(m_R2.m_N), 0.7, 1.4));
|
||||
bool out = m_last_out;
|
||||
|
||||
if (!btrig)
|
||||
{
|
||||
out = true;
|
||||
}
|
||||
else if (bthresh)
|
||||
{
|
||||
out = false;
|
||||
}
|
||||
|
||||
if (!m_last_out && out)
|
||||
{
|
||||
OUTANALOG(m_OUT, TERMANALOG(m_R1.m_P), NLTIME_FROM_NS(100));
|
||||
m_RDIS.set_R(R_OFF);
|
||||
}
|
||||
else if (m_last_out && !out)
|
||||
{
|
||||
OUTANALOG(m_OUT, TERMANALOG(m_R3.m_N), NLTIME_FROM_NS(100));
|
||||
m_RDIS.set_R(R_ON);
|
||||
}
|
||||
m_last_out = out;
|
||||
}
|
47
src/emu/netlist/devices/nld_NE555.h
Normal file
47
src/emu/netlist/devices/nld_NE555.h
Normal file
@ -0,0 +1,47 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
/*
|
||||
* nld_NE555.h
|
||||
*
|
||||
* NE555: PRECISION TIMERS
|
||||
*
|
||||
* +--------+
|
||||
* GND |1 ++ 8| VCC
|
||||
* TRIG |2 7| DISCH
|
||||
* OUT |3 6| THRES
|
||||
* RESET |4 5| CONT
|
||||
* +--------+
|
||||
*
|
||||
* Naming conventions follow Texas Instruments datasheet
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NLD_NE555_H_
|
||||
#define NLD_NE555_H_
|
||||
|
||||
#include "../nl_base.h"
|
||||
#include "nld_twoterm.h"
|
||||
|
||||
#define NETDEV_NE555(_name) \
|
||||
NET_REGISTER_DEV(NE555, _name) \
|
||||
|
||||
NETLIB_DEVICE(NE555,
|
||||
NETLIB_NAME(R) m_R1;
|
||||
NETLIB_NAME(R) m_R2;
|
||||
NETLIB_NAME(R) m_R3;
|
||||
NETLIB_NAME(R) m_RDIS;
|
||||
|
||||
netlist_logic_input_t m_RESET;
|
||||
netlist_analog_input_t m_THRES;
|
||||
netlist_analog_input_t m_TRIG;
|
||||
netlist_analog_output_t m_OUT;
|
||||
|
||||
bool m_last_out;
|
||||
|
||||
double clamp(const double v, const double a, const double b);
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
#endif /* NLD_NE555_H_ */
|
@ -120,7 +120,7 @@ NETLIB_FUNC_VOID(solver, post_start, ())
|
||||
for (net_list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
|
||||
{
|
||||
NL_VERBOSE_OUT(("setting up net\n"));
|
||||
for (netlist_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
|
||||
for (netlist_core_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
|
||||
{
|
||||
switch (p->type())
|
||||
{
|
||||
@ -170,13 +170,14 @@ NETLIB_UPDATE(solver)
|
||||
double gtot = 0;
|
||||
double iIdr = 0;
|
||||
|
||||
for (netlist_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
|
||||
for (netlist_core_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
|
||||
{
|
||||
if (p->isType(netlist_terminal_t::TERMINAL))
|
||||
if (p->isType(netlist_core_terminal_t::TERMINAL))
|
||||
{
|
||||
p->netdev().update_terminals();
|
||||
gtot += p->m_g;
|
||||
iIdr += p->m_Idr;
|
||||
netlist_terminal_t *pt = static_cast<netlist_terminal_t *>(p);
|
||||
pt->netdev().update_terminals();
|
||||
gtot += pt->m_g;
|
||||
iIdr += pt->m_Idr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +186,7 @@ NETLIB_UPDATE(solver)
|
||||
resched = true;
|
||||
pn->object()->m_cur.Analog = pn->object()->m_new.Analog = new_val;
|
||||
|
||||
NL_VERBOSE_OUT(("Info: %d\n", (*pn)->m_num_cons));
|
||||
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));
|
||||
}
|
||||
if (resched)
|
||||
|
@ -80,7 +80,7 @@ NETLIB_DEVICE_WITH_PARAMS(clock,
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
NETLIB_DEVICE_WITH_PARAMS(solver,
|
||||
typedef netlist_list_t<netlist_terminal_t *> terminal_list_t;
|
||||
typedef netlist_list_t<netlist_core_terminal_t *> terminal_list_t;
|
||||
typedef netlist_list_t<netlist_net_t *> net_list_t;
|
||||
|
||||
netlist_ttl_input_t m_fb_sync;
|
||||
|
@ -99,6 +99,9 @@ NETLIB_DEVICE_WITH_PARAMS_DERIVED(R, twoterm,
|
||||
|
||||
NETLIB_UPDATE_TERMINALS() { NETLIB_NAME(twoterm)::update_terminals(); }
|
||||
|
||||
public:
|
||||
inline void set_R(double R) { m_g = 1.0 / R; }
|
||||
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -28,4 +28,5 @@ NETLISTOBJS+= \
|
||||
$(NETLISTOBJ)/devices/nld_7404.o \
|
||||
$(NETLISTOBJ)/devices/nld_7474.o \
|
||||
$(NETLISTOBJ)/devices/nld_7486.o \
|
||||
$(NETLISTOBJ)/devices/nld_NE555.o \
|
||||
|
||||
|
@ -266,7 +266,7 @@ ATTR_COLD void netlist_device_t::register_sub(netlist_device_t &dev, const pstri
|
||||
dev.init(*m_setup, this->name() + "." + name);
|
||||
}
|
||||
|
||||
ATTR_COLD void netlist_device_t::register_subalias(const pstring &name, netlist_terminal_t &term)
|
||||
ATTR_COLD void netlist_device_t::register_subalias(const pstring &name, netlist_core_terminal_t &term)
|
||||
{
|
||||
pstring alias = this->name() + "." + name;
|
||||
|
||||
@ -294,7 +294,7 @@ ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_inp
|
||||
m_setup->register_object(*this, *this, name, inp, type);
|
||||
}
|
||||
|
||||
static void init_term(netlist_core_device_t &dev, netlist_terminal_t &term, netlist_input_t::state_e aState)
|
||||
static void init_term(netlist_core_device_t &dev, netlist_core_terminal_t &term, netlist_input_t::state_e aState)
|
||||
{
|
||||
if (!term.isInitalized())
|
||||
{
|
||||
@ -362,7 +362,7 @@ ATTR_COLD netlist_net_t::netlist_net_t(const type_t atype, const family_t afamil
|
||||
m_last.Q = 0;
|
||||
};
|
||||
|
||||
ATTR_COLD void netlist_net_t::register_railterminal(netlist_terminal_t &mr)
|
||||
ATTR_COLD void netlist_net_t::register_railterminal(netlist_output_t &mr)
|
||||
{
|
||||
assert(m_railterminal == NULL);
|
||||
m_railterminal = &mr;
|
||||
@ -384,10 +384,10 @@ ATTR_COLD void netlist_net_t::merge_net(netlist_net_t *othernet)
|
||||
}
|
||||
else
|
||||
{
|
||||
netlist_terminal_t *p = othernet->m_head;
|
||||
netlist_core_terminal_t *p = othernet->m_head;
|
||||
while (p != NULL)
|
||||
{
|
||||
netlist_terminal_t *pn = p->m_update_list_next;
|
||||
netlist_core_terminal_t *pn = p->m_update_list_next;
|
||||
register_con(*p);
|
||||
p = pn;
|
||||
}
|
||||
@ -396,7 +396,7 @@ ATTR_COLD void netlist_net_t::merge_net(netlist_net_t *othernet)
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_COLD void netlist_net_t::register_con(netlist_terminal_t &terminal)
|
||||
ATTR_COLD void netlist_net_t::register_con(netlist_core_terminal_t &terminal)
|
||||
{
|
||||
terminal.set_net(*this);
|
||||
|
||||
@ -408,7 +408,7 @@ ATTR_COLD void netlist_net_t::register_con(netlist_terminal_t &terminal)
|
||||
m_active++;
|
||||
}
|
||||
|
||||
ATTR_HOT inline void netlist_net_t::update_dev(const netlist_terminal_t *inp, const UINT32 mask)
|
||||
ATTR_HOT inline void netlist_net_t::update_dev(const netlist_core_terminal_t *inp, const UINT32 mask)
|
||||
{
|
||||
if ((inp->state() & mask) != 0)
|
||||
{
|
||||
@ -433,7 +433,7 @@ ATTR_HOT inline void netlist_net_t::update_devs()
|
||||
|
||||
const UINT32 mask = masks[ (m_last.Q << 1) | m_cur.Q ];
|
||||
|
||||
netlist_terminal_t *p = m_head;
|
||||
netlist_core_terminal_t *p = m_head;
|
||||
switch (m_num_cons)
|
||||
{
|
||||
case 2:
|
||||
@ -458,10 +458,8 @@ ATTR_HOT inline void netlist_net_t::update_devs()
|
||||
// netlist_terminal_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
ATTR_COLD netlist_terminal_t::netlist_terminal_t(const type_t atype, const family_t afamily)
|
||||
ATTR_COLD netlist_core_terminal_t::netlist_core_terminal_t(const type_t atype, const family_t afamily)
|
||||
: netlist_owned_object_t(atype, afamily)
|
||||
, m_Idr(0.0)
|
||||
, m_g(NETLIST_GMIN)
|
||||
, m_update_list_next(NULL)
|
||||
, m_net(NULL)
|
||||
, m_state(STATE_NONEX)
|
||||
@ -470,23 +468,20 @@ ATTR_COLD netlist_terminal_t::netlist_terminal_t(const type_t atype, const famil
|
||||
}
|
||||
|
||||
ATTR_COLD netlist_terminal_t::netlist_terminal_t()
|
||||
: netlist_owned_object_t(TERMINAL, ANALOG)
|
||||
: netlist_core_terminal_t(TERMINAL, ANALOG)
|
||||
, m_Idr(0.0)
|
||||
, m_g(NETLIST_GMIN)
|
||||
, m_update_list_next(NULL)
|
||||
, m_net(NULL)
|
||||
, m_state(STATE_NONEX)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ATTR_COLD void netlist_terminal_t::init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate)
|
||||
ATTR_COLD void netlist_core_terminal_t::init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate)
|
||||
{
|
||||
set_state(astate);
|
||||
netlist_owned_object_t::init_object(dev, aname);
|
||||
}
|
||||
|
||||
ATTR_COLD void netlist_terminal_t::set_net(netlist_net_t &anet)
|
||||
ATTR_COLD void netlist_core_terminal_t::set_net(netlist_net_t &anet)
|
||||
{
|
||||
m_net = &anet;
|
||||
}
|
||||
@ -500,7 +495,7 @@ ATTR_COLD void netlist_terminal_t::set_net(netlist_net_t &anet)
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
netlist_output_t::netlist_output_t(const type_t atype, const family_t afamily)
|
||||
: netlist_terminal_t(atype, afamily)
|
||||
: netlist_core_terminal_t(atype, afamily)
|
||||
, m_low_V(0.0)
|
||||
, m_high_V(0.0)
|
||||
, m_my_net(NET, afamily)
|
||||
@ -511,7 +506,7 @@ netlist_output_t::netlist_output_t(const type_t atype, const family_t afamily)
|
||||
|
||||
ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const pstring &aname)
|
||||
{
|
||||
netlist_terminal_t::init_object(dev, aname, STATE_OUT);
|
||||
netlist_core_terminal_t::init_object(dev, aname, STATE_OUT);
|
||||
net().init_object(dev.netlist(), aname);
|
||||
net().register_railterminal(*this);
|
||||
}
|
||||
|
@ -291,10 +291,10 @@ private:
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// net_terminal_t
|
||||
// netlist_core_terminal_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class netlist_terminal_t : public netlist_owned_object_t
|
||||
class netlist_core_terminal_t : public netlist_owned_object_t
|
||||
{
|
||||
public:
|
||||
|
||||
@ -309,8 +309,7 @@ public:
|
||||
STATE_NONEX = 256
|
||||
};
|
||||
|
||||
ATTR_COLD netlist_terminal_t(const type_t atype, const family_t afamily);
|
||||
ATTR_COLD netlist_terminal_t();
|
||||
ATTR_COLD netlist_core_terminal_t(const type_t atype, const family_t afamily);
|
||||
|
||||
ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate);
|
||||
|
||||
@ -327,28 +326,35 @@ public:
|
||||
m_state = astate;
|
||||
}
|
||||
|
||||
double m_Idr; // drive current
|
||||
double m_g; // conductance
|
||||
|
||||
netlist_terminal_t *m_update_list_next;
|
||||
netlist_core_terminal_t *m_update_list_next;
|
||||
|
||||
private:
|
||||
netlist_net_t * RESTRICT m_net;
|
||||
state_e m_state;
|
||||
};
|
||||
|
||||
class netlist_terminal_t : public netlist_core_terminal_t
|
||||
{
|
||||
public:
|
||||
ATTR_COLD netlist_terminal_t();
|
||||
|
||||
double m_Idr; // drive current
|
||||
double m_g; // conductance
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_input_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class netlist_input_t : public netlist_terminal_t
|
||||
class netlist_input_t : public netlist_core_terminal_t
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
ATTR_COLD netlist_input_t(const type_t atype, const family_t afamily)
|
||||
: netlist_terminal_t(atype, afamily)
|
||||
: netlist_core_terminal_t(atype, afamily)
|
||||
, m_low_thresh_V(0)
|
||||
, m_high_thresh_V(0)
|
||||
{
|
||||
@ -444,9 +450,9 @@ public:
|
||||
|
||||
ATTR_COLD netlist_net_t(const type_t atype, const family_t afamily);
|
||||
|
||||
ATTR_COLD void register_con(netlist_terminal_t &terminal);
|
||||
ATTR_COLD void register_con(netlist_core_terminal_t &terminal);
|
||||
ATTR_COLD void merge_net(netlist_net_t *othernet);
|
||||
ATTR_COLD void register_railterminal(netlist_terminal_t &mr);
|
||||
ATTR_COLD void register_railterminal(netlist_output_t &mr);
|
||||
|
||||
/* inline not always works out */
|
||||
ATTR_HOT inline void update_devs();
|
||||
@ -455,8 +461,8 @@ public:
|
||||
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 const netlist_terminal_t & RESTRICT railterminal() const { return *m_railterminal; }
|
||||
ATTR_HOT inline const netlist_terminal_t & RESTRICT railterminal() { 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 */
|
||||
|
||||
@ -494,17 +500,17 @@ protected:
|
||||
hybrid_t m_cur;
|
||||
hybrid_t m_new;
|
||||
|
||||
netlist_terminal_t *m_head;
|
||||
netlist_core_terminal_t *m_head;
|
||||
UINT32 m_num_cons;
|
||||
|
||||
private:
|
||||
ATTR_HOT void update_dev(const netlist_terminal_t *inp, const UINT32 mask);
|
||||
ATTR_HOT void update_dev(const netlist_core_terminal_t *inp, const UINT32 mask);
|
||||
|
||||
netlist_time m_time;
|
||||
INT32 m_active;
|
||||
UINT32 m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */
|
||||
|
||||
netlist_terminal_t * RESTRICT m_railterminal;
|
||||
netlist_core_terminal_t * RESTRICT m_railterminal;
|
||||
};
|
||||
|
||||
|
||||
@ -515,7 +521,7 @@ private:
|
||||
class NETLIB_NAME(mainclock);
|
||||
class NETLIB_NAME(solver);
|
||||
|
||||
class netlist_output_t : public netlist_terminal_t
|
||||
class netlist_output_t : public netlist_core_terminal_t
|
||||
{
|
||||
public:
|
||||
|
||||
@ -748,6 +754,8 @@ public:
|
||||
|
||||
ATTR_HOT inline const double INPANALOG(const netlist_analog_input_t &inp) const { return inp.Q_Analog(); }
|
||||
|
||||
ATTR_HOT inline const double TERMANALOG(const netlist_terminal_t &term) const { return term.net().Q_Analog(); }
|
||||
|
||||
ATTR_HOT inline void OUTANALOG(netlist_analog_output_t &out, const double val, const netlist_time &delay)
|
||||
{
|
||||
out.set_Q(val, delay);
|
||||
@ -794,7 +802,7 @@ public:
|
||||
ATTR_COLD bool variable_input_count() { return m_variable_input_count; }
|
||||
|
||||
ATTR_COLD void register_sub(netlist_device_t &dev, const pstring &name);
|
||||
ATTR_COLD void register_subalias(const pstring &name, netlist_terminal_t &term);
|
||||
ATTR_COLD void register_subalias(const pstring &name, netlist_core_terminal_t &term);
|
||||
|
||||
ATTR_COLD void register_terminal(const pstring &name, netlist_terminal_t &port);
|
||||
|
||||
|
@ -54,12 +54,12 @@ typedef delegate<void (const double)> netlist_output_delegate;
|
||||
// DEBUGGING
|
||||
//============================================================
|
||||
|
||||
#define NL_VERBOSE (0)
|
||||
#define NL_KEEP_STATISTICS (0)
|
||||
#define FATAL_ERROR_AFTER_NS (0) //(1000)
|
||||
#define NL_VERBOSE (0)
|
||||
#define NL_KEEP_STATISTICS (0)
|
||||
#define FATAL_ERROR_AFTER_NS (0) //(1000)
|
||||
|
||||
#if (NL_VERBOSE)
|
||||
#define NL_VERBOSE_OUT(x) printf x
|
||||
#define NL_VERBOSE_OUT(x) printf x
|
||||
#else
|
||||
#define NL_VERBOSE_OUT(x)
|
||||
#endif
|
||||
|
@ -96,8 +96,9 @@ void netlist_parser::netdev_device(const pstring &dev_type)
|
||||
m_p++;
|
||||
skipws();
|
||||
pstring output_name = getname2(',', ')');
|
||||
NL_VERBOSE_OUT(("Parser: ID: %s %s\n", output_name.cstr(), dev->m_terminals.item(cnt)->cstr()));
|
||||
m_setup.register_link(pstring::sprintf("%s.[%d]", devname.cstr(), cnt), output_name);
|
||||
pstring alias = pstring::sprintf("%s.[%d]", devname.cstr(), cnt);
|
||||
NL_VERBOSE_OUT(("Parser: ID: %s %s\n", output_name.cstr(), alias.cstr()));
|
||||
m_setup.register_link(alias, output_name);
|
||||
skipws();
|
||||
cnt++;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device
|
||||
case netlist_terminal_t::INPUT:
|
||||
case netlist_terminal_t::OUTPUT:
|
||||
{
|
||||
netlist_terminal_t &term = dynamic_cast<netlist_terminal_t &>(obj);
|
||||
netlist_core_terminal_t &term = dynamic_cast<netlist_core_terminal_t &>(obj);
|
||||
if (obj.isType(netlist_terminal_t::OUTPUT))
|
||||
dynamic_cast<netlist_output_t &>(term).init_object(upd_dev, dev.name() + "." + name);
|
||||
else
|
||||
@ -259,18 +259,18 @@ const pstring netlist_setup_t::resolve_alias(const pstring &name) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in)
|
||||
netlist_core_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in)
|
||||
{
|
||||
const pstring &tname = resolve_alias(terminal_in);
|
||||
netlist_terminal_t *ret;
|
||||
netlist_core_terminal_t *ret;
|
||||
|
||||
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname));
|
||||
ret = m_terminals.find(tname);
|
||||
/* look for default */
|
||||
if (ret == NULL)
|
||||
{
|
||||
/* look for ".Q" std output */
|
||||
pstring s = tname + ".Q";
|
||||
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(s));
|
||||
ret = m_terminals.find(s);
|
||||
}
|
||||
if (ret == NULL)
|
||||
fatalerror("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr());
|
||||
@ -278,18 +278,18 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in)
|
||||
return *ret;
|
||||
}
|
||||
|
||||
netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in, netlist_object_t::type_t atype)
|
||||
netlist_core_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in, netlist_object_t::type_t atype)
|
||||
{
|
||||
const pstring &tname = resolve_alias(terminal_in);
|
||||
netlist_terminal_t *ret;
|
||||
netlist_core_terminal_t *ret;
|
||||
|
||||
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname));
|
||||
ret = m_terminals.find(tname);
|
||||
/* look for default */
|
||||
if (ret == NULL && atype == netlist_object_t::OUTPUT)
|
||||
{
|
||||
/* look for ".Q" std output */
|
||||
pstring s = tname + ".Q";
|
||||
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(s));
|
||||
ret = m_terminals.find(s);
|
||||
}
|
||||
if (ret == NULL)
|
||||
fatalerror("terminal %s(%s) not found!\n", terminal_in.cstr(), tname.cstr());
|
||||
@ -411,7 +411,7 @@ void netlist_setup_t::connect_terminal_output(netlist_terminal_t &in, netlist_ou
|
||||
}
|
||||
}
|
||||
|
||||
void netlist_setup_t::connect_terminals(netlist_terminal_t &t1, netlist_terminal_t &t2)
|
||||
void netlist_setup_t::connect_terminals(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2)
|
||||
{
|
||||
//assert(in.isType(netlist_terminal_t::TERMINAL));
|
||||
//assert(out.isType(netlist_terminal_t::TERMINAL));
|
||||
@ -444,41 +444,40 @@ void netlist_setup_t::connect_terminals(netlist_terminal_t &t1, netlist_terminal
|
||||
}
|
||||
}
|
||||
|
||||
void netlist_setup_t::connect(netlist_terminal_t &t1, netlist_terminal_t &t2)
|
||||
void netlist_setup_t::connect(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2)
|
||||
{
|
||||
NL_VERBOSE_OUT(("Connecting %s to %s\n", t1.name().cstr(), t2s.name().cstr()));
|
||||
|
||||
NL_VERBOSE_OUT(("Connecting %s to %s\n", t1.name().cstr(), t2.name().cstr()));
|
||||
// FIXME: amend device design so that warnings can be turned into errors
|
||||
// Only variable inputs have this issue
|
||||
if (t1.isType(netlist_terminal_t::OUTPUT) && t2.isType(netlist_terminal_t::INPUT))
|
||||
if (t1.isType(netlist_core_terminal_t::OUTPUT) && t2.isType(netlist_core_terminal_t::INPUT))
|
||||
{
|
||||
if (t2.has_net())
|
||||
mame_printf_warning("Input %s already connected\n", t2.name().cstr());
|
||||
connect_input_output(dynamic_cast<netlist_input_t &>(t2), dynamic_cast<netlist_output_t &>(t1));
|
||||
}
|
||||
else if (t1.isType(netlist_terminal_t::INPUT) && t2.isType(netlist_terminal_t::OUTPUT))
|
||||
else if (t1.isType(netlist_core_terminal_t::INPUT) && t2.isType(netlist_core_terminal_t::OUTPUT))
|
||||
{
|
||||
if (t1.has_net())
|
||||
mame_printf_warning("Input %s already connected\n", t1.name().cstr());
|
||||
connect_input_output(dynamic_cast<netlist_input_t &>(t1), dynamic_cast<netlist_output_t &>(t2));
|
||||
}
|
||||
else if (t1.isType(netlist_terminal_t::OUTPUT) && t2.isType(netlist_terminal_t::TERMINAL))
|
||||
else if (t1.isType(netlist_core_terminal_t::OUTPUT) && t2.isType(netlist_core_terminal_t::TERMINAL))
|
||||
{
|
||||
connect_terminal_output(dynamic_cast<netlist_terminal_t &>(t2), dynamic_cast<netlist_output_t &>(t1));
|
||||
}
|
||||
else if (t1.isType(netlist_terminal_t::TERMINAL) && t2.isType(netlist_terminal_t::OUTPUT))
|
||||
else if (t1.isType(netlist_core_terminal_t::TERMINAL) && t2.isType(netlist_core_terminal_t::OUTPUT))
|
||||
{
|
||||
connect_terminal_output(dynamic_cast<netlist_terminal_t &>(t1), dynamic_cast<netlist_output_t &>(t2));
|
||||
}
|
||||
else if (t1.isType(netlist_terminal_t::INPUT) && t2.isType(netlist_terminal_t::TERMINAL))
|
||||
else if (t1.isType(netlist_core_terminal_t::INPUT) && t2.isType(netlist_core_terminal_t::TERMINAL))
|
||||
{
|
||||
connect_terminal_input(dynamic_cast<netlist_terminal_t &>(t2), dynamic_cast<netlist_input_t &>(t1));
|
||||
}
|
||||
else if (t1.isType(netlist_terminal_t::TERMINAL) && t2.isType(netlist_terminal_t::INPUT))
|
||||
else if (t1.isType(netlist_core_terminal_t::TERMINAL) && t2.isType(netlist_core_terminal_t::INPUT))
|
||||
{
|
||||
connect_terminal_input(dynamic_cast<netlist_terminal_t &>(t1), dynamic_cast<netlist_input_t &>(t2));
|
||||
}
|
||||
else if (t1.isType(netlist_terminal_t::TERMINAL) && t2.isType(netlist_terminal_t::TERMINAL))
|
||||
else if (t1.isType(netlist_core_terminal_t::TERMINAL) && t2.isType(netlist_core_terminal_t::TERMINAL))
|
||||
{
|
||||
connect_terminals(dynamic_cast<netlist_terminal_t &>(t1), dynamic_cast<netlist_terminal_t &>(t2));
|
||||
}
|
||||
@ -488,28 +487,14 @@ void netlist_setup_t::connect(netlist_terminal_t &t1, netlist_terminal_t &t2)
|
||||
|
||||
void netlist_setup_t::resolve_inputs(void)
|
||||
{
|
||||
NL_VERBOSE_OUT(("Searching for mainclock and solver ...\n"));
|
||||
/* find the main clock ... */
|
||||
for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
|
||||
{
|
||||
netlist_device_t *dev = entry->object();
|
||||
if (dynamic_cast<NETLIB_NAME(mainclock)*>(dev) != NULL)
|
||||
{
|
||||
m_netlist.set_mainclock_dev(dynamic_cast<NETLIB_NAME(mainclock)*>(dev));
|
||||
}
|
||||
if (dynamic_cast<NETLIB_NAME(solver)*>(dev) != NULL)
|
||||
{
|
||||
m_netlist.set_solver_dev(dynamic_cast<NETLIB_NAME(solver)*>(dev));
|
||||
}
|
||||
}
|
||||
|
||||
NL_VERBOSE_OUT(("Resolving ...\n"));
|
||||
for (tagmap_link_t::entry_t *entry = m_links.first(); entry != NULL; entry = m_links.next(entry))
|
||||
{
|
||||
const pstring t1s = entry->object().e1;
|
||||
const pstring t2s = entry->object().e2;
|
||||
netlist_terminal_t &t1 = find_terminal(t1s);
|
||||
netlist_terminal_t &t2 = find_terminal(t2s);
|
||||
netlist_core_terminal_t &t1 = find_terminal(t1s);
|
||||
netlist_core_terminal_t &t2 = find_terminal(t2s);
|
||||
|
||||
connect(t1, t2);
|
||||
}
|
||||
@ -530,6 +515,23 @@ void netlist_setup_t::resolve_inputs(void)
|
||||
|
||||
void netlist_setup_t::start_devices(void)
|
||||
{
|
||||
|
||||
NL_VERBOSE_OUT(("Searching for mainclock and solver ...\n"));
|
||||
/* find the main clock ... */
|
||||
for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
|
||||
{
|
||||
netlist_device_t *dev = entry->object();
|
||||
if (dynamic_cast<NETLIB_NAME(mainclock)*>(dev) != NULL)
|
||||
{
|
||||
m_netlist.set_mainclock_dev(dynamic_cast<NETLIB_NAME(mainclock)*>(dev));
|
||||
}
|
||||
if (dynamic_cast<NETLIB_NAME(solver)*>(dev) != NULL)
|
||||
{
|
||||
m_netlist.set_solver_dev(dynamic_cast<NETLIB_NAME(solver)*>(dev));
|
||||
}
|
||||
}
|
||||
|
||||
NL_VERBOSE_OUT(("Initializing devices ...\n"));
|
||||
for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
|
||||
{
|
||||
netlist_device_t *dev = entry->object();
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
typedef tagmap_t<netlist_device_t *, 393> tagmap_devices_t;
|
||||
typedef tagmap_t<pstring, 393> tagmap_nstring_t;
|
||||
typedef tagmap_t<netlist_param_t *, 393> tagmap_param_t;
|
||||
typedef tagmap_t<netlist_terminal_t *, 393> tagmap_terminal_t;
|
||||
typedef tagmap_t<netlist_core_terminal_t *, 393> tagmap_terminal_t;
|
||||
typedef netlist_list_t<link_t> tagmap_link_t;
|
||||
|
||||
netlist_setup_t(netlist_base_t &netlist);
|
||||
@ -108,10 +108,10 @@ public:
|
||||
void register_param(const pstring ¶m, const double value);
|
||||
|
||||
void 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 connect(netlist_terminal_t &t1, netlist_terminal_t &t2);
|
||||
void connect(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2);
|
||||
|
||||
netlist_terminal_t &find_terminal(const pstring &outname_in);
|
||||
netlist_terminal_t &find_terminal(const pstring &outname_in, netlist_object_t::type_t atype);
|
||||
netlist_core_terminal_t &find_terminal(const pstring &outname_in);
|
||||
netlist_core_terminal_t &find_terminal(const pstring &outname_in, netlist_object_t::type_t atype);
|
||||
|
||||
netlist_param_t &find_param(const pstring ¶m_in);
|
||||
|
||||
@ -142,7 +142,7 @@ private:
|
||||
|
||||
int m_proxy_cnt;
|
||||
|
||||
void connect_terminals(netlist_terminal_t &in, netlist_terminal_t &out);
|
||||
void connect_terminals(netlist_core_terminal_t &in, netlist_core_terminal_t &out);
|
||||
void connect_input_output(netlist_input_t &in, netlist_output_t &out);
|
||||
void connect_terminal_output(netlist_terminal_t &in, netlist_output_t &out);
|
||||
void connect_terminal_input(netlist_terminal_t &term, netlist_input_t &inp);
|
||||
|
@ -531,7 +531,6 @@ static NETLIST_START(pong_schematics)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
// astable NAND Multivibrator
|
||||
NETDEV_R(R1, 1000)
|
||||
NETDEV_C(C1, 1e-6)
|
||||
@ -544,6 +543,31 @@ static NETLIST_START(pong_schematics)
|
||||
//NETDEV_LOG(log2, n1.Q)
|
||||
//NETDEV_LOG(log3, n2.Q)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// astable NE555, 1.13 ms period
|
||||
NETDEV_R(RA, 5000)
|
||||
NETDEV_R(RB, 3000)
|
||||
NETDEV_C(C, 0.15e-6)
|
||||
NETDEV_NE555(555)
|
||||
|
||||
NET_C(V0, 555.GND)
|
||||
NET_C(V5, 555.VCC)
|
||||
|
||||
NET_C(RA.1, 555.VCC)
|
||||
NET_C(RA.2, 555.DISCH)
|
||||
|
||||
NET_C(RB.1, 555.DISCH)
|
||||
NET_C(RB.2, 555.TRIG)
|
||||
|
||||
NET_C(RB.2, 555.THRESH)
|
||||
|
||||
NET_C(555.TRIG, C.1)
|
||||
NET_C(C.2, V0)
|
||||
//NETDEV_LOG(log2, C.1)
|
||||
#endif
|
||||
|
||||
|
||||
NETLIST_END
|
||||
|
||||
static NETLIST_START(pong)
|
||||
|
Loading…
Reference in New Issue
Block a user