Netlist: introduced more consistent and general state saving. Useful for regression tests going forward.

This commit is contained in:
Couriersud 2013-12-22 21:32:13 +00:00
parent 452bae2722
commit f3a8aceab4
9 changed files with 152 additions and 101 deletions

2
.gitattributes vendored
View File

@ -2178,6 +2178,8 @@ src/emu/netlist/nl_setup.c svneol=native#text/plain
src/emu/netlist/nl_setup.h svneol=native#text/plain
src/emu/netlist/nl_time.h svneol=native#text/plain
src/emu/netlist/nl_util.h svneol=native#text/plain
src/emu/netlist/pstate.c svneol=native#text/plain
src/emu/netlist/pstate.h svneol=native#text/plain
src/emu/netlist/pstring.c svneol=native#text/plain
src/emu/netlist/pstring.h svneol=native#text/plain
src/emu/network.c svneol=native#text/plain

View File

@ -49,6 +49,7 @@
#include "netlist/nl_base.h"
#include "netlist/nl_setup.h"
#include "netlist/devices/net_lib.h"
#include "debugger.h"
//#define LOG_DEV_CALLS(x) printf x
#define LOG_DEV_CALLS(x) do { } while (0)
@ -178,37 +179,27 @@ void netlist_mame_device::device_timer(emu_timer &timer, device_timer_id id, int
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))
for (pstate_entry_t::list_t::entry_t *p = m_netlist->save_list().first(); p != NULL; p = m_netlist->save_list().next(p))
{
netlist_setup_t::save_entry_t *s = p->object();
pstate_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);
save_pointer((double *) s->m_ptr, s->m_name, s->m_count);
break;
case DT_INT64:
save_pointer((INT64 *) s->m_ptr, s->m_name, 1);
save_pointer((INT64 *) s->m_ptr, s->m_name, s->m_count);
break;
case DT_INT8:
save_pointer((INT8 *) s->m_ptr, s->m_name, 1);
save_pointer((INT8 *) s->m_ptr, s->m_name, s->m_count);
break;
case DT_INT:
save_pointer((int *) s->m_ptr, s->m_name, 1);
save_pointer((int *) s->m_ptr, s->m_name, s->m_count);
break;
case DT_BOOLEAN:
save_pointer((bool *) s->m_ptr, s->m_name, 1);
save_pointer((bool *) s->m_ptr, s->m_name, s->m_count);
break;
#if 0
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());
@ -225,13 +216,6 @@ ATTR_COLD void netlist_mame_device::save_state()
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
}
ATTR_COLD UINT64 netlist_mame_device::execute_clocks_to_cycles(UINT64 clocks) const
@ -246,12 +230,12 @@ ATTR_COLD UINT64 netlist_mame_device::execute_cycles_to_clocks(UINT64 cycles) co
ATTR_HOT void netlist_mame_device::execute_run()
{
//bool check_debugger = ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) != 0);
bool check_debugger = ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) != 0);
// debugging
//m_ppc = m_pc; // copy PC to previous PC
//if (check_debugger)
// debugger_instruction_hook(this, 0); //m_pc);
if (check_debugger)
debugger_instruction_hook(this, 0); //m_pc);
m_netlist->process_queue(m_icount);
}

View File

@ -22,6 +22,7 @@ NETLISTOBJS+= \
$(NETLISTOBJ)/nl_parser.o \
$(NETLISTOBJ)/nl_setup.o \
$(NETLISTOBJ)/pstring.o \
$(NETLISTOBJ)/pstate.o \
$(NETLISTOBJ)/devices/nld_7404.o \
$(NETLISTOBJ)/devices/nld_7474.o \
$(NETLISTOBJ)/devices/nld_7483.o \

View File

@ -39,23 +39,6 @@ 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
// ----------------------------------------------------------------------------------------

View File

