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:
couriersud 2015-06-03 22:52:06 +02:00
parent 574a2787fc
commit 7cd3ebf18a
10 changed files with 204 additions and 125 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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