Moved the state saving system to C++. For now the registration macros

are still intact. The new state_manager class has templatized methods
for saving the various types, and through template specialization can
save more complex system types cleanly (like bitmaps and attotimes).

Added new mechanism to detect proper state save types. This is much
more strict and there will likely be some games/devices that fatalerror
at startup until they are remedied. Spot checking has caught the more
common situations.

The new state_manager is embedded directly in the running_machine, 
allowing objects to register state saving in their constructors now.

Added NAME() macro which is a generalization of FUNC() and can be
used to wrap variables that are registered when directly using the
new methods as opposed to the previous macros. For example:

  machine->state().save_item(NAME(global_item))

Added methods in the device_t class that implicitly register state
against the current device, making for a cleaner interface.

Just a couple of required regexes for now:

state_save_register_postload( *)\(( *)([^,;]+), *
\3->state().register_postload\1\(\2

state_save_register_presave( *)\(( *)([^,;]+), *
\3->state().register_presave\1\(\2
This commit is contained in:
Aaron Giles 2011-02-08 06:48:39 +00:00
parent f4f3adf250
commit 4f7efb1ca4
133 changed files with 785 additions and 899 deletions

View File

@ -535,7 +535,6 @@ static CPU_INIT( arm )
state_save_register_device_item_array(device, 0, cpustate->coproRegister); state_save_register_device_item_array(device, 0, cpustate->coproRegister);
state_save_register_device_item(device, 0, cpustate->pendingIrq); state_save_register_device_item(device, 0, cpustate->pendingIrq);
state_save_register_device_item(device, 0, cpustate->pendingFiq); state_save_register_device_item(device, 0, cpustate->pendingFiq);
state_save_register_device_item(device, 0, cpustate->endian);
} }
@ -552,7 +551,6 @@ static CPU_INIT( arm_be )
state_save_register_device_item_array(device, 0, cpustate->coproRegister); state_save_register_device_item_array(device, 0, cpustate->coproRegister);
state_save_register_device_item(device, 0, cpustate->pendingIrq); state_save_register_device_item(device, 0, cpustate->pendingIrq);
state_save_register_device_item(device, 0, cpustate->pendingFiq); state_save_register_device_item(device, 0, cpustate->pendingFiq);
state_save_register_device_item(device, 0, cpustate->endian);
} }

View File

@ -275,7 +275,7 @@ static void cquestsnd_state_register(device_t *device)
state_save_register_device_item(device, 0, cpustate->prev_ipram); state_save_register_device_item(device, 0, cpustate->prev_ipram);
state_save_register_device_item(device, 0, cpustate->prev_ipwrt); state_save_register_device_item(device, 0, cpustate->prev_ipwrt);
state_save_register_postload(device->machine, cquestsnd_postload, (void *)device); device->machine->state().register_postload(cquestsnd_postload, (void *)device);
} }
static CPU_INIT( cquestsnd ) static CPU_INIT( cquestsnd )
@ -349,7 +349,7 @@ static void cquestrot_state_register(device_t *device)
state_save_register_device_item_pointer(device, 0, cpustate->dram, 16384); state_save_register_device_item_pointer(device, 0, cpustate->dram, 16384);
state_save_register_device_item_pointer(device, 0, cpustate->sram, 2048); state_save_register_device_item_pointer(device, 0, cpustate->sram, 2048);
state_save_register_postload(device->machine, cquestrot_postload, (void *)device); device->machine->state().register_postload(cquestrot_postload, (void *)device);
} }
static CPU_INIT( cquestrot ) static CPU_INIT( cquestrot )
@ -433,7 +433,7 @@ static void cquestlin_state_register(device_t *device)
state_save_register_device_item_pointer(device, 0, cpustate->e_stack, 32768); state_save_register_device_item_pointer(device, 0, cpustate->e_stack, 32768);
state_save_register_device_item_pointer(device, 0, cpustate->o_stack, 32768); state_save_register_device_item_pointer(device, 0, cpustate->o_stack, 32768);
state_save_register_postload(device->machine, cquestlin_postload, (void *)device); device->machine->state().register_postload(cquestlin_postload, (void *)device);
} }
static CPU_INIT( cquestlin ) static CPU_INIT( cquestlin )

View File

@ -365,7 +365,7 @@ static CPU_INIT( g65816 )
state_save_register_device_item(device, 0, cpustate->irq_delay); state_save_register_device_item(device, 0, cpustate->irq_delay);
state_save_register_device_item(device, 0, cpustate->stopped); state_save_register_device_item(device, 0, cpustate->stopped);
state_save_register_postload(device->machine, g65816_restore_state, cpustate); device->machine->state().register_postload(g65816_restore_state, cpustate);
} }
/************************************************************************** /**************************************************************************

View File

@ -237,7 +237,7 @@ static CPU_INIT(h8)
state_save_register_device_item(device, 0, h8->h8TSTR); state_save_register_device_item(device, 0, h8->h8TSTR);
state_save_register_device_item_array(device, 0, h8->h8TCNT); state_save_register_device_item_array(device, 0, h8->h8TCNT);
state_save_register_postload(device->machine, h8_onstateload, h8); device->machine->state().register_postload(h8_onstateload, h8);
h8_itu_init(h8); h8_itu_init(h8);
} }

View File

@ -259,7 +259,7 @@ static CPU_INIT(h8bit)
state_save_register_device_item(device, 0, h8->h8TSTR); state_save_register_device_item(device, 0, h8->h8TSTR);
state_save_register_device_item_array(device, 0, h8->h8TCNT); state_save_register_device_item_array(device, 0, h8->h8TCNT);
state_save_register_postload(h8->device->machine, h8_onstateload, h8); h8->device->machine->state().register_postload(h8_onstateload, h8);
} }
static CPU_RESET(h8bit) static CPU_RESET(h8bit)

View File

@ -541,7 +541,7 @@ static CPU_INIT( hd6309 )
state_save_register_device_item(device, 0, DP); state_save_register_device_item(device, 0, DP);
state_save_register_device_item(device, 0, CC); state_save_register_device_item(device, 0, CC);
state_save_register_device_item(device, 0, MD); state_save_register_device_item(device, 0, MD);
state_save_register_postload(device->machine, hd6309_postload, (void *) device); device->machine->state().register_postload(hd6309_postload, (void *) device);
state_save_register_device_item(device, 0, m68_state->int_state); state_save_register_device_item(device, 0, m68_state->int_state);
state_save_register_device_item(device, 0, m68_state->nmi_state); state_save_register_device_item(device, 0, m68_state->nmi_state);
state_save_register_device_item(device, 0, m68_state->irq_state[0]); state_save_register_device_item(device, 0, m68_state->irq_state[0]);

View File

@ -605,7 +605,7 @@ static CPU_INIT( i386 )
state_save_register_device_item(device, 0, cpustate->ldtr.flags); state_save_register_device_item(device, 0, cpustate->ldtr.flags);
state_save_register_device_item(device, 0, cpustate->irq_state); state_save_register_device_item(device, 0, cpustate->irq_state);
state_save_register_device_item(device, 0, cpustate->performed_intersegment_jump); state_save_register_device_item(device, 0, cpustate->performed_intersegment_jump);
state_save_register_postload(device->machine, i386_postload, (void *)device); device->machine->state().register_postload(i386_postload, (void *)device);
} }
static void build_opcode_table(i386_state *cpustate, UINT32 features) static void build_opcode_table(i386_state *cpustate, UINT32 features)

View File

@ -430,7 +430,7 @@ static void init_common(int isdsp, legacy_cpu_device *device, device_irq_callbac
state_save_register_device_item_array(device, 0, jaguar->a); state_save_register_device_item_array(device, 0, jaguar->a);
state_save_register_device_item_array(device, 0, jaguar->ctrl); state_save_register_device_item_array(device, 0, jaguar->ctrl);
state_save_register_device_item(device, 0, jaguar->ppc); state_save_register_device_item(device, 0, jaguar->ppc);
state_save_register_postload(device->machine, jaguar_postload, (void *)device); device->machine->state().register_postload(jaguar_postload, (void *)device);
} }

View File

@ -940,24 +940,16 @@ static CPU_INIT( m37710 )
state_save_register_device_item(device, 0, cpustate->irq_level); state_save_register_device_item(device, 0, cpustate->irq_level);
state_save_register_device_item(device, 0, cpustate->stopped); state_save_register_device_item(device, 0, cpustate->stopped);
state_save_register_device_item_array(device, 0, cpustate->m37710_regs); state_save_register_device_item_array(device, 0, cpustate->m37710_regs);
state_save_register_device_item(device, 0, cpustate->reload[0].seconds); state_save_register_device_item(device, 0, cpustate->reload[0]);
state_save_register_device_item(device, 0, cpustate->reload[0].attoseconds); state_save_register_device_item(device, 0, cpustate->reload[1]);
state_save_register_device_item(device, 0, cpustate->reload[1].seconds); state_save_register_device_item(device, 0, cpustate->reload[2]);
state_save_register_device_item(device, 0, cpustate->reload[1].attoseconds); state_save_register_device_item(device, 0, cpustate->reload[3]);
state_save_register_device_item(device, 0, cpustate->reload[2].seconds); state_save_register_device_item(device, 0, cpustate->reload[4]);
state_save_register_device_item(device, 0, cpustate->reload[2].attoseconds); state_save_register_device_item(device, 0, cpustate->reload[5]);
state_save_register_device_item(device, 0, cpustate->reload[3].seconds); state_save_register_device_item(device, 0, cpustate->reload[6]);
state_save_register_device_item(device, 0, cpustate->reload[3].attoseconds); state_save_register_device_item(device, 0, cpustate->reload[7]);
state_save_register_device_item(device, 0, cpustate->reload[4].seconds);
state_save_register_device_item(device, 0, cpustate->reload[4].attoseconds);
state_save_register_device_item(device, 0, cpustate->reload[5].seconds);
state_save_register_device_item(device, 0, cpustate->reload[5].attoseconds);
state_save_register_device_item(device, 0, cpustate->reload[6].seconds);
state_save_register_device_item(device, 0, cpustate->reload[6].attoseconds);
state_save_register_device_item(device, 0, cpustate->reload[7].seconds);
state_save_register_device_item(device, 0, cpustate->reload[7].attoseconds);
state_save_register_postload(device->machine, m37710_restore_state, cpustate); device->machine->state().register_postload(m37710_restore_state, cpustate);
} }
/************************************************************************** /**************************************************************************

View File

@ -769,8 +769,8 @@ static CPU_INIT( m68k )
state_save_register_device_item(device, 0, m68k->save_halted); state_save_register_device_item(device, 0, m68k->save_halted);
state_save_register_device_item(device, 0, m68k->pref_addr); state_save_register_device_item(device, 0, m68k->pref_addr);
state_save_register_device_item(device, 0, m68k->pref_data); state_save_register_device_item(device, 0, m68k->pref_data);
state_save_register_presave(device->machine, m68k_presave, m68k); device->machine->state().register_presave(m68k_presave, m68k);
state_save_register_postload(device->machine, m68k_postload, m68k); device->machine->state().register_postload(m68k_postload, m68k);
} }
/* Pulse the RESET line on the CPU */ /* Pulse the RESET line on the CPU */

View File

@ -1627,7 +1627,7 @@ static void mips_state_register( const char *type, legacy_cpu_device *device )
state_save_register_device_item( device, 0, psxcpu->multiplier_operation ); state_save_register_device_item( device, 0, psxcpu->multiplier_operation );
state_save_register_device_item( device, 0, psxcpu->multiplier_operand1 ); state_save_register_device_item( device, 0, psxcpu->multiplier_operand1 );
state_save_register_device_item( device, 0, psxcpu->multiplier_operand2 ); state_save_register_device_item( device, 0, psxcpu->multiplier_operand2 );
state_save_register_postload( device->machine, mips_postload, psxcpu ); device->machine->state().register_postload( mips_postload, psxcpu );
} }
static CPU_INIT( psxcpu ) static CPU_INIT( psxcpu )

View File

@ -669,7 +669,7 @@ static CPU_INIT( tms34010 )
state_save_register_device_item(device, 0, tms->pixelshift); state_save_register_device_item(device, 0, tms->pixelshift);
state_save_register_device_item(device, 0, tms->gfxcycles); state_save_register_device_item(device, 0, tms->gfxcycles);
state_save_register_device_item_pointer(device, 0, (&tms->regs[0].reg), ARRAY_LENGTH(tms->regs)); state_save_register_device_item_pointer(device, 0, (&tms->regs[0].reg), ARRAY_LENGTH(tms->regs));
state_save_register_postload(device->machine, tms34010_state_postload, tms); device->machine->state().register_postload(tms34010_state_postload, tms);
} }
static CPU_RESET( tms34010 ) static CPU_RESET( tms34010 )

View File

@ -244,7 +244,7 @@ void debug_command_init(running_machine *machine)
void *base; void *base;
/* stop when we run out of items */ /* stop when we run out of items */
name = state_save_get_indexed_item(machine, itemnum, &base, &valsize, &valcount); name = machine->state().indexed_item(itemnum, base, valsize, valcount);
if (name == NULL) if (name == NULL)
break; break;

View File

@ -177,7 +177,7 @@ void debug_view_memory::enumerate_sources()
// stop when we run out of items // stop when we run out of items
UINT32 valsize, valcount; UINT32 valsize, valcount;
void *base; void *base;
const char *itemname = state_save_get_indexed_item(&m_machine, itemnum, &base, &valsize, &valcount); const char *itemname = m_machine.state().indexed_item(itemnum, base, valsize, valcount);
if (itemname == NULL) if (itemname == NULL)
break; break;

View File

@ -134,8 +134,8 @@ void device_list::start_all()
m_machine->add_notifier(MACHINE_NOTIFY_EXIT, static_exit); m_machine->add_notifier(MACHINE_NOTIFY_EXIT, static_exit);
// add pre-save and post-load callbacks // add pre-save and post-load callbacks
state_save_register_presave(m_machine, static_pre_save, this); m_machine->state().register_presave(static_pre_save, this);
state_save_register_postload(m_machine, static_post_load, this); m_machine->state().register_postload(static_post_load, this);
// iterate over devices to start them // iterate over devices to start them
device_t *nextdevice; device_t *nextdevice;
@ -535,6 +535,7 @@ void device_interface::interface_debug_setup()
device_t::device_t(running_machine &_machine, const device_config &config) device_t::device_t(running_machine &_machine, const device_config &config)
: machine(&_machine), : machine(&_machine),
m_machine(_machine), m_machine(_machine),
m_state_manager(_machine.state()),
m_debug(NULL), m_debug(NULL),
m_execute(NULL), m_execute(NULL),
m_memory(NULL), m_memory(NULL),
@ -724,13 +725,13 @@ void device_t::start()
intf->interface_pre_start(); intf->interface_pre_start();
// remember the number of state registrations // remember the number of state registrations
int state_registrations = state_save_get_reg_count(machine); int state_registrations = machine->state().registration_count();
// start the device // start the device
device_start(); device_start();
// complain if nothing was registered by the device // complain if nothing was registered by the device
state_registrations = state_save_get_reg_count(machine) - state_registrations; state_registrations = machine->state().registration_count() - state_registrations;
device_execute_interface *exec; device_execute_interface *exec;
device_sound_interface *sound; device_sound_interface *sound;
if (state_registrations == 0 && (interface(exec) || interface(sound))) if (state_registrations == 0 && (interface(exec) || interface(sound)))

