summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2021-04-13 18:18:55 -0700
committer Aaron Giles <aaron@aarongiles.com>2021-04-13 18:18:55 -0700
commit889693e57e99a2d7d149aa60fc1de3036aa9f0ad (patch)
tree88795e7511c4e2435b0679968cd48cb2527889c9
parent8fb0991e0372ce92ff4cb19c71e719f0421b1dae (diff)
Add support for std::array and for custom types that map to integers/FP values. Fix up ymfm-related saving. Modernize AY8910 saving.
-rw-r--r--scripts/src/emu.lua2
-rw-r--r--scripts/src/osd/windows.lua4
-rw-r--r--src/devices/machine/wtl3132.cpp1
-rw-r--r--src/devices/sound/ay8910.cpp47
-rw-r--r--src/devices/sound/ay8910.h24
-rw-r--r--src/devices/sound/y8950.cpp21
-rw-r--r--src/devices/sound/y8950.h1
-rw-r--r--src/devices/sound/ym2151.cpp6
-rw-r--r--src/devices/sound/ym2203.cpp21
-rw-r--r--src/devices/sound/ym2203.h1
-rw-r--r--src/devices/sound/ym2413.cpp19
-rw-r--r--src/devices/sound/ym2413.h1
-rw-r--r--src/devices/sound/ym2608.cpp29
-rw-r--r--src/devices/sound/ym2608.h1
-rw-r--r--src/devices/sound/ym2610.cpp31
-rw-r--r--src/devices/sound/ym2610.h1
-rw-r--r--src/devices/sound/ym2612.cpp23
-rw-r--r--src/devices/sound/ym2612.h1
-rw-r--r--src/devices/sound/ym3526.cpp17
-rw-r--r--src/devices/sound/ym3526.h1
-rw-r--r--src/devices/sound/ym3812.cpp17
-rw-r--r--src/devices/sound/ym3812.h1
-rw-r--r--src/devices/sound/ymadpcm.cpp83
-rw-r--r--src/devices/sound/ymadpcm.h12
-rw-r--r--src/devices/sound/ymf262.cpp17
-rw-r--r--src/devices/sound/ymf262.h1
-rw-r--r--src/devices/sound/ymf278b.cpp79
-rw-r--r--src/devices/sound/ymf278b.h40
-rw-r--r--src/devices/sound/ymfm.h2
-rw-r--r--src/emu/dirom.h2
-rw-r--r--src/emu/save.h79
31 files changed, 357 insertions, 228 deletions
diff --git a/scripts/src/emu.lua b/scripts/src/emu.lua
index 6746847ef2a..31538b5cab2 100644
--- a/scripts/src/emu.lua
+++ b/scripts/src/emu.lua
@@ -242,6 +242,8 @@ files {
MAME_DIR .. "src/emu/debug/dvbpoints.h",
MAME_DIR .. "src/emu/debug/dvwpoints.cpp",
MAME_DIR .. "src/emu/debug/dvwpoints.h",
+ MAME_DIR .. "src/emu/debug/dvsave.cpp",
+ MAME_DIR .. "src/emu/debug/dvsave.h",
MAME_DIR .. "src/emu/debug/dvstate.cpp",
MAME_DIR .. "src/emu/debug/dvstate.h",
MAME_DIR .. "src/emu/debug/dvtext.cpp",
diff --git a/scripts/src/osd/windows.lua b/scripts/src/osd/windows.lua
index 963980b22ca..bfd2c9b7a81 100644
--- a/scripts/src/osd/windows.lua
+++ b/scripts/src/osd/windows.lua
@@ -197,6 +197,10 @@ project ("osd_" .. _OPTIONS["osd"])
MAME_DIR .. "src/osd/modules/debugger/win/memorywininfo.h",
MAME_DIR .. "src/osd/modules/debugger/win/pointswininfo.cpp",
MAME_DIR .. "src/osd/modules/debugger/win/pointswininfo.h",
+ MAME_DIR .. "src/osd/modules/debugger/win/saveviewinfo.cpp",
+ MAME_DIR .. "src/osd/modules/debugger/win/saveviewinfo.h",
+ MAME_DIR .. "src/osd/modules/debugger/win/savewininfo.cpp",
+ MAME_DIR .. "src/osd/modules/debugger/win/savewininfo.h",
MAME_DIR .. "src/osd/modules/debugger/win/uimetrics.cpp",
MAME_DIR .. "src/osd/modules/debugger/win/uimetrics.h",
MAME_DIR .. "src/osd/modules/debugger/win/debugwin.h",
diff --git a/src/devices/machine/wtl3132.cpp b/src/devices/machine/wtl3132.cpp
index 2e86798b878..3b82466529e 100644
--- a/src/devices/machine/wtl3132.cpp
+++ b/src/devices/machine/wtl3132.cpp
@@ -25,6 +25,7 @@
#include "logmacro.h"
ALLOW_SAVE_TYPE(float32_t);
+SAVE_TYPE_AS_FLOAT(float32_t);
// helper for extracting opcode fields
#define OPF(c, x) ((c & M_##x) >> S_##x)
diff --git a/src/devices/sound/ay8910.cpp b/src/devices/sound/ay8910.cpp
index 46a6ff8bf00..1e8c35cec99 100644
--- a/src/devices/sound/ay8910.cpp
+++ b/src/devices/sound/ay8910.cpp
@@ -1270,35 +1270,25 @@ void ay8910_device::build_mixer_table()
}
}
-void ay8910_device::ay8910_statesave()
+
+//-------------------------------------------------
+// device_register_save - register for save state
+//-------------------------------------------------
+
+void ay8910_device::device_register_save(save_registrar &save)
{
- save_item(STRUCT_MEMBER(m_tone, period));
- save_item(STRUCT_MEMBER(m_tone, volume));
- save_item(STRUCT_MEMBER(m_tone, duty));
- save_item(STRUCT_MEMBER(m_tone, count));
- save_item(STRUCT_MEMBER(m_tone, duty_cycle));
- save_item(STRUCT_MEMBER(m_tone, output));
-
- save_item(STRUCT_MEMBER(m_envelope, period));
- save_item(STRUCT_MEMBER(m_envelope, count));
- save_item(STRUCT_MEMBER(m_envelope, step));
- save_item(STRUCT_MEMBER(m_envelope, volume));
- save_item(STRUCT_MEMBER(m_envelope, hold));
- save_item(STRUCT_MEMBER(m_envelope, alternate));
- save_item(STRUCT_MEMBER(m_envelope, attack));
- save_item(STRUCT_MEMBER(m_envelope, holding));
-
- save_item(NAME(m_active));
- save_item(NAME(m_register_latch));
- save_item(NAME(m_regs));
- save_item(NAME(m_last_enable));
-
- save_item(NAME(m_count_noise));
- save_item(NAME(m_prescale_noise));
-
- save_item(NAME(m_rng));
- save_item(NAME(m_mode));
- save_item(NAME(m_flags));
+ // save our data
+ save.reg(NAME(m_tone))
+ .reg(NAME(m_envelope))
+ .reg(NAME(m_active))
+ .reg(NAME(m_register_latch))
+ .reg(NAME(m_regs))
+ .reg(NAME(m_last_enable))
+ .reg(NAME(m_count_noise))
+ .reg(NAME(m_prescale_noise))
+ .reg(NAME(m_rng))
+ .reg(NAME(m_mode))
+ .reg(NAME(m_flags));
}
//-------------------------------------------------
@@ -1335,7 +1325,6 @@ void ay8910_device::device_start()
m_channel = stream_alloc(0, m_streams, master_clock / 8);
ay_set_clock(master_clock);
- ay8910_statesave();
}
diff --git a/src/devices/sound/ay8910.h b/src/devices/sound/ay8910.h
index 79cf180ac59..63bf65767e2 100644
--- a/src/devices/sound/ay8910.h
+++ b/src/devices/sound/ay8910.h
@@ -133,6 +133,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
@@ -211,6 +212,16 @@ private:
{
duty = val;
}
+
+ void register_save(save_registrar &save)
+ {
+ save.reg(NAME(period))
+ .reg(NAME(volume))
+ .reg(NAME(duty))
+ .reg(NAME(count))
+ .reg(NAME(duty_cycle))
+ .reg(NAME(output));
+ }
};
struct envelope_t
@@ -256,6 +267,18 @@ private:
holding = 0;
volume = (step ^ attack);
}
+
+ void register_save(save_registrar &save)
+ {
+ save.reg(NAME(period))
+ .reg(NAME(count))
+ .reg(NAME(step))
+ .reg(NAME(volume))
+ .reg(NAME(hold))
+ .reg(NAME(alternate))
+ .reg(NAME(attack))
+ .reg(NAME(holding));
+ }
};
// inlines
@@ -277,7 +300,6 @@ private:
inline stream_buffer::sample_t mix_3D();
void ay8910_write_reg(int r, int v);
void build_mixer_table();
- void ay8910_statesave();
// internal state
psg_type_t m_type;
diff --git a/src/devices/sound/y8950.cpp b/src/devices/sound/y8950.cpp
index 922308b960a..1b11ccbb0ef 100644
--- a/src/devices/sound/y8950.cpp
+++ b/src/devices/sound/y8950.cpp
@@ -183,13 +183,22 @@ void y8950_device::device_start()
m_io_read_handler.resolve_safe(0);
m_io_write_handler.resolve_safe();
- // save our data
- save_item(YMFM_NAME(m_address));
- save_item(YMFM_NAME(m_io_ddr));
+ // initialize the FM engine
+ m_fm.init();
+}
+
+
+//-------------------------------------------------
+// device_register_save - register for save state
+//-------------------------------------------------
- // save the engines
- m_fm.save(*this);
- m_adpcm_b.save(*this);
+void y8950_device::device_register_save(save_registrar &save)
+{
+ // save our data
+ save.reg(NAME(m_address))
+ .reg(NAME(m_io_ddr))
+ .reg(NAME(m_fm))
+ .reg(NAME(m_adpcm_b));
}
diff --git a/src/devices/sound/y8950.h b/src/devices/sound/y8950.h
index d3285ee835d..0e92266cb09 100644
--- a/src/devices/sound/y8950.h
+++ b/src/devices/sound/y8950.h
@@ -50,6 +50,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
// ROM device overrides
virtual void rom_bank_updated() override;
diff --git a/src/devices/sound/ym2151.cpp b/src/devices/sound/ym2151.cpp
index 2d4feb5389a..30dcfcfc327 100644
--- a/src/devices/sound/ym2151.cpp
+++ b/src/devices/sound/ym2151.cpp
@@ -137,10 +137,8 @@ void ym2151_device::device_register_save(save_registrar &save)
{
// save our data
save.reg(NAME(m_address))
- .reg(NAME(m_reset_state));
-
- // save the engines
- m_fm.register_save(save);
+ .reg(NAME(m_reset_state))
+ .reg(NAME(m_fm));
}
diff --git a/src/devices/sound/ym2203.cpp b/src/devices/sound/ym2203.cpp
index d2e5e61fb03..13fe2bf43ad 100644
--- a/src/devices/sound/ym2203.cpp
+++ b/src/devices/sound/ym2203.cpp
@@ -108,11 +108,24 @@ void ym2203_device::device_start()
// create our stream
m_stream = stream_alloc(0, fm_engine::OUTPUTS, m_fm.sample_rate(clock()));
- // save our data
- save_item(YMFM_NAME(m_address));
+ // initialize the FM engine
+ m_fm.init();
+}
+
- // save the FM engine
- m_fm.save(*this);
+//-------------------------------------------------
+// device_register_save - register for save state
+//-------------------------------------------------
+
+void ym2203_device::device_register_save(save_registrar &save)
+{
+ // call our parent
+ save_registrar container(save, "psg");
+ ay8910_device::device_register_save(container);
+
+ // save our data
+ save.reg(NAME(m_address))
+ .reg(NAME(m_fm));
}
diff --git a/src/devices/sound/ym2203.h b/src/devices/sound/ym2203.h
index dbce4549340..c9d7f11f660 100644
--- a/src/devices/sound/ym2203.h
+++ b/src/devices/sound/ym2203.h
@@ -41,6 +41,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
// sound overrides
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
diff --git a/src/devices/sound/ym2413.cpp b/src/devices/sound/ym2413.cpp
index e680b4a31ff..841f6f9ebb9 100644
--- a/src/devices/sound/ym2413.cpp
+++ b/src/devices/sound/ym2413.cpp
@@ -78,11 +78,8 @@ void ym2413_device::device_start()
// create our stream
m_stream = stream_alloc(0, fm_engine::OUTPUTS, m_fm.sample_rate(clock()));
- // save our data
- save_item(YMFM_NAME(m_address));
-
- // save the engines
- m_fm.save(*this);
+ // initialize the FM engine
+ m_fm.init();
// set up the instrument data
m_fm.set_instrument_data(m_internal);
@@ -90,6 +87,18 @@ void ym2413_device::device_start()
//-------------------------------------------------
+// device_register_save - register for save state
+//-------------------------------------------------
+
+void ym2413_device::device_register_save(save_registrar &save)
+{
+ // save our data
+ save.reg(NAME(m_address))
+ .reg(NAME(m_fm));
+}
+
+
+//-------------------------------------------------
// device_reset - start of emulation
//-------------------------------------------------
diff --git a/src/devices/sound/ym2413.h b/src/devices/sound/ym2413.h
index 9cea40d1d00..b7a30f12994 100644
--- a/src/devices/sound/ym2413.h
+++ b/src/devices/sound/ym2413.h
@@ -34,6 +34,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
virtual const tiny_rom_entry *device_rom_region() const override;
// sound overrides
diff --git a/src/devices/sound/ym2608.cpp b/src/devices/sound/ym2608.cpp
index 35cdff227c8..c8f18e8770e 100644
--- a/src/devices/sound/ym2608.cpp
+++ b/src/devices/sound/ym2608.cpp
@@ -196,15 +196,28 @@ void ym2608_device::device_start()
// create our stream
m_stream = stream_alloc(0, fm_engine::OUTPUTS, m_fm.sample_rate(clock()));
+ // initialize the FM engine
+ m_fm.init();
+}
+
+
+//-------------------------------------------------
+// device_register_save - register for save state
+//-------------------------------------------------
+
+void ym2608_device::device_register_save(save_registrar &save)
+{
+ // call our parent
+ save_registrar container(save, "psg");
+ ay8910_device::device_register_save(container);
+
// save our data
- save_item(YMFM_NAME(m_address));
- save_item(YMFM_NAME(m_irq_enable));
- save_item(YMFM_NAME(m_flag_control));
-
- // save the engines
- m_fm.save(*this);
- m_adpcm_a.save(*this);
- m_adpcm_b.save(*this);
+ save.reg(NAME(m_address))
+ .reg(NAME(m_irq_enable))
+ .reg(NAME(m_flag_control))
+ .reg(NAME(m_fm))
+ .reg(NAME(m_adpcm_a))
+ .reg(NAME(m_adpcm_b));
}
diff --git a/src/devices/sound/ym2608.h b/src/devices/sound/ym2608.h
index 465b3ba1659..aa951c76d4d 100644
--- a/src/devices/sound/ym2608.h
+++ b/src/devices/sound/ym2608.h
@@ -36,6 +36,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
virtual const tiny_rom_entry *device_rom_region() const override;
// ROM device overrides
diff --git a/src/devices/sound/ym2610.cpp b/src/devices/sound/ym2610.cpp
index 9c5b3d6a499..f8c2503233b 100644
--- a/src/devices/sound/ym2610.cpp
+++ b/src/devices/sound/ym2610.cpp
@@ -192,15 +192,8 @@ void ym2610_device::device_start()
// create our stream
m_stream = stream_alloc(0, fm_engine::OUTPUTS, m_fm.sample_rate(clock()));
- // save our data
- save_item(YMFM_NAME(m_address));
- save_item(YMFM_NAME(m_eos_status));
- save_item(YMFM_NAME(m_flag_mask));
-
- // save the engines
- m_fm.save(*this);
- m_adpcm_a.save(*this);
- m_adpcm_b.save(*this);
+ // initialize the FM engine
+ m_fm.init();
// automatically map memory regions if not configured externally
if (!has_configured_map(0) && !has_configured_map(1))
@@ -217,6 +210,26 @@ void ym2610_device::device_start()
//-------------------------------------------------
+// device_register_save - register for save state
+//-------------------------------------------------
+
+void ym2610_device::device_register_save(save_registrar &save)
+{
+ // call our parent
+ save_registrar container(save, "psg");
+ ay8910_device::device_register_save(container);
+
+ // save our data
+ save.reg(NAME(m_address))
+ .reg(NAME(m_eos_status))
+ .reg(NAME(m_flag_mask))
+ .reg(NAME(m_fm))
+ .reg(NAME(m_adpcm_a))
+ .reg(NAME(m_adpcm_b));
+}
+
+
+//-------------------------------------------------
// device_reset - start of emulation
//-------------------------------------------------
diff --git a/src/devices/sound/ym2610.h b/src/devices/sound/ym2610.h
index 58f0d9528df..93d5dcd9c2d 100644
--- a/src/devices/sound/ym2610.h
+++ b/src/devices/sound/ym2610.h
@@ -36,6 +36,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
// memory space configuration
virtual space_config_vector memory_space_config() const override;
diff --git a/src/devices/sound/ym2612.cpp b/src/devices/sound/ym2612.cpp
index e97a431cc29..14b9c513455 100644
--- a/src/devices/sound/ym2612.cpp
+++ b/src/devices/sound/ym2612.cpp
@@ -141,14 +141,23 @@ void ym2612_device::device_start()
// call this for the variants that need to adjust the rate
device_clock_changed();
- // save our data
- save_item(YMFM_NAME(m_address));
- save_item(YMFM_NAME(m_dac_data));
- save_item(YMFM_NAME(m_dac_enable));
- save_item(YMFM_NAME(m_channel));
+ // initialize the FM engine
+ m_fm.init();
+}
+
+
+//-------------------------------------------------
+// device_register_save - register for save state
+//-------------------------------------------------
- // save the engines
- m_fm.save(*this);
+void ym2612_device::device_register_save(save_registrar &save)
+{
+ // save our data
+ save.reg(NAME(m_address))
+ .reg(NAME(m_dac_data))
+ .reg(NAME(m_dac_enable))
+ .reg(NAME(m_channel))
+ .reg(NAME(m_fm));
}
diff --git a/src/devices/sound/ym2612.h b/src/devices/sound/ym2612.h
index 658ddd275b7..9bd13b1e6ba 100644
--- a/src/devices/sound/ym2612.h
+++ b/src/devices/sound/ym2612.h
@@ -34,6 +34,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
// sound overrides
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
diff --git a/src/devices/sound/ym3526.cpp b/src/devices/sound/ym3526.cpp
index 76794058e1e..14e325392d1 100644
--- a/src/devices/sound/ym3526.cpp
+++ b/src/devices/sound/ym3526.cpp
@@ -100,11 +100,20 @@ void ym3526_device::device_start()
// create our stream
m_stream = stream_alloc(0, fm_engine::OUTPUTS, m_fm.sample_rate(clock()));
- // save our data
- save_item(YMFM_NAME(m_address));
+ // initialize the FM engine
+ m_fm.init();
+}
+
+
+//-------------------------------------------------
+// device_register_save - register for save state
+//-------------------------------------------------
- // save the engines
- m_fm.save(*this);
+void ym3526_device::device_register_save(save_registrar &save)
+{
+ // save our data
+ save.reg(NAME(m_address))
+ .reg(NAME(m_fm));
}
diff --git a/src/devices/sound/ym3526.h b/src/devices/sound/ym3526.h
index 496936befc9..c32c1dffad7 100644
--- a/src/devices/sound/ym3526.h
+++ b/src/devices/sound/ym3526.h
@@ -39,6 +39,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
// sound overrides
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
diff --git a/src/devices/sound/ym3812.cpp b/src/devices/sound/ym3812.cpp
index 07da3b73b3b..e8b6c4567b3 100644
--- a/src/devices/sound/ym3812.cpp
+++ b/src/devices/sound/ym3812.cpp
@@ -98,11 +98,20 @@ void ym3812_device::device_start()
// create our stream
m_stream = stream_alloc(0, fm_engine::OUTPUTS, m_fm.sample_rate(clock()));
- // save our data
- save_item(YMFM_NAME(m_address));
+ // initialize the FM engine
+ m_fm.init();
+}
+
+
+//-------------------------------------------------
+// device_register_save - register for save state
+//-------------------------------------------------
- // save the engines
- m_fm.save(*this);
+void ym3812_device::device_register_save(save_registrar &save)
+{
+ // save our data
+ save.reg(NAME(m_address))
+ .reg(NAME(m_fm));
}
diff --git a/src/devices/sound/ym3812.h b/src/devices/sound/ym3812.h
index 4e6c89afde3..7e1bc8b3561 100644
--- a/src/devices/sound/ym3812.h
+++ b/src/devices/sound/ym3812.h
@@ -39,6 +39,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
// sound overrides
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
diff --git a/src/devices/sound/ymadpcm.cpp b/src/devices/sound/ymadpcm.cpp
index 65169a610ff..b4321138deb 100644
--- a/src/devices/sound/ymadpcm.cpp
+++ b/src/devices/sound/ymadpcm.cpp
@@ -10,27 +10,16 @@
//*********************************************************
-// MACROS
-//*********************************************************
-
-// special naming helper to keep our namespace isolated from other
-// same-named objects in the device's namespace
-#define ADPCM_A_NAME(x) x, "adpcma." #x
-#define ADPCM_B_NAME(x) x, "adpcmb." #x
-
-
-
-//*********************************************************
// ADPCM "A" REGISTERS
//*********************************************************
//-------------------------------------------------
-// ymadpcm_a_registers - constructor
+// register_save - register for save states
//-------------------------------------------------
-void ymadpcm_a_registers::save(device_t &device)
+void ymadpcm_a_registers::register_save(save_registrar &save)
{
- device.save_item(ADPCM_A_NAME(m_regdata));
+ save.reg(NAME(m_regdata));
}
@@ -73,17 +62,17 @@ ymadpcm_a_channel::ymadpcm_a_channel(ymadpcm_a_engine &owner, u32 choffs, read8s
//-------------------------------------------------
-// save - register for save states
+// register_save - register for save states
//-------------------------------------------------
-void ymadpcm_a_channel::save(device_t &device, u32 index)
+void ymadpcm_a_channel::register_save(save_registrar &save)
{
- device.save_item(ADPCM_A_NAME(m_playing), index);
- device.save_item(ADPCM_A_NAME(m_curnibble), index);
- device.save_item(ADPCM_A_NAME(m_curbyte), index);
- device.save_item(ADPCM_A_NAME(m_curaddress), index);
- device.save_item(ADPCM_A_NAME(m_accumulator), index);
- device.save_item(ADPCM_A_NAME(m_step_index), index);
+ save.reg(NAME(m_playing))
+ .reg(NAME(m_curnibble))
+ .reg(NAME(m_curbyte))
+ .reg(NAME(m_curaddress))
+ .reg(NAME(m_accumulator))
+ .reg(NAME(m_step_index));
}
@@ -239,17 +228,13 @@ ymadpcm_a_engine::ymadpcm_a_engine(device_t &device, read8sm_delegate reader, u3
//-------------------------------------------------
-// save - register for save states
+// register_save - register for save states
//-------------------------------------------------
-void ymadpcm_a_engine::save(device_t &device)
+void ymadpcm_a_engine::register_save(save_registrar &save)
{
- // save register state
- m_regs.save(device);
-
- // save channel state
- for (int chnum = 0; chnum < std::size(m_channel); chnum++)
- m_channel[chnum]->save(device, chnum);
+ save.reg(NAME(m_regs))
+ .reg(NAME(m_channel));
}
@@ -326,9 +311,9 @@ void ymadpcm_a_engine::write(u32 regnum, u8 data)
// ymadpcm_b_registers - constructor
//-------------------------------------------------
-void ymadpcm_b_registers::save(device_t &device)
+void ymadpcm_b_registers::register_save(save_registrar &save)
{
- device.save_item(ADPCM_B_NAME(m_regdata));
+ save.reg(NAME(m_regdata));
}
@@ -372,20 +357,20 @@ ymadpcm_b_channel::ymadpcm_b_channel(ymadpcm_b_engine &owner, read8sm_delegate r
//-------------------------------------------------
-// save - register for save states
+// register_save - register for save states
//-------------------------------------------------
-void ymadpcm_b_channel::save(device_t &device, u32 index)
+void ymadpcm_b_channel::register_save(save_registrar &save)
{
- device.save_item(ADPCM_B_NAME(m_status), index);
- device.save_item(ADPCM_B_NAME(m_curnibble), index);
- device.save_item(ADPCM_B_NAME(m_curbyte), index);
- device.save_item(ADPCM_B_NAME(m_dummy_read), index);
- device.save_item(ADPCM_B_NAME(m_position), index);
- device.save_item(ADPCM_B_NAME(m_curaddress), index);
- device.save_item(ADPCM_B_NAME(m_accumulator), index);
- device.save_item(ADPCM_B_NAME(m_prev_accum), index);
- device.save_item(ADPCM_B_NAME(m_adpcm_step), index);
+ save.reg(NAME(m_status))
+ .reg(NAME(m_curnibble))
+ .reg(NAME(m_curbyte))
+ .reg(NAME(m_dummy_read))
+ .reg(NAME(m_position))
+ .reg(NAME(m_curaddress))
+ .reg(NAME(m_accumulator))
+ .reg(NAME(m_prev_accum))
+ .reg(NAME(m_adpcm_step));
}
@@ -674,17 +659,13 @@ ymadpcm_b_engine::ymadpcm_b_engine(device_t &device, read8sm_delegate reader, wr
//-------------------------------------------------
-// save - register for save states
+// register_save - register for save states
//-------------------------------------------------
-void ymadpcm_b_engine::save(device_t &device)
+void ymadpcm_b_engine::register_save(save_registrar &save)
{
- // save our state
- m_regs.save(device);
-
- // save channel state
- for (int chnum = 0; chnum < std::size(m_channel); chnum++)
- m_channel[chnum]->save(device, chnum);
+ save.reg(NAME(m_regs))
+ .reg(NAME(m_channel));
}
diff --git a/src/devices/sound/ymadpcm.h b/src/devices/sound/ymadpcm.h
index 847af0b93ff..97f9506081a 100644
--- a/src/devices/sound/ymadpcm.h
+++ b/src/devices/sound/ymadpcm.h
@@ -44,7 +44,7 @@ public:
ymadpcm_a_registers() { }
// register for save states
- void save(device_t &device);
+ void register_save(save_registrar &save);
// reset to initial state
void reset();
@@ -99,7 +99,7 @@ public:
ymadpcm_a_channel(ymadpcm_a_engine &owner, u32 choffs, read8sm_delegate reader, u32 addrshift);
// register for save states
- void save(device_t &device, u32 index);
+ void register_save(save_registrar &save);
// reset the channel state
void reset();
@@ -140,7 +140,7 @@ public:
ymadpcm_a_engine(device_t &device, read8sm_delegate reader, u32 addrshift);
// save state handling
- void save(device_t &device);
+ void register_save(save_registrar &save);
// reset our status
void reset();
@@ -218,7 +218,7 @@ public:
ymadpcm_b_registers() { }
// register for save states
- void save(device_t &device);
+ void register_save(save_registrar &save);
// reset to initial state
void reset();
@@ -271,7 +271,7 @@ public:
ymadpcm_b_channel(ymadpcm_b_engine &owner, read8sm_delegate reader, write8sm_delegate writer, u32 addrshift);
// register for save states
- void save(device_t &device, u32 index);
+ void register_save(save_registrar &save);
// reset the channel state
void reset();
@@ -336,7 +336,7 @@ public:
ymadpcm_b_engine(device_t &device, read8sm_delegate reader, write8sm_delegate writer, u32 addrshift = 0);
// save state handling
- void save(device_t &device);
+ void register_save(save_registrar &save);
// reset our status
void reset();
diff --git a/src/devices/sound/ymf262.cpp b/src/devices/sound/ymf262.cpp
index a7c77f743c7..ecdd55bf23d 100644
--- a/src/devices/sound/ymf262.cpp
+++ b/src/devices/sound/ymf262.cpp
@@ -86,11 +86,20 @@ void ymf262_device::device_start()
// create our stream
m_stream = stream_alloc(0, fm_engine::OUTPUTS, m_fm.sample_rate(clock()));
- // save our data
- save_item(YMFM_NAME(m_address));
+ // initialize the FM engine
+ m_fm.init();
+}
+
+
+//-------------------------------------------------
+// device_register_save - register for save state
+//-------------------------------------------------
- // save the engines
- m_fm.save(*this);
+void ymf262_device::device_register_save(save_registrar &save)
+{
+ // save our data
+ save.reg(NAME(m_address))
+ .reg(NAME(m_fm));
}
diff --git a/src/devices/sound/ymf262.h b/src/devices/sound/ymf262.h
index 78086532e7c..bb90baad145 100644
--- a/src/devices/sound/ymf262.h
+++ b/src/devices/sound/ymf262.h
@@ -34,6 +34,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
// sound overrides
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
diff --git a/src/devices/sound/ymf278b.cpp b/src/devices/sound/ymf278b.cpp
index ae84815ce67..3e3bbe2f1c9 100644
--- a/src/devices/sound/ymf278b.cpp
+++ b/src/devices/sound/ymf278b.cpp
@@ -824,62 +824,24 @@ void ymf278b_device::precompute_rate_tables()
}
}
-void ymf278b_device::register_save_state()
-{
- int i;
- save_item(NAME(m_pcmregs));
- save_item(NAME(m_wavetblhdr));
- save_item(NAME(m_memmode));
- save_item(NAME(m_memadr));
- save_item(NAME(m_fm_l));
- save_item(NAME(m_fm_r));
- save_item(NAME(m_fm_pos));
- save_item(NAME(m_pcm_l));
- save_item(NAME(m_pcm_r));
- save_item(NAME(m_port_AB));
- save_item(NAME(m_port_C));
- save_item(NAME(m_lastport));
- save_item(NAME(m_next_status_id));
-
- for (i = 0; i < 24; ++i)
- {
- save_item(NAME(m_slots[i].wave), i);
- save_item(NAME(m_slots[i].F_NUMBER), i);
- save_item(NAME(m_slots[i].octave), i);
- save_item(NAME(m_slots[i].preverb), i);
- save_item(NAME(m_slots[i].DAMP), i);
- save_item(NAME(m_slots[i].CH), i);
- save_item(NAME(m_slots[i].LD), i);
- save_item(NAME(m_slots[i].TL), i);
- save_item(NAME(m_slots[i].pan), i);
- save_item(NAME(m_slots[i].LFO), i);
- save_item(NAME(m_slots[i].VIB), i);
- save_item(NAME(m_slots[i].AM), i);
-
- save_item(NAME(m_slots[i].AR), i);
- save_item(NAME(m_slots[i].D1R), i);
- save_item(NAME(m_slots[i].DL), i);
- save_item(NAME(m_slots[i].D2R), i);
- save_item(NAME(m_slots[i].RC), i);
- save_item(NAME(m_slots[i].RR), i);
-
- save_item(NAME(m_slots[i].step), i);
- save_item(NAME(m_slots[i].stepptr), i);
-
- save_item(NAME(m_slots[i].active), i);
- save_item(NAME(m_slots[i].KEY_ON), i);
- save_item(NAME(m_slots[i].bits), i);
- save_item(NAME(m_slots[i].startaddr), i);
- save_item(NAME(m_slots[i].loopaddr), i);
- save_item(NAME(m_slots[i].endaddr), i);
-
- save_item(NAME(m_slots[i].env_step), i);
- save_item(NAME(m_slots[i].env_vol), i);
- save_item(NAME(m_slots[i].env_vol_step), i);
- save_item(NAME(m_slots[i].env_vol_lim), i);
- save_item(NAME(m_slots[i].env_preverb), i);
- }
+void ymf278b_device::device_register_save(save_registrar &save)
+{
+ save.reg(NAME(m_pcmregs))
+ .reg(NAME(m_wavetblhdr))
+ .reg(NAME(m_memmode))
+ .reg(NAME(m_memadr))
+ .reg(NAME(m_fm_l))
+ .reg(NAME(m_fm_r))
+ .reg(NAME(m_fm_pos))
+ .reg(NAME(m_pcm_l))
+ .reg(NAME(m_pcm_r))
+ .reg(NAME(m_port_AB))
+ .reg(NAME(m_port_C))
+ .reg(NAME(m_lastport))
+ .reg(NAME(m_next_status_id))
+ .reg(NAME(m_slots))
+ .reg(NAME(m_fm));
}
//-------------------------------------------------
@@ -926,11 +888,8 @@ void ymf278b_device::device_start()
m_mix_level[i] = m_volume[8*i+13];
m_mix_level[7] = 0;
- // Register state for saving
- register_save_state();
-
- // YMF262 related
- m_fm.save(*this);
+ // initialize the FM engine
+ m_fm.init();
}
diff --git a/src/devices/sound/ymf278b.h b/src/devices/sound/ymf278b.h
index b98b35bfe49..c8918e6452b 100644
--- a/src/devices/sound/ymf278b.h
+++ b/src/devices/sound/ymf278b.h
@@ -32,6 +32,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
+ virtual void device_register_save(save_registrar &save) override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
@@ -81,6 +82,45 @@ private:
int8_t env_preverb;
int num; /* slot number (for debug only) */
+
+ void register_save(save_registrar &save)
+ {
+ save.reg(NAME(wave))
+ .reg(NAME(F_NUMBER))
+ .reg(NAME(octave))
+ .reg(NAME(preverb))
+ .reg(NAME(DAMP))
+ .reg(NAME(CH))
+ .reg(NAME(LD))
+ .reg(NAME(TL))
+ .reg(NAME(pan))
+ .reg(NAME(LFO))
+ .reg(NAME(VIB))
+ .reg(NAME(AM))
+
+ .reg(NAME(AR))
+ .reg(NAME(D1R))
+ .reg(NAME(DL))
+ .reg(NAME(D2R))
+ .reg(NAME(RC))
+ .reg(NAME(RR))
+
+ .reg(NAME(step))
+ .reg(NAME(stepptr))
+
+ .reg(NAME(active))
+ .reg(NAME(KEY_ON))
+ .reg(NAME(bits))
+ .reg(NAME(startaddr))
+ .reg(NAME(loopaddr))
+ .reg(NAME(endaddr))
+
+ .reg(NAME(env_step))
+ .reg(NAME(env_vol))
+ .reg(NAME(env_vol_step))
+ .reg(NAME(env_vol_lim))
+ .reg(NAME(env_preverb));
+ }
};
int compute_rate(YMF278BSlot *slot, int val);
diff --git a/src/devices/sound/ymfm.h b/src/devices/sound/ymfm.h
index f0f949b423b..0cb2f843f49 100644
--- a/src/devices/sound/ymfm.h
+++ b/src/devices/sound/ymfm.h
@@ -1283,7 +1283,7 @@ public:
void init();
// register for save states
- void register_save(save_registrar &device);
+ void register_save(save_registrar &save);
// reset the overall state
void reset();
diff --git a/src/emu/dirom.h b/src/emu/dirom.h
index 8d5d64442a3..04bac0ccd9d 100644
--- a/src/emu/dirom.h
+++ b/src/emu/dirom.h
@@ -47,7 +47,7 @@ private:
virtual void interface_validity_check(validity_checker &valid) const override;
virtual void interface_pre_start() override;
- virtual void interface_post_start() override;
+ virtual void interface_post_load() override;
virtual void interface_register_save(save_registrar &save) override;
};
diff --git a/src/emu/save.h b/src/emu/save.h
index 1785d041270..39c0ada0982 100644
--- a/src/emu/save.h
+++ b/src/emu/save.h
@@ -67,6 +67,16 @@ TEST:
typedef named_delegate<void ()> save_prepost_delegate;
+#define SAVE_TYPE_AS_INT(Type) \
+ template<> struct save_registrar::is_signed_int_like<Type> { static constexpr bool value = true; };
+
+#define SAVE_TYPE_AS_UINT(Type) \
+ template<> struct save_registrar::is_unsigned_int_like<Type> { static constexpr bool value = true; };
+
+#define SAVE_TYPE_AS_FLOAT(Type) \
+ template<> struct save_registrar::is_floating_point_like<Type> { static constexpr bool value = true; };
+
+
// use this to declare a given type is a simple, non-pointer type that can be
// saved; in general, this is intended only to be used for specific enum types
// defined by your device
@@ -195,6 +205,22 @@ class save_registrar
}
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
+ // SAVE_TYPE_AS_INT macro
+ template<typename T> struct is_signed_int_like { static constexpr bool value = ((std::is_integral<T>::value && std::is_signed<T>::value) || std::is_enum<T>::value); };
+
+ // items that are unsigned_int_like are interpreted as 8/16/32/64-bit unsigned integers; this includes
+ // proper unsigned integral values; additional types may be added via the SAVE_TYPE_AS_UINT macro
+ template<typename T> struct is_unsigned_int_like { static constexpr bool value = (std::is_integral<T>::value && !std::is_signed<T>::value); };
+
+ // items that are floating_point_like are interpreted as 32/64-bit IEEE floating point; this includes
+ // 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); };
+
// construct a container within parent
save_registrar(save_registrar &parent, char const *name) :
save_registrar(parent, save_registered_item::TYPE_CONTAINER, 0, name)
@@ -214,35 +240,31 @@ public:
return *this;
}
- // enum types -- these are equivalent to ints of the save size
- template<typename T>
- std::enable_if_t<std::is_enum<T>::value, save_registrar> &reg(T &data, char const *name)
- {
- return register_internal(&data, save_registered_item::TYPE_INT, sizeof(data), name);
- }
-
// signed integral types
template<typename T>
- std::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value, save_registrar> &reg(T &data, char const *name)
+ 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);
}
// unsigned integral types
template<typename T>
- std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value, save_registrar> &reg(T &data, char const *name)
+ 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);
}
// floating-point types
template<typename T>
- std::enable_if_t<std::is_floating_point<T>::value, save_registrar> &reg(T &data, char const *name)
+ 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);
}
- // unique_ptrs -- these are containers with a single "unique" item within
+ // std::unique_ptrs -- these are containers with a single "unique" item within
template<typename T>
save_registrar &reg(std::unique_ptr<T> &data, char const *name)
{
@@ -264,7 +286,17 @@ public:
return *this;
}
- // vectors -- these are treated as arrays, with the size coming from the vector
+ // std::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>
+ save_registrar &reg(std::array<T, N> &data, char const *name)
+ {
+ save_registrar container(*this, save_registered_item::save_type(N), sizeof(data[0]), name, &data[0]);
+ container.reg(data[0], "");
+ return *this;
+ }
+
+ // std::vectors -- these are treated as arrays, with the size coming from the vector
template<typename T>
save_registrar &reg(std::vector<T> &data, char const *name)
{
@@ -281,7 +313,7 @@ public:
return *this;
}
- // unique_ptrs with arrays
+ // std::unique_ptrs with arrays
template<typename T>
save_registrar &reg(std::unique_ptr<T[]> &data, char const *name, std::size_t count)
{
@@ -307,8 +339,8 @@ public:
return *this;
}
- // structures (must have a _save method)
- template<typename T, std::enable_if_t<std::is_class<T>::value && !std::is_base_of<bitmap_t, T>::value, bool> = true>
+ // structures (must have a register_save method)
+ template<typename T, std::enable_if_t<std::is_class<T>::value && !std::is_base_of<bitmap_t, T>::value && !is_atom<T>::value, bool> = true>
save_registrar &reg(T &data, char const *name)
{
save_registrar container(*this, save_registered_item::TYPE_STRUCT, sizeof(data), name, &data);
@@ -319,14 +351,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); }
- // rgb_t as a special case
- save_registrar &reg(rgb_t &data, char const *name) { return register_internal(&data, save_registered_item::TYPE_UINT, sizeof(data), name); }
-
- // PAIR/PAIR64 as a special case
- save_registrar &reg(PAIR &data, char const *name) { return register_internal(&data, save_registered_item::TYPE_UINT, sizeof(data), name); }
- save_registrar &reg(PAIR64 &data, char const *name) { return register_internal(&data, save_registered_item::TYPE_UINT, sizeof(data), name); }
-
- // rectangle as a special case
+ // 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);
@@ -337,7 +362,7 @@ public:
return *this;
}
- // bitmaps as a special case
+ // bitmaps as a special case, since they're from an external library
template<typename BitmapType>
std::enable_if_t<std::is_base_of<bitmap_t, BitmapType>::value, save_registrar> &reg(BitmapType &data, char const *name)
{
@@ -367,6 +392,12 @@ private:
uintptr_t m_baseptr;
};
+// these types are small structures/unions that embed an integral type; treat them as raw
+// integral types for saving purposes
+SAVE_TYPE_AS_UINT(rgb_t);
+SAVE_TYPE_AS_UINT(PAIR);
+SAVE_TYPE_AS_UINT(PAIR64);
+