Changed the way NETLIST_START(NAME) is located and called. This is done
now solely by using a netlist_sources_t class. Netlist users just register sources like memregions, hardcoded strings, compiled netlists. Going forward this enables to eventually put macro model librariers into roms. The improvement comes with a price. Compiled netlists to be included must now be registered using LOCAL_SOURCE. [Couriersud]
This commit is contained in:
parent
574a2787fc
commit
7cd3ebf18a
@ -13,6 +13,7 @@
|
||||
#include "netlist/nl_base.h"
|
||||
#include "netlist/nl_setup.h"
|
||||
#include "netlist/nl_factory.h"
|
||||
#include "netlist/nl_parser.h"
|
||||
#include "netlist/devices/net_lib.h"
|
||||
#include "debugger.h"
|
||||
|
||||
@ -633,3 +634,14 @@ void netlist_mame_sound_device_t::sound_stream_update(sound_stream &stream, stre
|
||||
m_out[i]->buffer_reset(cur);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// memregion source support
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
bool netlist_source_memregion_t::parse(netlist_setup_t *setup, const pstring name)
|
||||
{
|
||||
const char *mem = (const char *)downcast<netlist_mame_t &>(setup->netlist()).machine().root_device().memregion(m_name.cstr())->base();
|
||||
netlist_parser p(*setup);
|
||||
return p.parse(mem, name);
|
||||
}
|
||||
|
@ -60,8 +60,21 @@
|
||||
// Extensions to interface netlist with MAME code ....
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#define NETLIST_MEMREGION(_name) \
|
||||
setup.parse((char *)downcast<netlist_mame_t &>(setup.netlist()).machine().root_device().memregion(_name)->base());
|
||||
class netlist_source_memregion_t : public netlist_source_t
|
||||
{
|
||||
public:
|
||||
netlist_source_memregion_t(pstring name)
|
||||
: netlist_source_t(), m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
bool parse(netlist_setup_t *setup, const pstring name);
|
||||
private:
|
||||
pstring m_name;
|
||||
};
|
||||
|
||||
#define MEMREGION_SOURCE(_name) \
|
||||
setup.register_source(palloc(netlist_source_memregion_t, _name));
|
||||
|
||||
#define NETDEV_ANALOG_CALLBACK_MEMBER(_name) \
|
||||
void _name(const double data, const attotime &time)
|
||||
|
@ -52,6 +52,7 @@ bool netlist_parser::parse(const char *buf, const pstring nlname)
|
||||
m_tok_PARAM = register_token("PARAM");
|
||||
m_tok_NET_MODEL = register_token("NET_MODEL");
|
||||
m_tok_INCLUDE = register_token("INCLUDE");
|
||||
m_tok_LOCAL_SOURCE = register_token("LOCAL_SOURCE");
|
||||
m_tok_SUBMODEL = register_token("SUBMODEL");
|
||||
m_tok_NETLIST_START = register_token("NETLIST_START");
|
||||
m_tok_NETLIST_END = register_token("NETLIST_END");
|
||||
@ -124,6 +125,8 @@ void netlist_parser::parse_netlist(ATTR_UNUSED const pstring &nlname)
|
||||
net_submodel();
|
||||
else if (token.is(m_tok_INCLUDE))
|
||||
net_include();
|
||||
else if (token.is(m_tok_LOCAL_SOURCE))
|
||||
net_local_source();
|
||||
else if (token.is(m_tok_TRUTHTABLE_START))
|
||||
net_truthtable_start();
|
||||
else if (token.is(m_tok_NETLIST_END))
|
||||
@ -210,8 +213,7 @@ void netlist_parser::net_submodel()
|
||||
require_token(m_tok_param_right);
|
||||
|
||||
m_setup.namespace_push(name);
|
||||
netlist_parser subparser(m_setup);
|
||||
subparser.parse(m_buf, model);
|
||||
m_setup.include(name);
|
||||
m_setup.namespace_pop();
|
||||
}
|
||||
|
||||
@ -221,8 +223,15 @@ void netlist_parser::net_include()
|
||||
pstring name = get_identifier();
|
||||
require_token(m_tok_param_right);
|
||||
|
||||
netlist_parser subparser(m_setup);
|
||||
subparser.parse(m_buf, name);
|
||||
m_setup.include(name);
|
||||
}
|
||||
|
||||
void netlist_parser::net_local_source()
|
||||
{
|
||||
// This directive is only for hardcoded netlists. Ignore it here.
|
||||
pstring name = get_identifier();
|
||||
require_token(m_tok_param_right);
|
||||
|
||||
}
|
||||
|
||||
void netlist_parser::net_alias()
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
void net_model();
|
||||
void net_submodel();
|
||||
void net_include();
|
||||
void net_local_source();
|
||||
void net_truthtable_start();
|
||||
|
||||
protected:
|
||||
@ -53,6 +54,7 @@ private:
|
||||
token_id_t m_tok_NETLIST_END;
|
||||
token_id_t m_tok_SUBMODEL;
|
||||
token_id_t m_tok_INCLUDE;
|
||||
token_id_t m_tok_LOCAL_SOURCE;
|
||||
token_id_t m_tok_TRUTHTABLE_START;
|
||||
token_id_t m_tok_TRUTHTABLE_END;
|
||||
token_id_t m_tok_TT_HEAD;
|
||||
@ -63,105 +65,5 @@ private:
|
||||
const char *m_buf;
|
||||
};
|
||||
|
||||
class netlist_source_t
|
||||
{
|
||||
public:
|
||||
typedef plist_t<netlist_source_t> list_t;
|
||||
|
||||
enum source_e
|
||||
{
|
||||
EMPTY,
|
||||
STRING,
|
||||
PROC,
|
||||
MEMORY
|
||||
};
|
||||
|
||||
netlist_source_t()
|
||||
: m_type(EMPTY),
|
||||
m_setup_func(NULL),
|
||||
m_setup_func_name(""),
|
||||
m_mem(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
netlist_source_t(pstring name, void (*setup_func)(netlist_setup_t &))
|
||||
: m_type(PROC),
|
||||
m_setup_func(setup_func),
|
||||
m_setup_func_name(name),
|
||||
m_mem(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
netlist_source_t(const char *mem)
|
||||
: m_type(MEMORY),
|
||||
m_setup_func(NULL),
|
||||
m_setup_func_name(""),
|
||||
m_mem(mem)
|
||||
{
|
||||
}
|
||||
|
||||
~netlist_source_t() { }
|
||||
|
||||
bool parse(netlist_setup_t &setup, const pstring name)
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case PROC:
|
||||
if (name == m_setup_func_name)
|
||||
{
|
||||
m_setup_func(setup);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case MEMORY:
|
||||
{
|
||||
netlist_parser p(setup);
|
||||
return p.parse(m_mem, name);
|
||||
}
|
||||
break;
|
||||
case STRING:
|
||||
case EMPTY:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
source_e m_type;
|
||||
|
||||
void (*m_setup_func)(netlist_setup_t &);
|
||||
pstring m_setup_func_name;
|
||||
const char *m_mem;
|
||||
|
||||
};
|
||||
|
||||
class netlist_sources_t
|
||||
{
|
||||
public:
|
||||
|
||||
netlist_sources_t() { }
|
||||
|
||||
~netlist_sources_t()
|
||||
{
|
||||
m_list.clear();
|
||||
}
|
||||
|
||||
void add(netlist_source_t src)
|
||||
{
|
||||
m_list.add(src);
|
||||
}
|
||||
|
||||
void parse(netlist_setup_t &setup, const pstring name)
|
||||
{
|
||||
for (std::size_t i=0; i < m_list.size(); i++)
|
||||
{
|
||||
if (m_list[i].parse(setup, name))
|
||||
return;
|
||||
}
|
||||
setup.netlist().error("unable to find %s in source collection", name.cstr());
|
||||
}
|
||||
|
||||
private:
|
||||
netlist_source_t::list_t m_list;
|
||||
};
|
||||
|
||||
#endif /* NL_PARSER_H_ */
|
||||
|
@ -24,6 +24,9 @@ static NETLIST_START(base)
|
||||
NET_REGISTER_DEV(gnd, GND)
|
||||
NET_REGISTER_DEV(netlistparams, NETLIST)
|
||||
|
||||
LOCAL_SOURCE(diode_models)
|
||||
LOCAL_SOURCE(bjt_models)
|
||||
|
||||
INCLUDE(diode_models);
|
||||
INCLUDE(bjt_models);
|
||||
|
||||
@ -777,12 +780,6 @@ void netlist_setup_t::start_devices()
|
||||
netlist().start();
|
||||
}
|
||||
|
||||
void netlist_setup_t::parse(const char *buf)
|
||||
{
|
||||
netlist_parser parser(*this);
|
||||
parser.parse(buf);
|
||||
}
|
||||
|
||||
void netlist_setup_t::print_stats() const
|
||||
{
|
||||
#if (NL_KEEP_STATISTICS)
|
||||
@ -797,3 +794,34 @@ void netlist_setup_t::print_stats() const
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Sources
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void netlist_sources_t::parse(netlist_setup_t *setup, const pstring name)
|
||||
{
|
||||
for (std::size_t i=0; i < m_list.size(); i++)
|
||||
{
|
||||
if (m_list[i]->parse(setup, name))
|
||||
return;
|
||||
}
|
||||
setup->netlist().error("unable to find %s in source collection", name.cstr());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// base sources
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool netlist_source_string_t::parse(netlist_setup_t *setup, const pstring name)
|
||||
{
|
||||
netlist_parser p(*setup);
|
||||
return p.parse(m_str, name);
|
||||
}
|
||||
|
||||
bool netlist_source_mem_t::parse(netlist_setup_t *setup, const pstring name)
|
||||
{
|
||||
netlist_parser p(*setup);
|
||||
return p.parse(m_str, name);
|
||||
}
|
||||
|
@ -57,14 +57,60 @@ ATTR_COLD void NETLIST_NAME(_name)(netlist_setup_t &setup)
|
||||
{
|
||||
#define NETLIST_END() }
|
||||
|
||||
#define LOCAL_SOURCE(_name) \
|
||||
setup.register_source(palloc(netlist_source_proc_t, # _name, &NETLIST_NAME(_name)));
|
||||
|
||||
#define INCLUDE(_name) \
|
||||
NETLIST_NAME(_name)(setup);
|
||||
setup.include(# _name);
|
||||
|
||||
#define SUBMODEL(_name, _model) \
|
||||
setup.namespace_push(# _name); \
|
||||
NETLIST_NAME(_model)(setup); \
|
||||
setup.namespace_pop();
|
||||
|
||||
class netlist_setup_t;
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// A Generic netlist sources implementation
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class netlist_source_t
|
||||
{
|
||||
public:
|
||||
typedef plist_t<netlist_source_t *> list_t;
|
||||
|
||||
netlist_source_t()
|
||||
{}
|
||||
|
||||
virtual ~netlist_source_t() { }
|
||||
|
||||
virtual bool parse(netlist_setup_t *setup, const pstring name) = 0;
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
class netlist_sources_t
|
||||
{
|
||||
public:
|
||||
|
||||
netlist_sources_t() { }
|
||||
|
||||
~netlist_sources_t()
|
||||
{
|
||||
m_list.clear_and_free();
|
||||
}
|
||||
|
||||
void add(netlist_source_t *src)
|
||||
{
|
||||
m_list.add(src);
|
||||
}
|
||||
|
||||
void parse(netlist_setup_t *setup, const pstring name);
|
||||
|
||||
private:
|
||||
netlist_source_t::list_t m_list;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_setup_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -137,8 +183,6 @@ public:
|
||||
|
||||
netlist_param_t *find_param(const pstring ¶m_in, bool required = true);
|
||||
|
||||
void parse(const char *buf);
|
||||
|
||||
void start_devices();
|
||||
void resolve_inputs();
|
||||
|
||||
@ -147,6 +191,14 @@ public:
|
||||
void namespace_push(const pstring &aname);
|
||||
void namespace_pop();
|
||||
|
||||
/* parse a source */
|
||||
|
||||
void include(pstring netlist_name) { m_sources.parse(this, netlist_name); }
|
||||
|
||||
/* register a source */
|
||||
|
||||
void register_source(netlist_source_t *src) { m_sources.add(src); }
|
||||
|
||||
netlist_factory_list_t &factory() { return *m_factory; }
|
||||
const netlist_factory_list_t &factory() const { return *m_factory; }
|
||||
|
||||
@ -173,6 +225,7 @@ private:
|
||||
int m_proxy_cnt;
|
||||
|
||||
pstack_t<pstring> m_stack;
|
||||
netlist_sources_t m_sources;
|
||||
|
||||
|
||||
void connect_terminals(netlist_core_terminal_t &in, netlist_core_terminal_t &out);
|
||||
@ -202,4 +255,63 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// base sources
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class netlist_source_string_t : public netlist_source_t
|
||||
{
|
||||
public:
|
||||
|
||||
netlist_source_string_t(pstring source)
|
||||
: netlist_source_t(), m_str(source)
|
||||
{
|
||||
}
|
||||
|
||||
bool parse(netlist_setup_t *setup, const pstring name);
|
||||
|
||||
private:
|
||||
pstring m_str;
|
||||
};
|
||||
|
||||
|
||||
class netlist_source_mem_t : public netlist_source_t
|
||||
{
|
||||
public:
|
||||
netlist_source_mem_t(const char *mem)
|
||||
: netlist_source_t(), m_str(mem)
|
||||
{
|
||||
}
|
||||
|
||||
bool parse(netlist_setup_t *setup, const pstring name);
|
||||
private:
|
||||
pstring m_str;
|
||||
};
|
||||
|
||||
class netlist_source_proc_t : public netlist_source_t
|
||||
{
|
||||
public:
|
||||
netlist_source_proc_t(pstring name, void (*setup_func)(netlist_setup_t &))
|
||||
: m_setup_func(setup_func),
|
||||
m_setup_func_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
bool parse(netlist_setup_t *setup, const pstring name)
|
||||
{
|
||||
if (name == m_setup_func_name)
|
||||
{
|
||||
m_setup_func(*setup);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
void (*m_setup_func)(netlist_setup_t &);
|
||||
pstring m_setup_func_name;
|
||||
};
|
||||
|
||||
|
||||
#endif /* NLSETUP_H_ */
|
||||
|
@ -29,6 +29,8 @@ NETLIST_END()
|
||||
|
||||
NETLIST_START(pong_fast)
|
||||
|
||||
LOCAL_SOURCE(lib)
|
||||
|
||||
INCLUDE(lib)
|
||||
SOLVER(Solver, 48000)
|
||||
PARAM(Solver.PARALLEL, 0) // Don't do parallel solvers
|
||||
|
@ -216,7 +216,9 @@ private:
|
||||
|
||||
static NETLIST_START(pong)
|
||||
|
||||
NETLIST_MEMREGION("maincpu")
|
||||
MEMREGION_SOURCE("maincpu")
|
||||
PARAM(NETLIST.USE_DEACTIVATE, 1)
|
||||
INCLUDE(pong_schematics)
|
||||
|
||||
NETLIST_END()
|
||||
|
||||
|
@ -51,6 +51,10 @@ NETLIST_END()
|
||||
|
||||
static NETLIST_START(nl_popeye)
|
||||
|
||||
/* register hard coded netlists */
|
||||
|
||||
LOCAL_SOURCE(nl_popeye_imp_changer)
|
||||
|
||||
/* Standard stuff */
|
||||
|
||||
SOLVER(Solver, 48000)
|
||||
|
@ -192,11 +192,8 @@ public:
|
||||
{
|
||||
// read the netlist ...
|
||||
|
||||
netlist_sources_t sources;
|
||||
|
||||
sources.add(netlist_source_t(buffer));
|
||||
sources.parse(*m_setup, name);
|
||||
//m_setup->parse(buffer);
|
||||
m_setup->register_source(palloc(netlist_source_mem_t, buffer));
|
||||
m_setup->include(name);
|
||||
log_setup();
|
||||
|
||||
// start devices
|
||||
@ -295,10 +292,8 @@ static void listdevices()
|
||||
nt.init();
|
||||
const netlist_factory_list_t::list_t &list = nt.setup().factory().list();
|
||||
|
||||
netlist_sources_t sources;
|
||||
|
||||
sources.add(netlist_source_t("dummy", &netlist_dummy));
|
||||
sources.parse(nt.setup(),"dummy");
|
||||
nt.setup().register_source(palloc(netlist_source_proc_t, "dummy", &netlist_dummy));
|
||||
nt.setup().include("dummy");
|
||||
|
||||
nt.setup().start_devices();
|
||||
nt.setup().resolve_inputs();
|
||||
|
Loading…
Reference in New Issue
Block a user