View File

@ -437,6 +437,12 @@ public:
void synchronize(device_timer_id id = 0, int param = 0, void *ptr = NULL) { timer_set(attotime::zero, id, param, ptr); } void synchronize(device_timer_id id = 0, int param = 0, void *ptr = NULL) { timer_set(attotime::zero, id, param, ptr); }
void timer_expired(emu_timer &timer, device_timer_id id, int param, void *ptr) { device_timer(timer, id, param, ptr); } void timer_expired(emu_timer &timer, device_timer_id id, int param, void *ptr) { device_timer(timer, id, param, ptr); }
// state saving interfaces
template<typename T>
void save_item(T &value, const char *valname, int index = 0) { m_state_manager.save_item(name(), tag(), index, value, valname); }
template<typename T>
void save_pointer(T *value, const char *valname, UINT32 count, int index = 0) { m_state_manager.save_pointer(name(), tag(), index, value, valname); }
// debugging // debugging
device_debug *debug() const { return m_debug; } device_debug *debug() const { return m_debug; }
@ -475,6 +481,7 @@ protected:
//------------------- end derived class overrides //------------------- end derived class overrides
running_machine & m_machine; running_machine & m_machine;
state_manager & m_state_manager;
device_debug * m_debug; device_debug * m_debug;
// for speed // for speed

View File

@ -569,8 +569,7 @@ void device_execute_interface::interface_pre_start()
state_save_register_device_item(&m_device, 0, m_nexteatcycles); state_save_register_device_item(&m_device, 0, m_nexteatcycles);
state_save_register_device_item(&m_device, 0, m_trigger); state_save_register_device_item(&m_device, 0, m_trigger);
state_save_register_device_item(&m_device, 0, m_totalcycles); state_save_register_device_item(&m_device, 0, m_totalcycles);
state_save_register_device_item(&m_device, 0, m_localtime.seconds); state_save_register_device_item(&m_device, 0, m_localtime);
state_save_register_device_item(&m_device, 0, m_localtime.attoseconds);
state_save_register_device_item(&m_device, 0, m_iloops); state_save_register_device_item(&m_device, 0, m_iloops);
} }

View File

@ -70,6 +70,10 @@
#include "memory.h" #include "memory.h"
#include "addrmap.h" #include "addrmap.h"
// machine-wide utilities
#include "romload.h"
#include "state.h"
// define machine_config_constructor here due to circular dependency // define machine_config_constructor here due to circular dependency
// between devices and the machine config // between devices and the machine config
class machine_config; class machine_config;
@ -103,10 +107,6 @@ typedef device_config * (*machine_config_constructor)(machine_config &config, de
#include "mconfig.h" #include "mconfig.h"
#include "driver.h" #include "driver.h"
// machine-wide utilities
#include "romload.h"
#include "state.h"
// image-related // image-related
#include "softlist.h" #include "softlist.h"
#include "image.h" #include "image.h"

View File

@ -198,6 +198,9 @@ inline void operator--(_Type &value) { value = (_Type)((int)value - 1); } \
inline void operator--(_Type &value, int) { value = (_Type)((int)value - 1); } inline void operator--(_Type &value, int) { value = (_Type)((int)value - 1); }
// this macro passes an item followed by a string version of itself as two consecutive parameters
#define NAME(x) x, #x
// this macro wraps a function 'x' and can be used to pass a function followed by its name // this macro wraps a function 'x' and can be used to pass a function followed by its name
#define FUNC(x) x, #x #define FUNC(x) x, #x

View File

@ -143,8 +143,8 @@ void palette_init(running_machine *machine)
palette->save_bright = auto_alloc_array(machine, float, numcolors); palette->save_bright = auto_alloc_array(machine, float, numcolors);
state_save_register_global_pointer(machine, palette->save_pen, numcolors); state_save_register_global_pointer(machine, palette->save_pen, numcolors);
state_save_register_global_pointer(machine, palette->save_bright, numcolors); state_save_register_global_pointer(machine, palette->save_bright, numcolors);
state_save_register_presave(machine, palette_presave, palette); machine->state().register_presave(palette_presave, palette);
state_save_register_postload(machine, palette_postload, palette); machine->state().register_postload(palette_postload, palette);
} }
} }

View File

@ -154,7 +154,6 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o
sample_rate(options_get_int(&options, OPTION_SAMPLERATE)), sample_rate(options_get_int(&options, OPTION_SAMPLERATE)),
debug_flags(0), debug_flags(0),
ui_active(false), ui_active(false),
state_data(NULL),
memory_data(NULL), memory_data(NULL),
palette_data(NULL), palette_data(NULL),
tilemap_data(NULL), tilemap_data(NULL),
@ -167,6 +166,7 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o
generic_video_data(NULL), generic_video_data(NULL),
generic_audio_data(NULL), generic_audio_data(NULL),
m_logerror_list(NULL), m_logerror_list(NULL),
m_state(*this),
m_scheduler(*this), m_scheduler(*this),
m_options(options), m_options(options),
m_osd(osd), m_osd(osd),
@ -264,15 +264,11 @@ void running_machine::start()
config_init(this); config_init(this);
input_init(this); input_init(this);
output_init(this); output_init(this);
state_init(this);
state_save_allow_registration(this, true);
palette_init(this); palette_init(this);
m_render = auto_alloc(this, render_manager(*this)); m_render = auto_alloc(this, render_manager(*this));
generic_machine_init(this); generic_machine_init(this);
generic_sound_init(this); generic_sound_init(this);
m_scheduler.register_for_save();
// allocate a soft_reset timer // allocate a soft_reset timer
m_soft_reset_timer = m_scheduler.timer_alloc(MSTUB(timer_expired, running_machine, soft_reset), this); m_soft_reset_timer = m_scheduler.timer_alloc(MSTUB(timer_expired, running_machine, soft_reset), this);
@ -344,7 +340,7 @@ void running_machine::start()
m_cheat = auto_alloc(this, cheat_manager(*this)); m_cheat = auto_alloc(this, cheat_manager(*this));
// disallow save state registrations starting here // disallow save state registrations starting here
state_save_allow_registration(this, false); m_state.allow_registration(false);
} }
@ -798,7 +794,7 @@ void running_machine::handle_saveload()
astring fullname(mame_file_full_name(file)); astring fullname(mame_file_full_name(file));
// read/write the save state // read/write the save state
state_save_error staterr = (m_saveload_schedule == SLS_LOAD) ? state_save_read_file(this, file) : state_save_write_file(this, file); state_save_error staterr = (m_saveload_schedule == SLS_LOAD) ? m_state.read_file(file) : m_state.write_file(file);
// handle the result // handle the result
switch (staterr) switch (staterr)

View File

@ -187,7 +187,6 @@ class video_manager;
class debug_view_manager; class debug_view_manager;
class osd_interface; class osd_interface;
typedef struct _state_private state_private;
typedef struct _memory_private memory_private; typedef struct _memory_private memory_private;
typedef struct _palette_private palette_private; typedef struct _palette_private palette_private;
typedef struct _tilemap_private tilemap_private; typedef struct _tilemap_private tilemap_private;
@ -356,6 +355,7 @@ public:
bool exit_pending() const { return m_exit_pending; } bool exit_pending() const { return m_exit_pending; }
bool new_driver_pending() const { return (m_new_driver_pending != NULL); } bool new_driver_pending() const { return (m_new_driver_pending != NULL); }
const char *new_driver_name() const { return m_new_driver_pending->name; } const char *new_driver_name() const { return m_new_driver_pending->name; }
state_manager &state() { return m_state; }
device_scheduler &scheduler() { return m_scheduler; } device_scheduler &scheduler() { return m_scheduler; }
osd_interface &osd() const { return m_osd; } osd_interface &osd() const { return m_osd; }
screen_device *first_screen() const { return primary_screen; } screen_device *first_screen() const { return primary_screen; }
@ -440,7 +440,6 @@ public:
generic_pointers generic; // generic pointers generic_pointers generic; // generic pointers
// internal core information // internal core information
state_private * state_data; // internal data from state.c
memory_private * memory_data; // internal data from memory.c memory_private * memory_data; // internal data from memory.c
palette_private * palette_data; // internal data from palette.c palette_private * palette_data; // internal data from palette.c
tilemap_private * tilemap_data; // internal data from tilemap.c tilemap_private * tilemap_data; // internal data from tilemap.c
@ -486,6 +485,7 @@ private:
}; };
logerror_callback_item *m_logerror_list; logerror_callback_item *m_logerror_list;
state_manager m_state; // state manager
device_scheduler m_scheduler; // scheduler object device_scheduler m_scheduler; // scheduler object
core_options & m_options; core_options & m_options;
osd_interface & m_osd; osd_interface & m_osd;

View File

@ -292,7 +292,7 @@ static DEVICE_START( pci_bus )
state_save_register_device_item(device, 0, pcibus->devicenum); state_save_register_device_item(device, 0, pcibus->devicenum);
state_save_register_device_item(device, 0, pcibus->busnum); state_save_register_device_item(device, 0, pcibus->busnum);
state_save_register_postload(device->machine, pci_bus_postload, pcibus); device->machine->state().register_postload(pci_bus_postload, pcibus);
} }

View File

@ -1105,8 +1105,7 @@ static void common_start( device_t *device, int device_type ) {
state_save_register_device_item(device, timerno, timer->null_count); state_save_register_device_item(device, timerno, timer->null_count);
state_save_register_device_item(device, timerno, timer->phase); state_save_register_device_item(device, timerno, timer->phase);
state_save_register_device_item(device, timerno, timer->cycles_to_output); state_save_register_device_item(device, timerno, timer->cycles_to_output);
state_save_register_device_item(device, timerno, timer->last_updated.seconds); state_save_register_device_item(device, timerno, timer->last_updated);
state_save_register_device_item(device, timerno, timer->last_updated.attoseconds);
state_save_register_device_item(device, timerno, timer->clock); state_save_register_device_item(device, timerno, timer->clock);
} }
} }

View File

@ -1590,7 +1590,7 @@ void memory_init(running_machine *machine)
space->locate_memory(); space->locate_memory();
// register a callback to reset banks when reloading state // register a callback to reset banks when reloading state
state_save_register_postload(machine, bank_reattach, NULL); machine->state().register_postload(bank_reattach, NULL);
// dump the final memory configuration // dump the final memory configuration
generate_memdump(machine); generate_memdump(machine);
@ -4092,7 +4092,7 @@ memory_block::memory_block(address_space &space, offs_t bytestart, offs_t byteen
int bytes_per_element = space.data_width() / 8; int bytes_per_element = space.data_width() / 8;
astring name; astring name;
name.printf("%08x-%08x", bytestart, byteend); name.printf("%08x-%08x", bytestart, byteend);
state_save_register_memory(&space.m_machine, "memory", space.device().tag(), space.spacenum(), name, m_data, bytes_per_element, (UINT32)(byteend + 1 - bytestart) / bytes_per_element, __FILE__, __LINE__); space.m_machine.state().save_memory("memory", space.device().tag(), space.spacenum(), name, m_data, bytes_per_element, (UINT32)(byteend + 1 - bytestart) / bytes_per_element);
} }
} }
@ -4142,7 +4142,7 @@ memory_bank::memory_bank(address_space &space, int index, offs_t bytestart, offs
m_name.printf("Bank '%s'", tag); m_name.printf("Bank '%s'", tag);
} }
if (!m_anonymous && state_save_registration_allowed(&space.m_machine)) if (!m_anonymous && space.m_machine.state().registration_allowed())
state_save_register_item(&space.m_machine, "memory", m_tag, 0, m_curentry); state_save_register_item(&space.m_machine, "memory", m_tag, 0, m_curentry);
} }

View File

@ -123,6 +123,8 @@ enum
TYPE DEFINITIONS TYPE DEFINITIONS
***************************************************************************/ ***************************************************************************/
class machine_config;
typedef device_config rom_source; typedef device_config rom_source;

View File

@ -283,12 +283,9 @@ void emu_timer::register_save()
// save the bits // save the bits
state_save_register_item(m_machine, "timer", name, index, m_param); state_save_register_item(m_machine, "timer", name, index, m_param);
state_save_register_item(m_machine, "timer", name, index, m_enabled); state_save_register_item(m_machine, "timer", name, index, m_enabled);
state_save_register_item(m_machine, "timer", name, index, m_period.seconds); state_save_register_item(m_machine, "timer", name, index, m_period);
state_save_register_item(m_machine, "timer", name, index, m_period.attoseconds); state_save_register_item(m_machine, "timer", name, index, m_start);
state_save_register_item(m_machine, "timer", name, index, m_start.seconds); state_save_register_item(m_machine, "timer", name, index, m_expire);
state_save_register_item(m_machine, "timer", name, index, m_start.attoseconds);
state_save_register_item(m_machine, "timer", name, index, m_expire.seconds);
state_save_register_item(m_machine, "timer", name, index, m_expire.attoseconds);
} }
@ -336,16 +333,10 @@ device_scheduler::device_scheduler(running_machine &machine) :
// append a single never-expiring timer so there is always one in the list // append a single never-expiring timer so there is always one in the list
m_timer_list = &m_timer_allocator.alloc()->init(m_machine, NULL, NULL, NULL, true); m_timer_list = &m_timer_allocator.alloc()->init(m_machine, NULL, NULL, NULL, true);
m_timer_list->adjust(attotime::never); m_timer_list->adjust(attotime::never);
}
// remove me once save state registration is embedded
void device_scheduler::register_for_save()
{
// register global states // register global states
state_save_register_item(&m_machine, "timer", NULL, 0, m_basetime.seconds); state_save_register_item(&m_machine, "timer", NULL, 0, m_basetime);
state_save_register_item(&m_machine, "timer", NULL, 0, m_basetime.attoseconds); m_machine.state().register_postload(&state_postload_stub<device_scheduler, &device_scheduler::postload>, this);
state_save_register_postload(&m_machine, &state_postload_stub<device_scheduler, &device_scheduler::postload>, this);
} }

View File

@ -155,7 +155,6 @@ public:
// construction/destruction // construction/destruction
device_scheduler(running_machine &machine); device_scheduler(running_machine &machine);
~device_scheduler(); ~device_scheduler();
void register_for_save();
// getters // getters
attotime time() const; attotime time() const;

View File

@ -379,22 +379,21 @@ void screen_device::device_start()
if (overname != NULL && strcmp(overname, "none") != 0) if (overname != NULL && strcmp(overname, "none") != 0)
load_effect_overlay(overname); load_effect_overlay(overname);
state_save_register_device_item(this, 0, m_width); // register items for saving
state_save_register_device_item(this, 0, m_height); save_item(NAME(m_width));
state_save_register_device_item(this, 0, m_visarea.min_x); save_item(NAME(m_height));
state_save_register_device_item(this, 0, m_visarea.min_y); save_item(NAME(m_visarea.min_x));
state_save_register_device_item(this, 0, m_visarea.max_x); save_item(NAME(m_visarea.min_y));
state_save_register_device_item(this, 0, m_visarea.max_y); save_item(NAME(m_visarea.max_x));
state_save_register_device_item(this, 0, m_last_partial_scan); save_item(NAME(m_visarea.max_y));
state_save_register_device_item(this, 0, m_frame_period); save_item(NAME(m_last_partial_scan));
state_save_register_device_item(this, 0, m_scantime); save_item(NAME(m_frame_period));
state_save_register_device_item(this, 0, m_pixeltime); save_item(NAME(m_scantime));
state_save_register_device_item(this, 0, m_vblank_period); save_item(NAME(m_pixeltime));
state_save_register_device_item(this, 0, m_vblank_start_time.seconds); save_item(NAME(m_vblank_period));
state_save_register_device_item(this, 0, m_vblank_start_time.attoseconds); save_item(NAME(m_vblank_start_time));
state_save_register_device_item(this, 0, m_vblank_end_time.seconds); save_item(NAME(m_vblank_end_time));
state_save_register_device_item(this, 0, m_vblank_end_time.attoseconds); save_item(NAME(m_frame_number));
state_save_register_device_item(this, 0, m_frame_number);
} }

