Netlist: Class factory is now initialized dynamically.

Note: Please delete all netlist related object files prior to compiling,  e.g.:

rm -rf  obj/windowsd/mame/drivers/pong.o obj/windowsd/emu/machine/net* obj/windowsd/emu/netlist/
This commit is contained in:
Couriersud 2013-12-02 23:20:39 +00:00
parent 954b9ff18e
commit 445a95b4fd
12 changed files with 158 additions and 77 deletions

View File

@ -901,79 +901,78 @@ NETLIB_FUNC_VOID(nic9316_sub, update_outputs, (void))
}
#define xstr(s) # s
#define ENTRY1(_nic, _name) 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) ));
#define ENTRY(_nic, _name) ENTRY1(NETLIB_NAME(_nic), _name)
static const net_device_t_base_factory *netregistry[] =
void netlist_factory::initialize()
{
ENTRY(R, NETDEV_R)
ENTRY(C, NETDEV_C)
ENTRY(D, NETDEV_D)
ENTRY(ttl_const, NETDEV_TTL_CONST)
ENTRY(analog_const, NETDEV_ANALOG_CONST)
ENTRY(logic_input, NETDEV_LOGIC_INPUT)
ENTRY(analog_input, NETDEV_ANALOG_INPUT)
ENTRY(log, NETDEV_LOG)
ENTRY(clock, NETDEV_CLOCK)
ENTRY(mainclock, NETDEV_MAINCLOCK)
ENTRY(ttl_const, NETDEV_TTL_CONST)
ENTRY(analog_const, NETDEV_ANALOG_CONST)
ENTRY(logic_input, NETDEV_LOGIC_INPUT)
ENTRY(analog_input, NETDEV_ANALOG_INPUT)
ENTRY(log, NETDEV_LOG)
ENTRY(clock, NETDEV_CLOCK)
ENTRY(mainclock, NETDEV_MAINCLOCK)
ENTRY(solver, NETDEV_SOLVER)
ENTRY(analog_callback, NETDEV_CALLBACK)
ENTRY(nicMultiSwitch, NETDEV_SWITCH2)
ENTRY(nicRSFF, NETDEV_RSFF)
ENTRY(nicMixer8, NETDEV_MIXER)
ENTRY(7400, TTL_7400_NAND)
ENTRY(7402, TTL_7402_NOR)
ENTRY(nic7404, TTL_7404_INVERT)
ENTRY(7410, TTL_7410_NAND)
ENTRY(7420, TTL_7420_NAND)
ENTRY(7425, TTL_7425_NOR)
ENTRY(7427, TTL_7427_NOR)
ENTRY(7430, TTL_7430_NAND)
ENTRY(nic7450, TTL_7450_ANDORINVERT)
ENTRY(7486, TTL_7486_XOR)
ENTRY(nic7448, TTL_7448)
ENTRY(7474, TTL_7474)
ENTRY(nic7483, TTL_7483)
ENTRY(nic7490, TTL_7490)
ENTRY(nic7493, TTL_7493)
ENTRY(nic74107, TTL_74107)
ENTRY(nic74107A, TTL_74107A)
ENTRY(nic74153, TTL_74153)
ENTRY(nic9316, TTL_9316)
ENTRY(NE555, NETDEV_NE555)
ENTRY(analog_callback, NETDEV_CALLBACK)
ENTRY(nicMultiSwitch, NETDEV_SWITCH2)
ENTRY(nicRSFF, NETDEV_RSFF)
ENTRY(nicMixer8, NETDEV_MIXER)
ENTRY(7400, TTL_7400_NAND)
ENTRY(7402, TTL_7402_NOR)
ENTRY(nic7404, TTL_7404_INVERT)
ENTRY(7410, TTL_7410_NAND)
ENTRY(7420, TTL_7420_NAND)
ENTRY(7425, TTL_7425_NOR)
ENTRY(7427, TTL_7427_NOR)
ENTRY(7430, TTL_7430_NAND)
ENTRY(nic7450, TTL_7450_ANDORINVERT)
ENTRY(7486, TTL_7486_XOR)
ENTRY(nic7448, TTL_7448)
ENTRY(7474, TTL_7474)
ENTRY(nic7483, TTL_7483)
ENTRY(nic7490, TTL_7490)
ENTRY(nic7493, TTL_7493)
ENTRY(nic74107, TTL_74107)
ENTRY(nic74107A, TTL_74107A)
ENTRY(nic74153, TTL_74153)
ENTRY(nic9316, TTL_9316)
ENTRY(NE555, NETDEV_NE555)
ENTRY(nicNE555N_MSTABLE, NE555N_MSTABLE)
NULL
};
netlist_device_t *net_create_device_by_classname(const pstring &classname, netlist_setup_t &setup)
{
const net_device_t_base_factory **p = &netregistry[0];
while (*p != NULL)
{
if (strcmp((*p)->classname(), classname) == 0)
{
netlist_device_t *ret = (*p)->Create();
return ret;
}
p++;
}
fatalerror("Class %s not found!\n", classname.cstr());
return NULL; // appease code analysis
}
netlist_device_t *net_create_device_by_name(const pstring &name, netlist_setup_t &setup)
netlist_device_t *netlist_factory::new_device_by_classname(const pstring &classname, netlist_setup_t &setup) const
{
const net_device_t_base_factory **p = &netregistry[0];
while (*p != NULL)
{
if (strcmp((*p)->name(), name) == 0)
{
netlist_device_t *ret = (*p)->Create();
//ret->init(setup, icname);
return ret;
}
p++;
}
fatalerror("Class %s not found!\n", name.cstr());
return NULL; // appease code analysis
for (list_t::entry_t *e = m_list.first(); e != NULL; e = m_list.next(e))
{
net_device_t_base_factory *p = e->object();
if (strcmp(p->classname(), classname) == 0)
{
netlist_device_t *ret = p->Create();
return ret;
}
p++;
}
fatalerror("Class %s not found!\n", classname.cstr());
return NULL; // appease code analysis
}
netlist_device_t *netlist_factory::new_device_by_name(const pstring &name, netlist_setup_t &setup) const
{
for (list_t::entry_t *e = m_list.first(); e != NULL; e = m_list.next(e))
{
net_device_t_base_factory *p = e->object();
if (strcmp(p->name(), name) == 0)
{
netlist_device_t *ret = p->Create();
return ret;
}
p++;
}
fatalerror("Class %s not found!\n", name.cstr());
return NULL; // appease code analysis
}

