diff --git a/src/emu/machine/netlist.c b/src/emu/machine/netlist.c index e80ed439d0f..54f2c7744a9 100644 --- a/src/emu/machine/netlist.c +++ b/src/emu/machine/netlist.c @@ -450,6 +450,7 @@ ATTR_COLD void netlist_mame_device_t::save_state() save_pointer((bool *) s->m_ptr, s->m_name, s->m_count); break; case DT_CUSTOM: + break; case NOT_SUPPORTED: default: netlist().error("found unsupported save element %s\n", s->m_name.cstr()); diff --git a/src/emu/netlist/analog/nld_fourterm.c b/src/emu/netlist/analog/nld_fourterm.c index 32376031396..5a62e0ffa3c 100644 --- a/src/emu/netlist/analog/nld_fourterm.c +++ b/src/emu/netlist/analog/nld_fourterm.c @@ -12,44 +12,46 @@ // ---------------------------------------------------------------------------------------- NETLIB_START(VCCS) -{ - configure(1.0, NETLIST_GMIN); -} - -NETLIB_RESET(VCCS) -{ -} - -ATTR_COLD void NETLIB_NAME(VCCS)::configure(const double Gfac, const double GI) { register_param("G", m_G, 1.0); + register_param("RI", m_RI, 1.0 / NETLIST_GMIN); register_terminal("IP", m_IP); register_terminal("IN", m_IN); register_terminal("OP", m_OP); register_terminal("ON", m_ON); - m_OP1.init_object(*this, name() + ".OP1"); - m_ON1.init_object(*this, name() + ".ON1"); + register_terminal("_OP1", m_OP1); + register_terminal("_ON1", m_ON1); - const double m_mult = m_G.Value() * Gfac; // 1.0 ==> 1V ==> 1A - m_IP.set(GI); m_IP.m_otherterm = &m_IN; // <= this should be NULL and terminal be filtered out prior to solving... - m_IN.set(GI); m_IN.m_otherterm = &m_IP; // <= this should be NULL and terminal be filtered out prior to solving... - m_OP.set(m_mult, 0.0); m_OP.m_otherterm = &m_IP; - m_OP1.set(-m_mult, 0.0); m_OP1.m_otherterm = &m_IN; - m_ON.set(-m_mult, 0.0); m_ON.m_otherterm = &m_IP; - m_ON1.set(m_mult, 0.0); m_ON1.m_otherterm = &m_IN; connect(m_OP, m_OP1); connect(m_ON, m_ON1); + + m_gfac = 1.0; +} + +NETLIB_RESET(VCCS) +{ + const double m_mult = m_G.Value() * m_gfac; // 1.0 ==> 1V ==> 1A + const double GI = 1.0 / m_RI.Value(); + + m_IP.set(GI); + m_IN.set(GI); + + m_OP.set(m_mult, 0.0); + m_OP1.set(-m_mult, 0.0); + + m_ON.set(-m_mult, 0.0); + m_ON1.set(m_mult, 0.0); } NETLIB_UPDATE_PARAM(VCCS) @@ -60,10 +62,14 @@ NETLIB_UPDATE(VCCS) { /* only called if connected to a rail net ==> notify the solver to recalculate */ /* Big FIXME ... */ - m_IP.net().solve(); - m_IN.net().solve(); - m_OP.net().solve(); - m_ON.net().solve(); + if (!m_IP.net().isRailNet()) + m_IP.net().solve(); + else if (!m_IN.net().isRailNet()) + m_IN.net().solve(); + else if (!m_OP.net().isRailNet()) + m_OP.net().solve(); + else if (!m_ON.net().isRailNet()) + m_ON.net().solve(); } // ---------------------------------------------------------------------------------------- @@ -72,17 +78,13 @@ NETLIB_UPDATE(VCCS) NETLIB_START(VCVS) { + NETLIB_NAME(VCCS)::start(); + register_param("RO", m_RO, 1.0); - const double gRO = 1.0 / m_RO.Value(); + register_terminal("_OP2", m_OP2); + register_terminal("_ON2", m_ON2); - configure(gRO, NETLIST_GMIN); - - m_OP2.init_object(*this, "OP2"); - m_ON2.init_object(*this, "ON2"); - - m_OP2.set(gRO); - m_ON2.set(gRO); m_OP2.m_otherterm = &m_ON2; m_ON2.m_otherterm = &m_OP2; @@ -90,6 +92,15 @@ NETLIB_START(VCVS) connect(m_ON2, m_ON1); } +NETLIB_RESET(VCVS) +{ + m_gfac = 1.0 / m_RO.Value(); + NETLIB_NAME(VCCS)::reset(); + + m_OP2.set(1.0 / m_RO.Value()); + m_ON2.set(1.0 / m_RO.Value()); +} + NETLIB_UPDATE_PARAM(VCVS) { } diff --git a/src/emu/netlist/analog/nld_fourterm.h b/src/emu/netlist/analog/nld_fourterm.h index 6ce1cceb586..6ef3c6ce3e9 100644 --- a/src/emu/netlist/analog/nld_fourterm.h +++ b/src/emu/netlist/analog/nld_fourterm.h @@ -83,8 +83,6 @@ protected: ATTR_COLD virtual void update_param(); ATTR_HOT ATTR_ALIGN void update(); - ATTR_COLD void configure(const double Gfac, const double GI); - netlist_terminal_t m_OP; netlist_terminal_t m_ON; @@ -95,6 +93,9 @@ protected: netlist_terminal_t m_ON1; netlist_param_double_t m_G; + netlist_param_double_t m_RI; + + double m_gfac; }; // ---------------------------------------------------------------------------------------- @@ -133,6 +134,7 @@ public: protected: ATTR_COLD virtual void start(); + ATTR_COLD virtual void reset(); ATTR_COLD virtual void update_param(); //ATTR_HOT ATTR_ALIGN void update(); diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c index 34a53e58f9f..897666a850b 100644 --- a/src/emu/netlist/analog/nld_solver.c +++ b/src/emu/netlist/analog/nld_solver.c @@ -19,9 +19,7 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &aowner) { - /* make sure we loop at least once */ - - m_owner = &aowner; + m_owner = &aowner; NL_VERBOSE_OUT(("New solver setup\n")); @@ -205,7 +203,10 @@ ATTR_COLD void netlist_matrix_solver_direct_t::setup(netlist_ne m_terms[m_term_num].net_other = ot; m_terms[m_term_num].term = terms[i]; if (ot>=0) + { m_term_num++; + SOLVER_VERBOSE_OUT(("Net %d Term %s %f %f\n", k, terms[i]->name().cstr(), terms[i]->m_gt, terms[i]->m_go)); + } } } m_rail_start = m_term_num; @@ -221,7 +222,10 @@ ATTR_COLD void netlist_matrix_solver_direct_t::setup(netlist_ne m_terms[m_term_num].net_other = ot; m_terms[m_term_num].term = terms[i]; if (ot<0) + { m_term_num++; + SOLVER_VERBOSE_OUT(("found term with missing othernet %s\n", terms[i]->name().cstr())); + } } for (int i = 0; i < rails.count(); i++) { @@ -229,6 +233,7 @@ ATTR_COLD void netlist_matrix_solver_direct_t::setup(netlist_ne m_terms[m_term_num].net_other = -1; //get_net_idx(&rails[i]->m_otherterm->net()); m_terms[m_term_num].term = rails[i]; m_term_num++; + SOLVER_VERBOSE_OUT(("Net %d Rail %s %f %f\n", k, rails[i]->name().cstr(), rails[i]->m_gt, rails[i]->m_go)); } } } @@ -258,6 +263,7 @@ ATTR_HOT inline void netlist_matrix_solver_direct_t::build_LE( for (int i = 0; i < m_rail_start; i++) { terms_t &t = m_terms[i]; + //printf("A %d %d %s %f %f\n",t.net_this, t.net_other, t.term->name().cstr(), t.term->m_gt, t.term->m_go); RHS[t.net_this] += t.term->m_Idr; A[t.net_this][t.net_this] += t.term->m_gt; @@ -280,6 +286,16 @@ ATTR_HOT inline void netlist_matrix_solver_direct_t::gauss_LE( double (* RESTRICT RHS), double (* RESTRICT x)) { +#if 0 + for (int i = 0; i < N(); i++) + { + for (int k = 0; k < N(); k++) + printf("%f ", A[i][k]); + printf("| %f = %f \n", x[i], RHS[i]); + } + printf("\n"); +#endif + for (int i = 0; i < N(); i++) { #if 0 @@ -322,8 +338,8 @@ ATTR_HOT inline void netlist_matrix_solver_direct_t::gauss_LE( tmp += A[j][k] * x[k]; x[j] = (RHS[j] - tmp) / A[j][j]; } - #if 0 + printf("Solution:\n"); for (int i = 0; i < N(); i++) { for (int k = 0; k < N(); k++) @@ -332,6 +348,7 @@ ATTR_HOT inline void netlist_matrix_solver_direct_t::gauss_LE( } printf("\n"); #endif + } template @@ -608,14 +625,14 @@ ATTR_COLD static void process_net(net_groups_t groups, int &cur_group, netlist_n if (net->m_head == NULL) return; /* add the net */ - NL_VERBOSE_OUT(("add %d - %s\n", cur_group, net->name().cstr())); + SOLVER_VERBOSE_OUT(("add %d - %s\n", cur_group, net->name().cstr())); groups[cur_group].add(net); for (netlist_core_terminal_t *p = net->m_head; p != NULL; p = p->m_update_list_next) { - NL_VERBOSE_OUT(("terminal %s\n", p->name().cstr())); + SOLVER_VERBOSE_OUT(("terminal %s\n", p->name().cstr())); if (p->isType(netlist_terminal_t::TERMINAL)) { - NL_VERBOSE_OUT(("isterminal\n")); + SOLVER_VERBOSE_OUT(("isterminal\n")); netlist_terminal_t *pt = static_cast(p); netlist_net_t *other_net = &pt->m_otherterm->net(); if (!already_processed(groups, cur_group, other_net)) @@ -805,9 +822,18 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() ms->m_resched_loops = m_resched_loops.Value(); ms->setup(groups[i], *this); m_mat_solvers.add(ms); - SOLVER_VERBOSE_OUT(("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr())); + SOLVER_VERBOSE_OUT(("%d ==> %d nets %s\n", i, groups[i].count(), (*groups[i].first())->m_head->name().cstr())); SOLVER_VERBOSE_OUT((" has %s elements\n", ms->is_dynamic() ? "dynamic" : "no dynamic")); SOLVER_VERBOSE_OUT((" has %s elements\n", ms->is_timestep() ? "timestep" : "no timestep")); + for (int j=0; jname().cstr())); + netlist_net_t *n = groups[i][j]; + for (netlist_core_terminal_t *p = n->m_head; p != NULL; p = p->m_update_list_next) + { + SOLVER_VERBOSE_OUT((" %s\n", p->name().cstr())); + } + } } } diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h index f43b514bde9..740ec26c0e7 100644 --- a/src/emu/netlist/analog/nld_solver.h +++ b/src/emu/netlist/analog/nld_solver.h @@ -13,8 +13,9 @@ // Macros // ---------------------------------------------------------------------------------------- -#define SOLVER(_name) \ - NET_REGISTER_DEV(solver, _name) +#define SOLVER(_name, _freq) \ + NET_REGISTER_DEV(solver, _name) \ + PARAM(_name.FREQ, _freq) // ---------------------------------------------------------------------------------------- // solver diff --git a/src/emu/netlist/devices/net_lib.c b/src/emu/netlist/devices/net_lib.c index d1ee184c385..459fcd9d85e 100644 --- a/src/emu/netlist/devices/net_lib.c +++ b/src/emu/netlist/devices/net_lib.c @@ -86,9 +86,9 @@ void netlist_factory_t::initialize() ENTRY(analog_input, ANALOG_INPUT, "IN") ENTRY(log, LOG, "+I") ENTRY(logD, LOGD, "+I,I2") - ENTRY(clock, CLOCK, "-") // FIXME - ENTRY(mainclock, MAINCLOCK, "-") // FIXME - ENTRY(solver, SOLVER, "-") // FIXME + ENTRY(clock, CLOCK, "FREQ") + ENTRY(mainclock, MAINCLOCK, "FREQ") + ENTRY(solver, SOLVER, "FREQ") ENTRY(gnd, NETDEV_GND, "-") ENTRY(switch2, SWITCH2, "+i1,i2") ENTRY(nicRSFF, NETDEV_RSFF, "+S,R") diff --git a/src/emu/netlist/devices/nld_system.h b/src/emu/netlist/devices/nld_system.h index 889bb835f90..4cbd8cbd2c1 100644 --- a/src/emu/netlist/devices/nld_system.h +++ b/src/emu/netlist/devices/nld_system.h @@ -18,20 +18,22 @@ // ---------------------------------------------------------------------------------------- #define TTL_INPUT(_name, _v) \ - NET_REGISTER_DEV(ttl_input, _name) \ + NET_REGISTER_DEV(ttl_input, _name) \ PARAM(_name.IN, _v) #define ANALOG_INPUT(_name, _v) \ - NET_REGISTER_DEV(analog_input, _name) \ + NET_REGISTER_DEV(analog_input, _name) \ PARAM(_name.IN, _v) -#define MAINCLOCK(_name) \ - NET_REGISTER_DEV(mainclock, _name) +#define MAINCLOCK(_name, _freq) \ + NET_REGISTER_DEV(mainclock, _name) \ + PARAM(_name.FREQ, _freq) -#define CLOCK(_name) \ - NET_REGISTER_DEV(clock, _name) +#define CLOCK(_name, _freq) \ + NET_REGISTER_DEV(clock, _name) \ + PARAM(_name.FREQ, _freq) -#define NETDEV_GND() \ +#define NETDEV_GND() \ NET_REGISTER_DEV(gnd, GND) // ---------------------------------------------------------------------------------------- diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index 0e1fee5778e..c6b6d6f3c0e 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -34,9 +34,9 @@ netlist_queue_t::netlist_queue_t(netlist_base_t &nl) void netlist_queue_t::register_state(pstate_manager_t &manager, const pstring &module) { NL_VERBOSE_OUT(("register_state\n")); - manager.save_item(m_qsize, module + "." + "qsize"); - manager.save_item(m_times, module + "." + "times"); - manager.save_item(&(m_name[0][0]), module + "." + "names", sizeof(m_name)); + manager.save_item(m_qsize, this, module + "." + "qsize"); + manager.save_item(m_times, this, module + "." + "times"); + manager.save_item(&(m_name[0][0]), this, module + "." + "names", sizeof(m_name)); } void netlist_queue_t::on_pre_save() @@ -140,18 +140,18 @@ static void tagmap_free_entries(T &tm) netlist_base_t::~netlist_base_t() { - tagmap_free_entries(m_devices); - - netlist_net_t * const *p = m_nets.first(); - while (p != NULL) + for (int i=0; i < m_nets.count(); i++) { - netlist_net_t * const *pn = m_nets.next(p); - if (!(*p)->isRailNet()) - delete (*p); - p = pn; + if (!m_nets[i]->isRailNet()) + { + delete m_nets[i]; + } } m_nets.reset(); + + tagmap_free_entries(m_devices); + pstring::resetmem(); } @@ -407,7 +407,6 @@ ATTR_COLD void netlist_device_t::register_output(const pstring &name, netlist_ou ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_input_t &inp) { - // FIXME: change register_object as well inp.m_family_desc = this->m_family_desc; setup().register_object(*this, name, inp); m_terminals.add(inp.name()); @@ -425,7 +424,6 @@ ATTR_COLD void netlist_device_t::register_param(const pstring &sname, C ¶m, pstring fullname = this->name() + "." + sname; param.init_object(*this, fullname); param.initial(initialVal); - //FIXME: pass fullname from above setup().register_object(*this, fullname, param); } @@ -456,6 +454,12 @@ ATTR_COLD netlist_net_t::netlist_net_t(const type_t atype, const family_t afamil m_cur.Analog = 0.0; }; +ATTR_COLD netlist_net_t::~netlist_net_t() +{ + netlist().remove_save_items(this); +} + + ATTR_COLD void netlist_net_t::reset() { m_last.Analog = 0.0; diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h index 6c54000c9e2..1275ea342e0 100644 --- a/src/emu/netlist/nl_base.h +++ b/src/emu/netlist/nl_base.h @@ -62,7 +62,6 @@ * This would however introduce macro devices for RC, diodes and transistors again. * * ==================================================================================== - * FIXME: Terminals are not yet implemented. * * Instead, the following approach in case of a pure terminal/input network is taken: * @@ -557,7 +556,6 @@ public: friend class netlist_analog_output_t; friend class netlist_setup_t; - // FIXME: union does not work struct hybrid_t { inline hybrid_t() : Q(0), Analog(0.0) {} @@ -566,6 +564,8 @@ public: }; ATTR_COLD netlist_net_t(const type_t atype, const family_t afamily); + ATTR_COLD virtual ~netlist_net_t(); + ATTR_COLD void init_object(netlist_base_t &nl, const pstring &aname); ATTR_COLD void register_con(netlist_core_terminal_t &terminal); @@ -638,28 +638,13 @@ public: typedef netlist_list_t terminal_list_t; terminal_list_t m_terms; - terminal_list_t m_rails; // FIXME: Make the solver use this ! + terminal_list_t m_rails; netlist_matrix_solver_t *m_solver; ATTR_HOT void solve(); netlist_core_terminal_t *m_head; - /* use this to register state.... */ - ATTR_COLD virtual void late_save_register() - { - save(NAME(m_last.Analog)); - save(NAME(m_cur.Analog)); - save(NAME(m_new.Analog)); - save(NAME(m_last.Q)); - save(NAME(m_cur.Q)); - save(NAME(m_new.Q)); - save(NAME(m_time)); - save(NAME(m_active)); - save(NAME(m_in_queue)); - netlist_object_t::save_register(); - } - protected: //FIXME: needed by current solver code UINT32 m_num_cons; @@ -671,13 +656,18 @@ public: protected: - /* we don't use this to save state - * because we may get deleted again ... - * FIXME: save_register should be called after setup is complete - */ ATTR_COLD virtual void save_register() { - //assert_always(false, "trying too early to register state in netlist_net_t"); + save(NAME(m_last.Analog)); + save(NAME(m_cur.Analog)); + save(NAME(m_new.Analog)); + save(NAME(m_last.Q)); + save(NAME(m_cur.Q)); + save(NAME(m_new.Q)); + save(NAME(m_time)); + save(NAME(m_active)); + save(NAME(m_in_queue)); + netlist_object_t::save_register(); } ATTR_COLD virtual void reset(); @@ -1235,7 +1225,6 @@ ATTR_HOT inline void netlist_net_t::push_to_queue(const netlist_time delay) { if (is_queued()) return; - // if (m_in_queue == 1) return; FIXME: check this at some time m_time = netlist().time() + delay; m_in_queue = (m_active > 0) ? 1 : 0; /* queued ? */ if (m_in_queue) diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c index e190acd4f68..3132ab2e52b 100644 --- a/src/emu/netlist/nl_setup.c +++ b/src/emu/netlist/nl_setup.c @@ -270,22 +270,6 @@ const pstring netlist_setup_t::resolve_alias(const pstring &name) const temp = m_alias.find(ret); } while (temp != ""); - int p = ret.find(".["); - if (p > 0) - { - pstring dname = ret; - netlist_device_t *dev = netlist().m_devices.find(dname.substr(0,p)); - if (dev == NULL) - netlist().error("Device for %s not found\n", name.cstr()); - int c = atoi(ret.substr(p+2,ret.len()-p-3)); - temp = dev->m_terminals[c]; - // reresolve .... - do { - ret = temp; - temp = m_alias.find(ret); - } while (temp != ""); - } - NL_VERBOSE_OUT(("%s==>%s\n", name.cstr(), ret.cstr())); return ret; } @@ -447,7 +431,6 @@ void netlist_setup_t::connect_terminal_input(netlist_terminal_t &term, netlist_i } } -// FIXME: optimize code ... void netlist_setup_t::connect_terminal_output(netlist_terminal_t &in, netlist_output_t &out) { if (out.isFamily(netlist_terminal_t::ANALOG)) @@ -521,18 +504,16 @@ void netlist_setup_t::connect(netlist_core_terminal_t &t1_in, netlist_core_termi netlist_core_terminal_t &t1 = resolve_proxy(t1_in); netlist_core_terminal_t &t2 = resolve_proxy(t2_in); - // FIXME: amend device design so that warnings can be turned into errors - // Only variable inputs have this issue if (t1.isType(netlist_core_terminal_t::OUTPUT) && t2.isType(netlist_core_terminal_t::INPUT)) { if (t2.has_net()) - NL_VERBOSE_OUT(("Input %s already connected\n", t2.name().cstr())); + netlist().error("Input %s already connected\n", t2.name().cstr()); connect_input_output(dynamic_cast(t2), dynamic_cast(t1)); } else if (t1.isType(netlist_core_terminal_t::INPUT) && t2.isType(netlist_core_terminal_t::OUTPUT)) { if (t1.has_net()) - NL_VERBOSE_OUT(("Input %s already connected\n", t1.name().cstr())); + netlist().error("Input %s already connected\n", t1.name().cstr()); connect_input_output(dynamic_cast(t1), dynamic_cast(t2)); } else if (t1.isType(netlist_core_terminal_t::OUTPUT) && t2.isType(netlist_core_terminal_t::TERMINAL)) @@ -585,24 +566,24 @@ void netlist_setup_t::resolve_inputs() netlist().log("deleting empty nets ..."); // delete empty nets ... + + netlist_net_t::list_t todelete; + for (netlist_net_t *const *pn = netlist().m_nets.first(); pn != NULL; pn = netlist().m_nets.next(pn)) { if ((*pn)->m_head == NULL) { - netlist().log("Deleting net %s ...", (*pn)->name().cstr()); - netlist_net_t *to_delete = *pn; - netlist().m_nets.remove(to_delete); - if (!to_delete->isRailNet()) - delete to_delete; - pn--; + todelete.add(*pn); } } - /* now that nets were deleted ... register all net items */ - netlist().log("late state saving for nets ..."); - - for (netlist_net_t * const * pn = netlist().m_nets.first(); pn != NULL; pn = netlist().m_nets.next(pn)) - (*pn)->late_save_register(); + for (int i=0; i < todelete.count(); i++) + { + netlist().log("Deleting net %s ...", todelete[i]->name().cstr()); + netlist().m_nets.remove(todelete[i]); + if (!todelete[i]->isRailNet()) + delete todelete[i]; + } pstring errstr(""); diff --git a/src/emu/netlist/pstate.c b/src/emu/netlist/pstate.c index e5f74dec6db..38cf979a792 100644 --- a/src/emu/netlist/pstate.c +++ b/src/emu/netlist/pstate.c @@ -12,7 +12,7 @@ ATTR_COLD pstate_manager_t::~pstate_manager_t() -ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pstate_data_type_e dt, const int size, const int count, void *ptr) +ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pstate_data_type_e dt, const void *owner, const int size, const int count, void *ptr) { pstring fullname = stname; ATTR_UNUSED pstring ts[] = { @@ -25,19 +25,36 @@ ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pst }; NL_VERBOSE_OUT(("SAVE: <%s> %s(%d) %p\n", fullname.cstr(), ts[dt].cstr(), size, ptr)); - pstate_entry_t *p = new pstate_entry_t(stname, dt, size, count, ptr); + pstate_entry_t *p = new pstate_entry_t(stname, dt, owner, size, count, ptr); m_save.add(p); } +ATTR_COLD void pstate_manager_t::remove_save_items(const void *owner) +{ + pstate_entry_t::list_t todelete; + + for (int i=0; i < m_save.count(); i++) + { + if (m_save[i]->m_owner == owner) + todelete.add(m_save[i]); + } + for (int i=0; i < todelete.count(); i++) + { + m_save.remove(todelete[i]); + } + todelete.reset_and_free(); +} ATTR_COLD void pstate_manager_t::pre_save() { - for (int i=0; i < m_callback.count(); i++) - m_callback[i]->on_pre_save(); + for (int i=0; i < m_save.count(); i++) + if (m_save[i]->m_dt == DT_CUSTOM) + m_save[i]->m_callback->on_pre_save(); } ATTR_COLD void pstate_manager_t::post_load() { - for (int i=0; i < m_callback.count(); i++) - m_callback[i]->on_post_load(); + for (int i=0; i < m_save.count(); i++) + if (m_save[i]->m_dt == DT_CUSTOM) + m_save[i]->m_callback->on_post_load(); } diff --git a/src/emu/netlist/pstate.h b/src/emu/netlist/pstate.h index bddd5af4ba5..0d6fb896229 100644 --- a/src/emu/netlist/pstate.h +++ b/src/emu/netlist/pstate.h @@ -21,7 +21,7 @@ #define PSTATE_INTERFACE(obj, manager, module) \ template ATTR_COLD void obj::save(C &state, const pstring &stname) \ { \ - manager->save_item(state, module + "." + stname); \ + manager->save_item(state, this, module + "." + stname); \ } enum pstate_data_type_e { @@ -50,19 +50,6 @@ NETLIST_SAVE_TYPE(UINT32, DT_INT); NETLIST_SAVE_TYPE(INT32, DT_INT); //NETLIST_SAVE_TYPE(netlist_time::INTERNALTYPE, DT_INT64); -struct pstate_entry_t -{ - typedef netlist_list_t list_t; - - pstate_entry_t(const pstring &stname, const pstate_data_type_e dt, const int size, const int count, void *ptr) : - m_name(stname), m_dt(dt), m_size(size), m_count(count), m_ptr(ptr) { } - pstring m_name; - pstate_data_type_e m_dt; - int m_size; - int m_count; - void *m_ptr; -}; - class pstate_manager_t; class pstate_callback_t @@ -78,50 +65,71 @@ public: protected: }; +struct pstate_entry_t +{ + typedef netlist_list_t list_t; + + pstate_entry_t(const pstring &stname, const pstate_data_type_e dt, const void *owner, + const int size, const int count, void *ptr) + : m_name(stname), m_dt(dt), m_owner(owner), m_callback(NULL), m_size(size), m_count(count), m_ptr(ptr) { } + + pstate_entry_t(const pstring &stname, const void *owner, pstate_callback_t *callback) + : m_name(stname), m_dt(DT_CUSTOM), m_owner(owner), m_callback(callback), m_size(0), m_count(0), m_ptr(NULL) { } + + pstring m_name; + const pstate_data_type_e m_dt; + const void *m_owner; + pstate_callback_t *m_callback; + const int m_size; + const int m_count; + void *m_ptr; +}; + class pstate_manager_t { public: ATTR_COLD ~pstate_manager_t(); - template ATTR_COLD void save_item(C &state, const pstring &stname) + template ATTR_COLD void save_item(C &state, const void *owner, const pstring &stname) { - save_state_ptr(stname, nl_datatype::type, sizeof(C), 1, &state); + save_state_ptr(stname, nl_datatype::type, owner, sizeof(C), 1, &state); } - template ATTR_COLD void save_item(C (&state)[N], const pstring &stname) + template ATTR_COLD void save_item(C (&state)[N], const void *owner, const pstring &stname) { - save_state_ptr(stname, nl_datatype::type, sizeof(state[0]), N, &(state[0])); + save_state_ptr(stname, nl_datatype::type, owner, sizeof(state[0]), N, &(state[0])); } - template ATTR_COLD void save_item(C *state, const pstring &stname, const int count) + template ATTR_COLD void save_item(C *state, const void *owner, const pstring &stname, const int count) { - save_state_ptr(stname, nl_datatype::type, sizeof(C), count, state); + save_state_ptr(stname, nl_datatype::type, owner, sizeof(C), count, state); } ATTR_COLD void pre_save(); ATTR_COLD void post_load(); + ATTR_COLD void remove_save_items(const void *owner); inline const pstate_entry_t::list_t &save_list() const { return m_save; } protected: - ATTR_COLD void save_state_ptr(const pstring &stname, const pstate_data_type_e, const int size, const int count, void *ptr); + ATTR_COLD void save_state_ptr(const pstring &stname, const pstate_data_type_e, const void *owner, const int size, const int count, void *ptr); private: pstate_entry_t::list_t m_save; - pstate_callback_t::list_t m_callback; }; -template<> ATTR_COLD inline void pstate_manager_t::save_item(pstate_callback_t &state, const pstring &stname) +template<> ATTR_COLD inline void pstate_manager_t::save_item(pstate_callback_t &state, const void *owner, const pstring &stname) { //save_state_ptr(stname, DT_CUSTOM, 0, 1, &state); - m_callback.add(&state); + pstate_entry_t *p = new pstate_entry_t(stname, owner, &state); + m_save.add(p); state.register_state(*this, stname); } -template<> ATTR_COLD inline void pstate_manager_t::save_item(netlist_time &nlt, const pstring &stname) +template<> ATTR_COLD inline void pstate_manager_t::save_item(netlist_time &nlt, const void *owner, const pstring &stname) { - save_state_ptr(stname, DT_INT64, sizeof(netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr()); + save_state_ptr(stname, DT_INT64, owner, sizeof(netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr()); } diff --git a/src/mame/drivers/1942.c b/src/mame/drivers/1942.c index a890bf03707..4154a18e364 100644 --- a/src/mame/drivers/1942.c +++ b/src/mame/drivers/1942.c @@ -82,8 +82,7 @@ static NETLIST_START(nl_1942) /* Standard stuff */ - SOLVER(Solver) - PARAM(Solver.FREQ, 48000) + SOLVER(Solver, 48000) ANALOG_INPUT(V5, 5) /* AY 8910 internal resistors */ diff --git a/src/mame/drivers/pong.c b/src/mame/drivers/pong.c index e81cdc40dfc..927bb535d37 100644 --- a/src/mame/drivers/pong.c +++ b/src/mame/drivers/pong.c @@ -94,8 +94,7 @@ enum input_changed_enum static NETLIST_START(pong_schematics) - SOLVER(Solver) - PARAM(Solver.FREQ, 48000) + SOLVER(Solver, 48000) PARAM(Solver.ACCURACY, 1e-4) // works and is sufficient ANALOG_INPUT(V5, 5) @@ -114,9 +113,8 @@ static NETLIST_START(pong_schematics) #else /* abstracting this, performance increases by 40% * No surprise, the clock is extremely expensive */ - MAINCLOCK(clk) - //CLOCK(clk) - PARAM(clk.FREQ, 7159000.0) + MAINCLOCK(clk, 7159000.0) + //CLOCK(clk, 7159000.0) #endif #else // benchmarking ...