View File

@ -112,7 +112,7 @@ sound_stream::sound_stream(device_t &device, int inputs, int outputs, int sample
astring state_tag; astring state_tag;
state_tag.printf("%d", m_device.machine->sound().m_stream_list.count()); state_tag.printf("%d", m_device.machine->sound().m_stream_list.count());
state_save_register_item(m_device.machine, "stream", state_tag, 0, m_sample_rate); state_save_register_item(m_device.machine, "stream", state_tag, 0, m_sample_rate);
state_save_register_postload(m_device.machine, state_postload_stub<sound_stream, &sound_stream::postload>, this); m_device.machine->state().register_postload(state_postload_stub<sound_stream, &sound_stream::postload>, this);
// save the gain of each input and output // save the gain of each input and output
for (int inputnum = 0; inputnum < m_inputs; inputnum++) for (int inputnum = 0; inputnum < m_inputs; inputnum++)
@ -806,8 +806,7 @@ sound_manager::sound_manager(running_machine &machine)
machine.add_notifier(MACHINE_NOTIFY_RESET, &sound_manager::reset); machine.add_notifier(MACHINE_NOTIFY_RESET, &sound_manager::reset);
// register global states // register global states
state_save_register_global(&machine, m_last_update.seconds); state_save_register_global(&machine, m_last_update);
state_save_register_global(&machine, m_last_update.attoseconds);
// set the starting attenuation // set the starting attenuation
set_attenuation(options_get_int(machine.options(), OPTION_VOLUME)); set_attenuation(options_get_int(machine.options(), OPTION_VOLUME));
@ -863,7 +862,7 @@ void sound_manager::set_attenuation(int attenuation)
bool sound_manager::indexed_speaker_input(int index, speaker_input &info) const bool sound_manager::indexed_speaker_input(int index, speaker_input &info) const
{ {
// scan through the speakers until we find the indexed input // scan through the speakers until we find the indexed input
for (info.speaker = downcast<speaker_device *>(m_machine.m_devicelist.first(SPEAKER)); info.speaker != NULL; info.speaker = downcast<speaker_device *>(info.speaker->typenext())) for (info.speaker = downcast<speaker_device *>(m_machine.m_devicelist.first(SPEAKER)); info.speaker != NULL; info.speaker = info.speaker->next_speaker())
{ {
if (index < info.speaker->inputs()) if (index < info.speaker->inputs())
{ {
@ -1004,7 +1003,7 @@ void sound_manager::update()
// force all the speaker streams to generate the proper number of samples // force all the speaker streams to generate the proper number of samples
int samples_this_update = 0; int samples_this_update = 0;
for (speaker_device *speaker = downcast<speaker_device *>(m_machine.m_devicelist.first(SPEAKER)); speaker != NULL; speaker = downcast<speaker_device *>(speaker->typenext())) for (speaker_device *speaker = downcast<speaker_device *>(m_machine.m_devicelist.first(SPEAKER)); speaker != NULL; speaker = speaker->next_speaker())
speaker->mix(m_leftmix, m_rightmix, samples_this_update, (m_muted & MUTE_REASON_SYSTEM)); speaker->mix(m_leftmix, m_rightmix, samples_this_update, (m_muted & MUTE_REASON_SYSTEM));
// now downmix the final result // now downmix the final result

View File

@ -61,7 +61,7 @@ static DEVICE_START( ym2151 )
info->chip = ym2151_init(device,device->clock(),rate); info->chip = ym2151_init(device,device->clock(),rate);
assert_always(info->chip != NULL, "Error creating YM2151 chip"); assert_always(info->chip != NULL, "Error creating YM2151 chip");
state_save_register_postload(device->machine, ym2151intf_postload, info); device->machine->state().register_postload(ym2151intf_postload, info);
ym2151_set_irq_handler(info->chip,info->intf->irqhandler); ym2151_set_irq_handler(info->chip,info->intf->irqhandler);
ym2151_set_port_write_handler(info->chip,info->intf->portwritehandler); ym2151_set_port_write_handler(info->chip,info->intf->portwritehandler);

View File

@ -144,7 +144,7 @@ static DEVICE_START( ym2203 )
info->chip = ym2203_init(info,device,device->clock(),rate,timer_handler,IRQHandler,&psgintf); info->chip = ym2203_init(info,device,device->clock(),rate,timer_handler,IRQHandler,&psgintf);
assert_always(info->chip != NULL, "Error creating YM2203 chip"); assert_always(info->chip != NULL, "Error creating YM2203 chip");
state_save_register_postload(device->machine, ym2203_intf_postload, info); device->machine->state().register_postload(ym2203_intf_postload, info);
} }
static DEVICE_STOP( ym2203 ) static DEVICE_STOP( ym2203 )

View File

@ -167,7 +167,7 @@ static DEVICE_START( ym2608 )
timer_handler,IRQHandler,&psgintf); timer_handler,IRQHandler,&psgintf);
assert_always(info->chip != NULL, "Error creating YM2608 chip"); assert_always(info->chip != NULL, "Error creating YM2608 chip");
state_save_register_postload(device->machine, ym2608_intf_postload, info); device->machine->state().register_postload(ym2608_intf_postload, info);
} }
static DEVICE_STOP( ym2608 ) static DEVICE_STOP( ym2608 )

View File

@ -179,7 +179,7 @@ static DEVICE_START( ym2610 )
timer_handler,IRQHandler,&psgintf); timer_handler,IRQHandler,&psgintf);
assert_always(info->chip != NULL, "Error creating YM2610 chip"); assert_always(info->chip != NULL, "Error creating YM2610 chip");
state_save_register_postload(device->machine, ym2610_intf_postload, info); device->machine->state().register_postload(ym2610_intf_postload, info);
} }
static DEVICE_STOP( ym2610 ) static DEVICE_STOP( ym2610 )

View File

@ -118,7 +118,7 @@ static DEVICE_START( ym2612 )
info->chip = ym2612_init(info,device,device->clock(),rate,timer_handler,IRQHandler); info->chip = ym2612_init(info,device,device->clock(),rate,timer_handler,IRQHandler);
assert_always(info->chip != NULL, "Error creating YM2612 chip"); assert_always(info->chip != NULL, "Error creating YM2612 chip");
state_save_register_postload(device->machine, ym2612_intf_postload, info); device->machine->state().register_postload(ym2612_intf_postload, info);
} }

View File

@ -1704,8 +1704,7 @@ static void FMsave_state_channel(device_t *device,FM_CH *CH,int num_ch)
static void FMsave_state_st(device_t *device,FM_ST *ST) static void FMsave_state_st(device_t *device,FM_ST *ST)
{ {
#if FM_BUSY_FLAG_SUPPORT #if FM_BUSY_FLAG_SUPPORT
state_save_register_device_item(device, 0, ST->busy_expiry_time.seconds ); state_save_register_device_item(device, 0, ST->busy_expiry_time );
state_save_register_device_item(device, 0, ST->busy_expiry_time.attoseconds );
#endif #endif
state_save_register_device_item(device, 0, ST->address ); state_save_register_device_item(device, 0, ST->address );
state_save_register_device_item(device, 0, ST->irq ); state_save_register_device_item(device, 0, ST->irq );

View File

@ -1707,8 +1707,7 @@ static void FMsave_state_channel(device_t *device,FM_CH *CH,int num_ch)
static void FMsave_state_st(device_t *device,FM_ST *ST) static void FMsave_state_st(device_t *device,FM_ST *ST)
{ {
#if FM_BUSY_FLAG_SUPPORT #if FM_BUSY_FLAG_SUPPORT
state_save_register_device_item(device, 0, ST->busy_expiry_time.seconds ); state_save_register_device_item(device, 0, ST->busy_expiry_time );
state_save_register_device_item(device, 0, ST->busy_expiry_time.attoseconds );
#endif #endif
state_save_register_device_item(device, 0, ST->address ); state_save_register_device_item(device, 0, ST->address );
state_save_register_device_item(device, 0, ST->irq ); state_save_register_device_item(device, 0, ST->irq );

View File

@ -1957,7 +1957,7 @@ static void OPL_save_state(FM_OPL *OPL, device_t *device)
state_save_register_device_item(device, 0, OPL->statusmask); state_save_register_device_item(device, 0, OPL->statusmask);
state_save_register_device_item(device, 0, OPL->mode); state_save_register_device_item(device, 0, OPL->mode);
state_save_register_postload(device->machine, OPL_postload, OPL); device->machine->state().register_postload(OPL_postload, OPL);
} }

View File

@ -674,7 +674,7 @@ static DEVICE_START( k054539 )
k054539_init_chip(device, info); k054539_init_chip(device, info);
state_save_register_postload(device->machine, reset_zones, info); device->machine->state().register_postload(reset_zones, info);
} }

View File

@ -799,7 +799,7 @@ static DEVICE_START( msm5232 )
chip->stream = device->machine->sound().stream_alloc(*device, 0, 11, rate, chip, MSM5232_update_one); chip->stream = device->machine->sound().stream_alloc(*device, 0, 11, rate, chip, MSM5232_update_one);
/* register with the save state system */ /* register with the save state system */
state_save_register_postload(device->machine, msm5232_postload, chip); device->machine->state().register_postload(msm5232_postload, chip);
state_save_register_device_item_array(device, 0, chip->EN_out16); state_save_register_device_item_array(device, 0, chip->EN_out16);
state_save_register_device_item_array(device, 0, chip->EN_out8); state_save_register_device_item_array(device, 0, chip->EN_out8);
state_save_register_device_item_array(device, 0, chip->EN_out4); state_save_register_device_item_array(device, 0, chip->EN_out4);

View File

@ -589,12 +589,9 @@ static void register_for_save(pokey_state *chip, device_t *device)
state_save_register_device_item(device, 0, chip->r9); state_save_register_device_item(device, 0, chip->r9);
state_save_register_device_item(device, 0, chip->r17); state_save_register_device_item(device, 0, chip->r17);
state_save_register_device_item(device, 0, chip->clockmult); state_save_register_device_item(device, 0, chip->clockmult);
state_save_register_device_item(device, 0, chip->timer_period[0].seconds); state_save_register_device_item(device, 0, chip->timer_period[0]);
state_save_register_device_item(device, 0, chip->timer_period[0].attoseconds); state_save_register_device_item(device, 0, chip->timer_period[1]);
state_save_register_device_item(device, 0, chip->timer_period[1].seconds); state_save_register_device_item(device, 0, chip->timer_period[2]);
state_save_register_device_item(device, 0, chip->timer_period[1].attoseconds);
state_save_register_device_item(device, 0, chip->timer_period[2].seconds);
state_save_register_device_item(device, 0, chip->timer_period[2].attoseconds);
state_save_register_device_item_array(device, 0, chip->timer_param); state_save_register_device_item_array(device, 0, chip->timer_param);
state_save_register_device_item_array(device, 0, chip->AUDF); state_save_register_device_item_array(device, 0, chip->AUDF);
state_save_register_device_item_array(device, 0, chip->AUDC); state_save_register_device_item_array(device, 0, chip->AUDC);

View File

@ -501,7 +501,7 @@ static DEVICE_START( samples )
state_save_register_device_item(device, i, info->channel[i].loop); state_save_register_device_item(device, i, info->channel[i].loop);
state_save_register_device_item(device, i, info->channel[i].paused); state_save_register_device_item(device, i, info->channel[i].paused);
} }
state_save_register_postload(device->machine, samples_postload, info); device->machine->state().register_postload(samples_postload, info);
/* initialize any custom handlers */ /* initialize any custom handlers */
if (intf->start) if (intf->start)

View File

@ -628,7 +628,7 @@ static void register_for_save(upd7759_state *chip, device_t *device)
state_save_register_device_item(device, 0, chip->sample); state_save_register_device_item(device, 0, chip->sample);
state_save_register_device_item(device, 0, chip->romoffset); state_save_register_device_item(device, 0, chip->romoffset);
state_save_register_postload(device->machine, upd7759_postload, chip); device->machine->state().register_postload(upd7759_postload, chip);
} }

View File

@ -726,7 +726,7 @@ static DEVICE_START( vlm5030 )
state_save_register_device_item(device,0,chip->target_pitch); state_save_register_device_item(device,0,chip->target_pitch);
state_save_register_device_item_array(device,0,chip->target_k); state_save_register_device_item_array(device,0,chip->target_k);
state_save_register_device_item_array(device,0,chip->x); state_save_register_device_item_array(device,0,chip->x);
state_save_register_postload(device->machine, vlm5030_restore_state, chip); device->machine->state().register_postload(vlm5030_restore_state, chip);
} }

View File

@ -1485,7 +1485,7 @@ static void ym2151_state_save_register( YM2151 *chip, device_t *device )
state_save_register_device_item_array(device, 0, chip->connect); state_save_register_device_item_array(device, 0, chip->connect);
state_save_register_postload(device->machine, ym2151_postload, chip); device->machine->state().register_postload(ym2151_postload, chip);
} }
#else #else
STATE_POSTLOAD( ym2151_postload ) STATE_POSTLOAD( ym2151_postload )

View File

@ -694,7 +694,7 @@ static DEVICE_START( ymz280b )
} }
} }
state_save_register_postload(device->machine, YMZ280B_state_save_update_step, chip); device->machine->state().register_postload(YMZ280B_state_save_update_step, chip);
#if MAKE_WAVS #if MAKE_WAVS
chip->wavresample = wav_open("resamp.wav", INTERNAL_SAMPLE_RATE, 2); chip->wavresample = wav_open("resamp.wav", INTERNAL_SAMPLE_RATE, 2);

View File