@ -155,6 +155,7 @@
#include "nl_lists.h"
#include "nl_time.h"
#include "pstring.h"
#include "pstate.h"
// ----------------------------------------------------------------------------------------
// Type definitions
@ -246,33 +247,6 @@ class netlist_matrix_solver_t;
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
// ----------------------------------------------------------------------------------------
@ -313,11 +287,14 @@ 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);
PSTATE_INTERFACE(*m_netlist, name())
#if 0
template<class C> ATTR_COLD void save(C &state, const pstring &stname)
{
save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), &state);
}
#endif
ATTR_HOT inline const type_t type() const { return m_objtype; }
ATTR_HOT inline const family_t family() const { return m_family; }
@ -330,6 +307,11 @@ public:
protected:
#if 0
// pstate_interface virtual
ATTR_COLD virtual void save_state_ptr(const pstring &stname, const netlist_data_type_e, const int size, const int count, void *ptr);
#endif
// must call parent save_register !
ATTR_COLD virtual void save_register() { };
@ -340,11 +322,6 @@ 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
// ----------------------------------------------------------------------------------------
@ -983,7 +960,7 @@ private:
typedef tagmap_t<netlist_device_t *, 393> tagmap_devices_t;
class netlist_base_t : public netlist_object_t
class netlist_base_t : public netlist_object_t, public pstate_manager_t
{
NETLIST_PREVENT_COPYING(netlist_base_t)
public:

View File

@ -49,7 +49,6 @@ 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);

View File

@ -135,28 +135,6 @@ 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:

30
src/emu/netlist/pstate.c Normal file
View File

@ -0,0 +1,30 @@
/*
* pstate.c
*
*/
#include "pstate.h"
ATTR_COLD pstate_manager_t::~pstate_manager_t()
{
m_save.reset_and_free();
}
ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const netlist_data_type_e dt, const int size, const int count, void *ptr)
{
pstring fullname = stname;
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));
pstate_entry_t *p = new pstate_entry_t(stname, dt, size, count, ptr);
m_save.add(p);
}

97
src/emu/netlist/pstate.h Normal file
View File

@ -0,0 +1,97 @@
/*
* pstate.h
*
*/
#ifndef PSTATE_H_
#define PSTATE_H_
#include "nl_config.h"
#include "nl_time.h"
#include "nl_lists.h"
#include "pstring.h"
// ----------------------------------------------------------------------------------------
// state saving ...
// ----------------------------------------------------------------------------------------
#define PSTATE_INTERFACE(manager, module) \
template<class C> ATTR_COLD void save(C &state, const pstring &stname) \
{ \
dynamic_cast<pstate_manager_t &>(manager).save_manager(state, module + "." + stname); \
}
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);
struct pstate_entry_t
{
typedef netlist_list_t<pstate_entry_t *> list_t;
pstate_entry_t(const pstring &stname, const netlist_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;
netlist_data_type_e m_dt;
int m_size;
int m_count;
void *m_ptr;
};
class pstate_manager_t
{
public:
ATTR_COLD ~pstate_manager_t();
template<class C> ATTR_COLD void save_manager(C &state, const pstring &stname)
{
save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), 1, &state);
}
template<class C> ATTR_COLD void save_manager(C *state, const pstring &stname, const int count)
{
save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), count, state);
}
template<class C, std::size_t N> ATTR_COLD void save_manager(C (&state)[N], const pstring &stname)
{
save_state_ptr(stname, nl_datatype<C>::type, sizeof(C), N, &(state[0]));
}
inline const pstate_entry_t::list_t &save_list() const { return m_save; }
protected:
ATTR_COLD void save_state_ptr(const pstring &stname, const netlist_data_type_e, const int size, const int count, void *ptr);
private:
pstate_entry_t::list_t m_save;
};
template<> ATTR_COLD inline void pstate_manager_t::save_manager(netlist_time &nlt, const pstring &stname)
{
save_state_ptr(stname, DT_INT64, sizeof(netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr());
}
#endif /* PSTATE_H_ */