View File

@ -41,4 +41,36 @@
NETLIB_SIGNAL(7400, 2, 0, 0);
NETLIB_DEVICE(7400pin,
NETLIB_NAME(7400) m_1;
NETLIB_NAME(7400) m_2;
NETLIB_NAME(7400) m_3;
NETLIB_NAME(7400) m_4;
);
inline NETLIB_START(7400pin)
{
register_sub(m_1, "1");
register_sub(m_2, "2");
register_sub(m_3, "3");
register_sub(m_4, "4");
register_subalias("1", m_1.m_i[0]);
register_subalias("2", m_1.m_i[1]);
register_subalias("3", m_1.m_Q);
register_subalias("4", m_2.m_i[0]);
register_subalias("5", m_2.m_i[1]);
register_subalias("6", m_2.m_Q);
register_subalias("9", m_3.m_i[0]);
register_subalias("10", m_3.m_i[1]);
register_subalias("8", m_3.m_Q);
register_subalias("12", m_4.m_i[0]);
register_subalias("13", m_4.m_i[1]);
register_subalias("11", m_4.m_Q);
}
#endif /* NLD_7400_H_ */

View File

@ -4,6 +4,7 @@
*/
#include "nld_log.h"
#include "sound/wavwrite.h"
NETLIB_START(log)
{
@ -22,3 +23,25 @@ NETLIB_NAME(log)::~NETLIB_NAME(log)()
{
fclose(m_file);
}
// FIXME: Implement wav later, this must be clock triggered device where the input to be written
// is on a subdevice ...
#if 0
NETLIB_START(wav)
{
register_input("I", m_I);
pstring filename = "netlist_" + name() + ".wav";
m_file = wav_open(filename, sample_rate(), active_inputs()/2)
}
NETLIB_UPDATE(wav)
{
fprintf(m_file, "%e %e\n", netlist().time().as_double(), INPANALOG(m_I));
}
NETLIB_NAME(log)::~NETLIB_NAME(wav)()
{
fclose(m_file);
}
#endif

View File

@ -31,4 +31,14 @@ private:
FILE *m_file;
);
#if 0
NETLIB_DEVICE(wav,
~NETLIB_NAME(wav)();
netlist_analog_input_t m_I;
private:
// FIXME: rewrite sound/wavwrite.h to be an object ...
void *m_file;
);
#endif
#endif /* NLD_LOG_H_ */