@ -85,6 +85,7 @@ public:
virtual device_t *alloc_device(running_machine &machine) const; virtual device_t *alloc_device(running_machine &machine) const;
// inline configuration helpers // inline configuration helpers
speaker_device_config *next_speaker() const { return downcast<speaker_device_config *>(typenext()); }
static void static_set_position(device_config *device, double x, double y, double z); static void static_set_position(device_config *device, double x, double y, double z);
protected: protected:
@ -109,6 +110,9 @@ class speaker_device : public device_t,
virtual ~speaker_device(); virtual ~speaker_device();
public: public:
// getters
speaker_device *next_speaker() const { return downcast<speaker_device *>(typenext()); }
// internally for use by the sound system // internally for use by the sound system
void mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress); void mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress);
@ -135,53 +139,4 @@ protected:
extern const device_type SPEAKER; extern const device_type SPEAKER;
//**************************************************************************
// INLINE HELPERS
//**************************************************************************
//-------------------------------------------------
// speaker_first - return the first speaker
// device config in a machine_config
//-------------------------------------------------
inline const speaker_device_config *speaker_first(const machine_config &config)
{
return downcast<speaker_device_config *>(config.m_devicelist.first(SPEAKER));
}
//-------------------------------------------------
// speaker_next - return the next speaker
// device config in a machine_config
//-------------------------------------------------
inline const speaker_device_config *speaker_next(const speaker_device_config *previous)
{
return downcast<speaker_device_config *>(previous->typenext());
}
//-------------------------------------------------
// speaker_first - return the first speaker
// device in a machine
//-------------------------------------------------
inline speaker_device *speaker_first(running_machine &machine)
{
return downcast<speaker_device *>(machine.m_devicelist.first(SPEAKER));
}
//-------------------------------------------------
// speaker_next - return the next speaker
// device in a machine
//-------------------------------------------------
inline speaker_device *speaker_next(speaker_device *previous)
{
return downcast<speaker_device *>(previous->typenext());
}
#endif /* __SOUND_H__ */ #endif /* __SOUND_H__ */

View File

