Netlist: fixed crash when using analog chips. Did some preparation work to generalize internal links.

This commit is contained in:
Couriersud 2013-11-25 00:31:54 +00:00
parent 6e7e019afd
commit d05677b0e6
6 changed files with 72 additions and 47 deletions

View File

@ -103,8 +103,8 @@ NETLIB_NAME(solver)::~NETLIB_NAME(solver)()
net_list_t::entry_t *p = m_nets.first();
while (p != NULL)
{
net_list_t::entry_t *pn = m_nets.next(pn);
delete pn->object();
net_list_t::entry_t *pn = m_nets.next(p);
delete p->object();
p = pn;
}
}

View File

@ -292,15 +292,33 @@ ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_inp
register_input(*this, name, inp, type);
}
static void init_term(netlist_core_device_t &dev, netlist_terminal_t &term, netlist_input_t::state_e aState)
{
if (!term.isInitalized())
{
switch (term.type())
{
case netlist_terminal_t::OUTPUT:
dynamic_cast<netlist_output_t &>(term).init_object(dev, "internal output");
break;
case netlist_terminal_t::INPUT:
dynamic_cast<netlist_input_t &>(term).init_object(dev, "internal input", aState);
break;
case netlist_terminal_t::TERMINAL:
dynamic_cast<netlist_terminal_t &>(term).init_object(dev, "internal terminal", aState);
break;
default:
fatalerror("Unknown terminal type");
}
}
}
// FIXME: Revise internal links ...
ATTR_COLD void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState)
{
in.init_object(dev, "internal input", aState);
// ensure we are not yet initialized ...
if (!out.net().isRailNet())
out.init_object(dev, "internal output");
//if (in.state() != net_input_t::INP_STATE_PASSIVE)
out.net().register_con(in);
init_term(dev, in, aState);
init_term(dev, out, aState);
m_setup->connect(in, out);
}
ATTR_COLD void netlist_device_t::register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState)

View File

@ -250,6 +250,7 @@ public:
virtual ~netlist_object_t();
ATTR_COLD void init_object(netlist_base_t &nl, const pstring &aname);
ATTR_COLD bool isInitalized() { return (m_netlist != NULL); }
ATTR_COLD const pstring &name() const;

View File

@ -65,7 +65,7 @@ public:
{
if (i->object() == elem)
{
while (i <= m_ptr)
while (i < m_ptr)
{
*i = *(i+1);
i++;

View File

@ -410,6 +410,48 @@ 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)
{
NL_VERBOSE_OUT(("Connecting %s to %s\n", t1.name().cstr(), t2s.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 (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))
{
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))
{
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))
{
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))
{
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))
{
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))
{
connect_terminals(dynamic_cast<netlist_terminal_t &>(t1), dynamic_cast<netlist_terminal_t &>(t2));
}
else
fatalerror("Connecting %s to %s not supported!\n", t1.name().cstr(), t2.name().cstr());
}
void netlist_setup_t::resolve_inputs(void)
{
NL_VERBOSE_OUT(("Searching for mainclock and solver ...\n"));
@ -435,44 +477,7 @@ void netlist_setup_t::resolve_inputs(void)
netlist_terminal_t &t1 = find_terminal(t1s);
netlist_terminal_t &t2 = find_terminal(t2s);
NL_VERBOSE_OUT(("Connecting %s to %s\n", t1s.cstr(), t2s.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 (t2.has_net())
mame_printf_warning("Input %s already connected\n", t2s.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))
{
if (t1.has_net())
mame_printf_warning("Input %s already connected\n", t1s.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))
{
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))
{
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))
{
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))
{
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))
{
connect_terminals(dynamic_cast<netlist_terminal_t &>(t1), dynamic_cast<netlist_terminal_t &>(t2));
}
else
fatalerror("Connecting %s to %s not supported!\n", t1s.cstr(), t2s.cstr());
connect(t1, t2);
}
/* print all outputs */

View File

@ -108,6 +108,7 @@ 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);
netlist_terminal_t &find_terminal(const pstring &outname_in);
netlist_terminal_t &find_terminal(const pstring &outname_in, netlist_object_t::type_t atype);