diff options
author | Couriersud <couriersud@users.noreply.github.com> | 2013-12-20 15:54:48 +0000 |
---|---|---|
committer | Couriersud <couriersud@users.noreply.github.com> | 2013-12-20 15:54:48 +0000 |
commit | f46847e487f4ea9eda52c6e3189deabaf0f3e34e (patch) | |
tree | 819ce92808aff399eb4b905660ab03baebc7e82b | |
parent | 5eb4f5530b1544324fd7e209d036d67991abd195 (diff) |
Netlist and Pong:
- Added save-state support.
- Fixed a compile issue with MSVC
The state saving is now 80% generic. This still needs some polishing, but works.
-rw-r--r-- | src/emu/machine/netlist.c | 114 | ||||
-rw-r--r-- | src/emu/machine/netlist.h | 12 | ||||
-rw-r--r-- | src/emu/netlist/devices/net_lib.c | 6 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_7483.c | 2 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_7490.c | 3 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_7493.c | 4 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_9316.c | 3 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_legacy.c | 8 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_log.c | 2 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_ne555.c | 2 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_signal.h | 9 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_solver.c | 38 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_solver.h | 2 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_twoterm.c | 9 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_twoterm.h | 8 | ||||
-rw-r--r-- | src/emu/netlist/nl_base.c | 64 | ||||
-rw-r--r-- | src/emu/netlist/nl_base.h | 118 | ||||
-rw-r--r-- | src/emu/netlist/nl_lists.h | 18 | ||||
-rw-r--r-- | src/emu/netlist/nl_setup.c | 48 | ||||
-rw-r--r-- | src/emu/netlist/nl_setup.h | 24 | ||||
-rw-r--r-- | src/emu/netlist/nl_time.h | 3 | ||||
-rw-r--r-- | src/emu/video/fixfreq.c | 26 | ||||
-rw-r--r-- | src/mame/drivers/pong.c | 4 |
23 files changed, 450 insertions, 77 deletions
diff --git a/src/emu/machine/netlist.c b/src/emu/machine/netlist.c index 5e5b5e67d7f..e7bebcfdee4 100644 --- a/src/emu/machine/netlist.c +++ b/src/emu/machine/netlist.c @@ -50,7 +50,8 @@ #include "netlist/nl_setup.h" #include "netlist/devices/net_lib.h" -#define LOG_DEV_CALLS(x) do { } while (0); +//#define LOG_DEV_CALLS(x) printf x +#define LOG_DEV_CALLS(x) do { } while (0) // ---------------------------------------------------------------------------------------- // netlist_mame_device @@ -61,6 +62,7 @@ const device_type NETLIST = &device_creator<netlist_mame_device>; netlist_mame_device::netlist_mame_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, NETLIST, "netlist", tag, owner, clock, "netlist_mame", __FILE__), device_execute_interface(mconfig, *this), + //device_state_interface(mconfig, *this), m_device_start_list(100), m_netlist(NULL), m_setup(NULL), @@ -86,11 +88,13 @@ void netlist_mame_device::device_start() LOG_DEV_CALLS(("device_start\n")); m_netlist = global_alloc_clear(netlist_mame_t(*this)); - m_netlist->set_clock_freq(this->clock()); - m_setup = global_alloc_clear(netlist_setup_t(*m_netlist)); + m_netlist->init_object(*m_netlist, "netlist"); + m_setup->init(); + + m_netlist->set_clock_freq(this->clock()); - // register additional devices + // register additional devices m_setup->factory().register_device<nld_analog_callback>( "NETDEV_CALLBACK", "nld_analog_callback"); @@ -107,7 +111,6 @@ void netlist_mame_device::device_start() m_netlist->xfatalerror("required elements not found\n"); save_state(); - /* TODO: we have to save the round robin queue as well */ // set our instruction counter m_icountptr = &m_icount; @@ -130,31 +133,113 @@ void netlist_mame_device::device_stop() m_netlist = NULL; } -void netlist_mame_device::device_post_load() +ATTR_COLD void netlist_mame_device::device_post_load() { + LOG_DEV_CALLS(("device_post_load\n")); + m_netlist->queue().clear(); + NL_VERBOSE_OUT(("current time %f qsize %d\n", m_netlist->time().as_double(), qsize)); + for (int i = 0; i < qsize; i++ ) + { + netlist_net_t *n = m_netlist->find_net(qtemp[i].m_name); + NL_VERBOSE_OUT(("Got %s ==> %p\n", qtemp[i].m_name, n)); + NL_VERBOSE_OUT(("schedule time %f (%f)\n", n->time().as_double(), qtemp[i].m_time.as_double())); + m_netlist->queue().push(netlist_base_t::queue_t::entry_t(qtemp[i].m_time, *n)); + } +} + +ATTR_COLD void netlist_mame_device::device_pre_save() +{ + LOG_DEV_CALLS(("device_pre_save\n")); + + qsize = m_netlist->queue().count(); + NL_VERBOSE_OUT(("current time %f qsize %d\n", m_netlist->time().as_double(), qsize)); + for (int i = 0; i < qsize; i++ ) + { + qtemp[i].m_time = m_netlist->queue().listptr()[i].time(); + const char *p = m_netlist->queue().listptr()[i].object().name().cstr(); + int n = MIN(63, strlen(p)); + strncpy(qtemp[i].m_name, p, n); + qtemp[i].m_name[n] = 0; + } +#if 0 + + netlist_time *nlt = (netlist_time *) ; + netlist_base_t::queue_t::entry_t *p = m_netlist->queue().listptr()[i]; + netlist_time *nlt = (netlist_time *) p->time_ptr(); + save_pointer(nlt->get_internaltype_ptr(), "queue", 1, i); +#endif } void netlist_mame_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { } -void netlist_mame_device::save_state() + + +ATTR_COLD void netlist_mame_device::save_state() { + for (netlist_setup_t::save_entry_list_t::entry_t *p = setup().m_save.first(); p != NULL; p = setup().m_save.next(p)) + { + netlist_setup_t::save_entry_t *s = p->object(); + NL_VERBOSE_OUT(("saving state for %s\n", s->m_name.cstr())); + switch (s->m_dt) + { + case DT_DOUBLE: + save_pointer((double *) s->m_ptr, s->m_name, 1); + break; + case DT_INT64: + save_pointer((INT64 *) s->m_ptr, s->m_name, 1); + break; + case DT_INT8: + save_pointer((INT8 *) s->m_ptr, s->m_name, 1); + break; + case DT_INT: + save_pointer((int *) s->m_ptr, s->m_name, 1); + break; + case DT_BOOLEAN: + save_pointer((bool *) s->m_ptr, s->m_name, 1); + break; #if 0 - for (netlist_setup_t::tagmap_output_t::entry_t *entry = m_setup->m_outputs.first(); entry != NULL; entry = m_setup->m_outputs.next(entry)) - { - save_item(*entry->object()->Q_ptr(), entry->tag().cstr(), 0); - save_item(*entry->object()->new_Q_ptr(), entry->tag().cstr(), 1); - } + case DT_NLTIME: + { + netlist_time *nlt = (netlist_time *) s->m_ptr; + //save_pointer((netlist_time::INTERNALTYPE *) s->m_ptr, s->m_name, 1); + //save_pointer(nlt->get_internaltype_ptr(), s->m_name, 1); + save_item(*nlt->get_internaltype_ptr(), s->m_name.cstr()); + } + break; +#endif + case NOT_SUPPORTED: + default: + m_netlist->xfatalerror("found unsupported save element %s\n", s->m_name.cstr()); + break; + } + } + + // handle the queue + + save_item(NAME(qsize)); + for (int i = 0; i < m_netlist->queue().capacity(); i++ ) + { + save_pointer(qtemp[i].m_time.get_internaltype_ptr(), "queue_time", 1, i); + save_pointer(qtemp[i].m_name, "queue_name", sizeof(qtemp[i].m_name), i); + + } +#if 0 + + netlist_time *nlt = (netlist_time *) ; + netlist_base_t::queue_t::entry_t *p = m_netlist->queue().listptr()[i]; + netlist_time *nlt = (netlist_time *) p->time_ptr(); + save_pointer(nlt->get_internaltype_ptr(), "queue", 1, i); #endif } -UINT64 netlist_mame_device::execute_clocks_to_cycles(UINT64 clocks) const +ATTR_COLD UINT64 netlist_mame_device::execute_clocks_to_cycles(UINT64 clocks) const { return clocks; } -UINT64 netlist_mame_device::execute_cycles_to_clocks(UINT64 cycles) const +ATTR_COLD UINT64 netlist_mame_device::execute_cycles_to_clocks(UINT64 cycles) const { return cycles; } @@ -169,5 +254,4 @@ ATTR_HOT void netlist_mame_device::execute_run() // debugger_instruction_hook(this, 0); //m_pc); m_netlist->process_queue(m_icount); - } diff --git a/src/emu/machine/netlist.h b/src/emu/machine/netlist.h index 9389838beab..1ad5588bb00 100644 --- a/src/emu/machine/netlist.h +++ b/src/emu/machine/netlist.h @@ -122,6 +122,7 @@ private: class netlist_mame_device : public device_t, public device_execute_interface + //public device_state_interface //, public device_memory_interface { public: @@ -158,6 +159,7 @@ protected: virtual void device_stop(); virtual void device_reset(); virtual void device_post_load(); + virtual void device_pre_save(); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const; virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const; @@ -168,6 +170,16 @@ protected: netlist_setup_t *m_setup; +// more save state ... needs to go somewhere else + + struct qentry { + netlist_time m_time; + char m_name[64]; + }; + + qentry qtemp[1024]; + int qsize; + private: void save_state(); diff --git a/src/emu/netlist/devices/net_lib.c b/src/emu/netlist/devices/net_lib.c index 93694000426..81a375bfd27 100644 --- a/src/emu/netlist/devices/net_lib.c +++ b/src/emu/netlist/devices/net_lib.c @@ -118,6 +118,8 @@ NETLIB_START(nic7448_sub) register_output("e", m_e); register_output("f", m_f); register_output("g", m_g); + + save(NAME(m_state)); } NETLIB_UPDATE(nic7448_sub) @@ -225,6 +227,10 @@ NETLIB_START(nic74107Asub) m_Q.initial(0); m_QQ.initial(1); + + save(NAME(m_Q1)); + save(NAME(m_Q2)); + save(NAME(m_F)); } NETLIB_START(nic74107A) diff --git a/src/emu/netlist/devices/nld_7483.c b/src/emu/netlist/devices/nld_7483.c index 4bf89303fda..eca61846241 100644 --- a/src/emu/netlist/devices/nld_7483.c +++ b/src/emu/netlist/devices/nld_7483.c @@ -24,6 +24,8 @@ NETLIB_START(7483) register_output("SC", m_SC); register_output("SD", m_SD); register_output("C4", m_C4); + + save(NAME(m_lastr)); } NETLIB_UPDATE(7483) diff --git a/src/emu/netlist/devices/nld_7490.c b/src/emu/netlist/devices/nld_7490.c index 56dddf21d7a..48b8bbc6b5c 100644 --- a/src/emu/netlist/devices/nld_7490.c +++ b/src/emu/netlist/devices/nld_7490.c @@ -19,6 +19,9 @@ NETLIB_START(7490) register_output("QB", m_Q[1]); register_output("QC", m_Q[2]); register_output("QD", m_Q[3]); + + save(NAME(m_cnt)); + } NETLIB_UPDATE(7490) diff --git a/src/emu/netlist/devices/nld_7493.c b/src/emu/netlist/devices/nld_7493.c index 96d955e2fce..a8c218de5a8 100644 --- a/src/emu/netlist/devices/nld_7493.c +++ b/src/emu/netlist/devices/nld_7493.c @@ -28,8 +28,12 @@ NETLIB_START(7493) NETLIB_START(7493ff) { + m_reset = 0; + register_input("CLK", m_I, netlist_input_t::STATE_INP_HL); register_output("Q", m_Q); + + save(NAME(m_reset)); } NETLIB_UPDATE(7493ff) diff --git a/src/emu/netlist/devices/nld_9316.c b/src/emu/netlist/devices/nld_9316.c index 0406609d902..ede8e0c0e68 100644 --- a/src/emu/netlist/devices/nld_9316.c +++ b/src/emu/netlist/devices/nld_9316.c @@ -48,6 +48,9 @@ NETLIB_START(9316_sub) register_output("QD", m_QD); register_output("RC", m_RC); + save(NAME(m_cnt)); + save(NAME(m_loadq)); + save(NAME(m_ent)); } NETLIB_UPDATE(9316_sub) diff --git a/src/emu/netlist/devices/nld_legacy.c b/src/emu/netlist/devices/nld_legacy.c index 990112ff02a..4afe74a45d8 100644 --- a/src/emu/netlist/devices/nld_legacy.c +++ b/src/emu/netlist/devices/nld_legacy.c @@ -21,6 +21,9 @@ NETLIB_START(nicMultiSwitch) } register_param("POS", m_POS, 0); register_output("Q", m_Q); + + save(NAME(m_position)); + } NETLIB_UPDATE(nicMultiSwitch) @@ -116,11 +119,14 @@ NETLIB_START(nicNE555N_MSTABLE) register_param("VS", m_VS, 5.0); register_param("VL", m_VL, 0.0 *5.0); - m_THRESHOLD_OUT.init_object(*this, "THRESHOLD"); + m_THRESHOLD_OUT.init_object(*this, name() + "THRESHOLD"); register_link_internal(m_THRESHOLD, m_THRESHOLD_OUT, netlist_input_t::STATE_INP_ACTIVE); m_Q.initial(5.0 * 0.4); m_last = false; + + save(NAME(m_last)); + } inline double NETLIB_NAME(nicNE555N_MSTABLE)::nicNE555N_cv() diff --git a/src/emu/netlist/devices/nld_log.c b/src/emu/netlist/devices/nld_log.c index 2101b0deb07..e175c4670a8 100644 --- a/src/emu/netlist/devices/nld_log.c +++ b/src/emu/netlist/devices/nld_log.c @@ -6,6 +6,8 @@ #include "nld_log.h" #include "sound/wavwrite.h" +//FIXME: what to do with save states? + NETLIB_START(log) { register_input("I", m_I); diff --git a/src/emu/netlist/devices/nld_ne555.c b/src/emu/netlist/devices/nld_ne555.c index 312c5984f1a..06a616f2bb9 100644 --- a/src/emu/netlist/devices/nld_ne555.c +++ b/src/emu/netlist/devices/nld_ne555.c @@ -48,6 +48,8 @@ NETLIB_START(NE555) setup().connect(m_RDIS.m_N, m_R3.m_N); m_last_out = false; + + save(NAME(m_last_out)); } NETLIB_UPDATE(NE555) diff --git a/src/emu/netlist/devices/nld_signal.h b/src/emu/netlist/devices/nld_signal.h index 461b071b4c7..a9e99ec381d 100644 --- a/src/emu/netlist/devices/nld_signal.h +++ b/src/emu/netlist/devices/nld_signal.h @@ -43,6 +43,7 @@ public: register_input(sIN[i], m_i[i], netlist_input_t::STATE_INP_ACTIVE); } m_Q.initial(1); + save(NAME(m_active)); } #if (USE_DEACTIVE_DEVICE) @@ -69,7 +70,7 @@ public: public: netlist_ttl_input_t m_i[_numdev]; netlist_ttl_output_t m_Q; - INT8 m_active; + INT32 m_active; }; @@ -92,6 +93,7 @@ public: { register_input(sIN[i], m_i[i]); } + save(NAME(m_active)); } #if (USE_DEACTIVE_DEVICE) @@ -142,7 +144,7 @@ public: public: netlist_ttl_input_t m_i[_numdev]; netlist_ttl_output_t m_Q; - INT8 m_active; + INT32 m_active; }; #if 1 @@ -165,6 +167,7 @@ public: { register_input(sIN[i], m_i[i], netlist_input_t::STATE_INP_ACTIVE); } + save(NAME(m_active)); } #if (USE_DEACTIVE_DEVICE) @@ -214,7 +217,7 @@ public: public: netlist_ttl_input_t m_i[2]; netlist_ttl_output_t m_Q; - INT8 m_active; + INT32 m_active; }; #endif diff --git a/src/emu/netlist/devices/nld_solver.c b/src/emu/netlist/devices/nld_solver.c index 78f82c8bd1b..b02f5e4d701 100644 --- a/src/emu/netlist/devices/nld_solver.c +++ b/src/emu/netlist/devices/nld_solver.c @@ -187,6 +187,8 @@ static bool already_processed(net_groups_t groups, int &cur_group, netlist_net_t static void process_net(net_groups_t groups, int &cur_group, netlist_net_t *net) { /* add the net */ + if (net->m_head == NULL) + return; groups[cur_group].add(net); for (netlist_core_terminal_t *p = net->m_head; p != NULL; p = p->m_update_list_next) { @@ -216,10 +218,18 @@ NETLIB_START(solver) register_param("ACCURACY", m_accuracy, 1e-3); register_param("CONVERG", m_convergence, 0.3); - register_link_internal(m_fb_sync, m_Q_sync, netlist_input_t::STATE_INP_ACTIVE); - register_link_internal(m_fb_step, m_Q_step, netlist_input_t::STATE_INP_ACTIVE); + // internal staff + + register_input("FB_sync", m_fb_sync, netlist_input_t::STATE_INP_ACTIVE); + register_input("FB_step", m_fb_step, netlist_input_t::STATE_INP_ACTIVE); + + setup().connect(m_fb_sync, m_Q_sync); + setup().connect(m_fb_step, m_Q_step); + m_last_step = netlist_time::zero; + save(NAME(m_last_step)); + } NETLIB_UPDATE_PARAM(solver) @@ -237,13 +247,6 @@ NETLIB_NAME(solver)::~NETLIB_NAME(solver)() e = en; } - netlist_net_t::list_t::entry_t *p = m_nets.first(); - while (p != NULL) - { - netlist_net_t::list_t::entry_t *pn = m_nets.next(p); - delete p->object(); - p = pn; - } } NETLIB_FUNC_VOID(solver, post_start, ()) @@ -251,24 +254,9 @@ NETLIB_FUNC_VOID(solver, post_start, ()) netlist_net_t::list_t groups[100]; int cur_group = -1; - NL_VERBOSE_OUT(("post start solver ...\n")); - - // delete empty nets ... - for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) - { - if (pn->object()->m_head == NULL) - { - NL_VERBOSE_OUT(("Deleting net ...\n")); - netlist_net_t *to_delete = pn->object(); - m_nets.remove(to_delete); - delete to_delete; - pn--; - } - } - SOLVER_VERBOSE_OUT(("Scanning net groups ...\n")); // determine net groups - for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn)) + for (netlist_net_t::list_t::entry_t *pn = netlist().m_nets.first(); pn != NULL; pn = netlist().m_nets.next(pn)) { if (!already_processed(groups, cur_group, pn->object())) { diff --git a/src/emu/netlist/devices/nld_solver.h b/src/emu/netlist/devices/nld_solver.h index 2598e4632f4..55216f70143 100644 --- a/src/emu/netlist/devices/nld_solver.h +++ b/src/emu/netlist/devices/nld_solver.h @@ -74,8 +74,6 @@ public: ~NETLIB_NAME(solver)(); - netlist_net_t::list_t m_nets; - ATTR_HOT inline void schedule(); ATTR_COLD void post_start(); diff --git a/src/emu/netlist/devices/nld_twoterm.c b/src/emu/netlist/devices/nld_twoterm.c index 39ac2b6e422..ddf7fc128cd 100644 --- a/src/emu/netlist/devices/nld_twoterm.c +++ b/src/emu/netlist/devices/nld_twoterm.c @@ -124,6 +124,9 @@ NETLIB_START(D) register_param("model", m_model, ""); m_Vd = 0.7; + + save(NAME(m_Vd)); + } @@ -197,6 +200,8 @@ NETLIB_START(QBJT_switch<_type>) setup().connect(m_RB.m_N, m_RC.m_N); setup().connect(m_RB.m_P, m_BV); setup().connect(m_RB.m_N, m_EV); + + save(NAME(m_state_on)); } NETLIB_UPDATE(Q) @@ -256,8 +261,8 @@ ATTR_COLD void NETLIB_NAME(VCCS)::configure(const double Gfac, const double GI) register_terminal("OP", m_OP); register_terminal("ON", m_ON); - m_OP1.init_object(*this, "OP1", netlist_core_terminal_t::STATE_INP_ACTIVE); - m_ON1.init_object(*this, "ON1", netlist_core_terminal_t::STATE_INP_ACTIVE); + m_OP1.init_object(*this, name() + ".OP1", netlist_core_terminal_t::STATE_INP_ACTIVE); + m_ON1.init_object(*this, name() + ".ON1", netlist_core_terminal_t::STATE_INP_ACTIVE); const double m_mult = m_G.Value() * Gfac; // 1.0 ==> 1V ==> 1A m_IP.set(GI); diff --git a/src/emu/netlist/devices/nld_twoterm.h b/src/emu/netlist/devices/nld_twoterm.h index 4e4b7073ed7..b5cb54f9aa1 100644 --- a/src/emu/netlist/devices/nld_twoterm.h +++ b/src/emu/netlist/devices/nld_twoterm.h @@ -219,9 +219,11 @@ public: } else { - //m_Vd = m_Vd + log((nVd - m_Vd) * m_VtInv + 1.0) * m_Vt; +#if defined(_MSC_VER) && _MSC_VER < 1200 + m_Vd = m_Vd + log((nVd - m_Vd) * m_VtInv + 1.0) * m_Vt; +#else m_Vd = m_Vd + log1p((nVd - m_Vd) * m_VtInv) * m_Vt; - +#endif const double eVDVt = exp(m_Vd * m_VtInv); Id = m_Is * (eVDVt - 1.0); @@ -348,7 +350,7 @@ protected: double m_gB; // base conductance / switch on double m_gC; // collector conductance / switch on double m_V; // internal voltage source - int m_state_on; + UINT8 m_state_on; private: }; diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index e2999ce0146..23d89fac573 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -29,6 +29,7 @@ ATTR_COLD void netlist_object_t::init_object(netlist_base_t &nl, const pstring & { m_netlist = &nl; m_name = aname; + save_register(); } ATTR_COLD const pstring &netlist_object_t::name() const @@ -38,6 +39,23 @@ ATTR_COLD const pstring &netlist_object_t::name() const return m_name; } +ATTR_COLD void netlist_object_t::save_state_ptr(const pstring &stname, const netlist_data_type_e dt, const int size, void *ptr) +{ + pstring fullname = name() + "." + stname; + // do nothing for now; + ATTR_UNUSED pstring ts[] = { + "NOT_SUPPORTED", + "DT_DOUBLE", + "DT_INT64", + "DT_INT8", + "DT_INT", + "DT_BOOLEAN" + }; + + NL_VERBOSE_OUT(("SAVE: <%s> %s(%d) %p\n", fullname.cstr(), ts[dt].cstr(), size, ptr)); + netlist().setup().save_state_ptr(fullname, dt, size, ptr); +} + // ---------------------------------------------------------------------------------------- // netlist_owned_object_t // ---------------------------------------------------------------------------------------- @@ -61,7 +79,8 @@ ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev, // ---------------------------------------------------------------------------------------- netlist_base_t::netlist_base_t() - : m_time_ps(netlist_time::zero), + : netlist_object_t(NETLIST, GENERIC), + m_time_ps(netlist_time::zero), m_rem(0), m_div(NETLIST_DIV), m_mainclock(NULL), @@ -82,9 +101,30 @@ static void tagmap_free_entries(T &tm) netlist_base_t::~netlist_base_t() { tagmap_free_entries<tagmap_devices_t>(m_devices); + + netlist_net_t::list_t::entry_t *p = m_nets.first(); + while (p != NULL) + { + netlist_net_t::list_t::entry_t *pn = m_nets.next(p); + if (!p->object()->isRailNet()) + delete p->object(); + p = pn; + } + + m_nets.reset(); pstring::resetmem(); } +ATTR_COLD netlist_net_t *netlist_base_t::find_net(const pstring &name) +{ + for (netlist_net_t::list_t::entry_t *p = m_nets.first(); p != NULL; p = m_nets.next(p)) + { + if (p->object()->name() == name) + return p->object(); + } + return NULL; +} + ATTR_COLD void netlist_base_t::set_mainclock_dev(NETLIB_NAME(mainclock) *dev) { m_mainclock = dev; @@ -339,6 +379,7 @@ ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_inp setup().register_object(*this, *this, name, inp, type); } +//FIXME: Get rid of this static void init_term(netlist_core_device_t &dev, netlist_core_terminal_t &term, netlist_input_t::state_e aState) { if (!term.isInitalized()) @@ -346,13 +387,13 @@ static void init_term(netlist_core_device_t &dev, netlist_core_terminal_t &term, switch (term.type()) { case netlist_terminal_t::OUTPUT: - dynamic_cast<netlist_output_t &>(term).init_object(dev, "internal output"); + dynamic_cast<netlist_output_t &>(term).init_object(dev, dev.name() + ".INTOUT"); break; case netlist_terminal_t::INPUT: - dynamic_cast<netlist_input_t &>(term).init_object(dev, "internal input", aState); + dynamic_cast<netlist_input_t &>(term).init_object(dev, dev.name() + ".INTINP", aState); break; case netlist_terminal_t::TERMINAL: - dynamic_cast<netlist_terminal_t &>(term).init_object(dev, "internal terminal", aState); + dynamic_cast<netlist_terminal_t &>(term).init_object(dev, dev.name() + ".INTTERM", aState); break; default: dev.netlist().xfatalerror("Unknown terminal type"); @@ -362,6 +403,7 @@ static void init_term(netlist_core_device_t &dev, netlist_core_terminal_t &term, } // FIXME: Revise internal links ... +//FIXME: Get rid of this ATTR_COLD void netlist_device_t::register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, const netlist_input_t::state_e aState) { init_term(dev, in, aState); @@ -377,9 +419,11 @@ ATTR_COLD void netlist_device_t::register_link_internal(netlist_input_t &in, net template <class C, class T> ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const pstring &sname, C ¶m, const T initialVal) { - param.init_object(dev, sname); + pstring fullname = dev.name() + "." + sname; + param.init_object(dev, fullname); param.initial(initialVal); - setup().register_object(*this, *this, sname, param, netlist_terminal_t::STATE_NONEX); + //FIXME: pass fullname from above + setup().register_object(*this, *this, fullname, param, netlist_terminal_t::STATE_NONEX); } template ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const pstring &sname, netlist_param_double_t ¶m, const double initialVal); @@ -405,6 +449,12 @@ ATTR_COLD netlist_net_t::netlist_net_t(const type_t atype, const family_t afamil { }; +ATTR_COLD void netlist_net_t::init_object(netlist_base_t &nl, const pstring &aname) +{ + netlist_object_t::init_object(nl, aname); + nl.m_nets.add(this); +} + ATTR_COLD void netlist_net_t::register_railterminal(netlist_output_t &mr) { assert(m_railterminal == NULL); @@ -551,7 +601,7 @@ netlist_output_t::netlist_output_t(const type_t atype, const family_t afamily) ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const pstring &aname) { netlist_core_terminal_t::init_object(dev, aname, STATE_OUT); - net().init_object(dev.netlist(), aname); + net().init_object(dev.netlist(), aname + ".net"); net().register_railterminal(*this); } diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h index 66efe4e7345..9134f4e4c51 100644 --- a/src/emu/netlist/nl_base.h +++ b/src/emu/netlist/nl_base.h @@ -247,6 +247,33 @@ class NETLIB_NAME(solver); class NETLIB_NAME(mainclock); // ---------------------------------------------------------------------------------------- +// state saving ... +// ---------------------------------------------------------------------------------------- + +enum netlist_data_type_e { + NOT_SUPPORTED, + DT_DOUBLE, + DT_INT64, + DT_INT8, + DT_INT, + DT_BOOLEAN +}; + +template<typename _ItemType> struct nl_datatype { static const netlist_data_type_e type = netlist_data_type_e(NOT_SUPPORTED); }; +//template<typename _ItemType> struct type_checker<_ItemType*> { static const bool is_atom = false; static const bool is_pointer = true; }; + +#define NETLIST_SAVE_TYPE(TYPE, TYPEDESC) template<> struct nl_datatype<TYPE>{ static const netlist_data_type_e type = netlist_data_type_e(TYPEDESC); } + +NETLIST_SAVE_TYPE(double, DT_DOUBLE); +NETLIST_SAVE_TYPE(INT8, DT_INT8); +NETLIST_SAVE_TYPE(UINT8, DT_INT8); +NETLIST_SAVE_TYPE(INT64, DT_INT64); +NETLIST_SAVE_TYPE(UINT64, DT_INT64); +NETLIST_SAVE_TYPE(bool, DT_BOOLEAN); +NETLIST_SAVE_TYPE(UINT32, DT_INT); +NETLIST_SAVE_TYPE(INT32, DT_INT); + +// ---------------------------------------------------------------------------------------- // netlist_object_t // ---------------------------------------------------------------------------------------- @@ -261,6 +288,7 @@ public: PARAM = 3, NET = 4, DEVICE = 5, + NETLIST = 6, }; enum family_t { // Terminal families @@ -285,6 +313,12 @@ public: ATTR_COLD const pstring &name() const; + ATTR_COLD void save_state_ptr(const pstring &stname, const netlist_data_type_e, const int size, void *ptr); + template<class C> ATTR_COLD void save(C &state, const pstring &stname) + { + save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), &state); + } + ATTR_HOT inline const type_t type() const { return m_objtype; } ATTR_HOT inline const family_t family() const { return m_family; } @@ -294,6 +328,11 @@ public: ATTR_HOT inline netlist_base_t & RESTRICT netlist() { return *m_netlist; } ATTR_HOT inline const netlist_base_t & RESTRICT netlist() const { return *m_netlist; } +protected: + + // must call parent save_register ! + ATTR_COLD virtual void save_register() { }; + private: pstring m_name; const type_t m_objtype; @@ -301,6 +340,11 @@ private: netlist_base_t * RESTRICT m_netlist; }; +template<> ATTR_COLD inline void netlist_object_t::save(netlist_time &state, const pstring &stname) +{ + save_state_ptr(stname, DT_INT64, sizeof(netlist_time::INTERNALTYPE), state.get_internaltype_ptr()); +} + // ---------------------------------------------------------------------------------------- // netlist_owned_object_t // ---------------------------------------------------------------------------------------- @@ -338,6 +382,7 @@ public: STATE_NONEX = 256 }; + ATTR_COLD netlist_core_terminal_t(const type_t atype, const family_t afamily); ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate); @@ -357,11 +402,17 @@ public: netlist_core_terminal_t *m_update_list_next; +protected: + ATTR_COLD virtual void save_register() { save(NAME(m_state)); netlist_owned_object_t::save_register(); } + private: netlist_net_t * RESTRICT m_net; state_e m_state; }; +NETLIST_SAVE_TYPE(netlist_core_terminal_t::state_e, DT_INT); + + class netlist_terminal_t : public netlist_core_terminal_t { NETLIST_PREVENT_COPYING(netlist_terminal_t) @@ -394,6 +445,16 @@ public: netlist_terminal_t *m_otherterm; + +protected: + ATTR_COLD virtual void save_register() + { + save(NAME(m_Idr)); + save(NAME(m_go)); + save(NAME(m_gt)); + netlist_core_terminal_t::save_register(); + } + }; @@ -502,6 +563,7 @@ public: }; ATTR_COLD netlist_net_t(const type_t atype, const family_t afamily); + ATTR_COLD void init_object(netlist_base_t &nl, const pstring &aname); ATTR_COLD void register_con(netlist_core_terminal_t &terminal); ATTR_COLD void merge_net(netlist_net_t *othernet); @@ -568,6 +630,21 @@ protected: UINT32 m_num_cons; +protected: + ATTR_COLD virtual void 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(); + } + private: ATTR_HOT void update_dev(const netlist_core_terminal_t *inp, const UINT32 mask) const; @@ -688,6 +765,13 @@ public: ATTR_COLD inline void initial(const double val) { m_param = val; } ATTR_HOT inline const double Value() const { return m_param; } +protected: + ATTR_COLD virtual void save_register() + { + save(NAME(m_param)); + netlist_param_t::save_register(); + } + private: double m_param; }; @@ -703,6 +787,13 @@ public: ATTR_HOT inline const int Value() const { return m_param; } +protected: + ATTR_COLD virtual void save_register() + { + save(NAME(m_param)); + netlist_param_t::save_register(); + } + private: int m_param; }; @@ -832,7 +923,7 @@ public: protected: ATTR_HOT virtual void update() { } - ATTR_HOT virtual void start() { } + ATTR_COLD virtual void start() { } private: }; @@ -892,7 +983,7 @@ private: typedef tagmap_t<netlist_device_t *, 393> tagmap_devices_t; -class netlist_base_t +class netlist_base_t : public netlist_object_t { NETLIST_PREVENT_COPYING(netlist_base_t) public: @@ -920,6 +1011,8 @@ public: ATTR_COLD void set_solver_dev(NETLIB_NAME(solver) *dev); ATTR_COLD void set_setup(netlist_setup_t *asetup) { m_setup = asetup; } + ATTR_COLD netlist_net_t *find_net(const pstring &name); + ATTR_COLD void set_clock_freq(UINT64 clockfreq); ATTR_COLD netlist_setup_t &setup() { return *m_setup; } @@ -928,11 +1021,23 @@ public: ATTR_COLD void xfatalerror(const char *format, ...) const; tagmap_devices_t m_devices; + netlist_net_t::list_t m_nets; protected: // any derived netlist must override this ... virtual void vfatalerror(const char *format, va_list ap) const = 0; + +protected: + ATTR_COLD virtual void save_register() + { + //queue_t m_queue; + save(NAME(m_time_ps)); + save(NAME(m_rem)); + save(NAME(m_div)); + netlist_object_t::save_register(); + } + #if (NL_KEEP_STATISTICS) // performance int m_perf_out_processed; @@ -978,9 +1083,8 @@ public: protected: ATTR_COLD void start() { - m_I.init_object(*this, "I", netlist_terminal_t::STATE_INP_ACTIVE); - - m_Q.init_object(*this, "Q"); + register_input("I", m_I, netlist_terminal_t::STATE_INP_ACTIVE); + register_output("Q", m_Q); m_Q.initial(1); } @@ -1020,8 +1124,8 @@ public: protected: ATTR_COLD void start() { - m_I.init_object(*this, "I", netlist_terminal_t::STATE_INP_ACTIVE); - m_Q.init_object(*this, "Q"); + register_input("I", m_I, netlist_terminal_t::STATE_INP_ACTIVE); + register_output("Q", m_Q); m_Q.initial(0); } diff --git a/src/emu/netlist/nl_lists.h b/src/emu/netlist/nl_lists.h index c2882248787..3d4d70c0231 100644 --- a/src/emu/netlist/nl_lists.h +++ b/src/emu/netlist/nl_lists.h @@ -113,6 +113,15 @@ public: ATTR_HOT inline bool empty() const { return (m_ptr < m_list); } ATTR_HOT inline void reset() { m_ptr = m_list - 1; } + ATTR_COLD void reset_and_free() + { + for (entry_t *i = m_list; i <= m_ptr; i++) + { + delete i->object(); + } + reset(); + } + //ATTR_HOT inline entry_t *item(int i) const { return &m_list[i]; } ATTR_HOT inline _ListClass& operator[](const int & index) { return m_list[index].m_obj; } ATTR_HOT inline const _ListClass& operator[](const int & index) const { return m_list[index].m_obj; } @@ -142,6 +151,9 @@ public: inline entry_t(const _Time atime, _Element &elem) : m_time(atime), m_object(&elem) {} ATTR_HOT inline const _Time &time() const { return m_time; } ATTR_HOT inline _Element & object() const { return *m_object; } + + ATTR_HOT inline const _Time *time_ptr() const { return &m_time; } + ATTR_HOT inline _Element *object_ptr() const { return m_object; } private: _Time m_time; _Element *m_object; @@ -153,6 +165,7 @@ public: clear(); } + ATTR_HOT inline int capacity() const { return _Size; } ATTR_HOT inline bool is_empty() const { return (m_end == &m_list[0]); } ATTR_HOT inline bool is_not_empty() const { return (m_end > &m_list[0]); } @@ -193,6 +206,11 @@ public: m_end = &m_list[0]; } + // save state support + + ATTR_COLD entry_t *listptr() { return &m_list[0]; } + ATTR_COLD int count() const { return m_end - m_list; } + #if (NL_KEEP_STATISTICS) // profiling INT32 m_prof_start; diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c index d1f513c88c8..d17e83990b4 100644 --- a/src/emu/netlist/nl_setup.c +++ b/src/emu/netlist/nl_setup.c @@ -33,6 +33,10 @@ netlist_setup_t::netlist_setup_t(netlist_base_t &netlist) , m_proxy_cnt(0) { netlist.set_setup(this); +} + +void netlist_setup_t::init() +{ m_factory.initialize(); NETLIST_NAME(base)(*this); } @@ -45,6 +49,7 @@ netlist_setup_t::~netlist_setup_t() m_params.reset(); m_terminals.reset(); m_params_temp.reset(); + m_save.reset_and_free(); netlist().set_setup(NULL); @@ -132,6 +137,9 @@ pstring netlist_setup_t::objtype_as_astr(netlist_object_t &in) case netlist_terminal_t::DEVICE: return "DEVICE"; break; + case netlist_terminal_t::NETLIST: + return "NETLIST"; + break; } // FIXME: noreturn netlist().xfatalerror("Unknown object type %d\n", in.type()); @@ -161,10 +169,8 @@ void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device break; case netlist_terminal_t::PARAM: { - netlist_param_t ¶m = dynamic_cast<netlist_param_t &>(obj); - pstring temp = param.netdev().name() + "." + name; - const pstring val = m_params_temp.find(temp); + const pstring val = m_params_temp.find(name); if (val != "") { switch (param.param_type()) @@ -174,17 +180,17 @@ void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device NL_VERBOSE_OUT(("Found parameter ... %s : %s\n", temp.cstr(), val->cstr())); double vald = 0; if (sscanf(val.cstr(), "%lf", &vald) != 1) - netlist().xfatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val.cstr()); + netlist().xfatalerror("Invalid number conversion %s : %s\n", name.cstr(), val.cstr()); dynamic_cast<netlist_param_double_t &>(param).initial(vald); } break; case netlist_param_t::INTEGER: case netlist_param_t::LOGIC: { - NL_VERBOSE_OUT(("Found parameter ... %s : %s\n", temp.cstr(), val->cstr())); + NL_VERBOSE_OUT(("Found parameter ... %s : %s\n", name.cstr(), val->cstr())); int vald = 0; if (sscanf(val.cstr(), "%d", &vald) != 1) - netlist().xfatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val.cstr()); + netlist().xfatalerror("Invalid number conversion %s : %s\n", name.cstr(), val.cstr()); dynamic_cast<netlist_param_int_t &>(param).initial(vald); } break; @@ -213,14 +219,18 @@ void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device } break; default: - netlist().xfatalerror("Parameter is not supported %s : %s\n", temp.cstr(), val.cstr()); + netlist().xfatalerror("Parameter is not supported %s : %s\n", name.cstr(), val.cstr()); } } - if (!(m_params.add(temp, ¶m, false)==TMERR_NONE)) + if (!(m_params.add(name, ¶m, false)==TMERR_NONE)) netlist().xfatalerror("Error adding parameter %s to parameter list\n", name.cstr()); } break; case netlist_terminal_t::DEVICE: + netlist().xfatalerror("Device registration not yet supported - \n", name.cstr()); + break; + case netlist_terminal_t::NETLIST: + netlist().xfatalerror("Netlist registration not yet supported - \n", name.cstr()); break; } } @@ -462,9 +472,9 @@ void netlist_setup_t::connect_terminals(netlist_core_terminal_t &t1, netlist_cor NL_VERBOSE_OUT(("adding net ...\n")); netlist_net_t *anet = new netlist_net_t(netlist_object_t::NET, netlist_object_t::ANALOG); t1.set_net(*anet); - m_netlist.solver()->m_nets.add(anet); + //m_netlist.solver()->m_nets.add(anet); // FIXME: Nets should have a unique name - t1.net().init_object(netlist(),"some net"); + t1.net().init_object(netlist(),"net." + t1.name() ); t1.net().register_con(t2); t1.net().register_con(t1); } @@ -533,6 +543,23 @@ void netlist_setup_t::resolve_inputs() //VERBOSE_OUT(("%s %d\n", out->netdev()->name(), *out->Q_ptr())); } +#if 0 + NL_VERBOSE_OUT(("deleting empty nets ...\n")); + + // delete empty nets ... + for (netlist_net_t::list_t::entry_t *pn = netlist().m_nets.first(); pn != NULL; pn = netlist().m_nets.next(pn)) + { + if (pn->object()->m_head == NULL) + { + NL_VERBOSE_OUT(("Deleting net ...\n")); + netlist_net_t *to_delete = pn->object(); + netlist().m_nets.remove(to_delete); + if (!to_delete->isRailNet()) + delete to_delete; + pn--; + } + } +#endif if (m_netlist.solver() != NULL) m_netlist.solver()->post_start(); @@ -578,6 +605,7 @@ void netlist_setup_t::start_devices() netlist_device_t *dev = entry->object(); dev->init(netlist(), entry->tag().cstr()); } + } void netlist_setup_t::parse(const char *buf) diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h index 8d9c0eefa4d..401a9921f8f 100644 --- a/src/emu/netlist/nl_setup.h +++ b/src/emu/netlist/nl_setup.h @@ -102,6 +102,8 @@ public: netlist_setup_t(netlist_base_t &netlist); ~netlist_setup_t(); + void init(); + netlist_base_t &netlist() { return m_netlist; } const netlist_base_t &netlist() const { return m_netlist; } netlist_factory &factory() { return m_factory; } @@ -133,6 +135,28 @@ public: void print_stats(); + /* save state */ + + struct save_entry_t + { + save_entry_t(const pstring &stname, const netlist_data_type_e dt, const int size, void *ptr) : + m_name(stname), m_dt(dt), m_size(size), m_ptr(ptr) { } + pstring m_name; + netlist_data_type_e m_dt; + int m_size; + void *m_ptr; + }; + + typedef netlist_list_t<save_entry_t *> save_entry_list_t; + + void save_state_ptr(const pstring &stname, const netlist_data_type_e dt, const int size, void *ptr) + { + save_entry_t *p = new save_entry_t(stname, dt, size, ptr); + m_save.add(p); + } + + save_entry_list_t m_save; + protected: private: diff --git a/src/emu/netlist/nl_time.h b/src/emu/netlist/nl_time.h index 36f7d26fd7b..bfdeda38c32 100644 --- a/src/emu/netlist/nl_time.h +++ b/src/emu/netlist/nl_time.h @@ -50,6 +50,9 @@ public: ATTR_HOT inline const INTERNALTYPE as_raw() const { return m_time; } ATTR_HOT inline const double as_double() const { return (double) m_time / (double) RESOLUTION; } + // for save states .... + ATTR_HOT inline INTERNALTYPE *get_internaltype_ptr() { return &m_time; } + ATTR_HOT static inline const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); } ATTR_HOT static inline const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); } ATTR_HOT static inline const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); } diff --git a/src/emu/video/fixfreq.c b/src/emu/video/fixfreq.c index 3a9e60c9537..0ab0c7f7b88 100644 --- a/src/emu/video/fixfreq.c +++ b/src/emu/video/fixfreq.c @@ -113,6 +113,31 @@ void fixedfreq_device::device_start() m_bitmap[1] = NULL; //m_vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vga_device::vblank_timer_cb),this)); recompute_parameters(false); + + save_item(NAME(m_vid)); + save_item(NAME(m_last_x)); + save_item(NAME(m_last_y)); + save_item(NAME(m_last_time)); + save_item(NAME(m_line_time)); + save_item(NAME(m_last_hsync_time)); + save_item(NAME(m_last_vsync_time)); + save_item(NAME(m_refresh)); + save_item(NAME(m_clock_period)); + //save_item(NAME(m_bitmap[0])); + //save_item(NAME(m_bitmap[1])); + save_item(NAME(m_cur_bm)); + + /* sync separator */ + save_item(NAME(m_vint)); + save_item(NAME(m_int_trig)); + save_item(NAME(m_mult)); + + save_item(NAME(m_sig_vsync)); + save_item(NAME(m_sig_composite)); + save_item(NAME(m_sig_field)); + + + } void fixedfreq_device::device_reset() @@ -122,6 +147,7 @@ void fixedfreq_device::device_reset() m_last_hsync_time = attotime::zero; m_last_vsync_time = attotime::zero; m_vint = 0; + } diff --git a/src/mame/drivers/pong.c b/src/mame/drivers/pong.c index 2ac1cf0c82d..c88c6e51bbd 100644 --- a/src/mame/drivers/pong.c +++ b/src/mame/drivers/pong.c @@ -982,5 +982,5 @@ ROM_START( pongf ) /* dummy to satisfy game entry*/ ROM_END -GAME( 1972, pong, 0, pong, pong, driver_device, 0, ROT0, "Atari", "Pong (Rev E)", 0 ) -GAME( 1972, pongf, 0, pongf, pong, driver_device, 0, ROT0, "Atari", "Pong (Rev E), no subcycles", 0 ) +GAME( 1972, pong, 0, pong, pong, driver_device, 0, ROT0, "Atari", "Pong (Rev E)", GAME_SUPPORTS_SAVE ) +GAME( 1972, pongf, 0, pongf, pong, driver_device, 0, ROT0, "Atari", "Pong (Rev E), no subcycles", GAME_SUPPORTS_SAVE ) |