@ -4,8 +4,36 @@
Save state management functions. Save state management functions.
Copyright Nicola Salmoria and the MAME Team. ****************************************************************************
Visit http://mamedev.org for licensing and usage restrictions.
Copyright Aaron Giles
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name 'MAME' nor the names of its contributors may be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
**************************************************************************** ****************************************************************************
@ -28,25 +56,24 @@
#include <zlib.h> #include <zlib.h>
//**************************************************************************
// DEBUGGING
//**************************************************************************
/*************************************************************************** #define VERBOSE 1
DEBUGGING
***************************************************************************/
#define VERBOSE 0
#define LOG(x) do { if (VERBOSE) logerror x; } while (0) #define LOG(x) do { if (VERBOSE) logerror x; } while (0)
/*************************************************************************** //**************************************************************************
CONSTANTS // CONSTANTS
***************************************************************************/ //**************************************************************************
#define SAVE_VERSION 2 const int SAVE_VERSION = 2;
#define HEADER_SIZE 32 const int HEADER_SIZE = 32;
/* Available flags */ // Available flags
enum enum
{ {
SS_MSB_FIRST = 0x02 SS_MSB_FIRST = 0x02
@ -54,394 +81,325 @@ enum
/*************************************************************************** //**************************************************************************
TYPE DEFINITIONS // GLOBAL VARIABLES
***************************************************************************/ //**************************************************************************
typedef struct _state_entry state_entry;
struct _state_entry
{
state_entry * next; /* pointer to next entry */
running_machine * machine; /* pointer back to the owning machine */
void * data; /* pointer to the memory to save/restore */
astring name; /* full name */
UINT8 typesize; /* size of the raw data type */
UINT32 typecount; /* number of items */
UINT32 offset; /* offset within the final structure */
};
typedef struct _state_callback state_callback;
struct _state_callback
{
state_callback * next; /* pointer to next entry */
running_machine * machine; /* pointer back to the owning machine */
void * param; /* function parameter */
union
{
state_presave_func presave; /* presave callback */
state_postload_func postload; /* postload callback */
} func; /* function pointers */
};
/* In mame.h: typedef struct _state_private state_private; */
struct _state_private
{
UINT8 reg_allowed; /* are registrations allowed? */
int illegal_regs; /* number of illegal registrations */
state_entry * entrylist; /* list of live entries */
state_callback * prefunclist; /* presave function list */
state_callback * postfunclist; /* postsave function list */
UINT8 * ioarray; /* array where we accumulate all the data */
UINT32 ioarraysize; /* size of the array */
mame_file * iofile; /* file currently in use */
};
/***************************************************************************
GLOBAL VARIABLES
***************************************************************************/
#ifdef MESS #ifdef MESS
static const char ss_magic_num[8] = { 'M', 'E', 'S', 'S', 'S', 'A', 'V', 'E' }; const char state_manager::s_magic_num[8] = { 'M', 'E', 'S', 'S', 'S', 'A', 'V', 'E' };
#else #else
static const char ss_magic_num[8] = { 'M', 'A', 'M', 'E', 'S', 'A', 'V', 'E' }; const char state_manager::s_magic_num[8] = { 'M', 'A', 'M', 'E', 'S', 'A', 'V', 'E' };
#endif #endif
/*************************************************************************** //**************************************************************************
INLINE FUNCTIONS // INITIALIZATION
***************************************************************************/ //**************************************************************************
/*------------------------------------------------- //-------------------------------------------------
flip_data - reverse the endianness of a // state_manager - constructor
block of data //-------------------------------------------------
-------------------------------------------------*/
INLINE void flip_data(state_entry *entry) state_manager::state_manager(running_machine &machine)
: m_machine(machine),
m_reg_allowed(true),
m_illegal_regs(0),
m_entry_list(machine.m_respool),
m_presave_list(machine.m_respool),
m_postload_list(machine.m_respool)
{ {
UINT16 *data16;
UINT32 *data32;
UINT64 *data64;
int count;
switch (entry->typesize)
{
case 2:
data16 = (UINT16 *)entry->data;
for (count = 0; count < entry->typecount; count++)
data16[count] = FLIPENDIAN_INT16(data16[count]);
break;
case 4:
data32 = (UINT32 *)entry->data;
for (count = 0; count < entry->typecount; count++)
data32[count] = FLIPENDIAN_INT32(data32[count]);
break;
case 8:
data64 = (UINT64 *)entry->data;
for (count = 0; count < entry->typecount; count++)
data64[count] = FLIPENDIAN_INT64(data64[count]);
break;
}
} }
//-------------------------------------------------
// allow_registration - allow/disallow
// registrations to happen
//-------------------------------------------------
/*************************************************************************** void state_manager::allow_registration(bool allowed)
INITIALIZATION
***************************************************************************/
/*-------------------------------------------------
state_init - initialize the system and reset
all registrations
-------------------------------------------------*/
enum test_enum_type { test_val };
class test_class_type { public: int dummy; };
void state_init(running_machine *machine)
{ {
bool test_bool = false; // allow/deny registration
INT8 test_INT8 = 0; m_reg_allowed = allowed;
UINT8 test_UINT8 = 0;
INT16 test_INT16 = 0;
UINT16 test_UINT16 = 0;
INT32 test_INT32 = 0;
UINT32 test_UINT32 = 0;
INT64 test_INT64 = 0;
UINT64 test_UINT64 = 0;
float test_float = 0.0f;
double test_double = 0.0;
test_enum_type test_enum = test_val;
#ifdef __GNUC__
test_class_type test_class;
#endif
assert_always(IS_VALID_SAVE_TYPE(test_bool), "bool is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_INT8), "INT8 is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_UINT8), "UINT8 is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_INT16), "INT16 is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_UINT16), "UINT16 is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_INT32), "INT32 is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_UINT32), "UINT32 is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_INT64), "INT64 is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_UINT64), "UINT64 is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_float), "float is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_double), "double is not a valid type for save");
assert_always(IS_VALID_SAVE_TYPE(test_enum), "enums are not a valid type for save");
#ifdef __GNUC__
assert_always(!IS_VALID_SAVE_TYPE(test_class), "classes are a valid type for save");
#endif
machine->state_data = auto_alloc_clear(machine, state_private);
}
/*-------------------------------------------------
state_save_get_reg_count - return the number
of total registrations so far
-------------------------------------------------*/
int state_save_get_reg_count(running_machine *machine)
{
state_private *global = machine->state_data;
state_entry *entry;
int count = 0;
/* count entries */
for (entry = global->entrylist; entry != NULL; entry = entry->next)
count++;
return count;
}
/***************************************************************************
REGISTRATION HANDLING
***************************************************************************/
/*-------------------------------------------------
state_save_allow_registration - allow/disallow
registrations to happen
-------------------------------------------------*/
void state_save_allow_registration(running_machine *machine, int allowed)
{
/* allow/deny registration */
machine->state_data->reg_allowed = allowed;
if (!allowed) if (!allowed)
state_save_dump_registry(machine); dump_registry();
} }
/*------------------------------------------------- //-------------------------------------------------
state_save_registration_allowed - query // indexed_item - return an item with the given
whether or not registrations are allowed // index
-------------------------------------------------*/ //-------------------------------------------------
int state_save_registration_allowed(running_machine *machine) const char *state_manager::indexed_item(int index, void *&base, UINT32 &valsize, UINT32 &valcount) const
{ {
return machine->state_data->reg_allowed; state_entry *entry = m_entry_list.find(index);
if (entry == NULL)
return NULL;
base = entry->m_data;
valsize = entry->m_typesize;
valcount = entry->m_typecount;
return entry->m_name;
} }
/*------------------------------------------------- //-------------------------------------------------
state_save_register_memory - register an // register_presave - register a pre-save
array of data in memory // function callback
-------------------------------------------------*/ //-------------------------------------------------
void state_save_register_memory(running_machine *machine, const char *module, const char *tag, UINT32 index, const char *name, void *val, UINT32 valsize, UINT32 valcount, const char *file, int line) void state_manager::register_presave(prepost_func func, void *param)
{ {
state_private *global = machine->state_data; // check for invalid timing
state_entry **entryptr, *next; if (!m_reg_allowed)
astring totalname; fatalerror("Attempt to register callback function after state registration is closed!");
// scan for duplicates and push through to the end
for (state_callback *cb = m_presave_list.first(); cb != NULL; cb = cb->next())
if (cb->m_func == func && cb->m_param == param)
fatalerror("Duplicate save state function (%p, %p)", param, func);
// allocate a new entry
m_presave_list.append(*auto_alloc(&m_machine, state_callback(func, param)));
}
//-------------------------------------------------
// state_save_register_postload -
// register a post-load function callback
//-------------------------------------------------
void state_manager::register_postload(prepost_func func, void *param)
{
// check for invalid timing
if (!m_reg_allowed)
fatalerror("Attempt to register callback function after state registration is closed!");
// scan for duplicates and push through to the end
for (state_callback *cb = m_postload_list.first(); cb != NULL; cb = cb->next())
if (cb->m_func == func && cb->m_param == param)
fatalerror("Duplicate save state function (%p, %p)", param, func);
// allocate a new entry
m_postload_list.append(*auto_alloc(&m_machine, state_callback(func, param)));
}
//-------------------------------------------------
// save_memory - register an array of data in
// memory
//-------------------------------------------------
void state_manager::save_memory(const char *module, const char *tag, UINT32 index, const char *name, void *val, UINT32 valsize, UINT32 valcount)
{
assert(valsize == 1 || valsize == 2 || valsize == 4 || valsize == 8); assert(valsize == 1 || valsize == 2 || valsize == 4 || valsize == 8);
/* check for invalid timing */ // check for invalid timing
if (!global->reg_allowed) if (!m_reg_allowed)
{ {
logerror("Attempt to register save state entry after state registration is closed!\nFile: %s, line %d, module %s tag %s name %s\n", file, line, module, tag, name); logerror("Attempt to register save state entry after state registration is closed!\nModule %s tag %s name %s\n", module, tag, name);
if (machine->gamedrv->flags & GAME_SUPPORTS_SAVE) if (m_machine.gamedrv->flags & GAME_SUPPORTS_SAVE)
fatalerror("Attempt to register save state entry after state registration is closed!\nFile: %s, line %d, module %s tag %s name %s\n", file, line, module, tag, name); fatalerror("Attempt to register save state entry after state registration is closed!\nModule %s tag %s name %s\n", module, tag, name);
global->illegal_regs++; m_illegal_regs++;
return; return;
} }
/* create the full name */ // create the full name
astring totalname;
if (tag != NULL) if (tag != NULL)
totalname.printf("%s/%s/%X/%s", module, tag, index, name); totalname.printf("%s/%s/%X/%s", module, tag, index, name);
else else
totalname.printf("%s/%X/%s", module, index, name); totalname.printf("%s/%X/%s", module, index, name);
/* look for duplicates and an entry to insert in front of */ // look for duplicates and an entry to insert in front of
for (entryptr = &global->entrylist; *entryptr != NULL; entryptr = &(*entryptr)->next) state_entry *insert_after = NULL;
for (state_entry *entry = m_entry_list.first(); entry != NULL; entry = entry->next())
{ {
/* stop if the next guy's string is greater than ours */ // stop when we find an entry whose name is after ours
int cmpval = (*entryptr)->name.cmp(totalname); if (entry->m_name > totalname)
if (cmpval > 0)
break; break;
insert_after = entry;
/* error if we are equal */ // error if we are equal
if (cmpval == 0) if (entry->m_name == totalname)
fatalerror("Duplicate save state registration entry (%s)", totalname.cstr()); fatalerror("Duplicate save state registration entry (%s)", totalname.cstr());
} }
/* didn't find one; allocate a new one */ // insert us into the list
next = *entryptr; m_entry_list.insert_after(*auto_alloc(&m_machine, state_entry(val, totalname, valsize, valcount)), insert_after);
*entryptr = auto_alloc_clear(machine, state_entry);
/* fill in the rest */
(*entryptr)->next = next;
(*entryptr)->machine = machine;
(*entryptr)->data = val;
(*entryptr)->name = totalname;
(*entryptr)->typesize = valsize;
(*entryptr)->typecount = valcount;
} }
/*------------------------------------------------- //-------------------------------------------------
state_save_register_bitmap - register a // check_file - check if a file is a valid save
bitmap to be saved // state
-------------------------------------------------*/ //-------------------------------------------------
void state_save_register_bitmap(running_machine *machine, const char *module, const char *tag, UINT32 index, const char *name, bitmap_t *val, const char *file, int line) state_save_error state_manager::check_file(running_machine *machine, mame_file *file, const char *gamename, void (CLIB_DECL *errormsg)(const char *fmt, ...))
{ {
state_save_register_memory(machine, module, tag, index, name, val->base, val->bpp / 8, val->rowpixels * val->height, file, line); // if we want to validate the signature, compute it
} UINT32 sig = 0;
if (machine != NULL)
sig = machine->state().signature();
// seek to the beginning and read the header
mame_fcompress(file, FCOMPRESS_NONE);
/*************************************************************************** mame_fseek(file, 0, SEEK_SET);
CALLBACK FUNCTION REGISTRATION UINT8 header[HEADER_SIZE];
***************************************************************************/ if (mame_fread(file, header, sizeof(header)) != sizeof(header))
/*-------------------------------------------------
state_save_register_presave -
register a pre-save function callback
-------------------------------------------------*/
void state_save_register_presave(running_machine *machine, state_presave_func func, void *param)
{
state_private *global = machine->state_data;
state_callback **cbptr;
/* check for invalid timing */
if (!global->reg_allowed)
fatalerror("Attempt to register callback function after state registration is closed!");
/* scan for duplicates and push through to the end */
for (cbptr = &global->prefunclist; *cbptr != NULL; cbptr = &(*cbptr)->next)
if ((*cbptr)->func.presave == func && (*cbptr)->param == param)
fatalerror("Duplicate save state function (%p, %p)", param, func);
/* allocate a new entry */
*cbptr = auto_alloc(machine, state_callback);
/* fill it in */
(*cbptr)->next = NULL;
(*cbptr)->machine = machine;
(*cbptr)->func.presave = func;
(*cbptr)->param = param;
}
/*-------------------------------------------------
state_save_register_postload -
register a post-load function callback
-------------------------------------------------*/
void state_save_register_postload(running_machine *machine, state_postload_func func, void *param)
{
state_private *global = machine->state_data;
state_callback **cbptr;
/* check for invalid timing */
if (!global->reg_allowed)
fatalerror("Attempt to register callback function after state registration is closed!");
/* scan for duplicates and push through to the end */
for (cbptr = &global->postfunclist; *cbptr != NULL; cbptr = &(*cbptr)->next)
if ((*cbptr)->func.postload == func && (*cbptr)->param == param)
fatalerror("Duplicate save state function (%p, %p)", param, func);
/* allocate a new entry */
*cbptr = auto_alloc(machine, state_callback);
/* fill it in */
(*cbptr)->next = NULL;
(*cbptr)->machine = machine;
(*cbptr)->func.postload = func;
(*cbptr)->param = param;
}
/***************************************************************************
PROCESSING HELPERS
***************************************************************************/
/*-------------------------------------------------
get_signature - compute the signature, which
is a CRC over the structure of the data
-------------------------------------------------*/
static UINT32 get_signature(running_machine *machine)
{
state_private *global = machine->state_data;
state_entry *entry;
UINT32 crc = 0;
/* iterate over entries */
for (entry = global->entrylist; entry != NULL; entry = entry->next)
{ {
UINT32 temp[2]; if (errormsg != NULL)
(*errormsg)("Could not read " APPNAME " save file header");
/* add the entry name to the CRC */ return STATERR_READ_ERROR;
crc = crc32(crc, (UINT8 *)entry->name.cstr(), entry->name.len());
/* add the type and size to the CRC */
temp[0] = LITTLE_ENDIANIZE_INT32(entry->typecount);
temp[1] = LITTLE_ENDIANIZE_INT32(entry->typesize);
crc = crc32(crc, (UINT8 *)&temp[0], sizeof(temp));
} }
// let the generic header check work out the rest
return validate_header(header, gamename, sig, errormsg, "");
}
//-------------------------------------------------
// read_file - read the data from a file
//-------------------------------------------------
state_save_error state_manager::read_file(mame_file *file)
{
// if we have illegal registrations, return an error
if (m_illegal_regs > 0)
return STATERR_ILLEGAL_REGISTRATIONS;
// read the header and turn on compression for the rest of the file
mame_fcompress(file, FCOMPRESS_NONE);
mame_fseek(file, 0, SEEK_SET);
UINT8 header[HEADER_SIZE];
if (mame_fread(file, header, sizeof(header)) != sizeof(header))
return STATERR_READ_ERROR;
mame_fcompress(file, FCOMPRESS_MEDIUM);
// verify the header and report an error if it doesn't match
UINT32 sig = signature();
if (validate_header(header, m_machine.gamedrv->name, sig, popmessage, "Error: ") != STATERR_NONE)
return STATERR_INVALID_HEADER;
// determine whether or not to flip the data when done
bool flip = NATIVE_ENDIAN_VALUE_LE_BE((header[9] & SS_MSB_FIRST) != 0, (header[9] & SS_MSB_FIRST) == 0);
// read all the data, flipping if necessary
for (state_entry *entry = m_entry_list.first(); entry != NULL; entry = entry->next())
{
UINT32 totalsize = entry->m_typesize * entry->m_typecount;
if (mame_fread(file, entry->m_data, totalsize) != totalsize)
return STATERR_READ_ERROR;
// handle flipping
if (flip)
entry->flip_data();
}
// call the post-load functions
for (state_callback *func = m_postload_list.first(); func != NULL; func = func->next())
(*func->m_func)(&m_machine, func->m_param);
return STATERR_NONE;
}
//-------------------------------------------------
// write_file - writes the data to a file
//-------------------------------------------------
state_save_error state_manager::write_file(mame_file *file)
{
// if we have illegal registrations, return an error
if (m_illegal_regs > 0)
return STATERR_ILLEGAL_REGISTRATIONS;
// generate the header
UINT8 header[HEADER_SIZE];
memcpy(&header[0], s_magic_num, 8);
header[8] = SAVE_VERSION;
header[9] = NATIVE_ENDIAN_VALUE_LE_BE(0, SS_MSB_FIRST);
strncpy((char *)&header[0x0a], m_machine.gamedrv->name, 0x1c - 0x0a);
UINT32 sig = signature();
*(UINT32 *)&header[0x1c] = LITTLE_ENDIANIZE_INT32(sig);
// write the header and turn on compression for the rest of the file
mame_fcompress(file, FCOMPRESS_NONE);
mame_fseek(file, 0, SEEK_SET);
if (mame_fwrite(file, header, sizeof(header)) != sizeof(header))
return STATERR_WRITE_ERROR;
mame_fcompress(file, FCOMPRESS_MEDIUM);
// call the pre-save functions
for (state_callback *func = m_presave_list.first(); func != NULL; func = func->next())
(*func->m_func)(&m_machine, func->m_param);
// then write all the data
for (state_entry *entry = m_entry_list.first(); entry != NULL; entry = entry->next())
{
UINT32 totalsize = entry->m_typesize * entry->m_typecount;
if (mame_fwrite(file, entry->m_data, totalsize) != totalsize)
return STATERR_WRITE_ERROR;
}
return STATERR_NONE;
}
//-------------------------------------------------
// signature - compute the signature, which
// is a CRC over the structure of the data
//-------------------------------------------------
UINT32 state_manager::signature() const
{
// iterate over entries
UINT32 crc = 0;
for (state_entry *entry = m_entry_list.first(); entry != NULL; entry = entry->next())
{
// add the entry name to the CRC
crc = crc32(crc, (UINT8 *)entry->m_name.cstr(), entry->m_name.len());
// add the type and size to the CRC
UINT32 temp[2];
temp[0] = LITTLE_ENDIANIZE_INT32(entry->m_typecount);
temp[1] = LITTLE_ENDIANIZE_INT32(entry->m_typesize);
crc = crc32(crc, (UINT8 *)&temp[0], sizeof(temp));
}
return crc; return crc;
} }
//-------------------------------------------------
// dump_registry - dump the registry to the
// logfile
//-------------------------------------------------
/*************************************************************************** void state_manager::dump_registry() const
SAVE STATE FILE PROCESSING {
***************************************************************************/ for (state_entry *entry = m_entry_list.first(); entry != NULL; entry = entry->next())
LOG(("%s: %d x %d\n", entry->m_name.cstr(), entry->m_typesize, entry->m_typecount));
}
/*-------------------------------------------------
validate_header - validate the data in the
header
-------------------------------------------------*/
static state_save_error validate_header(const UINT8 *header, const char *gamename, UINT32 signature, //-------------------------------------------------
// validate_header - validate the data in the
// header
//-------------------------------------------------
state_save_error state_manager::validate_header(const UINT8 *header, const char *gamename, UINT32 signature,
void (CLIB_DECL *errormsg)(const char *fmt, ...), const char *error_prefix) void (CLIB_DECL *errormsg)(const char *fmt, ...), const char *error_prefix)
{ {
/* check magic number */ // check magic number
if (memcmp(header, ss_magic_num, 8)) if (memcmp(header, s_magic_num, 8))
{ {
if (errormsg != NULL) if (errormsg != NULL)
(*errormsg)("%sThis is not a " APPNAME " save file", error_prefix); (*errormsg)("%sThis is not a " APPNAME " save file", error_prefix);
return STATERR_INVALID_HEADER; return STATERR_INVALID_HEADER;
} }
/* check save state version */ // check save state version
if (header[8] != SAVE_VERSION) if (header[8] != SAVE_VERSION)
{ {
if (errormsg != NULL) if (errormsg != NULL)
@ -449,7 +407,7 @@ static state_save_error validate_header(const UINT8 *header, const char *gamenam
return STATERR_INVALID_HEADER; return STATERR_INVALID_HEADER;
} }
/* check gamename, if we were asked to */ // check gamename, if we were asked to
if (gamename != NULL && strncmp(gamename, (const char *)&header[0x0a], 0x1c - 0x0a)) if (gamename != NULL && strncmp(gamename, (const char *)&header[0x0a], 0x1c - 0x0a))
{ {
if (errormsg != NULL) if (errormsg != NULL)
@ -457,7 +415,7 @@ static state_save_error validate_header(const UINT8 *header, const char *gamenam
return STATERR_INVALID_HEADER; return STATERR_INVALID_HEADER;
} }
/* check signature, if we were asked to */ // check signature, if we were asked to
if (signature != 0) if (signature != 0)
{ {
UINT32 rawsig = *(UINT32 *)&header[0x1c]; UINT32 rawsig = *(UINT32 *)&header[0x1c];
@ -472,175 +430,63 @@ static state_save_error validate_header(const UINT8 *header, const char *gamenam
} }
/*------------------------------------------------- //-------------------------------------------------
state_save_check_file - check if a file is // state_callback - constructor
a valid save state //-------------------------------------------------
-------------------------------------------------*/
state_save_error state_save_check_file(running_machine *machine, mame_file *file, const char *gamename, void (CLIB_DECL *errormsg)(const char *fmt, ...)) state_manager::state_callback::state_callback(prepost_func callback, void *param)
: m_next(NULL),
m_param(param),
m_func(callback)
{ {
UINT8 header[HEADER_SIZE]; }
UINT32 signature = 0;
/* if we want to validate the signature, compute it */
if (machine != NULL)
signature = get_signature(machine);
/* seek to the beginning and read the header */ //-------------------------------------------------
mame_fcompress(file, FCOMPRESS_NONE); // state_entry - constructor
mame_fseek(file, 0, SEEK_SET); //-------------------------------------------------
if (mame_fread(file, header, sizeof(header)) != sizeof(header))
state_manager::state_entry::state_entry(void *data, const char *name, UINT8 size, UINT32 count)
: m_next(NULL),
m_data(data),
m_name(name),
m_typesize(size),
m_typecount(count),
m_offset(0)
{
}
//-------------------------------------------------
// flip_data - reverse the endianness of a
// block of data
//-------------------------------------------------
void state_manager::state_entry::flip_data()
{
UINT16 *data16;
UINT32 *data32;
UINT64 *data64;
int count;
switch (m_typesize)
{ {
if (errormsg != NULL) case 2:
(*errormsg)("Could not read " APPNAME " save file header"); data16 = (UINT16 *)m_data;
return STATERR_READ_ERROR; for (count = 0; count < m_typecount; count++)
data16[count] = FLIPENDIAN_INT16(data16[count]);
break;
case 4:
data32 = (UINT32 *)m_data;
for (count = 0; count < m_typecount; count++)
data32[count] = FLIPENDIAN_INT32(data32[count]);
break;
case 8:
data64 = (UINT64 *)m_data;
for (count = 0; count < m_typecount; count++)
data64[count] = FLIPENDIAN_INT64(data64[count]);
break;
} }
/* let the generic header check work out the rest */
return validate_header(header, gamename, signature, errormsg, "");
} }
/*-------------------------------------------------
state_save_write_file - writes the data to
a file
-------------------------------------------------*/
state_save_error state_save_write_file(running_machine *machine, mame_file *file)
{
state_private *global = machine->state_data;
UINT32 signature = get_signature(machine);
UINT8 header[HEADER_SIZE];
state_callback *func;
state_entry *entry;
/* if we have illegal registrations, return an error */
if (global->illegal_regs > 0)
return STATERR_ILLEGAL_REGISTRATIONS;
/* generate the header */
memcpy(&header[0], ss_magic_num, 8);
header[8] = SAVE_VERSION;
header[9] = NATIVE_ENDIAN_VALUE_LE_BE(0, SS_MSB_FIRST);
strncpy((char *)&header[0x0a], machine->gamedrv->name, 0x1c - 0x0a);
*(UINT32 *)&header[0x1c] = LITTLE_ENDIANIZE_INT32(signature);
/* write the header and turn on compression for the rest of the file */
mame_fcompress(file, FCOMPRESS_NONE);
mame_fseek(file, 0, SEEK_SET);
if (mame_fwrite(file, header, sizeof(header)) != sizeof(header))
return STATERR_WRITE_ERROR;
mame_fcompress(file, FCOMPRESS_MEDIUM);
/* call the pre-save functions */
for (func = global->prefunclist; func != NULL; func = func->next)
(*func->func.presave)(machine, func->param);
/* then write all the data */
for (entry = global->entrylist; entry != NULL; entry = entry->next)
{
UINT32 totalsize = entry->typesize * entry->typecount;
if (mame_fwrite(file, entry->data, totalsize) != totalsize)
return STATERR_WRITE_ERROR;
}
return STATERR_NONE;
}
/*-------------------------------------------------
state_save_read_file - read the data from a
file
-------------------------------------------------*/
state_save_error state_save_read_file(running_machine *machine, mame_file *file)
{
state_private *global = machine->state_data;
UINT32 signature = get_signature(machine);
UINT8 header[HEADER_SIZE];
state_callback *func;
state_entry *entry;
int flip;
/* if we have illegal registrations, return an error */
if (global->illegal_regs > 0)
return STATERR_ILLEGAL_REGISTRATIONS;
/* read the header and turn on compression for the rest of the file */
mame_fcompress(file, FCOMPRESS_NONE);
mame_fseek(file, 0, SEEK_SET);
if (mame_fread(file, header, sizeof(header)) != sizeof(header))
return STATERR_READ_ERROR;
mame_fcompress(file, FCOMPRESS_MEDIUM);
/* verify the header and report an error if it doesn't match */
if (validate_header(header, machine->gamedrv->name, signature, popmessage, "Error: ") != STATERR_NONE)
return STATERR_INVALID_HEADER;
/* determine whether or not to flip the data when done */
flip = NATIVE_ENDIAN_VALUE_LE_BE((header[9] & SS_MSB_FIRST) != 0, (header[9] & SS_MSB_FIRST) == 0);
/* read all the data, flipping if necessary */
for (entry = global->entrylist; entry != NULL; entry = entry->next)
{
UINT32 totalsize = entry->typesize * entry->typecount;
if (mame_fread(file, entry->data, totalsize) != totalsize)
return STATERR_READ_ERROR;
/* handle flipping */
if (flip)
flip_data(entry);
}
/* call the post-load functions */
for (func = global->postfunclist; func != NULL; func = func->next)
(*func->func.postload)(machine, func->param);
return STATERR_NONE;
}
/***************************************************************************
DEBUGGING
***************************************************************************/
/*-------------------------------------------------
state_save_get_indexed_item - return an item
with the given index
-------------------------------------------------*/
const char *state_save_get_indexed_item(running_machine *machine, int index, void **base, UINT32 *valsize, UINT32 *valcount)
{
state_private *global = machine->state_data;
state_entry *ss;
for (ss = global->entrylist; ss != NULL; ss = ss->next)
if (index-- == 0)
{
if (base != NULL)
*base = ss->data;
if (valsize != NULL)
*valsize = ss->typesize;
if (valcount != NULL)
*valcount = ss->typecount;
return ss->name;
}
return NULL;
}
/*-------------------------------------------------
state_save_dump_registry - dump the registry
to the logfile
-------------------------------------------------*/
void state_save_dump_registry(running_machine *machine)
{
state_private *global = machine->state_data;
state_entry *entry;
for (entry = global->entrylist; entry; entry=entry->next)
LOG(("%s: %d x %d\n", entry->name.cstr(), entry->typesize, entry->typecount));
}

View File

@ -4,8 +4,36 @@
Save state management functions. Save state management functions.
Copyright Nicola Salmoria and the MAME Team. ****************************************************************************
Visit http://mamedev.org for licensing and usage restrictions.
Copyright Aaron Giles
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name 'MAME' nor the names of its contributors may be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/ ***************************************************************************/
@ -18,25 +46,13 @@
#ifndef __STATE_H__ #ifndef __STATE_H__
#define __STATE_H__ #define __STATE_H__
#ifdef __GNUC__
#include <tr1/type_traits>
#endif
/*************************************************************************** //**************************************************************************
TYPE DEFINTIONS // CONSTANTS
***************************************************************************/ //**************************************************************************
typedef void (*state_presave_func)(running_machine *machine, void *param); enum state_save_error
typedef void (*state_postload_func)(running_machine *machine, void *param);
/***************************************************************************
CONSTANTS
***************************************************************************/
enum _state_save_error
{ {
STATERR_NONE, STATERR_NONE,
STATERR_ILLEGAL_REGISTRATIONS, STATERR_ILLEGAL_REGISTRATIONS,
@ -44,13 +60,12 @@ enum _state_save_error
STATERR_READ_ERROR, STATERR_READ_ERROR,
STATERR_WRITE_ERROR STATERR_WRITE_ERROR
}; };
typedef enum _state_save_error state_save_error;
/*************************************************************************** //**************************************************************************
MACROS // MACROS
***************************************************************************/ //**************************************************************************
#define STATE_PRESAVE(name) void name(running_machine *machine, void *param) #define STATE_PRESAVE(name) void name(running_machine *machine, void *param)
#define STATE_POSTLOAD(name) void name(running_machine *machine, void *param) #define STATE_POSTLOAD(name) void name(running_machine *machine, void *param)
@ -71,139 +86,235 @@ void state_postload_stub(running_machine *machine, void *param)
} }
#ifdef __GNUC__ // register items with explicit tags
#define IS_VALID_SAVE_TYPE(_var) \
(std::tr1::is_arithmetic<typeof(_var)>::value || std::tr1::is_enum<typeof(_var)>::value || \
std::tr1::is_same<typeof(_var), PAIR>::value || std::tr1::is_same<typeof(_var), PAIR64>::value)
#else
#define IS_VALID_SAVE_TYPE(_var) \
(sizeof(_var) == 1 || sizeof(_var) == 2 || sizeof(_var) == 4 || sizeof(_var) == 8)
#endif
/* generic registration; all further registrations are based on this */
#define state_save_register_generic(_mach, _mod, _tag, _index, _name, _val, _valsize, _count) \
do { \
assert_always(IS_VALID_SAVE_TYPE(_valsize), "Invalid data type supplied for state saving."); \
state_save_register_memory(_mach, _mod, _tag, _index, _name, _val, sizeof(_valsize), _count, __FILE__, __LINE__); \
} while (0)
/* register items with explicit tags */
#define state_save_register_item(_mach, _mod, _tag, _index, _val) \ #define state_save_register_item(_mach, _mod, _tag, _index, _val) \
state_save_register_generic(_mach, _mod, _tag, _index, #_val, &_val, _val, 1) (_mach)->state().save_item(_mod, _tag, _index, _val, #_val)
#define state_save_register_item_pointer(_mach, _mod, _tag, _index, _val, _count) \ #define state_save_register_item_pointer(_mach, _mod, _tag, _index, _val, _count) \
state_save_register_generic(_mach, _mod, _tag, _index, #_val, &_val[0], _val[0], _count) (_mach)->state().save_pointer(_mod, _tag, _index, _val, #_val, _count)
#define state_save_register_item_array(_mach, _mod, _tag, _index, _val) \ #define state_save_register_item_array(_mach, _mod, _tag, _index, _val) \
state_save_register_item_pointer(_mach, _mod, _tag, _index, _val, sizeof(_val)/sizeof(_val[0])) (_mach)->state().save_item(_mod, _tag, _index, _val, #_val)
#define state_save_register_item_2d_array(_mach, _mod, _tag, _index, _val) \ #define state_save_register_item_2d_array(_mach, _mod, _tag, _index, _val) \
state_save_register_item_pointer(_mach, _mod, _tag, _index, _val[0], sizeof(_val)/sizeof(_val[0][0])) (_mach)->state().save_item(_mod, _tag, _index, _val, #_val)
#define state_save_register_item_bitmap(_mach, _mod, _tag, _index, _val) \ #define state_save_register_item_bitmap(_mach, _mod, _tag, _index, _val) \
state_save_register_bitmap(_mach, _mod, _tag, _index, #_val, _val, __FILE__, __LINE__) (_mach)->state().save_item(_mod, _tag, _index, *(_val), #_val)
/* register device items */ // register device items
#define state_save_register_device_item(_dev, _index, _val) \ #define state_save_register_device_item(_dev, _index, _val) \
state_save_register_generic((_dev)->machine, (_dev)->name(), (_dev)->tag(), _index, #_val, &_val, _val, 1) (_dev)->machine->state().save_item((_dev)->name(), (_dev)->tag(), _index, _val, #_val)
#define state_save_register_device_item_pointer(_dev, _index, _val, _count) \ #define state_save_register_device_item_pointer(_dev, _index, _val, _count) \
state_save_register_generic((_dev)->machine, (_dev)->name(), (_dev)->tag(), _index, #_val, &_val[0], _val[0], _count) (_dev)->machine->state().save_pointer((_dev)->name(), (_dev)->tag(), _index, _val, #_val, _count)
#define state_save_register_device_item_array(_dev, _index, _val) \ #define state_save_register_device_item_array(_dev, _index, _val) \
state_save_register_item_pointer((_dev)->machine, (_dev)->name(), (_dev)->tag(), _index, _val, sizeof(_val)/sizeof(_val[0])) (_dev)->machine->state().save_item((_dev)->name(), (_dev)->tag(), _index, _val, #_val)
#define state_save_register_device_item_2d_array(_dev, _index, _val) \ #define state_save_register_device_item_2d_array(_dev, _index, _val) \
state_save_register_item_pointer((_dev)->machine, (_dev)->name(), (_dev)->tag(), _index, _val[0], sizeof(_val)/sizeof(_val[0][0])) (_dev)->machine->state().save_item((_dev)->name(), (_dev)->tag(), _index, _val, #_val)
#define state_save_register_device_item_bitmap(_dev, _index, _val) \ #define state_save_register_device_item_bitmap(_dev, _index, _val) \
state_save_register_bitmap((_dev)->machine, (_dev)->name(), (_dev)->tag(), _index, #_val, _val, __FILE__, __LINE__) (_dev)->machine->state().save_item((_dev)->name(), (_dev)->tag(), _index, *(_val), #_val)
/* register global items */ // register global items
#define state_save_register_global(_mach, _val) \ #define state_save_register_global(_mach, _val) \
state_save_register_item(_mach, "globals", NULL, 0, _val) (_mach)->state().save_item(_val, #_val)
#define state_save_register_global_pointer(_mach, _val, _count) \ #define state_save_register_global_pointer(_mach, _val, _count) \
state_save_register_item_pointer(_mach, "globals", NULL, 0, _val, _count) (_mach)->state().save_pointer(_val, #_val, _count)
#define state_save_register_global_array(_mach, _val) \ #define state_save_register_global_array(_mach, _val) \
state_save_register_item_array(_mach, "globals", NULL, 0, _val) (_mach)->state().save_item(_val, #_val)
#define state_save_register_global_2d_array(_mach, _val) \ #define state_save_register_global_2d_array(_mach, _val) \
state_save_register_item_2d_array(_mach, "globals", NULL, 0, _val) (_mach)->state().save_item(_val, #_val)
#define state_save_register_global_bitmap(_mach, _val) \ #define state_save_register_global_bitmap(_mach, _val) \
state_save_register_bitmap(_mach, "globals", NULL, 0, #_val, _val, __FILE__, __LINE__) (_mach)->state().save_item(*(_val), #_val)
/*************************************************************************** //**************************************************************************
FUNCTION PROTOTYPES // TYPE DEFINITIONS
***************************************************************************/ //**************************************************************************
class state_manager
{
// type_checker is a set of templates to identify valid save types
template<typename T> struct type_checker { static const bool is_atom = false; static const bool is_pointer = false; };
template<typename T> struct type_checker<T*> { static const bool is_atom = false; static const bool is_pointer = true; };
public:
typedef void (*prepost_func)(running_machine *machine, void *param);
// construction/destruction
state_manager(running_machine &machine);
// getters
int registration_count() const { return m_entry_list.count(); }
bool registration_allowed() const { return m_reg_allowed; }
// registration control
void allow_registration(bool allowed = true);
const char *indexed_item(int index, void *&base, UINT32 &valsize, UINT32 &valcount) const;
// function registration
void register_presave(prepost_func func, void *param);
void register_postload(prepost_func func, void *param);
// generic memory registration
void save_memory(const char *module, const char *tag, UINT32 index, const char *name, void *val, UINT32 valsize, UINT32 valcount = 1);
// templatized wrapper for general objects
template<typename T>
void save_item(const char *module, const char *tag, int index, T &value, const char *valname)
{
if (type_checker<T>::is_pointer) throw emu_fatalerror("Called save_item on a pointer with no count!");
if (!type_checker<T>::is_atom) throw emu_fatalerror("Called save_item on a non-fundamental type!");
save_memory(module, tag, index, valname, &value, sizeof(value));
}
// templatized wrapper for 1-dimensional arrays
template<typename T, std::size_t N>
void save_item(const char *module, const char *tag, int index, T (&value)[N], const char *valname)
{
if (!type_checker<T>::is_atom) throw emu_fatalerror("Called save_item on a non-fundamental type!");
save_memory(module, tag, index, valname, &value[0], sizeof(value[0]), N);
}
// templatized wrapper for 2-dimensional arrays
template<typename T, std::size_t M, std::size_t N>
void save_item(const char *module, const char *tag, int index, T (&value)[M][N], const char *valname)
{
if (!type_checker<T>::is_atom) throw emu_fatalerror("Called save_item on a non-fundamental type!");
save_memory(module, tag, index, valname, &value[0][0], sizeof(value[0][0]), M * N);
}
// templatized wrapper for pointers
template<typename T>
void save_pointer(const char *module, const char *tag, int index, T *value, const char *valname, UINT32 count)
{
if (!type_checker<T>::is_atom) throw emu_fatalerror("Called save_item on a non-fundamental type!");
save_memory(module, tag, index, valname, value, sizeof(*value), count);
}
// global memory registration
template<typename T>
void save_item(T &value, const char *valname, int index = 0) { save_item("global", NULL, index, value, valname); }
template<typename T>
void save_pointer(T *value, const char *valname, UINT32 count, int index = 0) { save_pointer("global", NULL, index, value, valname, count); }
// file processing
static state_save_error check_file(running_machine *machine, mame_file *file, const char *gamename, void (CLIB_DECL *errormsg)(const char *fmt, ...));
state_save_error write_file(mame_file *file);
state_save_error read_file(mame_file *file);
private:
// internal helpers
UINT32 signature() const;
void dump_registry() const;
static state_save_error validate_header(const UINT8 *header, const char *gamename, UINT32 signature, void (CLIB_DECL *errormsg)(const char *fmt, ...), const char *error_prefix);
// state callback item
class state_callback
{
public:
// construction/destruction
state_callback(prepost_func callback, void *param);
// getters
state_callback *next() const { return m_next; }
// state
state_callback * m_next; // pointer to next entry
void * m_param; // function parameter
prepost_func m_func; // pointer to the function
};
class state_entry
{
public:
// construction/destruction
state_entry(void *data, const char *name, UINT8 size, UINT32 count);
// getters
state_entry *next() const { return m_next; }
// helpers
void flip_data();
// state
state_entry * m_next; // pointer to next entry
void * m_data; // pointer to the memory to save/restore
astring m_name; // full name
UINT8 m_typesize; // size of the raw data type
UINT32 m_typecount; // number of items
UINT32 m_offset; // offset within the final structure
};
// internal state
running_machine & m_machine; // reference to our machine
bool m_reg_allowed; // are registrations allowed?
int m_illegal_regs; // number of illegal registrations
simple_list<state_entry> m_entry_list; // list of reigstered entries
simple_list<state_callback> m_presave_list; // list of pre-save functions
simple_list<state_callback> m_postload_list; // list of post-load functions
static const char s_magic_num[8]; // magic number for header
};
/* ----- core system operations ----- */ // template specializations to enumerate the fundamental atomic types you are allowed to save
template<> struct state_manager::type_checker<bool> { static const bool is_atom = true; static const bool is_pointer = false; };
/* initialize the system and reset all registrations */ template<> struct state_manager::type_checker<INT8> { static const bool is_atom = true; static const bool is_pointer = false; };
void state_init(running_machine *machine); template<> struct state_manager::type_checker<UINT8> { static const bool is_atom = true; static const bool is_pointer = false; };
template<> struct state_manager::type_checker<INT16> { static const bool is_atom = true; static const bool is_pointer = false; };
/* return the number of total registrations so far */ template<> struct state_manager::type_checker<UINT16> { static const bool is_atom = true; static const bool is_pointer = false; };
int state_save_get_reg_count(running_machine *machine); template<> struct state_manager::type_checker<INT32> { static const bool is_atom = true; static const bool is_pointer = false; };
template<> struct state_manager::type_checker<UINT32> { static const bool is_atom = true; static const bool is_pointer = false; };
template<> struct state_manager::type_checker<INT64> { static const bool is_atom = true; static const bool is_pointer = false; };
template<> struct state_manager::type_checker<UINT64> { static const bool is_atom = true; static const bool is_pointer = false; };
template<> struct state_manager::type_checker<PAIR> { static const bool is_atom = true; static const bool is_pointer = false; };
template<> struct state_manager::type_checker<PAIR64> { static const bool is_atom = true; static const bool is_pointer = false; };
template<> struct state_manager::type_checker<float> { static const bool is_atom = true; static const bool is_pointer = false; };
template<> struct state_manager::type_checker<double> { static const bool is_atom = true; static const bool is_pointer = false; };
/* ----- registration handling ----- */ //**************************************************************************
// INLINE FUNCTIONS
//**************************************************************************
/* allow/disallow registrations to happen (called by the core) */ //-------------------------------------------------
void state_save_allow_registration(running_machine *machine, int allowed); // save_item - specialized save_item for bitmaps
//-------------------------------------------------
/* query whether or not registrations are allowed */ template<>
int state_save_registration_allowed(running_machine *machine); inline void state_manager::save_item(const char *module, const char *tag, int index, bitmap_t &value, const char *name)
{
/* register an array of data in memory */ save_memory(module, tag, index, name, value.base, value.bpp / 8, value.rowpixels * value.height);
void state_save_register_memory(running_machine *machine, const char *module, const char *tag, UINT32 index, const char *name, void *val, UINT32 valsize, UINT32 valcount, const char *file, int line); }
/* register a bitmap to be saved */
void state_save_register_bitmap(running_machine *machine, const char *module, const char *tag, UINT32 index, const char *name, bitmap_t *val, const char *file, int line);
//-------------------------------------------------
// save_item - specialized save_item for attotimes
//-------------------------------------------------
/* ----- callback function registraton ----- */ template<>
inline void state_manager::save_item(const char *module, const char *tag, int index, attotime &value, const char *name)
/* register a pre-save function callback */ {
void state_save_register_presave(running_machine *machine, state_presave_func func, void *param); astring tempstr(name, ".attoseconds");
save_memory(module, tag, index, tempstr, &value.attoseconds, sizeof(value.attoseconds));
/* register a post-load function callback */ tempstr.cpy(name).cat(".seconds");
void state_save_register_postload(running_machine *machine, state_postload_func func, void *param); save_memory(module, tag, index, tempstr, &value.seconds, sizeof(value.seconds));
}
/* ----- save state file processing ----- */
/* check if a file is a valid save state */
state_save_error state_save_check_file(running_machine *machine, mame_file *file, const char *gamename, void (CLIB_DECL *errormsg)(const char *fmt, ...));
/* write out the save state file */
state_save_error state_save_write_file(running_machine *machine, mame_file *file);
/* read in a save state file */
state_save_error state_save_read_file(running_machine *machine, mame_file *file);
/* ----- debugging ----- */
/* return an item with the given index */
const char *state_save_get_indexed_item(running_machine *machine, int index, void **base, UINT32 *valsize, UINT32 *valcount);
/* dump the registry to the logfile */
void state_save_dump_registry(running_machine *machine);
#endif /* __STATE_H__ */ #endif /* __STATE_H__ */

View File

@ -411,7 +411,7 @@ static tilemap_t *tilemap_create_common(running_machine *machine, void *get_info
machine->tilemap_data->instance++; machine->tilemap_data->instance++;
/* reset everything after a load */ /* reset everything after a load */
state_save_register_postload(machine, tilemap_postload, tmap); machine->state().register_postload(tilemap_postload, tmap);
return tmap; return tmap;
} }

View File

@ -286,7 +286,7 @@ void timer_device::device_start()
m_timer = timer_alloc(); m_timer = timer_alloc();
// register for save states // register for save states
state_save_register_device_item(this, 0, m_first_time); save_item(NAME(m_first_time));
} }

View File

@ -136,7 +136,7 @@ video_manager::video_manager(running_machine &machine)
{ {
// request a callback upon exiting // request a callback upon exiting
machine.add_notifier(MACHINE_NOTIFY_EXIT, exit_static); machine.add_notifier(MACHINE_NOTIFY_EXIT, exit_static);
state_save_register_postload(&machine, state_postload_stub<video_manager, &video_manager::postload>, this); machine.state().register_postload(state_postload_stub<video_manager, &video_manager::postload>, this);
// extract initial execution state from global configuration settings // extract initial execution state from global configuration settings
update_refresh_speed(); update_refresh_speed();

View File

@ -909,7 +909,7 @@ static void common_start(device_t *device, int device_type)
mc6845->vert_char_total = 0x7f; mc6845->vert_char_total = 0x7f;
/* register for state saving */ /* register for state saving */
state_save_register_postload(device->machine, mc6845_state_save_postload, mc6845); device->machine->state().register_postload(mc6845_state_save_postload, mc6845);
state_save_register_device_item(device, 0, mc6845->clock); state_save_register_device_item(device, 0, mc6845->clock);
state_save_register_device_item(device, 0, mc6845->hpixels_per_column); state_save_register_device_item(device, 0, mc6845->hpixels_per_column);

View File

@ -53,7 +53,7 @@ void pc_video_start(running_machine *machine,
video_start_generic_bitmapped(machine); video_start_generic_bitmapped(machine);
} }
state_save_register_postload(machine, pc_video_postload, NULL); machine->state().register_postload(pc_video_postload, NULL);
} }

View File

@ -347,7 +347,7 @@ poly_manager *poly_alloc(running_machine *machine, int max_polys, size_t extra_d
poly->queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ); poly->queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ);
/* request a pre-save callback for synchronization */ /* request a pre-save callback for synchronization */
state_save_register_presave(machine, poly_state_presave, poly); machine->state().register_presave(poly_state_presave, poly);
return poly; return poly;
} }

View File

@ -283,7 +283,7 @@ static DEVICE_START( tms9927 )
} }
/* register for state saving */ /* register for state saving */
state_save_register_postload(device->machine, tms9927_state_save_postload, tms); device->machine->state().register_postload(tms9927_state_save_postload, tms);
state_save_register_device_item(device, 0, tms->clock); state_save_register_device_item(device, 0, tms->clock);
state_save_register_device_item_array(device, 0, tms->reg); state_save_register_device_item_array(device, 0, tms->reg);

View File

@ -656,7 +656,7 @@ static void init_save_state(device_t *device)
voodoo_state *v = get_safe_token(device); voodoo_state *v = get_safe_token(device);
int index, subindex; int index, subindex;
state_save_register_postload(device->machine, voodoo_postload, v); device->machine->state().register_postload(voodoo_postload, v);
/* register states: core */ /* register states: core */
state_save_register_device_item(device, 0, v->extra_cycles); state_save_register_device_item(device, 0, v->extra_cycles);
@ -669,8 +669,7 @@ static void init_save_state(device_t *device)
state_save_register_device_item(device, 0, v->pci.init_enable); state_save_register_device_item(device, 0, v->pci.init_enable);
state_save_register_device_item(device, 0, v->pci.stall_state); state_save_register_device_item(device, 0, v->pci.stall_state);
state_save_register_device_item(device, 0, v->pci.op_pending); state_save_register_device_item(device, 0, v->pci.op_pending);
state_save_register_device_item(device, 0, v->pci.op_end_time.seconds); state_save_register_device_item(device, 0, v->pci.op_end_time);
state_save_register_device_item(device, 0, v->pci.op_end_time.attoseconds);
state_save_register_device_item_array(device, 0, v->pci.fifo_mem); state_save_register_device_item_array(device, 0, v->pci.fifo_mem);
/* register states: dac */ /* register states: dac */

View File

@ -924,7 +924,7 @@ MACHINE_START( schaser_sh )
state_save_register_global(machine, state->schaser_effect_555_is_low); state_save_register_global(machine, state->schaser_effect_555_is_low);
state_save_register_global(machine, state->schaser_effect_555_time_remain_savable); state_save_register_global(machine, state->schaser_effect_555_time_remain_savable);
state_save_register_global(machine, state->port_2_last_extra); state_save_register_global(machine, state->port_2_last_extra);
state_save_register_postload(machine, schaser_reinit_555_time_remain, NULL); machine->state().register_postload(schaser_reinit_555_time_remain, NULL);
} }

View File

@ -183,8 +183,7 @@ void cage_init(running_machine *machine, offs_t speedup)
state_save_register_global(machine, cpu_to_cage_ready); state_save_register_global(machine, cpu_to_cage_ready);
state_save_register_global(machine, cage_to_cpu_ready); state_save_register_global(machine, cage_to_cpu_ready);
state_save_register_global(machine, serial_period_per_word.seconds); state_save_register_global(machine, serial_period_per_word);
state_save_register_global(machine, serial_period_per_word.attoseconds);
state_save_register_global(machine, dma_enabled); state_save_register_global(machine, dma_enabled);
state_save_register_global(machine, dma_timer_enabled); state_save_register_global(machine, dma_timer_enabled);
state_save_register_global_array(machine, cage_timer_enabled); state_save_register_global_array(machine, cage_timer_enabled);

View File

@ -929,7 +929,7 @@ static void dcs_register_state(running_machine *machine)
state_save_register_global_pointer(machine, dcs_sram, 0x8000*4 / sizeof(dcs_sram[0])); state_save_register_global_pointer(machine, dcs_sram, 0x8000*4 / sizeof(dcs_sram[0]));
if (dcs.rev == 2) if (dcs.rev == 2)
state_save_register_postload(machine, sdrc_postload, NULL); machine->state().register_postload(sdrc_postload, NULL);
} }
void dcs_init(running_machine *machine) void dcs_init(running_machine *machine)

View File

@ -338,7 +338,7 @@ static MACHINE_START( 20pacgal )
state_save_register_global(machine, state->game_selected); state_save_register_global(machine, state->game_selected);
state_save_register_global_pointer(machine, state->ram_48000, 0x2000); state_save_register_global_pointer(machine, state->ram_48000, 0x2000);
state_save_register_postload(machine, postload_20pacgal, NULL); machine->state().register_postload(postload_20pacgal, NULL);
} }
static MACHINE_RESET( 20pacgal ) static MACHINE_RESET( 20pacgal )

View File

@ -329,7 +329,7 @@ static MACHINE_START( ace )
{ {
ace_state *state = machine->driver_data<ace_state>(); ace_state *state = machine->driver_data<ace_state>();
state_save_register_global_array(machine, state->objpos); state_save_register_global_array(machine, state->objpos);
state_save_register_postload(machine, ace_postload, NULL); machine->state().register_postload(ace_postload, NULL);
} }
static MACHINE_RESET( ace ) static MACHINE_RESET( ace )

View File

@ -1765,7 +1765,7 @@ static DRIVER_INIT( profpac )
/* reset banking */ /* reset banking */
profpac_banksw_w(iospace, 0, 0); profpac_banksw_w(iospace, 0, 0);
state_save_register_postload(machine, profbank_banksw_restore, NULL); machine->state().register_postload(profbank_banksw_restore, NULL);
} }
@ -1781,7 +1781,7 @@ static DRIVER_INIT( demndrgn )
/* reset banking */ /* reset banking */
profpac_banksw_w(iospace, 0, 0); profpac_banksw_w(iospace, 0, 0);
state_save_register_postload(machine, profbank_banksw_restore, NULL); machine->state().register_postload(profbank_banksw_restore, NULL);
} }
@ -1802,7 +1802,7 @@ static DRIVER_INIT( tenpindx )
/* reset banking */ /* reset banking */
profpac_banksw_w(iospace, 0, 0); profpac_banksw_w(iospace, 0, 0);
state_save_register_postload(machine, profbank_banksw_restore, NULL); machine->state().register_postload(profbank_banksw_restore, NULL);
} }

