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:
Couriersud 2013-12-01 15:45:12 +00:00
parent ecac6034c6
commit 7069a5828c
21 changed files with 282 additions and 116 deletions

2
.gitattributes vendored
View File

@ -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

View File

@ -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
};

View File

@ -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)

View File

@ -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_ */

View File

@ -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);

View File

@ -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_ */

View File

@ -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);

View File

@ -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;

View 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;
}

View 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_ */

View File

@ -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)

View File

@ -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;

View File

@ -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; }
);
// ----------------------------------------------------------------------------------------

View File

@ -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 \

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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++;
}

View File

@ -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();

View File

@ -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 &param, 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 &param_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);

View File

@ -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)