summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/pc_kbd/hle_mouse.cpp2
-rw-r--r--src/devices/cpu/bcp/dp8344.cpp2
-rw-r--r--src/devices/cpu/cosmac/cosmac.cpp4
-rw-r--r--src/devices/cpu/dsp16/dsp16.cpp5
-rw-r--r--src/devices/cpu/mcs40/mcs40.cpp5
-rw-r--r--src/devices/cpu/mips/mips1.cpp2
-rw-r--r--src/devices/cpu/pace/pace.cpp2
-rw-r--r--src/devices/cpu/pic17/pic17.cpp2
-rw-r--r--src/devices/cpu/rii/riscii.cpp2
-rw-r--r--src/devices/cpu/romp/romp.cpp2
-rw-r--r--src/devices/cpu/tlcs90/tlcs90.cpp2
-rw-r--r--src/devices/cpu/vt61/vt61.cpp3
-rw-r--r--src/devices/machine/28fxxx.cpp2
-rw-r--r--src/devices/machine/adc0804.cpp2
-rw-r--r--src/devices/machine/adc0808.cpp3
-rw-r--r--src/devices/machine/ay31015.h2
-rw-r--r--src/devices/machine/cxd1185.cpp2
-rw-r--r--src/devices/machine/ds1315.h2
-rw-r--r--src/devices/machine/eepromser.cpp9
-rw-r--r--src/devices/machine/i82586.cpp3
-rw-r--r--src/devices/machine/i8291a.cpp13
-rw-r--r--src/devices/machine/m3002.cpp2
-rw-r--r--src/devices/machine/ncr5380n.cpp2
-rw-r--r--src/devices/machine/pic8259.cpp2
-rw-r--r--src/devices/machine/rtc9701.cpp3
-rw-r--r--src/devices/machine/scn_pci.cpp3
-rw-r--r--src/devices/machine/serflash.cpp2
-rw-r--r--src/devices/machine/upd7004.cpp3
-rw-r--r--src/devices/machine/wtl3132.cpp1
-rw-r--r--src/devices/sound/flt_biquad.cpp3
-rw-r--r--src/devices/sound/mas3507d.cpp5
-rw-r--r--src/devices/sound/mea8000.cpp3
-rw-r--r--src/devices/sound/multipcm.cpp1
-rw-r--r--src/devices/sound/s14001a.cpp2
-rw-r--r--src/devices/sound/s_dsp.cpp3
-rw-r--r--src/devices/video/huc6270.cpp3
-rw-r--r--src/devices/video/t6963c.cpp2
-rw-r--r--src/devices/video/tms3556.cpp2
-rw-r--r--src/emu/debug/dvsave.cpp73
-rw-r--r--src/emu/debug/dvsave.h7
-rw-r--r--src/emu/machine.cpp2
-rw-r--r--src/emu/save.cpp396
-rw-r--r--src/emu/save.h290
-rw-r--r--src/mame/drivers/namcos22.cpp3
-rw-r--r--src/mame/drivers/subsino2.cpp2
-rw-r--r--src/mame/drivers/ttchamp.cpp2
-rw-r--r--src/mame/machine/rosetta.cpp2
-rw-r--r--src/mame/machine/thomflop.cpp2
-rw-r--r--src/mame/machine/x68k_hdc.cpp2
49 files changed, 430 insertions, 464 deletions
diff --git a/src/devices/bus/pc_kbd/hle_mouse.cpp b/src/devices/bus/pc_kbd/hle_mouse.cpp
index 9cb96f94983..b1e0d829ec0 100644
--- a/src/devices/bus/pc_kbd/hle_mouse.cpp
+++ b/src/devices/bus/pc_kbd/hle_mouse.cpp
@@ -49,8 +49,6 @@
DEFINE_DEVICE_TYPE(HLE_PS2_MOUSE, hle_ps2_mouse_device, "hle_ps2_mouse", "HLE PS/2 Mouse")
-ALLOW_SAVE_TYPE(hle_ps2_mouse_device::serial_state);
-
INPUT_PORTS_START(hle_ps2_mouse_device)
PORT_START("mouse_x_axis")
PORT_BIT(0xffff, 0, IPT_MOUSE_X) PORT_SENSITIVITY(100)
diff --git a/src/devices/cpu/bcp/dp8344.cpp b/src/devices/cpu/bcp/dp8344.cpp
index 3e78cb0d0dd..9fd361e8256 100644
--- a/src/devices/cpu/bcp/dp8344.cpp
+++ b/src/devices/cpu/bcp/dp8344.cpp
@@ -56,8 +56,6 @@ DEFINE_DEVICE_TYPE(DP8344B, dp8344b_device, "dp8344b", "National Semiconductor D
// DEVICE CONSTRUCTION AND INITIALIZATION
//**************************************************************************
-ALLOW_SAVE_TYPE(dp8344_device::inst_state);
-
//-------------------------------------------------
// dp8344_device - constructor
//-------------------------------------------------
diff --git a/src/devices/cpu/cosmac/cosmac.cpp b/src/devices/cpu/cosmac/cosmac.cpp
index 978c4e76fc8..2160f45317a 100644
--- a/src/devices/cpu/cosmac/cosmac.cpp
+++ b/src/devices/cpu/cosmac/cosmac.cpp
@@ -20,10 +20,6 @@ TODO:
#include "cosmac.h"
#include "coreutil.h"
-// permit our enums to be saved
-ALLOW_SAVE_TYPE(cosmac_device::cosmac_mode);
-ALLOW_SAVE_TYPE(cosmac_device::cosmac_state);
-
//**************************************************************************
// CONSTANTS
diff --git a/src/devices/cpu/dsp16/dsp16.cpp b/src/devices/cpu/dsp16/dsp16.cpp
index d7da812acf2..beb7809106d 100644
--- a/src/devices/cpu/dsp16/dsp16.cpp
+++ b/src/devices/cpu/dsp16/dsp16.cpp
@@ -111,11 +111,6 @@ DEFINE_DEVICE_TYPE(DSP16A, dsp16a_device, "dsp16a", "WE|AT&T DSP16A")
DSP16 SERIES BASE IMPLEMENTATION
***************************************************************************/
-ALLOW_SAVE_TYPE(dsp16_device_base::cache);
-ALLOW_SAVE_TYPE(dsp16_device_base::phase);
-ALLOW_SAVE_TYPE(dsp16_device_base::flags);
-ALLOW_SAVE_TYPE(dsp16_device_base::sio_flags);
-
WRITE_LINE_MEMBER(dsp16_device_base::exm_w)
{
if (bool(state) != bool(m_exm_in))
diff --git a/src/devices/cpu/mcs40/mcs40.cpp b/src/devices/cpu/mcs40/mcs40.cpp
index 969f08c4197..7665967fd8d 100644
--- a/src/devices/cpu/mcs40/mcs40.cpp
+++ b/src/devices/cpu/mcs40/mcs40.cpp
@@ -73,11 +73,6 @@ DEFINE_DEVICE_TYPE(I4004, i4004_cpu_device, "i4004", "Intel 4004")
DEFINE_DEVICE_TYPE(I4040, i4040_cpu_device, "i4040", "Intel 4040")
-ALLOW_SAVE_TYPE(mcs40_cpu_device_base::cycle);
-ALLOW_SAVE_TYPE(mcs40_cpu_device_base::pmem);
-ALLOW_SAVE_TYPE(mcs40_cpu_device_base::phase);
-
-
static constexpr u8 f_cm_ram_table[8] = { 0x0eU, 0x0dU, 0x0bU, 0x07U, 0x09U, 0x05U, 0x03U, 0x01U };
diff --git a/src/devices/cpu/mips/mips1.cpp b/src/devices/cpu/mips/mips1.cpp
index c5f18b2989e..a35030b3728 100644
--- a/src/devices/cpu/mips/mips1.cpp
+++ b/src/devices/cpu/mips/mips1.cpp
@@ -54,8 +54,6 @@ DEFINE_DEVICE_TYPE(R3071, r3071_device, "r3071", "IDT R3071")
DEFINE_DEVICE_TYPE(R3081, r3081_device, "r3081", "IDT R3081")
DEFINE_DEVICE_TYPE(SONYPS2_IOP, iop_device, "sonyiop", "Sony Playstation 2 IOP")
-ALLOW_SAVE_TYPE(mips1core_device_base::branch_state);
-
mips1core_device_base::mips1core_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, u32 cpurev, size_t icache_size, size_t dcache_size)
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config_be("program", ENDIANNESS_BIG, 32, 32)
diff --git a/src/devices/cpu/pace/pace.cpp b/src/devices/cpu/pace/pace.cpp
index 2bfba2cc338..ec01b564e68 100644
--- a/src/devices/cpu/pace/pace.cpp
+++ b/src/devices/cpu/pace/pace.cpp
@@ -56,8 +56,6 @@ DEFINE_DEVICE_TYPE(INS8900, ins8900_device, "ins8900", "National Semiconductor I
// DEVICE CONSTRUCTION AND INITIALIZATION
//**************************************************************************
-ALLOW_SAVE_TYPE(pace_device::cycle);
-
//-------------------------------------------------
// pace_device - constructor
//-------------------------------------------------
diff --git a/src/devices/cpu/pic17/pic17.cpp b/src/devices/cpu/pic17/pic17.cpp
index 99dff413d54..6d46ce3af49 100644
--- a/src/devices/cpu/pic17/pic17.cpp
+++ b/src/devices/cpu/pic17/pic17.cpp
@@ -62,8 +62,6 @@
#include "pic17.h"
#include "pic17d.h"
-ALLOW_SAVE_TYPE(pic17_cpu_device::exec_phase);
-
pic17_cpu_device::pic17_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u16 rom_size, address_map_constructor data_map)
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 16, 16, -1, address_map_constructor(FUNC(pic17_cpu_device::program_map), this))
diff --git a/src/devices/cpu/rii/riscii.cpp b/src/devices/cpu/rii/riscii.cpp
index 804280dc6e1..d3f9baa068d 100644
--- a/src/devices/cpu/rii/riscii.cpp
+++ b/src/devices/cpu/rii/riscii.cpp
@@ -25,8 +25,6 @@
// device type definitions
DEFINE_DEVICE_TYPE(EPG3231, epg3231_device, "epg3231", "Elan ePG3231")
-ALLOW_SAVE_TYPE(riscii_series_device::exec_state);
-
//**************************************************************************
// DEVICE CONSTRUCTION AND INITIALIZATION
diff --git a/src/devices/cpu/romp/romp.cpp b/src/devices/cpu/romp/romp.cpp
index d68988cb876..8109d2b4fb3 100644
--- a/src/devices/cpu/romp/romp.cpp
+++ b/src/devices/cpu/romp/romp.cpp
@@ -31,8 +31,6 @@
DEFINE_DEVICE_TYPE(ROMP, romp_device, "romp", "IBM ROMP")
-ALLOW_SAVE_TYPE(romp_device::branch_state);
-
romp_device::romp_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
: cpu_device(mconfig, ROMP, tag, owner, clock)
, m_mem_config("memory", ENDIANNESS_BIG, 32, 32)
diff --git a/src/devices/cpu/tlcs90/tlcs90.cpp b/src/devices/cpu/tlcs90/tlcs90.cpp
index bd02b9cc197..e90c204d97d 100644
--- a/src/devices/cpu/tlcs90/tlcs90.cpp
+++ b/src/devices/cpu/tlcs90/tlcs90.cpp
@@ -17,8 +17,6 @@
#include "tlcs90.h"
#include "tlcs90d.h"
-ALLOW_SAVE_TYPE(tlcs90_device::e_mode); // allow save_item on a non-fundamental type
-
DEFINE_DEVICE_TYPE(TMP90840, tmp90840_device, "tmp90840", "Toshiba TMP90840")
DEFINE_DEVICE_TYPE(TMP90841, tmp90841_device, "tmp90841", "Toshiba TMP90841")
diff --git a/src/devices/cpu/vt61/vt61.cpp b/src/devices/cpu/vt61/vt61.cpp
index 216187e0a55..2fb0378c48a 100644
--- a/src/devices/cpu/vt61/vt61.cpp
+++ b/src/devices/cpu/vt61/vt61.cpp
@@ -15,9 +15,6 @@
// device type definition
DEFINE_DEVICE_TYPE(VT61_CPU, vt61_cpu_device, "vt61_cpu", "DEC VT61 CPU")
-ALLOW_SAVE_TYPE(vt61_cpu_device::state);
-ALLOW_SAVE_TYPE(vt61_cpu_device::pc_mode);
-
vt61_cpu_device::vt61_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: cpu_device(mconfig, VT61_CPU, tag, owner, clock)
, m_program_config("microprogram", ENDIANNESS_LITTLE, 16, 10, -1)
diff --git a/src/devices/machine/28fxxx.cpp b/src/devices/machine/28fxxx.cpp
index e434a761c46..2e28a718ded 100644
--- a/src/devices/machine/28fxxx.cpp
+++ b/src/devices/machine/28fxxx.cpp
@@ -46,8 +46,6 @@ DEFINE_DEVICE_TYPE(INTEL_28F010, intel_28f010_device, "intel_28f010", "Intel 28F
DEFINE_DEVICE_TYPE(AMD_28F010, amd_28f010_device, "amd_28f010", "Am28F010 1 Megabit (128K x 8-Bit) CMOS 12.0 Volt, Bulk Erase Flash Memory")
DEFINE_DEVICE_TYPE(AMD_28F020, amd_28f020_device, "amd_28f020", "Am28F020 2 Megabit (256K x 8-Bit) CMOS 12.0 Volt, Bulk Erase Flash Memory")
-ALLOW_SAVE_TYPE(base_28fxxx_device::state);
-
base_28fxxx_device::base_28fxxx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 size, u8 manufacturer_code, u8 device_code)
: device_t(mconfig, type, tag, owner, clock)
, device_nvram_interface(mconfig, *this)
diff --git a/src/devices/machine/adc0804.cpp b/src/devices/machine/adc0804.cpp
index 048b99734b6..7d6e8d358d7 100644
--- a/src/devices/machine/adc0804.cpp
+++ b/src/devices/machine/adc0804.cpp
@@ -46,8 +46,6 @@
DEFINE_DEVICE_TYPE(ADC0803, adc0803_device, "adc0803", "ADC0803 A/D Converter")
DEFINE_DEVICE_TYPE(ADC0804, adc0804_device, "adc0804", "ADC0804 A/D Converter")
-ALLOW_SAVE_TYPE(adc0804_device::read_mode);
-
//**************************************************************************
// DEVICE CONSTRUCTION AND INITIALIZATION
diff --git a/src/devices/machine/adc0808.cpp b/src/devices/machine/adc0808.cpp
index 3988254dc71..f7a0f6ee53b 100644
--- a/src/devices/machine/adc0808.cpp
+++ b/src/devices/machine/adc0808.cpp
@@ -32,9 +32,6 @@ DEFINE_DEVICE_TYPE(M58990, m58990_device, "m58990", "M58990 A/D Converter")
// LIVE DEVICE
//**************************************************************************
-// permit our enum to be saved
-ALLOW_SAVE_TYPE(adc0808_device::state);
-
//-------------------------------------------------
// adc0808_device - constructor
//-------------------------------------------------
diff --git a/src/devices/machine/ay31015.h b/src/devices/machine/ay31015.h
index 4e27bc8e11f..748bda40227 100644
--- a/src/devices/machine/ay31015.h
+++ b/src/devices/machine/ay31015.h
@@ -164,8 +164,6 @@ protected:
};
-ALLOW_SAVE_TYPE(ay31015_device::state_t);
-
DECLARE_DEVICE_TYPE(AY31015, ay31015_device) // For AY-3-1014A, AY-3-1015(D) and HD6402 variants
DECLARE_DEVICE_TYPE(AY51013, ay51013_device) // For AY-3-1014, AY-5-1013 and AY-6-1013 variants
diff --git a/src/devices/machine/cxd1185.cpp b/src/devices/machine/cxd1185.cpp
index b599d307783..36fe299010d 100644
--- a/src/devices/machine/cxd1185.cpp
+++ b/src/devices/machine/cxd1185.cpp
@@ -41,8 +41,6 @@ static unsigned const SCSI_BUS_SETTLE = 400;
static unsigned const SCSI_BUS_SKEW = 10;
static unsigned const SCSI_RST_HOLD = 25'000;
-ALLOW_SAVE_TYPE(cxd1185_device::state);
-
cxd1185_device::cxd1185_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
: nscsi_device(mconfig, CXD1185, tag, owner, clock)
, nscsi_slot_card_interface(mconfig, *this, DEVICE_SELF)
diff --git a/src/devices/machine/ds1315.h b/src/devices/machine/ds1315.h
index 720c4a08202..95232eeb926 100644
--- a/src/devices/machine/ds1315.h
+++ b/src/devices/machine/ds1315.h
@@ -58,8 +58,6 @@ private:
uint8_t m_raw_data[8*8];
};
-ALLOW_SAVE_TYPE(ds1315_device::mode_t);
-
DECLARE_DEVICE_TYPE(DS1315, ds1315_device)
#endif // MAME_MACHINE_DS1315_H
diff --git a/src/devices/machine/eepromser.cpp b/src/devices/machine/eepromser.cpp
index a8502e72fe3..33060eb30e8 100644
--- a/src/devices/machine/eepromser.cpp
+++ b/src/devices/machine/eepromser.cpp
@@ -139,15 +139,6 @@
//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-ALLOW_SAVE_TYPE(eeprom_serial_base_device::eeprom_command);
-ALLOW_SAVE_TYPE(eeprom_serial_base_device::eeprom_state);
-
-
-
-//**************************************************************************
// BASE DEVICE IMPLEMENTATION
//**************************************************************************
diff --git a/src/devices/machine/i82586.cpp b/src/devices/machine/i82586.cpp
index 7dfc6272435..d543a019d7d 100644
--- a/src/devices/machine/i82586.cpp
+++ b/src/devices/machine/i82586.cpp
@@ -42,9 +42,6 @@
#include "logmacro.h"
-ALLOW_SAVE_TYPE(i82586_base_device::cu_state);
-ALLOW_SAVE_TYPE(i82586_base_device::ru_state);
-
DEFINE_DEVICE_TYPE(I82586, i82586_device, "i82586", "Intel 82586 IEEE 802.3 Ethernet LAN Coprocessor")
DEFINE_DEVICE_TYPE(I82596_LE16, i82596_le16_device, "i82596sx_le", "Intel 82596 SX High-Performance 32-Bit Local Area Network Coprocessor (little)")
DEFINE_DEVICE_TYPE(I82596_BE16, i82596_be16_device, "i82596sx_be", "Intel 82596 SX High-Performance 32-Bit Local Area Network Coprocessor (big)")
diff --git a/src/devices/machine/i8291a.cpp b/src/devices/machine/i8291a.cpp
index 3692ba95a28..8d32baab895 100644
--- a/src/devices/machine/i8291a.cpp
+++ b/src/devices/machine/i8291a.cpp
@@ -23,19 +23,6 @@
#include "logmacro.h"
DEFINE_DEVICE_TYPE(I8291A, i8291a_device, "i8291a", "Intel I8291A GPIB Talker/Listener")
-ALLOW_SAVE_TYPE(i8291a_device::listener_state);
-ALLOW_SAVE_TYPE(i8291a_device::talker_state);
-ALLOW_SAVE_TYPE(i8291a_device::talker_primary_state);
-ALLOW_SAVE_TYPE(i8291a_device::listener_primary_state);
-ALLOW_SAVE_TYPE(i8291a_device::parallel_poll_state);
-ALLOW_SAVE_TYPE(i8291a_device::device_trigger_state);
-ALLOW_SAVE_TYPE(i8291a_device::device_clear_state);
-ALLOW_SAVE_TYPE(i8291a_device::talker_serial_poll_state);
-ALLOW_SAVE_TYPE(i8291a_device::serial_poll_state);
-ALLOW_SAVE_TYPE(i8291a_device::remote_local_state);
-ALLOW_SAVE_TYPE(i8291a_device::source_handshake_state);
-ALLOW_SAVE_TYPE(i8291a_device::acceptor_handshake_state);
-
i8291a_device::i8291a_device(const machine_config &mconfig, const char *tag,
device_t *owner, uint32_t clock) :
device_t{mconfig, I8291A, tag, owner, clock},
diff --git a/src/devices/machine/m3002.cpp b/src/devices/machine/m3002.cpp
index fd93666a55f..3414346e8ad 100644
--- a/src/devices/machine/m3002.cpp
+++ b/src/devices/machine/m3002.cpp
@@ -28,8 +28,6 @@ DEFINE_DEVICE_TYPE(M3000, m3000_device, "m3000", "EM M 3000 Real Time Clock")
// DEVICE CONSTRUCTION AND INITIALIZATION
//**************************************************************************
-ALLOW_SAVE_TYPE(m3002_device::mux_state);
-
//-------------------------------------------------
// m3002_device - constructor
//-------------------------------------------------
diff --git a/src/devices/machine/ncr5380n.cpp b/src/devices/machine/ncr5380n.cpp
index a74b744f9da..f2a22f34c9e 100644
--- a/src/devices/machine/ncr5380n.cpp
+++ b/src/devices/machine/ncr5380n.cpp
@@ -29,8 +29,6 @@ DEFINE_DEVICE_TYPE(NCR5380N, ncr5380n_device, "ncr5380_new", "NCR 5380 SCSI (new
DEFINE_DEVICE_TYPE(NCR53C80, ncr53c80_device, "ncr53c80", "NCR 53C80 SCSI")
DEFINE_DEVICE_TYPE(CXD1180, cxd1180_device, "cxd1180", "Sony CXD1180")
-ALLOW_SAVE_TYPE(ncr5380n_device::state);
-
ncr5380n_device::ncr5380n_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, bool has_lbs)
: nscsi_device(mconfig, type, tag, owner, clock)
, nscsi_slot_card_interface(mconfig, *this, DEVICE_SELF)
diff --git a/src/devices/machine/pic8259.cpp b/src/devices/machine/pic8259.cpp
index d5104413691..a1a6a67448e 100644
--- a/src/devices/machine/pic8259.cpp
+++ b/src/devices/machine/pic8259.cpp
@@ -27,8 +27,6 @@
#define LOGOCW(...) LOGMASKED(LOG_OCW, __VA_ARGS__)
-ALLOW_SAVE_TYPE(pic8259_device::state_t); // allow save_item on a non-fundamental type
-
void pic8259_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
/* check the various IRQs */
diff --git a/src/devices/machine/rtc9701.cpp b/src/devices/machine/rtc9701.cpp
index a8ccc5cec7f..8cbf5e4066a 100644
--- a/src/devices/machine/rtc9701.cpp
+++ b/src/devices/machine/rtc9701.cpp
@@ -15,9 +15,6 @@
#include "machine/rtc9701.h"
-ALLOW_SAVE_TYPE(rtc9701_device::state_t);
-
-
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
diff --git a/src/devices/machine/scn_pci.cpp b/src/devices/machine/scn_pci.cpp
index 73ef2590e66..91142db8132 100644
--- a/src/devices/machine/scn_pci.cpp
+++ b/src/devices/machine/scn_pci.cpp
@@ -150,9 +150,6 @@ const u16 scn2641_device::s_br_divisors[16] = {
// DEVICE CONSTRUCTION & INITIALIZATION
//**************************************************************************
-ALLOW_SAVE_TYPE(scn_pci_device::rcvr_state);
-ALLOW_SAVE_TYPE(scn_pci_device::xmtr_state);
-
//-------------------------------------------------
// scn_pci_device - constructor
//-------------------------------------------------
diff --git a/src/devices/machine/serflash.cpp b/src/devices/machine/serflash.cpp
index c616b4d34a7..5ea6c22292b 100644
--- a/src/devices/machine/serflash.cpp
+++ b/src/devices/machine/serflash.cpp
@@ -10,8 +10,6 @@
#include <algorithm>
-ALLOW_SAVE_TYPE(serflash_device::flash_state_t);
-
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
diff --git a/src/devices/machine/upd7004.cpp b/src/devices/machine/upd7004.cpp
index e3cfb911864..f49a0b84eb3 100644
--- a/src/devices/machine/upd7004.cpp
+++ b/src/devices/machine/upd7004.cpp
@@ -25,9 +25,6 @@
DEFINE_DEVICE_TYPE(UPD7004, upd7004_device, "upd7004", "UPD7004 A/D Converter")
-// permit our enum to be saved
-ALLOW_SAVE_TYPE(upd7004_device::state);
-
//**************************************************************************
// LIVE DEVICE
diff --git a/src/devices/machine/wtl3132.cpp b/src/devices/machine/wtl3132.cpp
index 3b82466529e..d7a5fec6478 100644
--- a/src/devices/machine/wtl3132.cpp
+++ b/src/devices/machine/wtl3132.cpp
@@ -24,7 +24,6 @@
//#define VERBOSE (LOG_GENERAL|LOG_REGS|LOG_IO|LOG_BYPASS)
#include "logmacro.h"
-ALLOW_SAVE_TYPE(float32_t);
SAVE_TYPE_AS_FLOAT(float32_t);
// helper for extracting opcode fields
diff --git a/src/devices/sound/flt_biquad.cpp b/src/devices/sound/flt_biquad.cpp
index 659c8a5cd29..665c2531724 100644
--- a/src/devices/sound/flt_biquad.cpp
+++ b/src/devices/sound/flt_biquad.cpp
@@ -33,9 +33,6 @@
// device type definition
DEFINE_DEVICE_TYPE(FILTER_BIQUAD, filter_biquad_device, "filter_biquad", "Biquad Filter")
-// allow the enum class for the biquad filter type to be saved by the savestate system
-ALLOW_SAVE_TYPE(filter_biquad_device::biquad_type);
-
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
diff --git a/src/devices/sound/mas3507d.cpp b/src/devices/sound/mas3507d.cpp
index c2b50088d11..de21090cd1e 100644
--- a/src/devices/sound/mas3507d.cpp
+++ b/src/devices/sound/mas3507d.cpp
@@ -31,11 +31,6 @@
#define LOGCONFIG(...) LOGMASKED(LOG_CONFIG, __VA_ARGS__)
#define LOGOTHER(...) LOGMASKED(LOG_OTHER, __VA_ARGS__)
-ALLOW_SAVE_TYPE(mas3507d_device::i2c_bus_state_t)
-ALLOW_SAVE_TYPE(mas3507d_device::i2c_bus_address_t)
-ALLOW_SAVE_TYPE(mas3507d_device::i2c_subdest_t)
-ALLOW_SAVE_TYPE(mas3507d_device::i2c_command_t)
-
// device type definition
DEFINE_DEVICE_TYPE(MAS3507D, mas3507d_device, "mas3507d", "MAS 3507D MPEG decoder")
diff --git a/src/devices/sound/mea8000.cpp b/src/devices/sound/mea8000.cpp
index 3cf2ad51a6e..b2a468bddb4 100644
--- a/src/devices/sound/mea8000.cpp
+++ b/src/devices/sound/mea8000.cpp
@@ -39,9 +39,6 @@
/******************* utilitiy function and macros ********************/
-ALLOW_SAVE_TYPE( mea8000_device::mea8000_state );
-
-
/* digital filters work at 8 kHz */
#define F0 (clock() / 480)
diff --git a/src/devices/sound/multipcm.cpp b/src/devices/sound/multipcm.cpp
index 7243340c9fe..e6c76e923c9 100644
--- a/src/devices/sound/multipcm.cpp
+++ b/src/devices/sound/multipcm.cpp
@@ -38,7 +38,6 @@
#include "multipcm.h"
#include "wavwrite.h"
-ALLOW_SAVE_TYPE(multipcm_device::state_t); // allow save_item on a non-fundamental type
/*******************************
ENVELOPE SECTION
diff --git a/src/devices/sound/s14001a.cpp b/src/devices/sound/s14001a.cpp
index 50f2ca07eaa..b1338699173 100644
--- a/src/devices/sound/s14001a.cpp
+++ b/src/devices/sound/s14001a.cpp
@@ -210,8 +210,6 @@ s14001a_device::s14001a_device(const machine_config &mconfig, const char *tag, d
// device_start - device-specific startup
//-------------------------------------------------
-ALLOW_SAVE_TYPE(s14001a_device::states); // allow save_item on a non-fundamental type
-
void s14001a_device::device_start()
{
m_stream = stream_alloc(0, 1, clock() ? clock() : machine().sample_rate());
diff --git a/src/devices/sound/s_dsp.cpp b/src/devices/sound/s_dsp.cpp
index 98cd204b503..6da6d3c4a60 100644
--- a/src/devices/sound/s_dsp.cpp
+++ b/src/devices/sound/s_dsp.cpp
@@ -135,9 +135,6 @@ static const int ENVCNT[0x20]
};
-ALLOW_SAVE_TYPE(s_dsp_device::env_state_t32);
-
-
DEFINE_DEVICE_TYPE(S_DSP, s_dsp_device, "s_dsp", "Nintendo/Sony S-DSP")
diff --git a/src/devices/video/huc6270.cpp b/src/devices/video/huc6270.cpp
index 09f49963ba9..e384d53932e 100644
--- a/src/devices/video/huc6270.cpp
+++ b/src/devices/video/huc6270.cpp
@@ -80,9 +80,6 @@ enum {
DVSSR = 0x13
};
-ALLOW_SAVE_TYPE(huc6270_device::v_state);
-ALLOW_SAVE_TYPE(huc6270_device::h_state);
-
/* Bits in the VDC status register */
#define HUC6270_BSY 0x40 /* Set when the VDC accesses VRAM */
diff --git a/src/devices/video/t6963c.cpp b/src/devices/video/t6963c.cpp
index a853e6d7b00..3d3f85c0945 100644
--- a/src/devices/video/t6963c.cpp
+++ b/src/devices/video/t6963c.cpp
@@ -26,8 +26,6 @@ DEFINE_DEVICE_TYPE(LM24014H, lm24014h_device, "lm24014h", "LM24014H LCD Unit (24
// T6963C LCD CONTROLLER
//**************************************************************************
-ALLOW_SAVE_TYPE(t6963c_device::auto_mode);
-
//-------------------------------------------------
// t6963c_device - constructor
//-------------------------------------------------
diff --git a/src/devices/video/tms3556.cpp b/src/devices/video/tms3556.cpp
index 3088e02e685..688d41466d0 100644
--- a/src/devices/video/tms3556.cpp
+++ b/src/devices/video/tms3556.cpp
@@ -44,8 +44,6 @@
#define VDP_BAGC3 m_address_regs[6]
#define VDP_BAMTF m_address_regs[7]
-ALLOW_SAVE_TYPE(tms3556_device::dma_mode_tt);
-
//**************************************************************************
diff --git a/src/emu/debug/dvsave.cpp b/src/emu/debug/dvsave.cpp
index 67fc5707a97..efea78a58c4 100644
--- a/src/emu/debug/dvsave.cpp
+++ b/src/emu/debug/dvsave.cpp
@@ -60,7 +60,7 @@ void debug_view_save::reset()
void debug_view_save::build_list_recursive(save_registered_item &item, uintptr_t objbase, int depth, int count)
{
// update the base pointer and forward if a trivial unwrap
- if (item.unwrap_and_update_objbase(objbase))
+ if (item.unwrap_and_update_base(objbase))
return build_list_recursive(item.subitems().front(), objbase, depth, count);
// switch off the type
@@ -85,27 +85,35 @@ void debug_view_save::build_list_recursive(save_registered_item &item, uintptr_t
break;
// arrays are multiples of a single item
- default:
- if (m_type < save_registered_item::TYPE_ARRAY)
+ case save_registered_item::TYPE_STATIC_ARRAY:
+ case save_registered_item::TYPE_RUNTIME_ARRAY:
+ {
+ m_save_list.push_back(save_item(item, objbase, depth, count));
+ auto subitem = item.subitems().begin();
+ auto last = std::prev(item.subitems().end());
+ int items_per_row = 1;
+ if (subitem == last)
{
- m_save_list.push_back(save_item(item, objbase, depth, count));
- auto &subitem = item.subitems().front();
- int items_per_row = 1;
- if (subitem.type() == save_registered_item::TYPE_BOOL)
+ if (subitem->type() == save_registered_item::TYPE_BOOL)
items_per_row = 32;
- else if (subitem.type() == save_registered_item::TYPE_INT || subitem.type() == save_registered_item::TYPE_UINT)
+ else if (subitem->is_int())
{
- if (subitem.native_size() <= 2)
- items_per_row = 16 / subitem.native_size();
+ if (subitem->native_size() <= 2)
+ items_per_row = 16 / subitem->native_size();
else
- items_per_row = 32 / subitem.native_size();
+ items_per_row = 32 / subitem->native_size();
}
- else if (subitem.type() == save_registered_item::TYPE_FLOAT)
+ else if (subitem->type() == save_registered_item::TYPE_FLOAT)
items_per_row = 4;
- for (uint32_t rep = 0; rep < item.count(); rep += items_per_row)
- build_list_recursive(subitem, objbase + rep * item.native_size(), depth + 1, std::min<int>(items_per_row, item.count() - rep));
+ }
+ for (uint32_t rep = 0; rep < item.count(); rep += items_per_row)
+ {
+ build_list_recursive(*subitem, objbase + rep * item.native_size(), depth + 1, std::min<int>(items_per_row, item.count() - rep));
+ if (subitem != last)
+ ++subitem;
}
break;
+ }
}
}
@@ -293,7 +301,7 @@ std::string debug_view_save::save_item::value()
std::string debug_view_save::save_item::value(save_registered_item &item, int count, uintptr_t objbase, bool collapsed)
{
// update the base pointer and forward if a trivial unwrap
- if (item.unwrap_and_update_objbase(objbase))
+ if (item.unwrap_and_update_base(objbase))
return value(item.subitems().front(), 0, objbase, collapsed);
char tempbuf[256];
@@ -377,25 +385,30 @@ std::string debug_view_save::save_item::value(save_registered_item &item, int co
}
// arrays are multiples of a single item
- default:
- if (item.type() < save_registered_item::TYPE_ARRAY)
+ case save_registered_item::TYPE_STATIC_ARRAY:
+ case save_registered_item::TYPE_RUNTIME_ARRAY:
+ {
+ if (!collapsed)
+ catprintf(tempbuf, pos, "[%d]", item.count());
+ else
{
- if (!collapsed)
- catprintf(tempbuf, pos, "[%d]", item.count());
- else
+ catprintf(tempbuf, pos, "[");
+ auto subitem = item.subitems().begin();
+ auto last = std::prev(item.subitems().end());
+ for (int num = 0; num < item.count(); num++)
{
- catprintf(tempbuf, pos, "[");
- auto &subitem = item.subitems().front();
- for (int num = 0; num < item.count(); num++)
- {
- std::string val = value(subitem, 0, objbase + num * item.native_size(), true);
- if (!catprintf(tempbuf, pos, "%s%s", (num == 0) ? "" : ",", val.c_str()))
- break;
- }
- catprintf(tempbuf, pos, "]");
+ std::string val = value(*subitem, 0, objbase + num * item.native_size(), true);
+ if (!catprintf(tempbuf, pos, "%s%s", (num == 0) ? "" : ",", val.c_str()))
+ break;
+ if (subitem != last)
+ ++subitem;
}
- return tempbuf;
+ catprintf(tempbuf, pos, "]");
}
+ return tempbuf;
+ }
+
+ default:
return "(unknown)";
}
}
diff --git a/src/emu/debug/dvsave.h b/src/emu/debug/dvsave.h
index 9a85aa2c339..0290008789d 100644
--- a/src/emu/debug/dvsave.h
+++ b/src/emu/debug/dvsave.h
@@ -50,12 +50,7 @@ private:
{
}
- bool collapsible() const
- {
- return (m_item.type() == save_registered_item::TYPE_CONTAINER ||
- m_item.type() == save_registered_item::TYPE_STRUCT ||
- m_item.type() < save_registered_item::TYPE_ARRAY);
- }
+ bool collapsible() const { return (m_item.is_struct_or_container() || m_item.is_array()); }
char const *name() const { return m_item.name(); }
std::string value();
save_registered_item::save_type type() const { return m_item.type(); }
diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp
index f57a8624667..7e7952f935e 100644
--- a/src/emu/machine.cpp
+++ b/src/emu/machine.cpp
@@ -263,7 +263,7 @@ void running_machine::start()
save().register_presave(save_prepost_delegate(FUNC(running_machine::presave_all_devices), this));
start_all_devices();
for (device_t &device : device_enumerator(root_device()))
- m_save.root_registrar().reg(device, device.tag());
+ m_save.root_registrar().reg(device, device.tag(), device.type().size());
save().register_postload(save_prepost_delegate(FUNC(running_machine::postload_all_devices), this));
// save outputs created before start time
diff --git a/src/emu/save.cpp b/src/emu/save.cpp
index c23b27b0218..26669466746 100644
--- a/src/emu/save.cpp
+++ b/src/emu/save.cpp
@@ -227,8 +227,8 @@ public:
save_zip_state &json_append(char const *buffer);
save_zip_state &json_append_indent(int count);
save_zip_state &json_append_name(char const *name);
- save_zip_state &json_append_signed(int64_t value);
- save_zip_state &json_append_unsigned(uint64_t value);
+ save_zip_state &json_append_signed(s64 value);
+ save_zip_state &json_append_unsigned(u64 value);
save_zip_state &json_append_float(double value);
// stage an item to be output as raw data
@@ -333,12 +333,12 @@ save_zip_state &save_zip_state::json_append_name(char const *name)
// value to the JSON stream
//-------------------------------------------------
-save_zip_state &save_zip_state::json_append_signed(int64_t value)
+save_zip_state &save_zip_state::json_append_signed(s64 value)
{
json_check_reserve();
// quote values that don't fit into a double
- bool quote = (int64_t(double(value)) != value);
+ bool quote = (s64(double(value)) != value);
if (quote)
json_append('"');
@@ -359,12 +359,12 @@ save_zip_state &save_zip_state::json_append_signed(int64_t value)
// integer value to the JSON stream
//-------------------------------------------------
-save_zip_state &save_zip_state::json_append_unsigned(uint64_t value)
+save_zip_state &save_zip_state::json_append_unsigned(u64 value)
{
json_check_reserve();
// quote values that don't fit into a double
- bool quote = (uint64_t(double(value)) != value);
+ bool quote = (u64(double(value)) != value);
if (quote)
json_append('"');
@@ -912,8 +912,8 @@ public:
bool json_matches(char target);
bool json_matches(char const *target);
bool json_parse_number(double &result);
- bool json_parse_int_string(int64_t &result);
- bool json_parse_uint_string(uint64_t &result);
+ bool json_parse_int_string(s64 &result);
+ bool json_parse_uint_string(u64 &result);
bool json_parse_string(std::string &result);
// initialize, checking the input file basic validity
@@ -1031,7 +1031,7 @@ bool load_zip_state::json_parse_number(double &result)
// integer from a string
//-------------------------------------------------
-bool load_zip_state::json_parse_int_string(int64_t &result)
+bool load_zip_state::json_parse_int_string(s64 &result)
{
if (!json_matches('"'))
return false;
@@ -1046,7 +1046,7 @@ bool load_zip_state::json_parse_int_string(int64_t &result)
// integer from a string
//-------------------------------------------------
-bool load_zip_state::json_parse_uint_string(uint64_t &result)
+bool load_zip_state::json_parse_uint_string(u64 &result)
{
if (!json_matches('"'))
return false;
@@ -1276,15 +1276,15 @@ bool load_zip_state::read_data_recursive(zlib_read_streamer &zlib, save_register
save_registered_item::save_registered_item() :
m_ptr_offset(0),
- m_type(TYPE_CONTAINER),
+ m_type_count(TYPE_CONTAINER),
m_native_size(0)
{
}
// constructor for a new item
-save_registered_item::save_registered_item(uintptr_t ptr_offset, save_type type, uint32_t native_size, char const *name) :
+save_registered_item::save_registered_item(uintptr_t ptr_offset, save_type type, u32 native_size, char const *name, u32 count) :
m_ptr_offset(ptr_offset),
- m_type(type),
+ m_type_count(u32(type) | (count << 4)),
m_native_size(native_size),
m_name(name)
{
@@ -1300,12 +1300,11 @@ save_registered_item::save_registered_item(uintptr_t ptr_offset, save_type type,
// append - append a new item to the current one
//-------------------------------------------------
-std::string type_string(save_registered_item::save_type type, uint32_t native_size)
+std::string type_string(save_registered_item::save_type type, u32 native_size)
{
switch (type)
{
case save_registered_item::TYPE_CONTAINER: return "CONTAINER";
- case save_registered_item::TYPE_POINTER: return "POINTER";
case save_registered_item::TYPE_UNIQUE: return "UNIQUE";
case save_registered_item::TYPE_VECTOR: return "VECTOR";
case save_registered_item::TYPE_STRUCT: return "STRUCT";
@@ -1317,7 +1316,7 @@ std::string type_string(save_registered_item::save_type type, uint32_t native_si
}
}
-save_registered_item &save_registered_item::append(uintptr_t ptr_offset, save_type type, uint32_t native_size, char const *name)
+save_registered_item &save_registered_item::append(uintptr_t ptr_offset, save_type type, u32 native_size, char const *name, u32 count)
{
// make sure there are no duplicates
if (find(name) != nullptr)
@@ -1326,7 +1325,7 @@ save_registered_item &save_registered_item::append(uintptr_t ptr_offset, save_ty
//printf("%s '%s': adding %s '%s' @ %llX, size %d\n", type_string(m_type, m_native_size).c_str(), m_name.c_str(), type_string(type, native_size).c_str(), name, ptr_offset, native_size);
// add the item to the back of the list
- m_items.emplace_back(ptr_offset, type, native_size, name);
+ m_items.emplace_back(ptr_offset, type, native_size, name, count);
return m_items.back();
}
@@ -1350,6 +1349,44 @@ save_registered_item *save_registered_item::find(char const *name)
//-------------------------------------------------
+// is_replicatable - can this item be replicated
+// across an array?
+//-------------------------------------------------
+
+bool save_registered_item::is_replicatable(bool parent_is_array) const
+{
+ switch (type())
+ {
+ // numeric types are always replicatable
+ case TYPE_BOOL:
+ case TYPE_INT:
+ case TYPE_UINT:
+ case TYPE_FLOAT:
+ return true;
+
+ // unique pointers, vectors, and runtime arrays are non-replicatable
+ case TYPE_UNIQUE:
+ case TYPE_VECTOR:
+ case TYPE_RUNTIME_ARRAY:
+ return false;
+
+ // structs, containers, and static arrays are replicatable if all their owned items are
+ case TYPE_STATIC_ARRAY:
+ case TYPE_CONTAINER:
+ case TYPE_STRUCT:
+ for (auto &item : m_items)
+ if (!item.is_replicatable(false))
+ return false;
+ return true;
+
+ // when it doubt, no
+ default:
+ return false;
+ }
+}
+
+
+//-------------------------------------------------
// sort_and_prune - prune empty subitems and
// sort them by name
//-------------------------------------------------
@@ -1370,7 +1407,7 @@ bool save_registered_item::sort_and_prune()
}
// then sort the rest if we have more than 1
- if (m_items.size() > 1)
+ if (is_struct_or_container() && m_items.size() > 1)
m_items.sort([] (auto const &x, auto const &y) { return (std::strcmp(x.name(), y.name()) < 0); });
// return true if we have nothing
@@ -1379,17 +1416,17 @@ bool save_registered_item::sort_and_prune()
//-------------------------------------------------
-// unwrap_and_update_objbase - unwrap trivial
-// type and update the object base
+// unwrap_and_update_base - unwrap special
+// types and update the object base
//-------------------------------------------------
-bool save_registered_item::unwrap_and_update_objbase(uintptr_t &objbase) const
+bool save_registered_item::unwrap_and_update_base(uintptr_t &objbase) const
{
// update the base pointer with our local base/offset
objbase += m_ptr_offset;
// switch off the type
- switch (m_type)
+ switch (type())
{
// unique ptrs retrieve the pointer from their container
case TYPE_UNIQUE:
@@ -1401,11 +1438,6 @@ bool save_registered_item::unwrap_and_update_objbase(uintptr_t &objbase) const
objbase = reinterpret_cast<uintptr_t>(&(*reinterpret_cast<generic_vector *>(objbase))[0]);
return true;
- // pointers just extract the pointer directly
- case TYPE_POINTER:
- objbase = reinterpret_cast<uintptr_t>(*reinterpret_cast<generic_pointer *>(objbase));
- return true;
-
// containers are always based at 0
case TYPE_CONTAINER:
objbase = 0;
@@ -1423,15 +1455,15 @@ bool save_registered_item::unwrap_and_update_objbase(uintptr_t &objbase) const
// items into a binary form
//-------------------------------------------------
-uint64_t save_registered_item::save_binary(uint8_t *ptr, uint64_t length, uintptr_t objbase) const
+u64 save_registered_item::save_binary(u8 *ptr, u64 length, uintptr_t objbase) const
{
- // update the base pointer and forward if a trivial unwrap
- if (unwrap_and_update_objbase(objbase))
+ // update the base pointer and forward if a special unwrap
+ if (unwrap_and_update_base(objbase))
return m_items.front().save_binary(ptr, length, objbase);
// switch off the type
- uint64_t offset = 0;
- switch (m_type)
+ u64 offset = 0;
+ switch (type())
{
// boolean types save as a single byte
case TYPE_BOOL:
@@ -1457,14 +1489,19 @@ uint64_t save_registered_item::save_binary(uint8_t *ptr, uint64_t length, uintpt
break;
// arrays are multiples of a single item
- default:
- if (is_array())
+ case TYPE_STATIC_ARRAY:
+ case TYPE_RUNTIME_ARRAY:
+ {
+ auto item = m_items.begin();
+ auto last = std::prev(m_items.end());
+ for (u32 rep = 0; rep < count(); rep++)
{
- auto &item = m_items.front();
- for (uint32_t rep = 0; rep < m_type; rep++)
- offset += item.save_binary(&ptr[offset], (offset < length) ? length - offset : 0, objbase + rep * m_native_size);
+ offset += item->save_binary(&ptr[offset], (offset < length) ? length - offset : 0, objbase + rep * m_native_size);
+ if (item != last)
+ ++item;
}
break;
+ }
}
return offset;
}
@@ -1475,15 +1512,15 @@ uint64_t save_registered_item::save_binary(uint8_t *ptr, uint64_t length, uintpt
// owned items from binary form
//-------------------------------------------------
-uint64_t save_registered_item::restore_binary(uint8_t const *ptr, uint64_t length, uintptr_t objbase) const
+u64 save_registered_item::restore_binary(u8 const *ptr, u64 length, uintptr_t objbase) const
{
// update the base pointer and forward if a trivial unwrap
- if (unwrap_and_update_objbase(objbase))
+ if (unwrap_and_update_base(objbase))
return m_items.front().restore_binary(ptr, length, objbase);
// switch off the type
- uint64_t offset = 0;
- switch (m_type)
+ u64 offset = 0;
+ switch (type())
{
// boolean types save as a single byte
case TYPE_BOOL:
@@ -1509,14 +1546,19 @@ uint64_t save_registered_item::restore_binary(uint8_t const *ptr, uint64_t lengt
break;
// arrays are multiples of a single item
- default:
- if (is_array())
+ case TYPE_STATIC_ARRAY:
+ case TYPE_RUNTIME_ARRAY:
+ {
+ auto item = m_items.begin();
+ auto last = std::prev(m_items.end());
+ for (u32 rep = 0; rep < count(); rep++)
{
- auto &item = m_items.front();
- for (uint32_t rep = 0; rep < m_type; rep++)
- offset += item.restore_binary(&ptr[offset], (offset < length) ? length - offset : 0, objbase + rep * m_native_size);
+ offset += item->restore_binary(&ptr[offset], (offset < length) ? length - offset : 0, objbase + rep * m_native_size);
+ if (item != last)
+ ++item;
}
break;
+ }
}
return offset;
}
@@ -1529,7 +1571,7 @@ uint64_t save_registered_item::restore_binary(uint8_t const *ptr, uint64_t lengt
void save_registered_item::save_json(save_zip_state &zipstate, char const *nameprefix, int indent, bool inline_form, uintptr_t objbase)
{
// update the base pointer and forward if a trivial unwrap
- if (unwrap_and_update_objbase(objbase))
+ if (unwrap_and_update_base(objbase))
return m_items.front().save_json(zipstate, nameprefix, indent, inline_form, objbase);
// update the name prefix
@@ -1545,7 +1587,7 @@ void save_registered_item::save_json(save_zip_state &zipstate, char const *namep
zipstate.json_append_name(m_name.c_str());
// switch off the type
- switch (m_type)
+ switch (type())
{
// boolean types
case TYPE_BOOL:
@@ -1599,75 +1641,75 @@ void save_registered_item::save_json(save_zip_state &zipstate, char const *namep
break;
// arrays are multiples of a single item
- default:
- if (is_array())
+ case TYPE_STATIC_ARRAY:
+ case TYPE_RUNTIME_ARRAY:
+ {
+ // look for large arrays of ints/floats
+ u32 total, unitsize;
+ if (is_endpoint_array(total, unitsize) && total * unitsize >= save_zip_state::JSON_EXTERNAL_BINARY_THRESHOLD)
{
- auto &item = m_items.front();
+ char const *filename = zipstate.add_data_file(localname.c_str(), *this, objbase);
+
+ zipstate.json_append('[').json_append('{');
+ zipstate.json_append_name("external_file");
+ zipstate.json_append('"').json_append(filename).json_append('"').json_append(',');
+ zipstate.json_append_name("unit");
+ zipstate.json_append_signed(unitsize).json_append(',');
+ zipstate.json_append_name("count");
+ zipstate.json_append_signed(total).json_append(',');
+ zipstate.json_append_name("little_endian");
+ zipstate.json_append((ENDIANNESS_NATIVE == ENDIANNESS_LITTLE) ? "true" : "false");
+ zipstate.json_append('}').json_append(']');
+ }
+ else
+ {
+ auto item = m_items.begin();
+ auto last = std::prev(m_items.end());
- // look for large arrays of ints/floats
- save_registered_item *inner = &item;
- u32 total = count();
- while (inner->is_array())
+ // compute the size of an item to determine if we show it inline
+ u32 item_size = item->compute_binary_size(objbase);
+ if (inline_form || count() * item_size <= 16)
{
- total *= inner->count();
- inner = &inner->m_items.front();
- }
- if (inner->is_int_or_float() && total * inner->m_native_size >= save_zip_state::JSON_EXTERNAL_BINARY_THRESHOLD)
- {
- char const *filename = zipstate.add_data_file(localname.c_str(), *this, objbase);
-
- zipstate.json_append('[').json_append('{');
- zipstate.json_append_name("external_file");
- zipstate.json_append('"').json_append(filename).json_append('"').json_append(',');
- zipstate.json_append_name("unit");
- zipstate.json_append_signed(inner->m_native_size).json_append(',');
- zipstate.json_append_name("count");
- zipstate.json_append_signed(total).json_append(',');
- zipstate.json_append_name("little_endian");
- zipstate.json_append((ENDIANNESS_NATIVE == ENDIANNESS_LITTLE) ? "true" : "false");
- zipstate.json_append('}').json_append(']');
+ // strictly inline form outputs everything on a single line
+ zipstate.json_append('[');
+ for (u32 rep = 0; rep < count(); rep++)
+ {
+ item->save_json(zipstate, localname.c_str(), 0, true, objbase + rep * m_native_size);
+ if (rep != count() - 1)
+ zipstate.json_append(',');
+ if (item != last)
+ ++item;
+ }
+ zipstate.json_append(']');
}
else
{
- uint32_t item_size = item.compute_binary_size(objbase);
- if (inline_form || m_type * item_size <= 16)
- {
- // strictly inline form outputs everything on a single line
- zipstate.json_append('[');
- for (uint32_t rep = 0; rep < m_type; rep++)
- {
- item.save_json(zipstate, localname.c_str(), 0, true, objbase + rep * m_native_size);
- if (rep != m_type - 1)
- zipstate.json_append(',');
- }
- zipstate.json_append(']');
- }
- else
+ // normal form outputs a certain number of items per row
+ zipstate.json_append('[').json_append_eol();
+ u32 items_per_row = 1;
+ if (item->is_int_or_float())
+ items_per_row = (item_size <= 2) ? 32 : 16;
+
+ // iterate over the items
+ for (u32 rep = 0; rep < count(); rep++)
{
- // normal form outputs a certain number of items per row
- zipstate.json_append('[').json_append_eol();
- uint32_t items_per_row = 1;
- if (item.is_int_or_float())
- items_per_row = (item_size <= 2) ? 32 : 16;
-
- // iterate over the items
- for (uint32_t rep = 0; rep < m_type; rep++)
- {
- if (rep % items_per_row == 0)
- zipstate.json_append_indent(indent + 1);
- item.save_json(zipstate, localname.c_str(), indent + 1, false, objbase + rep * m_native_size);
- if (rep != m_type - 1)
- zipstate.json_append(',');
- if (rep % items_per_row == items_per_row - 1)
- zipstate.json_append_eol();
- }
- if (m_type % items_per_row != 0)
+ if (rep % items_per_row == 0)
+ zipstate.json_append_indent(indent + 1);
+ item->save_json(zipstate, localname.c_str(), indent + 1, false, objbase + rep * m_native_size);
+ if (rep != count() - 1)
+ zipstate.json_append(',');
+ if (rep % items_per_row == items_per_row - 1)
zipstate.json_append_eol();
- zipstate.json_append_indent(indent).json_append(']');
+ if (item != last)
+ ++item;
}
+ if (count() % items_per_row != 0)
+ zipstate.json_append_eol();
+ zipstate.json_append_indent(indent).json_append(']');
}
}
break;
+ }
}
}
@@ -1680,7 +1722,7 @@ void save_registered_item::save_json(save_zip_state &zipstate, char const *namep
void save_registered_item::restore_json(load_zip_state &input, char const *nameprefix, json_restore_mode mode, uintptr_t objbase)
{
// update the base pointer and forward if a trivial unwrap
- if (unwrap_and_update_objbase(objbase))
+ if (unwrap_and_update_base(objbase))
return m_items.front().restore_json(input, nameprefix, mode, objbase);
// update the name prefix
@@ -1693,7 +1735,7 @@ void save_registered_item::restore_json(load_zip_state &input, char const *namep
}
// switch off the type
- switch (m_type)
+ switch (type())
{
// boolean types
case TYPE_BOOL:
@@ -1716,12 +1758,12 @@ void save_registered_item::restore_json(load_zip_state &input, char const *namep
case TYPE_INT:
{
double dvalue;
- int64_t ivalue;
+ s64 ivalue;
if (input.json_parse_number(dvalue))
{
if (mode == RESTORE_DATA && !write_int_signed(objbase, m_native_size, dvalue))
input.report_warning("%s: Value of out range: %1.17g", localname.c_str(), dvalue);
- else if (mode == COMPARE_DATA && read_int_signed(objbase, m_native_size) != int64_t(dvalue))
+ else if (mode == COMPARE_DATA && read_int_signed(objbase, m_native_size) != s64(dvalue))
input.report_warning("%s: Compare failed: JSON says %I64d, data says %1.17g", localname.c_str(), dvalue, read_int_signed(objbase, m_native_size));
}
else if (input.json_parse_int_string(ivalue))
@@ -1740,12 +1782,12 @@ void save_registered_item::restore_json(load_zip_state &input, char const *namep
case TYPE_UINT:
{
double dvalue;
- uint64_t ivalue;
+ u64 ivalue;
if (input.json_parse_number(dvalue))
{
if (mode == RESTORE_DATA && !write_int_unsigned(objbase, m_native_size, dvalue))
input.report_warning("%s: Value of out range: %1.17g", localname.c_str(), dvalue);
- else if (mode == COMPARE_DATA && read_int_unsigned(objbase, m_native_size) != uint64_t(dvalue))
+ else if (mode == COMPARE_DATA && read_int_unsigned(objbase, m_native_size) != u64(dvalue))
input.report_warning("%s: Compare failed: JSON says %I64d, data says %1.17g", localname.c_str(), dvalue, read_int_unsigned(objbase, m_native_size));
}
else if (input.json_parse_uint_string(ivalue))
@@ -1789,7 +1831,7 @@ void save_registered_item::restore_json(load_zip_state &input, char const *namep
save_registered_item *target = find(name.c_str());
if (target == nullptr)
input.report_warning("%s: Found extraneous item '%s'", localname.c_str(), name.c_str());
- target->restore_json(input, nameprefix, (target == nullptr) ? PARSE_ONLY : mode, objbase);
+ target->restore_json(input, localname.c_str(), (target == nullptr) ? PARSE_ONLY : mode, objbase);
if (input.json_matches('}'))
break;
if (!input.json_matches(','))
@@ -1798,35 +1840,38 @@ void save_registered_item::restore_json(load_zip_state &input, char const *namep
break;
// arrays are multiples of a single item
- default:
- if (is_array())
+ case TYPE_STATIC_ARRAY:
+ case TYPE_RUNTIME_ARRAY:
+ {
+ auto item = m_items.begin();
+ auto last = std::prev(m_items.end());
+ if (!input.json_matches('['))
+ input.report_error(STATERR_INCOMPATIBLE_DATA, "%s: Expected '['", localname.c_str());
+ if (parse_external_data(input, *this, localname.c_str(), mode, objbase))
{
- auto &item = m_items.front();
- if (!input.json_matches('['))
- input.report_error(STATERR_INCOMPATIBLE_DATA, "%s: Expected '['", localname.c_str());
- if (parse_external_data(input, *this, localname.c_str(), mode, objbase))
- {
- if (!input.json_matches(']'))
- input.report_error(STATERR_MALFORMED_JSON, "%s: Expected ']'", localname.c_str());
- }
- else
- {
- u32 rep = 0;
- if (!input.json_matches(']'))
- while (1)
- {
- item.restore_json(input, nameprefix, (rep >= count()) ? PARSE_ONLY : mode, objbase + rep * m_native_size);
- rep++;
- if (input.json_matches(']'))
- break;
- if (!input.json_matches(','))
- input.report_error(STATERR_MALFORMED_JSON, "%s: Expected ','", localname.c_str());
- }
- if (rep != count())
- input.report_warning("%s: Found %s array items than expected", localname.c_str(), (rep < count()) ? "fewer" : "more");
- }
+ if (!input.json_matches(']'))
+ input.report_error(STATERR_MALFORMED_JSON, "%s: Expected ']'", localname.c_str());
+ }
+ else
+ {
+ u32 rep = 0;
+ if (!input.json_matches(']'))
+ while (1)
+ {
+ item->restore_json(input, localname.c_str(), (rep >= count()) ? PARSE_ONLY : mode, objbase + rep * m_native_size);
+ rep++;
+ if (item != last)
+ ++item;
+ if (input.json_matches(']'))
+ break;
+ if (!input.json_matches(','))
+ input.report_error(STATERR_MALFORMED_JSON, "%s: Expected ','", localname.c_str());
+ }
+ if (rep != count())
+ input.report_warning("%s: Found %s array items than expected", localname.c_str(), (rep < count()) ? "fewer" : "more");
}
break;
+ }
}
}
@@ -1926,14 +1971,14 @@ bool save_registered_item::parse_external_data(load_zip_state &input, save_regis
// of the given size
//-------------------------------------------------
-uint64_t save_registered_item::read_int_unsigned(uintptr_t objbase, int size) const
+u64 save_registered_item::read_int_unsigned(uintptr_t objbase, int size) const
{
switch (size)
{
- case 1: return *reinterpret_cast<uint8_t const *>(objbase);
- case 2: return *reinterpret_cast<uint16_t const *>(objbase);
- case 4: return *reinterpret_cast<uint32_t const *>(objbase);
- case 8: return *reinterpret_cast<uint64_t const *>(objbase);
+ case 1: return *reinterpret_cast<u8 const *>(objbase);
+ case 2: return *reinterpret_cast<u16 const *>(objbase);
+ case 4: return *reinterpret_cast<u32 const *>(objbase);
+ case 8: return *reinterpret_cast<u64 const *>(objbase);
}
return 0;
}
@@ -1944,14 +1989,14 @@ uint64_t save_registered_item::read_int_unsigned(uintptr_t objbase, int size) co
// given size
//-------------------------------------------------
-int64_t save_registered_item::read_int_signed(uintptr_t objbase, int size) const
+s64 save_registered_item::read_int_signed(uintptr_t objbase, int size) const
{
switch (size)
{
- case 1: return *reinterpret_cast<int8_t const *>(objbase);
- case 2: return *reinterpret_cast<int16_t const *>(objbase);
- case 4: return *reinterpret_cast<int32_t const *>(objbase);
- case 8: return *reinterpret_cast<int64_t const *>(objbase);
+ case 1: return *reinterpret_cast<s8 const *>(objbase);
+ case 2: return *reinterpret_cast<s16 const *>(objbase);
+ case 4: return *reinterpret_cast<s32 const *>(objbase);
+ case 8: return *reinterpret_cast<s64 const *>(objbase);
}
return 0;
}
@@ -1978,21 +2023,21 @@ double save_registered_item::read_float(uintptr_t objbase, int size) const
// the given size
//-------------------------------------------------
-bool save_registered_item::write_int_signed(uintptr_t objbase, int size, int64_t data) const
+bool save_registered_item::write_int_signed(uintptr_t objbase, int size, s64 data) const
{
switch (size)
{
- case 1: *reinterpret_cast<int8_t *>(objbase) = int8_t(data); return (data >= -0x80 && data <= 0x7f);
- case 2: *reinterpret_cast<int16_t *>(objbase) = int16_t(data); return (data >= -0x8000 && data <= 0x7fff);
- case 4: *reinterpret_cast<int32_t *>(objbase) = int32_t(data); return (data >= -0x80000000ll && data <= 0x7fffffffll);
- case 8: *reinterpret_cast<int64_t *>(objbase) = int64_t(data); return true;
+ case 1: *reinterpret_cast<s8 *>(objbase) = s8(data); return (data >= -0x80 && data <= 0x7f);
+ case 2: *reinterpret_cast<s16 *>(objbase) = s16(data); return (data >= -0x8000 && data <= 0x7fff);
+ case 4: *reinterpret_cast<s32 *>(objbase) = s32(data); return (data >= -0x80000000ll && data <= 0x7fffffffll);
+ case 8: *reinterpret_cast<s64 *>(objbase) = s64(data); return true;
}
return false;
}
bool save_registered_item::write_int_signed(uintptr_t objbase, int size, double data) const
{
- int64_t converted = int64_t(data);
+ s64 converted = s64(data);
bool ok = (double(converted) == data);
return write_int_signed(objbase, size, converted) && ok;
}
@@ -2003,21 +2048,21 @@ bool save_registered_item::write_int_signed(uintptr_t objbase, int size, double
// of the given size
//-------------------------------------------------
-bool save_registered_item::write_int_unsigned(uintptr_t objbase, int size, uint64_t data) const
+bool save_registered_item::write_int_unsigned(uintptr_t objbase, int size, u64 data) const
{
switch (size)
{
- case 1: *reinterpret_cast<uint8_t *>(objbase) = uint8_t(data); return (data <= 0xff);
- case 2: *reinterpret_cast<uint16_t *>(objbase) = uint16_t(data); return (data <= 0xffff);
- case 4: *reinterpret_cast<uint32_t *>(objbase) = uint32_t(data); return (data <= 0xffffffffull);
- case 8: *reinterpret_cast<uint64_t *>(objbase) = uint64_t(data); return true;
+ case 1: *reinterpret_cast<u8 *>(objbase) = u8(data); return (data <= 0xff);
+ case 2: *reinterpret_cast<u16 *>(objbase) = u16(data); return (data <= 0xffff);
+ case 4: *reinterpret_cast<u32 *>(objbase) = u32(data); return (data <= 0xffffffffull);
+ case 8: *reinterpret_cast<u64 *>(objbase) = u64(data); return true;
}
return false;
}
bool save_registered_item::write_int_unsigned(uintptr_t objbase, int size, double data) const
{
- uint64_t converted = uint64_t(data);
+ u64 converted = u64(data);
bool ok = (data >= 0 && double(converted) == data);
return write_int_unsigned(objbase, size, converted) && ok;
}
@@ -2039,6 +2084,37 @@ bool save_registered_item::write_float(uintptr_t objbase, int size, double data)
}
+//-------------------------------------------------
+// is_endpoint_array - return true if this item
+// is a (multi-dimensional) array of an endpoint
+// type
+//-------------------------------------------------
+
+bool save_registered_item::is_endpoint_array(u32 &total, u32 &unitsize) const
+{
+ // we must be an array ourselves
+ if (!is_array())
+ return false;
+
+ // scan downward through simple arrays
+ save_registered_item const *current = this;
+ total = 1;
+ while (current->is_array() && current->m_items.size() == 1)
+ {
+ total *= current->count();
+ current = &current->m_items.front();
+ }
+
+ // if we didn't end at an endpoint type, fail
+ if (!current->is_int_or_float())
+ return false;
+
+ // set the unit size and return true
+ unitsize = current->native_size();
+ return true;
+}
+
+
//**************************************************************************
// SAVE MANAGER
diff --git a/src/emu/save.h b/src/emu/save.h
index 368a9584882..e826b38dddb 100644
--- a/src/emu/save.h
+++ b/src/emu/save.h
@@ -51,43 +51,22 @@ enum save_error
// MACROS
//**************************************************************************
-/*
-TEST:
-#define REGISTER_SAVE_1(a) .reg(a, #a)
-#define REGISTER_SAVE_2(a,b) REGISTER_SAVE_1(a) REGISTER_SAVE_1(b)
-#define REGISTER_SAVE_3(a,b,c) REGISTER_SAVE_1(a) REGISTER_SAVE_2(b,c)
-#define REGISTER_SAVE_4(a,b,c,d) REGISTER_SAVE_1(a) REGISTER_SAVE_3(b,c,d)
-#define REGISTER_SAVE_5(a,b,c,d,e) REGISTER_SAVE_1(a) REGISTER_SAVE_4(b,c,d,e)
-#define REGISTER_SAVE_6(a,b,c,d,e,f) REGISTER_SAVE_1(a) REGISTER_SAVE_5(b,c,d,e,f)
-#define REGISTER_SAVE_7(a,b,c,d,e,f,g) REGISTER_SAVE_1(a) REGISTER_SAVE_6(b,c,d,e,f,g)
-#define REGISTER_SAVE_8(a,b,c,d,e,f,g,h) REGISTER_SAVE_1(a) REGISTER_SAVE_7(b,c,d,e,f,g,h)
-#define REGISTER_SAVE_9(a,b,c,d,e,f,g,h,i) REGISTER_SAVE_1(a) REGISTER_SAVE_8(b,c,d,e,f,g,h,i)
-
-#define GET_SAVE_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, NAME, ...) NAME
-#define REGISTER_SAVE(...) GET_SAVE_N(__VA_ARGS__, REGISTER_SAVE_9, REGISTER_SAVE_8, REGISTER_SAVE_7, REGISTER_SAVE_6, REGISTER_SAVE_5, REGISTER_SAVE_4, REGISTER_SAVE_3, REGISTER_SAVE_2, REGISTER_SAVE_1)(__VA_ARGS__)
-*/
-
-
// callback delegate for presave/postload
typedef named_delegate<void ()> save_prepost_delegate;
-
+// use this macro to save a given type as a signed integer
#define SAVE_TYPE_AS_INT(Type) \
template<> struct save_registrar::is_signed_int_like<Type> { static constexpr bool value = true; };
+// use this macro to save a given type as an unsigned integer
#define SAVE_TYPE_AS_UINT(Type) \
template<> struct save_registrar::is_unsigned_int_like<Type> { static constexpr bool value = true; };
+// use this macro to save a given type as a floating-point value
#define SAVE_TYPE_AS_FLOAT(Type) \
template<> struct save_registrar::is_floating_point_like<Type> { static constexpr bool value = true; };
-
-// remove me
-#define ALLOW_SAVE_TYPE(TYPE)
-#define ALLOW_SAVE_TYPE_AND_VECTOR(TYPE)
-
-
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -119,86 +98,101 @@ public:
};
// the various types supported
- enum save_type : uint32_t
+ enum save_type : u32
{
- TYPE_ARRAY = 0xffff0000, // array is relative, and contains 1 data item that is replicated
- TYPE_CONTAINER, // container is absolute, and contains absolute data
- TYPE_POINTER, // pointer is absolute, and contains 1 data item pointed to by the pointer
- TYPE_UNIQUE, // unique is relative, and contains 1 data item pointed to by std::unique_ptr
- TYPE_VECTOR, // vector is relative, and contains an array of items pointed to by std::vector
- TYPE_STRUCT, // struct is relative, and contains a list of relative items
- TYPE_BOOL, // bool is relative, size 1
- TYPE_INT, // int is relative, same size as native
- TYPE_UINT, // uint is relative, same size as native
- TYPE_FLOAT // float is relative, same size as native
+ // type native_size ptr_offset items
+ TYPE_BOOL, // sizeof(bool) relative none
+ TYPE_INT, // sizeof(value) relative none
+ TYPE_UINT, // sizeof(value) relative none
+ TYPE_FLOAT, // sizeof(value) relative none
+
+ TYPE_CONTAINER, // 0 0 list of contained items
+ TYPE_STRUCT, // sizeof(struct) relative list of contained items
+ TYPE_STATIC_ARRAY, // space-between-elems relative l
+ TYPE_RUNTIME_ARRAY, // space-between-elems relative
+
+ TYPE_UNIQUE, // sizeof(unique_ptr) relative item at pointer
+ TYPE_VECTOR, // sizeof(vector) relative TYPE_RUNTIME_ARRAY at pointer
};
// root constructor
save_registered_item();
// constructor for a new item
- save_registered_item(uintptr_t ptr_offset, save_type type, uint32_t native_size, char const *name);
+ save_registered_item(uintptr_t ptr_offset, save_type type, u32 native_size, char const *name, u32 count = 0);
// simple getters
char const *name() const { return m_name.c_str(); }
- save_type type() const { return m_type; }
- bool is_struct_or_container() const { return (m_type == TYPE_STRUCT || m_type == TYPE_CONTAINER); }
- bool is_array() const { return (m_type < TYPE_ARRAY); }
- bool is_int() const { return (m_type == TYPE_INT || m_type == TYPE_UINT); }
- bool is_int_or_float() const { return (is_int() || m_type == TYPE_FLOAT); }
+ save_type type() const { return save_type(m_type_count & 15); }
+ u32 count() const { return m_type_count >> 4; }
+ bool is_struct_or_container() const { return (type() == TYPE_STRUCT || type() == TYPE_CONTAINER); }
+ bool is_array() const { return (type() == TYPE_STATIC_ARRAY || type() == TYPE_RUNTIME_ARRAY); }
+ bool is_int() const { return (type() == TYPE_INT || type() == TYPE_UINT); }
+ bool is_int_or_float() const { return (is_int() || type() == TYPE_FLOAT); }
std::list<save_registered_item> &subitems() { return m_items; }
- uint32_t native_size() const { return m_native_size; }
- uint32_t count() const { return is_array() ? m_type : 1; }
+ u32 native_size() const { return m_native_size; }
uintptr_t ptr_offset() const { return m_ptr_offset; }
// append a new item to the current one
- save_registered_item &append(uintptr_t ptr_offset, save_type type, uint32_t native_size, char const *name);
+ save_registered_item &append(uintptr_t ptr_offset, save_type type, u32 native_size, char const *name, u32 count = 0);
// find an item by name
save_registered_item *find(char const *name);
+ // is this item replicatable (i.e., can we replicate it for all elements in an array?)
+ bool is_replicatable(bool parent_is_array) const;
+
// sort subitems by name and prune any empty items
bool sort_and_prune();
- // update the object base and unwrap trivial items
- bool unwrap_and_update_objbase(uintptr_t &objbase) const;
+ // update the object base and unwrap special items
+ bool unwrap_and_update_base(uintptr_t &objbase) const;
// compute the binary size by just saving with a null
- uint64_t compute_binary_size(uintptr_t objbase = 0) const { return save_binary(nullptr, 0, objbase); }
+ u64 compute_binary_size(uintptr_t parentbase = 0) const { return save_binary(nullptr, 0, parentbase); }
// save this item and all owned items into a binary form
- uint64_t save_binary(uint8_t *ptr, uint64_t length, uintptr_t objbase = 0) const;
+ u64 save_binary(u8 *ptr, u64 length, uintptr_t parentbase = 0) const;
// restore this item and all owned items from binary form
- uint64_t restore_binary(uint8_t const *ptr, uint64_t length, uintptr_t objbase = 0) const;
+ u64 restore_binary(u8 const *ptr, u64 length, uintptr_t parentbase = 0) const;
// save this item into a JSON stream
- void save_json(save_zip_state &output, char const *nameprefix = "", int indent = 0, bool inline_form = false, uintptr_t objbase = 0);
+ void save_json(save_zip_state &output, char const *nameprefix = "", int indent = 0, bool inline_form = false, uintptr_t parentbase = 0);
// restore this item from a JSON stream
- void restore_json(load_zip_state &input, char const *nameprefix = "", json_restore_mode mode = RESTORE_DATA, uintptr_t objbase = 0);
-
- // read/write helpers
- bool read_bool(uintptr_t objbase) const { return *reinterpret_cast<bool const *>(objbase); }
- uint64_t read_int_unsigned(uintptr_t objbase, int size) const;
- int64_t read_int_signed(uintptr_t objbase, int size) const;
- double read_float(uintptr_t objbase, int size) const;
- void write_bool(uintptr_t objbase, bool data) const { *reinterpret_cast<bool *>(objbase) = data; }
- bool write_int_signed(uintptr_t objbase, int size, int64_t data) const;
- bool write_int_signed(uintptr_t objbase, int size, double data) const;
- bool write_int_unsigned(uintptr_t objbase, int size, uint64_t data) const;
- bool write_int_unsigned(uintptr_t objbase, int size, double data) const;
- bool write_float(uintptr_t objbase, int size, double data) const;
+ void restore_json(load_zip_state &input, char const *nameprefix = "", json_restore_mode mode = RESTORE_DATA, uintptr_t parentbase = 0);
+
+ // read/write helpers for bools
+ bool read_bool(uintptr_t objptr) const { return *reinterpret_cast<bool const *>(objptr); }
+ void write_bool(uintptr_t objptr, bool data) const { *reinterpret_cast<bool *>(objptr) = data; }
+
+ // read/write helpers for signed integers
+ s64 read_int_signed(uintptr_t objptr, int size) const;
+ bool write_int_signed(uintptr_t objptr, int size, s64 data) const;
+ bool write_int_signed(uintptr_t objptr, int size, double data) const;
+
+ // read/write helpers for unsigned integers
+ u64 read_int_unsigned(uintptr_t objptr, int size) const;
+ bool write_int_unsigned(uintptr_t objptr, int size, u64 data) const;
+ bool write_int_unsigned(uintptr_t objptr, int size, double data) const;
+
+ // read/write helpers for floats
+ double read_float(uintptr_t objptr, int size) const;
+ bool write_float(uintptr_t objptr, int size, double data) const;
private:
+ // true if this item is an array of endpoints
+ bool is_endpoint_array(u32 &total, u32 &unitsize) const;
+
// parse out an external file spec from the JSON
- bool parse_external_data(load_zip_state &input, save_registered_item &baseitem, char const *localname, bool parseonly, uintptr_t objbase);
+ bool parse_external_data(load_zip_state &input, save_registered_item &baseitem, char const *localname, bool parseonly, uintptr_t parentbase);
// internal state
std::list<save_registered_item> m_items; // list of embedded items
uintptr_t m_ptr_offset; // pointer or offset
- save_type m_type; // type of native
- uint32_t m_native_size; // native size of item
+ u32 m_type_count; // type and count
+ u32 m_native_size; // native size of item
std::string m_name; // name of item
};
@@ -213,12 +207,21 @@ class save_registrar
friend class device_t;
// extended constructor for internal use only
- save_registrar(save_registrar &parent, save_registered_item::save_type type, uint32_t native_size, char const *name, void *baseptr = nullptr, void *containerbase = nullptr) :
- m_parent(parent.parent_item().append((baseptr == nullptr) ? 0 : uintptr_t(baseptr) - parent.m_baseptr, type, native_size, name)),
- m_baseptr((containerbase == nullptr) ? uintptr_t(baseptr) : uintptr_t(containerbase))
+ save_registrar(save_registrar &parent, void *baseptr, save_registered_item::save_type type, u32 native_size, char const *name, u32 count, void *regcontainerbase, u32 regcontainersize) :
+ m_parent_item(parent.parent_item().append((baseptr == nullptr) ? 0 : uintptr_t(baseptr) - parent.m_regcontainerbase, type, native_size, name, count)),
+ m_regcontainerbase(uintptr_t(regcontainerbase)),
+ m_regcontainersize(regcontainersize)
{
}
+ // internal constructor
+ save_registrar(save_registered_item &parent, void *baseptr = nullptr) :
+ m_parent_item(parent),
+ m_regcontainerbase(uintptr_t(baseptr)),
+ m_regcontainersize(0)
+ {
+ }
+
public:
// items that are signed_int_like are interpreted as 8/16/32/64-bit signed integers; this includes
// proper signed integral values and enums by default; additional types may be added via the
@@ -233,22 +236,22 @@ public:
// proper float and double values; additional types may be added via the SAVE_TYPE_AS_FLOAT macro
template<typename T> struct is_floating_point_like { static constexpr bool value = std::is_floating_point<T>::value; };
- // items are considered atoms if they fall into one of the three classes above
- template<typename T> struct is_atom { static constexpr bool value = (is_signed_int_like<T>::value || is_unsigned_int_like<T>::value || is_floating_point_like<T>::value); };
+ // items are considered endpoints if they fall into one of the three classes above
+ template<typename T> struct is_endpoint { static constexpr bool value = (is_signed_int_like<T>::value || is_unsigned_int_like<T>::value || is_floating_point_like<T>::value); };
// construct a container within parent
save_registrar(save_registrar &parent, char const *name) :
- save_registrar(parent, save_registered_item::TYPE_CONTAINER, 0, name)
+ save_registrar(parent, nullptr, save_registered_item::TYPE_CONTAINER, 0, name, 0, nullptr, 0)
{
}
// return a reference to the parent item
- save_registered_item &parent_item() const { return m_parent; }
+ save_registered_item &parent_item() const { return m_parent_item; }
- // append a bucket
+ // append a bucket by stealing its items
save_registrar &reg(save_registrar &src, char const *name)
{
- save_registrar container(*this, save_registered_item::TYPE_CONTAINER, 0, name);
+ save_registrar container(*this, name);
auto &srcitems = src.parent_item().subitems();
auto &dstitems = container.parent_item().subitems();
dstitems.splice(dstitems.end(), srcitems);
@@ -258,7 +261,7 @@ public:
// bool as a special case
save_registrar &reg(bool &data, char const *name)
{
- return register_internal(&data, save_registered_item::TYPE_BOOL, sizeof(data), name);
+ return register_endpoint(&data, save_registered_item::TYPE_BOOL, sizeof(data), name);
}
// signed integral types
@@ -266,7 +269,7 @@ public:
std::enable_if_t<is_signed_int_like<T>::value, save_registrar> &reg(T &data, char const *name)
{
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8);
- return register_internal(&data, save_registered_item::TYPE_INT, sizeof(data), name);
+ return register_endpoint(&data, save_registered_item::TYPE_INT, sizeof(data), name);
}
// unsigned integral types
@@ -274,7 +277,7 @@ public:
std::enable_if_t<is_unsigned_int_like<T>::value, save_registrar> &reg(T &data, char const *name)
{
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8);
- return register_internal(&data, save_registered_item::TYPE_UINT, sizeof(data), name);
+ return register_endpoint(&data, save_registered_item::TYPE_UINT, sizeof(data), name);
}
// floating-point types
@@ -282,7 +285,7 @@ public:
std::enable_if_t<is_floating_point_like<T>::value, save_registrar> &reg(T &data, char const *name)
{
static_assert(sizeof(T) == 4 || sizeof(T) == 8);
- return register_internal(&data, save_registered_item::TYPE_FLOAT, sizeof(data), name);
+ return register_endpoint(&data, save_registered_item::TYPE_FLOAT, sizeof(data), name);
}
// std::unique_ptrs -- these are containers with a single "unique" item within
@@ -292,82 +295,66 @@ public:
if (data.get() == nullptr)
throw emu_fatalerror("Passed null pointer to save state registration.");
- save_registrar container(*this, save_registered_item::TYPE_UNIQUE, sizeof(data), name, &data, data.get());
+ save_registrar container(*this, &data, save_registered_item::TYPE_UNIQUE, sizeof(data), name, 0, data.get(), sizeof(T));
container.reg(*data.get(), name);
return *this;
}
+ // pointers with count -- treat as an array
+ template<typename T>
+ save_registrar &reg(T *data, char const *name, std::size_t count)
+ {
+ return register_array(data, save_registered_item::TYPE_RUNTIME_ARRAY, name, count);
+ }
+
// arrays -- these are containers with a single item representing the underlying data,
// which is replicated across the whole array
- template<typename T, std::size_t N>
+ template<typename T, u32 N>
save_registrar &reg(T (&data)[N], char const *name)
- {
- save_registrar container(*this, save_registered_item::save_type(N), uintptr_t(&data[1]) - uintptr_t(&data[0]), name, &data[0]);
- container.reg(data[0], "");
- return *this;
- }
+ {
+ return register_array(&data[0], save_registered_item::TYPE_STATIC_ARRAY, name, N);
+ }
// std::arrays -- treat these identically to arrays
- template<typename T, std::size_t N>
+ template<typename T, u32 N>
save_registrar &reg(std::array<T, N> &data, char const *name)
- {
- save_registrar container(*this, save_registered_item::save_type(N), uintptr_t(&data[1]) - uintptr_t(&data[0]), name, &data[0]);
- container.reg(data[0], "");
- return *this;
- }
-
- // pointers -- treat as an array with a specific count
- template<typename T>
- save_registrar &reg(T *data, char const *name, std::size_t count)
{
- if (data == nullptr)
- throw emu_fatalerror("Passed null pointer to save state registration.");
-
- save_registrar container(*this, save_registered_item::save_type(count), uintptr_t(&data[1]) - uintptr_t(&data[0]), name, &data[0]);
- container.reg(data[0], "");
- return *this;
+ return register_array(&data[0], save_registered_item::TYPE_STATIC_ARRAY, name, N);
}
// std::vectors -- these are treated as arrays, but wrapped
template<typename T>
save_registrar &reg(std::vector<T> &data, char const *name)
{
- // skip if nothing
+ // skip if no items
if (data.size() == 0)
return *this;
- // create an outer container for the vector
- save_registrar container(*this, save_registered_item::TYPE_VECTOR, sizeof(data), name, &data, &data[0]);
-
- // then an array container within
- save_registrar subcontainer(container, save_registered_item::save_type(data.size()), uintptr_t(&data[1]) - uintptr_t(&data[0]), name, &data[0]);
- subcontainer.reg(data[0], "");
- return *this;
+ // create an outer container for the vector, then a regular array container within
+ save_registrar container(*this, &data, save_registered_item::TYPE_VECTOR, sizeof(data), name, 0, &data[0], sizeof(T));
+ container.register_array(&data[0], save_registered_item::TYPE_RUNTIME_ARRAY, name, data.size());
+ return *this;
}
// std::unique_ptrs with arrays
template<typename T>
save_registrar &reg(std::unique_ptr<T[]> &data, char const *name, std::size_t count)
{
- // skip if nothing
+ // skip if no items
if (count == 0)
return *this;
- if (data.get() == nullptr)
- throw emu_fatalerror("Passed null pointer to save state registration.");
-
- save_registrar container(*this, save_registered_item::TYPE_UNIQUE, sizeof(data), name, &data, data.get());
-
- save_registrar subcontainer(container, save_registered_item::save_type(count), uintptr_t(&data[1]) - uintptr_t(&data[0]), name, &data[0]);
- subcontainer.reg(data[0], "");
+ // create an outer container for the unique_ptr, then a regular array container within
+ save_registrar container(*this, &data, save_registered_item::TYPE_UNIQUE, sizeof(data), name, 0, data.get(), sizeof(T));
+ container.register_array(&data[0], save_registered_item::TYPE_RUNTIME_ARRAY, name, count);
return *this;
}
// structures & unions (must have a register_save method)
- template<typename T, std::enable_if_t<(std::is_class<T>::value || std::is_union<T>::value) && !std::is_base_of<bitmap_t, T>::value && !is_atom<T>::value, bool> = true>
- save_registrar &reg(T &data, char const *name)
+ template<typename T, std::enable_if_t<(std::is_class<T>::value || std::is_union<T>::value) && !std::is_base_of<bitmap_t, T>::value && !is_endpoint<T>::value, bool> = true>
+ save_registrar &reg(T &data, char const *name, std::size_t datasize = 0)
{
- save_registrar container(*this, save_registered_item::TYPE_STRUCT, sizeof(data), name, &data);
+ save_registrar container(*this, &data, save_registered_item::TYPE_STRUCT, sizeof(data), name, 0, &data, (datasize == 0) ? sizeof(T) : datasize);
data.register_save(container);
return *this;
}
@@ -375,11 +362,8 @@ public:
// rectangle as a special case, since it's from an external library
save_registrar &reg(rectangle &data, char const *name)
{
- save_registrar container(*this, save_registered_item::TYPE_STRUCT, sizeof(data), name, &data);
- container.reg(data.min_x, "min_x")
- .reg(data.max_x, "max_x")
- .reg(data.min_y, "min_y")
- .reg(data.max_y, "max_y");
+ save_registrar container(*this, &data, save_registered_item::TYPE_STRUCT, sizeof(data), name, 0, &data, sizeof(data));
+ container.reg(data.min_x, "min_x").reg(data.max_x, "max_x").reg(data.min_y, "min_y").reg(data.max_y, "max_y");
return *this;
}
@@ -387,30 +371,54 @@ public:
template<typename BitmapType>
std::enable_if_t<std::is_base_of<bitmap_t, BitmapType>::value, save_registrar> &reg(BitmapType &data, char const *name)
{
- save_registrar rows(*this, save_registered_item::save_type(data.height()), data.rowbytes(), name, data.raw_pixptr(0));
- save_registrar cols(rows, save_registered_item::save_type(data.width()), sizeof(BitmapType::pixel_t), "", data.raw_pixptr(0));
- cols.register_internal(data.raw_pixptr(0), save_registered_item::TYPE_UINT, sizeof(BitmapType::pixel_t), "");
+ void *pixbase = data.raw_pixptr(0);
+ save_registrar rows(*this, pixbase, save_registered_item::TYPE_RUNTIME_ARRAY, data.rowbytes(), name, data.height(), pixbase, 0);
+ save_registrar cols(rows, pixbase, save_registered_item::TYPE_RUNTIME_ARRAY, sizeof(BitmapType::pixel_t), "", data.width(), pixbase, 0);
+ cols.register_endpoint(pixbase, save_registered_item::TYPE_UINT, sizeof(BitmapType::pixel_t), "");
return *this;
}
private:
- // internal constructor
- save_registrar(save_registered_item &parent, void *baseptr = nullptr) :
- m_parent(parent),
- m_baseptr(uintptr_t(baseptr))
+ // register an endpoint item (containing no subitems)
+ save_registrar &register_endpoint(void *memptr, save_registered_item::save_type type, std::size_t itemsize, char const *itemname)
{
- }
-
- // internal registration
- save_registrar &register_internal(void *memptr, save_registered_item::save_type type, std::size_t itemsize, char const *itemname)
- {
- m_parent.append(uintptr_t(memptr) - m_baseptr, type, itemsize, itemname);
+ uintptr_t delta = uintptr_t(memptr) - m_regcontainerbase;
+ if (m_regcontainersize != 0 && delta >= m_regcontainersize)
+ throw emu_fatalerror("Attempted to register item outside of parent element's bounds");
+ m_parent_item.append(delta, type, itemsize, itemname);
return *this;
}
+ // register an array item
+ template<typename T>
+ save_registrar &register_array(T *data, save_registered_item::save_type type, char const *name, std::size_t count)
+ {
+ // skip 0-length items
+ if (count == 0)
+ return *this;
+
+ // error on null pointer
+ if (data == nullptr)
+ throw emu_fatalerror("Passed null pointer to save state registration.");
+
+ // create a container and register the first item
+ save_registrar container(*this, data, type, uintptr_t(&data[1]) - uintptr_t(&data[0]), name, count, &data[0], sizeof(T));
+ container.reg(data[0], "");
+
+ // if the first item was non-replicatable, register remaining items independently
+ if (!container.m_parent_item.subitems().front().is_replicatable(true))
+ for (int index = 1; index < count; index++)
+ {
+ container.m_regcontainerbase = uintptr_t(&data[index]);
+ container.reg(data[index], "");
+ }
+ return *this;
+ }
+
// internal state
- save_registered_item &m_parent;
- uintptr_t m_baseptr;
+ save_registered_item &m_parent_item;
+ uintptr_t m_regcontainerbase;
+ u32 m_regcontainersize;
};
// these types are small structures/unions that embed an integral type; treat them as raw
diff --git a/src/mame/drivers/namcos22.cpp b/src/mame/drivers/namcos22.cpp
index 55389d5814d..aae9ed5567b 100644
--- a/src/mame/drivers/namcos22.cpp
+++ b/src/mame/drivers/namcos22.cpp
@@ -3607,9 +3607,6 @@ void namcos22_state::device_post_load()
m_gfxdecode->gfx(0)->mark_all_dirty();
}
-// allow save_item on a non-fundamental type
-ALLOW_SAVE_TYPE(namcos22_dsp_upload_state);
-
void namcos22_state::machine_start()
{
m_mcu_out.resolve();
diff --git a/src/mame/drivers/subsino2.cpp b/src/mame/drivers/subsino2.cpp
index 726ee99f967..d4cfe01dfea 100644
--- a/src/mame/drivers/subsino2.cpp
+++ b/src/mame/drivers/subsino2.cpp
@@ -65,8 +65,6 @@ enum tilesize_t : uint8_t
TILE_64x32
};
-ALLOW_SAVE_TYPE(tilesize_t);
-
enum vram_t
{
VRAM_LO,
diff --git a/src/mame/drivers/ttchamp.cpp b/src/mame/drivers/ttchamp.cpp
index 17523eb68fe..b595ee3ded3 100644
--- a/src/mame/drivers/ttchamp.cpp
+++ b/src/mame/drivers/ttchamp.cpp
@@ -149,8 +149,6 @@ private:
void ttchamp_map(address_map &map);
};
-ALLOW_SAVE_TYPE(ttchamp_state::picmode);
-
void ttchamp_state::machine_start()
{
diff --git a/src/mame/machine/rosetta.cpp b/src/mame/machine/rosetta.cpp
index a459647b933..f06e83dbd15 100644
--- a/src/mame/machine/rosetta.cpp
+++ b/src/mame/machine/rosetta.cpp
@@ -173,8 +173,6 @@ static u8 const led_pattern[16] =
DEFINE_DEVICE_TYPE(ROSETTA, rosetta_device, "rosetta", "IBM Rosetta")
-ALLOW_SAVE_TYPE(rosetta_device::mear_state)
-
rosetta_device::rosetta_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, ram_size ram)
: device_t(mconfig, ROSETTA, tag, owner, clock)
, rsc_cpu_interface(mconfig, *this)
diff --git a/src/mame/machine/thomflop.cpp b/src/mame/machine/thomflop.cpp
index 2179377c8b5..1352c937f44 100644
--- a/src/mame/machine/thomflop.cpp
+++ b/src/mame/machine/thomflop.cpp
@@ -836,8 +836,6 @@ enum : uint8_t
DEFINE_DEVICE_TYPE(THMFC1, thmfc1_device, "thmfc1", "Thomson THMFC1 floppy controller")
-ALLOW_SAVE_TYPE(thmfc1_device::thmfc1_op);
-
thmfc1_device::thmfc1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, THMFC1, tag, owner, clock)
, thomson_legacy_floppy_interface(mconfig, *this)
diff --git a/src/mame/machine/x68k_hdc.cpp b/src/mame/machine/x68k_hdc.cpp
index d3051b8bcb9..cfa2ce9902e 100644
--- a/src/mame/machine/x68k_hdc.cpp
+++ b/src/mame/machine/x68k_hdc.cpp
@@ -22,8 +22,6 @@
#include "imagedev/harddriv.h"
#include "image.h"
-ALLOW_SAVE_TYPE(x68k_hdc_image_device::sasi_phase);
-
DEFINE_DEVICE_TYPE(X68KHDC, x68k_hdc_image_device, "x68k_hdc_image", "SASI Hard Disk")
x68k_hdc_image_device::x68k_hdc_image_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)