View File

@ -1176,7 +1176,7 @@ static void init_g1_common(running_machine *machine, offs_t slapstic_base, int s
pitfightb_cheap_slapstic_init(machine); pitfightb_cheap_slapstic_init(machine);
state_save_register_global(machine, state->bslapstic_bank); state_save_register_global(machine, state->bslapstic_bank);
state_save_register_global(machine, state->bslapstic_primed); state_save_register_global(machine, state->bslapstic_primed);
state_save_register_postload(machine, pitfightb_state_postload, NULL); machine->state().register_postload(pitfightb_state_postload, NULL);
} }
else if (slapstic != 0) else if (slapstic != 0)
atarigen_slapstic_init(machine->device("maincpu"), slapstic_base, 0, slapstic); atarigen_slapstic_init(machine->device("maincpu"), slapstic_base, 0, slapstic);

View File

@ -230,7 +230,7 @@ static MACHINE_START( atarisy2 )
state_save_register_global(machine, state->which_adc); state_save_register_global(machine, state->which_adc);
state_save_register_global(machine, state->p2portwr_state); state_save_register_global(machine, state->p2portwr_state);
state_save_register_global(machine, state->p2portrd_state); state_save_register_global(machine, state->p2portrd_state);
state_save_register_postload(machine, bankselect_postload, NULL); machine->state().register_postload(bankselect_postload, NULL);
state_save_register_global(machine, state->sound_reset_state); state_save_register_global(machine, state->sound_reset_state);
} }