View File

@ -89,7 +89,7 @@ NETLIB_START(solver)
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, 50000.0);
register_param("FREQ", m_freq, 48000.0);
m_inc = netlist_time::from_hz(m_freq.Value());
register_link_internal(m_fb_sync, m_Q_sync, netlist_input_t::STATE_INP_ACTIVE);

View File

@ -1139,8 +1139,21 @@ public:
}
};
netlist_device_t *net_create_device_by_classname(const pstring &classname, netlist_setup_t &setup);
netlist_device_t *net_create_device_by_name(const pstring &name, netlist_setup_t &setup);
class netlist_factory
{
public:
void initialize();
netlist_device_t *new_device_by_classname(const pstring &classname, netlist_setup_t &setup) const;
netlist_device_t *new_device_by_name(const pstring &name, netlist_setup_t &setup) const;
private:
typedef netlist_list_t<net_device_t_base_factory *> list_t;
list_t m_list;
};
#endif /* NLBASE_H_ */

View File

@ -16,8 +16,6 @@
// SETUP
//============================================================
//#define astring breakme()
#define USE_DELEGATES (0)
/*
* The next options needs -Wno-pmf-conversions to compile and gcc

View File

@ -75,12 +75,12 @@ public:
}
}
}
ATTR_HOT inline entry_t *first() { return (m_ptr >= m_list ? &m_list[0] : NULL ); }
ATTR_HOT inline entry_t *next(entry_t *lc) { return (lc < last() ? lc + 1 : NULL ); }
ATTR_HOT inline entry_t *last() { return m_ptr; }
ATTR_HOT inline entry_t *item(int i) { return &m_list[i]; }
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 *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 bool empty() { 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; }
private:
entry_t * m_ptr;

View File

@ -67,7 +67,7 @@ void netlist_parser::netdev_const(const pstring &dev_name)
skipws();
name = getname(',');
dev = net_create_device_by_name(dev_name, m_setup);
dev = m_setup.factory().new_device_by_name(dev_name, m_setup);
m_setup.register_dev(dev, name);
skipws();
val = eval_param();
@ -86,7 +86,7 @@ void netlist_parser::netdev_device(const pstring &dev_type)
skipws();
devname = getname2(',', ')');
dev = net_create_device_by_name(dev_type, m_setup);
dev = m_setup.factory().new_device_by_name(dev_type, m_setup);
m_setup.register_dev(dev, devname);
skipws();
NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));

View File

@ -25,6 +25,7 @@ netlist_setup_t::netlist_setup_t(netlist_base_t &netlist)
: m_netlist(netlist)
, m_proxy_cnt(0)
{
m_factory.initialize();
NETLIST_NAME(base)(*this);
}

View File

@ -20,7 +20,7 @@
#define NET_ALIAS(_alias, _name) \
netlist.register_alias(# _alias, # _name);
#define NET_NEW(_type) net_create_device_by_classname(NETLIB_NAME_STR(_type), netlist)
#define NET_NEW(_type) netlist.factory().new_device_by_classname(NETLIB_NAME_STR(_type), netlist)
#define NET_REGISTER_DEV(_type, _name) \
netlist.register_dev(NET_NEW(_type), # _name);
@ -98,6 +98,7 @@ public:
~netlist_setup_t();
netlist_base_t &netlist() { return m_netlist; }
netlist_factory &factory() { return m_factory; }
netlist_device_t *register_dev(netlist_device_t *dev, const pstring &name);
void remove_dev(const pstring &name);
@ -140,6 +141,8 @@ private:
tagmap_link_t m_links;
tagmap_nstring_t m_params_temp;
netlist_factory m_factory;
int m_proxy_cnt;
void connect_terminals(netlist_core_terminal_t &in, netlist_core_terminal_t &out);

View File

@ -7,6 +7,8 @@
#include <cstdio>
// The following will work on linux, however not on Windows ....
//pblockpool *pstring::m_pool = new pblockpool;
//pstring::str_t *pstring::m_zero = new(pstring::m_pool, 0) pstring::str_t(0);