View File

@ -119,7 +119,7 @@ static MACHINE_START( atetris )
/* Set up save state */ /* Set up save state */
state_save_register_global(machine, state->current_bank); state_save_register_global(machine, state->current_bank);
state_save_register_global(machine, state->nvram_write_enable); state_save_register_global(machine, state->nvram_write_enable);
state_save_register_postload(machine, atetris_postload, NULL); machine->state().register_postload(atetris_postload, NULL);
} }

View File

@ -585,7 +585,7 @@ static MACHINE_START( crystal )
state_save_register_global(machine, state->PIO); state_save_register_global(machine, state->PIO);
state_save_register_global_array(machine, state->DMActrl); state_save_register_global_array(machine, state->DMActrl);
state_save_register_global(machine, state->OldPort4); state_save_register_global(machine, state->OldPort4);
state_save_register_postload(machine, crystal_banksw_postload, NULL); machine->state().register_postload(crystal_banksw_postload, NULL);
} }
static MACHINE_RESET( crystal ) static MACHINE_RESET( crystal )

View File

@ -899,7 +899,7 @@ static MACHINE_START( darius )
state_save_register_global(machine, state->nmi_enable); state_save_register_global(machine, state->nmi_enable);
state_save_register_global_array(machine, state->vol); state_save_register_global_array(machine, state->vol);
state_save_register_global_array(machine, state->pan); state_save_register_global_array(machine, state->pan);
state_save_register_postload(machine, darius_postload, NULL); machine->state().register_postload(darius_postload, NULL);
} }

View File

@ -1442,7 +1442,7 @@ static MACHINE_START( djmain )
state_save_register_global(machine, v_ctrl); state_save_register_global(machine, v_ctrl);
state_save_register_global_array(machine, obj_regs); state_save_register_global_array(machine, obj_regs);
state_save_register_postload(machine, djmain_postload, NULL); machine->state().register_postload(djmain_postload, NULL);
} }

View File

@ -4933,7 +4933,7 @@ static MACHINE_START( tenkai )
{ {
MACHINE_START_CALL(dynax); MACHINE_START_CALL(dynax);
state_save_register_postload(machine, tenkai_bank_postload, NULL); machine->state().register_postload(tenkai_bank_postload, NULL);
} }
static MACHINE_CONFIG_START( tenkai, dynax_state ) static MACHINE_CONFIG_START( tenkai, dynax_state )
@ -4996,7 +4996,7 @@ static MACHINE_START( gekisha )
{ {
MACHINE_START_CALL(dynax); MACHINE_START_CALL(dynax);
state_save_register_postload(machine, gekisha_bank_postload, NULL); machine->state().register_postload(gekisha_bank_postload, NULL);
} }
static MACHINE_RESET( gekisha ) static MACHINE_RESET( gekisha )

View File

@ -107,7 +107,7 @@ static MACHINE_START( forte2 )
/* register for save states */ /* register for save states */
state_save_register_global(machine, forte2_input_mask); state_save_register_global(machine, forte2_input_mask);
state_save_register_postload(machine, forte2, NULL); machine->state().register_postload(forte2, NULL);
} }
static MACHINE_RESET( forte2 ) static MACHINE_RESET( forte2 )

View File

@ -294,10 +294,8 @@ static MACHINE_START( gottlieb )
state_save_register_global_pointer(machine, laserdisc_audio_buffer, AUDIORAM_SIZE); state_save_register_global_pointer(machine, laserdisc_audio_buffer, AUDIORAM_SIZE);
state_save_register_global(machine, laserdisc_audio_address); state_save_register_global(machine, laserdisc_audio_address);
state_save_register_global_array(machine, laserdisc_last_samples); state_save_register_global_array(machine, laserdisc_last_samples);
state_save_register_global(machine, laserdisc_last_time.seconds); state_save_register_global(machine, laserdisc_last_time);
state_save_register_global(machine, laserdisc_last_time.attoseconds); state_save_register_global(machine, laserdisc_last_clock);
state_save_register_global(machine, laserdisc_last_clock.seconds);
state_save_register_global(machine, laserdisc_last_clock.attoseconds);
state_save_register_global(machine, laserdisc_zero_seen); state_save_register_global(machine, laserdisc_zero_seen);
state_save_register_global(machine, laserdisc_audio_bits); state_save_register_global(machine, laserdisc_audio_bits);
state_save_register_global(machine, laserdisc_audio_bit_count); state_save_register_global(machine, laserdisc_audio_bit_count);

View File

@ -146,9 +146,9 @@ void liberatr_state::machine_start()
{ {
atarigen_state::machine_start(); atarigen_state::machine_start();
state_save_register_device_item(this, 0, m_trackball_offset); save_item(NAME(m_trackball_offset));
state_save_register_device_item(this, 0, m_ctrld); save_item(NAME(m_ctrld));
state_save_register_device_item_array(this, 0, m_videoram); save_item(NAME(m_videoram));
} }

View File

@ -1148,7 +1148,7 @@ static DRIVER_INIT( quizf1 )
set_m90_bank(machine); set_m90_bank(machine);
state_save_register_global(machine, bankaddress); state_save_register_global(machine, bankaddress);
state_save_register_postload(machine, quizf1_postload, NULL); machine->state().register_postload(quizf1_postload, NULL);
} }

View File

@ -233,7 +233,7 @@ static MACHINE_START( m92 )
state_save_register_global(machine, state->irqvector); state_save_register_global(machine, state->irqvector);
state_save_register_global(machine, state->sound_status); state_save_register_global(machine, state->sound_status);
state_save_register_global(machine, state->bankaddress); state_save_register_global(machine, state->bankaddress);
state_save_register_postload(machine, m92_postload, NULL); machine->state().register_postload(m92_postload, NULL);
state->scanline_timer = machine->scheduler().timer_alloc(FUNC(m92_scanline_interrupt)); state->scanline_timer = machine->scheduler().timer_alloc(FUNC(m92_scanline_interrupt));
} }

View File

@ -467,7 +467,7 @@ static MACHINE_START( mjsister )
state_save_register_global(machine, state->dac_bank); state_save_register_global(machine, state->dac_bank);
state_save_register_global(machine, state->dac_adr_s); state_save_register_global(machine, state->dac_adr_s);
state_save_register_global(machine, state->dac_adr_e); state_save_register_global(machine, state->dac_adr_e);
state_save_register_postload(machine, mjsister_redraw, 0); machine->state().register_postload(mjsister_redraw, 0);
} }
static MACHINE_RESET( mjsister ) static MACHINE_RESET( mjsister )

View File

@ -900,7 +900,7 @@ static MACHINE_START( maze )
/* setup for save states */ /* setup for save states */
state_save_register_global(machine, state->maze_tone_timing_state); state_save_register_global(machine, state->maze_tone_timing_state);
state_save_register_postload(machine, maze_update_discrete, NULL); machine->state().register_postload(maze_update_discrete, NULL);
MACHINE_START_CALL(mw8080bw); MACHINE_START_CALL(mw8080bw);
} }

View File

@ -865,7 +865,7 @@ static MACHINE_START( mystwarr )
state_save_register_global(machine, mw_irq_control); state_save_register_global(machine, mw_irq_control);
state_save_register_global(machine, cur_sound_region); state_save_register_global(machine, cur_sound_region);
state_save_register_postload(machine, mystwarr_postload, NULL); machine->state().register_postload(mystwarr_postload, NULL);
} }
static MACHINE_RESET(mystwarr) static MACHINE_RESET(mystwarr)

View File

@ -1102,7 +1102,7 @@ static MACHINE_START( neogeo )
state_save_register_global(machine, state->led2_value); state_save_register_global(machine, state->led2_value);
state_save_register_global(machine, state->recurse); state_save_register_global(machine, state->recurse);
state_save_register_postload(machine, neogeo_postload, NULL); machine->state().register_postload(neogeo_postload, NULL);
} }

View File

@ -783,7 +783,7 @@ static MACHINE_START( ninjaw )
state_save_register_global(machine, state->cpua_ctrl); state_save_register_global(machine, state->cpua_ctrl);
state_save_register_global(machine, state->banknum); state_save_register_global(machine, state->banknum);
state_save_register_global_array(machine, state->pandata); state_save_register_global_array(machine, state->pandata);
state_save_register_postload(machine, ninjaw_postload, NULL); machine->state().register_postload(ninjaw_postload, NULL);
} }
static MACHINE_RESET( ninjaw ) static MACHINE_RESET( ninjaw )

View File

@ -706,7 +706,7 @@ static MACHINE_START( othunder )
state_save_register_global(machine, state->ad_irq); state_save_register_global(machine, state->ad_irq);
state_save_register_global(machine, state->banknum); state_save_register_global(machine, state->banknum);
state_save_register_global_array(machine, state->pan); state_save_register_global_array(machine, state->pan);
state_save_register_postload(machine, othunder_postload, NULL); machine->state().register_postload(othunder_postload, NULL);
} }
static MACHINE_RESET( othunder ) static MACHINE_RESET( othunder )

View File

@ -248,7 +248,7 @@ static MACHINE_START( pengadvb )
state_save_register_global_pointer(machine, main_mem, 0x4000); state_save_register_global_pointer(machine, main_mem, 0x4000);
state_save_register_global(machine, mem_map); state_save_register_global(machine, mem_map);
state_save_register_global_array(machine, mem_banks); state_save_register_global_array(machine, mem_banks);
state_save_register_postload(machine, pengadvb, NULL); machine->state().register_postload(pengadvb, NULL);
} }
static MACHINE_RESET( pengadvb ) static MACHINE_RESET( pengadvb )

View File

@ -1072,8 +1072,8 @@ static void install_hotgmck_pcm_bank(running_machine *machine)
set_hotgmck_pcm_bank(machine, 1); set_hotgmck_pcm_bank(machine, 1);
memory_install_write32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x5800008, 0x580000b, 0, 0, hotgmck_pcm_bank_w ); memory_install_write32_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x5800008, 0x580000b, 0, 0, hotgmck_pcm_bank_w );
state_save_register_postload(machine, hotgmck_pcm_bank_postload, (void *)0); machine->state().register_postload(hotgmck_pcm_bank_postload, (void *)0);
state_save_register_postload(machine, hotgmck_pcm_bank_postload, (void *)1); machine->state().register_postload(hotgmck_pcm_bank_postload, (void *)1);
} }
static DRIVER_INIT( hotgmck ) static DRIVER_INIT( hotgmck )

View File

@ -265,7 +265,7 @@ static MACHINE_START( renegade )
state_save_register_global(machine, mcu_key); state_save_register_global(machine, mcu_key);
state_save_register_global(machine, bank); state_save_register_global(machine, bank);
state_save_register_postload(machine, renegade_postload, NULL); machine->state().register_postload(renegade_postload, NULL);
} }
static DRIVER_INIT( renegade ) static DRIVER_INIT( renegade )

View File

@ -547,7 +547,7 @@ static MACHINE_START( slapshot )
state->banknum = 0; state->banknum = 0;
state_save_register_global(machine, state->banknum); state_save_register_global(machine, state->banknum);
state_save_register_postload(machine, slapshot_postload, NULL); machine->state().register_postload(slapshot_postload, NULL);
} }

View File

@ -5744,7 +5744,7 @@ static DRIVER_INIT( driveout )
state_save_register_global(machine, state->driveout_sound_latch); state_save_register_global(machine, state->driveout_sound_latch);
state_save_register_global(machine, state->oki_bank); state_save_register_global(machine, state->oki_bank);
state_save_register_global(machine, state->nibble); state_save_register_global(machine, state->nibble);
state_save_register_postload(machine, driveout_postload, NULL); machine->state().register_postload(driveout_postload, NULL);
} }

View File

@ -534,7 +534,7 @@ static MACHINE_START( taitoh )
state->tc0080vco = machine->device("tc0080vco"); state->tc0080vco = machine->device("tc0080vco");
state_save_register_global(machine, state->banknum); state_save_register_global(machine, state->banknum);
state_save_register_postload(machine, taitoh_postload, NULL); machine->state().register_postload(taitoh_postload, NULL);
} }

View File

@ -898,7 +898,7 @@ static MACHINE_START( taitox )
state->taitox_banknum = -1; state->taitox_banknum = -1;
state_save_register_global(machine, state->taitox_banknum); state_save_register_global(machine, state->taitox_banknum);
state_save_register_postload(machine, taitox_postload, NULL); machine->state().register_postload(taitox_postload, NULL);
} }
static const tc0140syt_interface taitox_tc0140syt_intf = static const tc0140syt_interface taitox_tc0140syt_intf =

View File

@ -2994,7 +2994,7 @@ static MACHINE_START( taitoz )
memory_configure_bank(machine, "bank10", 0, banks, machine->region("audiocpu")->base() + 0xc000, 0x4000); memory_configure_bank(machine, "bank10", 0, banks, machine->region("audiocpu")->base() + 0xc000, 0x4000);
state_save_register_postload(machine, taitoz_postload, NULL); machine->state().register_postload(taitoz_postload, NULL);
MACHINE_START_CALL(bshark); MACHINE_START_CALL(bshark);
} }
@ -4888,7 +4888,7 @@ static DRIVER_INIT( bshark )
state->dblaxle_vibration = 0; state->dblaxle_vibration = 0;
state->eep_latch = 0; state->eep_latch = 0;
state_save_register_postload(machine, bshark_postload, NULL); machine->state().register_postload(bshark_postload, NULL);
state_save_register_global(machine, state->eep_latch); state_save_register_global(machine, state->eep_latch);
} }

View File

@ -630,7 +630,7 @@ static MACHINE_START( taitoair )
state_save_register_item(machine, "globals", NULL, i, state->q.p[i].y); state_save_register_item(machine, "globals", NULL, i, state->q.p[i].y);
} }
state_save_register_postload(machine, taitoair_postload, NULL); machine->state().register_postload(taitoair_postload, NULL);
} }
static MACHINE_RESET( taitoair ) static MACHINE_RESET( taitoair )

View File

@ -662,7 +662,7 @@ static MACHINE_START( topspeed )
state_save_register_global(machine, state->cpua_ctrl); state_save_register_global(machine, state->cpua_ctrl);
state_save_register_global(machine, state->ioc220_port); state_save_register_global(machine, state->ioc220_port);
state_save_register_global(machine, state->banknum); state_save_register_global(machine, state->banknum);
state_save_register_postload(machine, topspeed_postload, NULL); machine->state().register_postload(topspeed_postload, NULL);
} }
static MACHINE_RESET( topspeed ) static MACHINE_RESET( topspeed )

View File

@ -565,7 +565,7 @@ static MACHINE_START( vegas )
state_save_register_global(machine, sio_led_state); state_save_register_global(machine, sio_led_state);
state_save_register_global(machine, pending_analog_read); state_save_register_global(machine, pending_analog_read);
state_save_register_global(machine, cmos_unlocked); state_save_register_global(machine, cmos_unlocked);
state_save_register_postload(machine, vegas_postload, NULL); machine->state().register_postload(vegas_postload, NULL);
} }

View File

@ -558,7 +558,7 @@ static MACHINE_START( warriorb )
state_save_register_global(machine, state->banknum); state_save_register_global(machine, state->banknum);
state_save_register_global_array(machine, state->pandata); state_save_register_global_array(machine, state->pandata);
state_save_register_postload(machine, warriorb_postload, NULL); machine->state().register_postload(warriorb_postload, NULL);
} }
static MACHINE_RESET( taito_dualscreen ) static MACHINE_RESET( taito_dualscreen )

View File

@ -964,7 +964,7 @@ static MACHINE_START( wgp )
state_save_register_global(machine, state->cpua_ctrl); state_save_register_global(machine, state->cpua_ctrl);
state_save_register_global(machine, state->banknum); state_save_register_global(machine, state->banknum);
state_save_register_global(machine, state->port_sel); state_save_register_global(machine, state->port_sel);
state_save_register_postload(machine, wgp_postload, NULL); machine->state().register_postload(wgp_postload, NULL);
} }
static const tc0100scn_interface wgp_tc0100scn_intf = static const tc0100scn_interface wgp_tc0100scn_intf =

View File

@ -493,7 +493,7 @@ static MACHINE_START( xexex )
state_save_register_global(machine, state->cur_control2); state_save_register_global(machine, state->cur_control2);
state_save_register_global(machine, state->cur_sound_region); state_save_register_global(machine, state->cur_sound_region);
state_save_register_postload(machine, xexex_postload, NULL); machine->state().register_postload(xexex_postload, NULL);
state->dmadelay_timer = machine->scheduler().timer_alloc(FUNC(dmaend_callback)); state->dmadelay_timer = machine->scheduler().timer_alloc(FUNC(dmaend_callback));
} }

View File

@ -330,7 +330,7 @@ static MACHINE_START( xmen )
state_save_register_global(machine, state->sprite_colorbase); state_save_register_global(machine, state->sprite_colorbase);
state_save_register_global_array(machine, state->layer_colorbase); state_save_register_global_array(machine, state->layer_colorbase);
state_save_register_global_array(machine, state->layerpri); state_save_register_global_array(machine, state->layerpri);
state_save_register_postload(machine, xmen_postload, NULL); machine->state().register_postload(xmen_postload, NULL);
} }
static MACHINE_RESET( xmen ) static MACHINE_RESET( xmen )

View File

@ -165,7 +165,7 @@ void atarigen_init(running_machine *machine)
state_save_register_global(machine, state->playfield2_latch); state_save_register_global(machine, state->playfield2_latch);
/* need a postload to reset the state */ /* need a postload to reset the state */
state_save_register_postload(machine, slapstic_postload, NULL); machine->state().register_postload(slapstic_postload, NULL);
} }

View File

@ -258,8 +258,7 @@ static TIMER_CALLBACK( reset_timer )
static void pic_register_state(running_machine *machine) static void pic_register_state(running_machine *machine)
{ {
state_save_register_global(machine, pic.latch); state_save_register_global(machine, pic.latch);
state_save_register_global(machine, pic.latch_expire_time.seconds); state_save_register_global(machine, pic.latch_expire_time);
state_save_register_global(machine, pic.latch_expire_time.attoseconds);
state_save_register_global(machine, pic.state); state_save_register_global(machine, pic.state);
state_save_register_global(machine, pic.index); state_save_register_global(machine, pic.index);
state_save_register_global(machine, pic.total); state_save_register_global(machine, pic.total);

View File

@ -413,7 +413,7 @@ static void init_save_state(device_t *device)
{ {
naomibd_state *v = get_safe_token(device); naomibd_state *v = get_safe_token(device);
state_save_register_postload(device->machine, naomibd_postload, v); device->machine->state().register_postload(naomibd_postload, v);
/* register states */ /* register states */
state_save_register_device_item(device, 0, v->rom_offset); state_save_register_device_item(device, 0, v->rom_offset);

View File

@ -140,7 +140,7 @@ static DEVICE_START( nmk112 )
nmk112->page_mask = ~intf->disable_page_mask; nmk112->page_mask = ~intf->disable_page_mask;
state_save_register_device_item_array(device, 0, nmk112->current_bank); state_save_register_device_item_array(device, 0, nmk112->current_bank);
state_save_register_postload(device->machine, nmk112_postload_bankswitch, nmk112); device->machine->state().register_postload(nmk112_postload_bankswitch, nmk112);
} }
static DEVICE_RESET( nmk112 ) static DEVICE_RESET( nmk112 )

Some files were not shown because too many files have changed in this diff Show More