serialize: move code out of serialize.cpp and into modules

This commit is contained in:
Flyinghead 2023-01-31 10:13:03 +01:00
parent 27ea6ca092
commit 04c418d02a
15 changed files with 379 additions and 509 deletions

View File

@ -2,6 +2,8 @@
#include "types.h"
#include "stdclass.h"
extern u32 SB_ADST;
namespace aica
{

View File

@ -13,6 +13,7 @@
#include "hw/pvr/pvr_sb_regs.h"
#include "emulator.h"
#include "hw/bba/bba.h"
#include "serialize.h"
std::array<RegisterStruct, 0x540> sb_regs;
@ -752,3 +753,30 @@ void sb_Term()
naomi_reg_Term();
asic_reg_Term();
}
void sb_serialize(Serializer& ser)
{
register_serialize(sb_regs, ser);
ser << SB_ISTNRM;
ser << SB_ISTNRM1;
ser << SB_ADST;
}
void sb_deserialize(Deserializer& deser)
{
register_deserialize(sb_regs, deser);
deser >> SB_ISTNRM;
if (deser.version() >= Deserializer::V24)
deser >> SB_ISTNRM1;
else
SB_ISTNRM1 = 0;
if (deser.version() < Deserializer::V30)
{
deser.skip<u32>(); // SB_FFST_rc;
deser.skip<u32>(); // SB_FFST;
}
if (deser.version() >= Deserializer::V15)
deser >> SB_ADST;
else
SB_ADST = 0;
}

View File

@ -12,6 +12,8 @@ void sb_WriteMem(u32 addr, u32 data);
void sb_Init();
void sb_Reset(bool hard);
void sb_Term();
void sb_serialize(Serializer& ser);
void sb_deserialize(Deserializer& deser);
extern std::array<RegisterStruct, 0x540> sb_regs;

View File

@ -27,6 +27,7 @@
#include "hw/sh4/sh4_sched.h"
#include "network/picoppp.h"
#include "serialize.h"
#include "cfg/option.h"
#ifndef NDEBUG
#include "oslib/oslib.h"
@ -53,7 +54,7 @@ static modemreg_t modem_regs;
static u8 dspram[0x1000];
int modem_sched;
static int modem_sched;
enum ModemStates
{
@ -753,6 +754,7 @@ void ModemWriteMem_A0_006(u32 addr, u32 data, u32 size)
void ModemSerialize(Serializer& ser)
{
sh4_sched_serialize(ser, modem_sched);
ser << modem_regs;
ser << dspram;
ser << state;
@ -762,6 +764,8 @@ void ModemSerialize(Serializer& ser)
}
void ModemDeserialize(Deserializer& deser)
{
if (!config::EmulateBBA || deser.version() > Deserializer::V31)
sh4_sched_deserialize(deser, modem_sched);
if (deser.version() >= Deserializer::V20)
{
deser >> modem_regs;

View File

@ -43,6 +43,8 @@ void ubc_term();
void tmu_init();
void tmu_reset(bool hard);
void tmu_term();
void tmu_serialize(Serializer& ser);
void tmu_deserialize(Deserializer& deser);
void ccn_init();
void ccn_reset(bool hard);

View File

@ -6,16 +6,16 @@
#include "hw/sh4/sh4_sched.h"
#include "hw/sh4/sh4_interrupts.h"
#include "hw/sh4/sh4_mmr.h"
#include "serialize.h"
#define tmu_underflow 0x0100
#define tmu_UNIE 0x0020
u32 tmu_shift[3];
u32 tmu_mask[3];
u64 tmu_mask64[3];
static u32 tmu_shift[3];
static u32 tmu_mask[3];
static u64 tmu_mask64[3];
u32 old_mode[3] = { 0xFFFF, 0xFFFF, 0xFFFF};
static u32 old_mode[3] = { 0xFFFF, 0xFFFF, 0xFFFF};
static const InterruptID tmu_intID[3] = { sh4_TMU0_TUNI0, sh4_TMU1_TUNI1, sh4_TMU2_TUNI2 };
int tmu_sched[3];
@ -73,8 +73,8 @@ void UpdateTMU_i(u32 Cycles)
}
#endif
u32 tmu_ch_base[3];
u64 tmu_ch_base64[3];
static u32 tmu_ch_base[3];
static u64 tmu_ch_base64[3];
static u32 read_TMU_TCNTch(u32 ch)
{
@ -328,3 +328,23 @@ void tmu_term()
sched_id = -1;
}
}
void tmu_serialize(Serializer& ser)
{
ser << tmu_shift;
ser << tmu_mask;
ser << tmu_mask64;
ser << old_mode;
ser << tmu_ch_base;
ser << tmu_ch_base64;
}
void tmu_deserialize(Deserializer& deser)
{
deser >> tmu_shift;
deser >> tmu_mask;
deser >> tmu_mask64;
deser >> old_mode;
deser >> tmu_ch_base;
deser >> tmu_ch_base64;
}

View File

@ -15,6 +15,7 @@
#include "sh4_mmr.h"
#include "oslib/oslib.h"
#include "debug/gdb_server.h"
#include "serialize.h"
#include <cassert>
//these are fixed
@ -241,3 +242,25 @@ void interrupts_term()
{
}
void interrupts_serialize(Serializer& ser)
{
ser << InterruptEnvId;
ser << InterruptBit;
ser << InterruptLevelBit;
ser << interrupt_vpend;
ser << interrupt_vmask;
ser << decoded_srimask;
}
void interrupts_deserialize(Deserializer& deser)
{
if (deser.version() < Deserializer::V9_LIBRETRO)
deser.skip(2);
deser >> InterruptEnvId;
deser >> InterruptBit;
deser >> InterruptLevelBit;
deser >> interrupt_vpend;
deser >> interrupt_vmask;
deser >> decoded_srimask;
}

View File

@ -97,3 +97,5 @@ void SIIDRebuild();
void interrupts_init();
void interrupts_reset();
void interrupts_term();
void interrupts_serialize(Serializer& ser);
void interrupts_deserialize(Deserializer& deser);

View File

@ -9,13 +9,17 @@
#include "modules/ccn.h"
#include "modules/modules.h"
#include "sh4_cache.h"
#include "serialize.h"
#include "sh4_interrupts.h"
#include "sh4_sched.h"
#include "sh4_interpreter.h"
#include <array>
#include <map>
//64bytes of sq // now on context ~
std::array<u8, OnChipRAM_SIZE> OnChipRAM;
static std::array<u8, OnChipRAM_SIZE> OnChipRAM;
//All registers are 4 byte aligned
@ -903,3 +907,147 @@ void map_p4()
addrspace::mapHandler(p4mmr_handler, 0xFF, 0xFF);
}
namespace sh4
{
void serialize(Serializer& ser)
{
ser << OnChipRAM;
register_serialize(CCN, ser);
register_serialize(UBC, ser);
register_serialize(BSC, ser);
register_serialize(DMAC, ser);
register_serialize(CPG, ser);
register_serialize(RTC, ser);
register_serialize(INTC, ser);
register_serialize(TMU, ser);
register_serialize(SCI, ser);
register_serialize(SCIF, ser);
icache.Serialize(ser);
ocache.Serialize(ser);
if (!ser.rollback())
mem_b.serialize(ser);
interrupts_serialize(ser);
ser << (*p_sh4rcb).sq_buffer;
ser << (*p_sh4rcb).cntx;
sh4_sched_serialize(ser);
}
void deserialize(Deserializer& deser)
{
deser >> OnChipRAM;
register_deserialize(CCN, deser);
register_deserialize(UBC, deser);
register_deserialize(BSC, deser);
register_deserialize(DMAC, deser);
register_deserialize(CPG, deser);
register_deserialize(RTC, deser);
register_deserialize(INTC, deser);
register_deserialize(TMU, deser);
register_deserialize(SCI, deser);
register_deserialize(SCIF, deser);
if (deser.version() >= Deserializer::V9
// Note (lr): was added in V11 fa49de29 24/12/2020 but ver not updated until V12 (13/4/2021)
|| (deser.version() >= Deserializer::V11_LIBRETRO && deser.version() <= Deserializer::VLAST_LIBRETRO))
icache.Deserialize(deser);
else
icache.Reset(true);
if (deser.version() >= Deserializer::V10
// Note (lr): was added in V11 2eb66879 27/12/2020 but ver not updated until V12 (13/4/2021)
|| (deser.version() >= Deserializer::V11_LIBRETRO && deser.version() <= Deserializer::VLAST_LIBRETRO))
ocache.Deserialize(deser);
else
ocache.Reset(true);
if (!deser.rollback())
mem_b.deserialize(deser);
interrupts_deserialize(deser);
if (deser.version() <= Deserializer::V31)
deser.skip<int>(); // do_sqw index
CCN_QACR_write<0>(0, CCN_QACR0.reg_data);
CCN_QACR_write<1>(0, CCN_QACR1.reg_data);
deser >> (*p_sh4rcb).sq_buffer;
deser >> (*p_sh4rcb).cntx;
if (deser.version() < Deserializer::V9_LIBRETRO)
{
deser.skip<u32>(); // old_rm
deser.skip<u32>(); // old_dn
}
if (deser.version() >= Deserializer::V19 && deser.version() < Deserializer::V21)
deser.skip<u32>(); // sh4InterpCycles
if (deser.version() < Deserializer::V21)
p_sh4rcb->cntx.cycle_counter = SH4_TIMESLICE;
sh4_sched_deserialize(deser);
}
void serialize2(Serializer& ser)
{
ser << SCIF_SCFSR2;
ser << SCIF_SCSCR2;
ser << BSC_PDTRA;
tmu_serialize(ser);
ser << CCN_QACR_TR; // FIXME this is set in CCN_QACR_write<>() above, so useless. And it's really a cached thing
ser << UTLB;
ser << ITLB;
ser << sq_remap;
}
void deserialize2(Deserializer& deser)
{
deser >> SCIF_SCFSR2;
if (deser.version() < Deserializer::V9_LIBRETRO
|| (deser.version() >= Deserializer::V5 && deser.version() < Deserializer::V8))
{
deser.skip<bool>(); // SCIF_SCFRDR2
deser.skip<u32>(); // SCIF_SCFDR2
}
else if ((deser.version() >= Deserializer::V11_LIBRETRO && deser.version() <= Deserializer::VLAST_LIBRETRO)
|| deser.version() >= Deserializer::V11)
deser >> SCIF_SCSCR2;
deser >> BSC_PDTRA;
tmu_deserialize(deser);
deser >> CCN_QACR_TR;
if (deser.version() < Deserializer::V6_LIBRETRO)
{
for (int i = 0; i < 64; i++)
{
deser >> UTLB[i].Address;
deser >> UTLB[i].Data;
}
for (int i = 0; i < 4; i++)
{
deser >> ITLB[i].Address;
deser >> ITLB[i].Data;
}
}
else
{
deser >> UTLB;
deser >> ITLB;
}
if (deser.version() >= Deserializer::V11
|| (deser.version() >= Deserializer::V11_LIBRETRO && deser.version() <= Deserializer::VLAST_LIBRETRO))
deser >> sq_remap;
deser.skip(64 * 4, Deserializer::V23); // ITLB_LRU_USE
}
} //namespace sh4

View File

@ -28,6 +28,16 @@ void sh4_mmr_init();
void sh4_mmr_reset(bool hard);
void sh4_mmr_term();
namespace sh4
{
void serialize(Serializer& ser);
void deserialize(Deserializer& deser);
void serialize2(Serializer& ser);
void deserialize2(Deserializer& deser);
}
void sh4_rio_reg(RegisterStruct *arr, u32 addr, RegIO flags, RegReadAddrFP *rf = nullptr, RegWriteAddrFP *wf = nullptr);
#define SH4IO_REGN(mod, addr) ((mod)[((addr) & 255) / 4].data32)

View File

@ -1,6 +1,7 @@
#include "types.h"
#include "sh4_if.h"
#include "sh4_sched.h"
#include "serialize.h"
#include <algorithm>
#include <vector>
@ -20,10 +21,17 @@
sh4_sched_now()
*/
struct sched_list
{
sh4_sched_callback* cb;
int tag;
int start;
int end;
};
u64 sh4_sched_ffb;
std::vector<sched_list> sch_list;
int sh4_sched_next_id = -1;
static u64 sh4_sched_ffb;
static std::vector<sched_list> sch_list;
static int sh4_sched_next_id = -1;
static u32 sh4_sched_now();
@ -184,3 +192,80 @@ void sh4_sched_reset(bool hard)
Sh4cntx.sh4_sched_next = 0;
}
}
void sh4_sched_serialize(Serializer& ser, int id)
{
ser << sch_list[id].tag;
ser << sch_list[id].start;
ser << sch_list[id].end;
}
void sh4_sched_deserialize(Deserializer& deser, int id)
{
deser >> sch_list[id].tag;
deser >> sch_list[id].start;
deser >> sch_list[id].end;
}
// FIXME modules should save their scheduling data so that it doesn't depend on their scheduler id
namespace aica
{
// hw/aica/aica.cpp
extern int aica_schid;
extern int rtc_schid;
// hw/aica/aica_if.cpp
extern int dma_sched_id;
}
// hw/gdrom/gdromv3.cpp
extern int gdrom_schid;
// hw/maple/maple_if.cpp
extern int maple_schid;
// hw/pvr/spg.cpp
extern int render_end_schid;
extern int vblank_schid;
// hw/sh4/modules/tmu.cpp
extern int tmu_sched[3];
void sh4_sched_serialize(Serializer& ser)
{
ser << sh4_sched_ffb;
sh4_sched_serialize(ser, aica::aica_schid);
sh4_sched_serialize(ser, aica::rtc_schid);
sh4_sched_serialize(ser, gdrom_schid);
sh4_sched_serialize(ser, maple_schid);
sh4_sched_serialize(ser, aica::dma_sched_id);
for (int id : tmu_sched)
sh4_sched_serialize(ser, id);
sh4_sched_serialize(ser, render_end_schid);
sh4_sched_serialize(ser, vblank_schid);
}
void sh4_sched_deserialize(Deserializer& deser)
{
deser >> sh4_sched_ffb;
if (deser.version() >= Deserializer::V19 && deser.version() <= Deserializer::V31)
deser.skip<u32>(); // sh4_sched_next_id
else if ((deser.version() >= Deserializer::V5 && deser.version() < Deserializer::V8)
|| deser.version() < Deserializer::V9_LIBRETRO)
deser.skip<u32>(); // sh4_sched_intr
sh4_sched_deserialize(deser, aica::aica_schid);
sh4_sched_deserialize(deser, aica::rtc_schid);
sh4_sched_deserialize(deser, gdrom_schid);
sh4_sched_deserialize(deser, maple_schid);
sh4_sched_deserialize(deser, aica::dma_sched_id);
for (int id : tmu_sched)
sh4_sched_deserialize(deser, id);
sh4_sched_deserialize(deser, render_end_schid);
sh4_sched_deserialize(deser, vblank_schid);
if ((deser.version() >= Deserializer::V5 && deser.version() < Deserializer::V8)
|| deser.version() < Deserializer::V9_LIBRETRO)
{
deser.skip<u32>(); // sch_list[time_sync].tag
deser.skip<u32>(); // sch_list[time_sync].start
deser.skip<u32>(); // sch_list[time_sync].end
}
}

View File

@ -44,12 +44,9 @@ void sh4_sched_tick(int cycles);
void sh4_sched_ffts();
void sh4_sched_reset(bool hard);
struct sched_list
{
sh4_sched_callback* cb;
int tag;
int start;
int end;
};
void sh4_sched_serialize(Serializer& ser);
void sh4_sched_deserialize(Deserializer& deser);
void sh4_sched_serialize(Serializer& ser, int id);
void sh4_sched_deserialize(Deserializer& deser, int id);
#endif //SH4_SCHED_H

View File

@ -8,131 +8,23 @@
#include "hw/maple/maple_cfg.h"
#include "hw/modem/modem.h"
#include "hw/pvr/pvr.h"
#include "hw/pvr/pvr_mem.h"
#include "hw/sh4/sh4_sched.h"
#include "hw/sh4/sh4_mmr.h"
#include "hw/sh4/modules/mmu.h"
#include "reios/gdrom_hle.h"
#include "hw/naomi/naomi.h"
#include "hw/naomi/naomi_cart.h"
#include "hw/sh4/sh4_cache.h"
#include "hw/sh4/sh4_interpreter.h"
#include "hw/bba/bba.h"
#include "cfg/option.h"
#include <array>
#include <vector>
namespace aica
{
//./core/hw/aica/aica.o
extern int aica_schid;
extern int rtc_schid;
//./core/hw/aica/aica_if.o
extern int dma_sched_id;
}
extern u32 SB_ADST;
//./core/hw/gdrom/gdromv3.o
extern int gdrom_schid;
//./core/hw/maple/maple_if.o
extern int maple_schid;
//./core/hw/modem/modem.cpp
extern int modem_sched;
//./core/hw/pvr/spg.o
extern int render_end_schid;
extern int vblank_schid;
//./core/hw/sh4/sh4_mmr.o
extern std::array<u8, OnChipRAM_SIZE> OnChipRAM;
//./core/hw/sh4/sh4_mem.o
extern RamRegion mem_b;
//./core/hw/sh4/sh4_interrupts.o
alignas(64) extern Sh4ExceptionCode InterruptEnvId[32];
alignas(64) extern u32 InterruptBit[32];
alignas(64) extern u32 InterruptLevelBit[16];
extern u32 interrupt_vpend; // Vector of pending interrupts
extern u32 interrupt_vmask; // Vector of masked interrupts (-1 inhibits all interrupts)
extern u32 decoded_srimask; // Vector of interrupts allowed by SR.IMSK (-1 inhibits all interrupts)
//./core/hw/sh4/sh4_core_regs.o
extern Sh4RCB* p_sh4rcb;
//./core/hw/sh4/sh4_sched.o
extern u64 sh4_sched_ffb;
extern std::vector<sched_list> sch_list;
extern int sh4_sched_next_id;
//./core/hw/sh4/modules/serial.o
extern SCIF_SCFSR2_type SCIF_SCFSR2;
extern SCIF_SCSCR2_type SCIF_SCSCR2;
//./core/hw/sh4/modules/bsc.o
extern BSC_PDTRA_type BSC_PDTRA;
//./core/hw/sh4/modules/tmu.o
extern u32 tmu_shift[3];
extern u32 tmu_mask[3];
extern u64 tmu_mask64[3];
extern u32 old_mode[3];
extern int tmu_sched[3];
extern u32 tmu_ch_base[3];
extern u64 tmu_ch_base64[3];
//./core/hw/sh4/modules/ccn.o
extern u32 CCN_QACR_TR[2];
//./core/hw/sh4/modules/mmu.o
extern TLB_Entry UTLB[64];
extern TLB_Entry ITLB[4];
extern u32 sq_remap[64];
//./core/imgread/common.o
extern u32 NullDriveDiscType;
extern u8 q_subchannel[96];
template<typename T>
void register_serialize(const T& regs, Serializer& ser)
{
for (const auto& reg : regs)
ser << reg.data32;
}
template<typename T>
void register_deserialize(T& regs, Deserializer& deser)
{
for (auto& reg : regs)
{
if (deser.version() < Deserializer::V5)
deser.skip<u32>(); // regs.data[i].flags
if (!(reg.flags & REG_RF))
deser >> reg.data32;
else
deser.skip<u32>();
}
}
static const std::array<int, 11> getSchedulerIds() {
return { aica::aica_schid, aica::rtc_schid, gdrom_schid, maple_schid, aica::dma_sched_id,
tmu_sched[0], tmu_sched[1], tmu_sched[2], render_end_schid, vblank_schid,
modem_sched };
}
void dc_serialize(Serializer& ser)
{
aica::serialize(ser);
register_serialize(sb_regs, ser);
ser << SB_ISTNRM;
ser << SB_ISTNRM1;
ser << SB_ADST;
sb_serialize(ser);
nvmem::serialize(ser);
@ -142,93 +34,14 @@ void dc_serialize(Serializer& ser)
pvr::serialize(ser);
ser << OnChipRAM;
register_serialize(CCN, ser);
register_serialize(UBC, ser);
register_serialize(BSC, ser);
register_serialize(DMAC, ser);
register_serialize(CPG, ser);
register_serialize(RTC, ser);
register_serialize(INTC, ser);
register_serialize(TMU, ser);
register_serialize(SCI, ser);
register_serialize(SCIF, ser);
icache.Serialize(ser);
ocache.Serialize(ser);
if (!ser.rollback())
mem_b.serialize(ser);
ser << InterruptEnvId;
ser << InterruptBit;
ser << InterruptLevelBit;
ser << interrupt_vpend;
ser << interrupt_vmask;
ser << decoded_srimask;
//default to nommu_full
int i = 3;
if ( do_sqw_nommu == &do_sqw_nommu_area_3)
i = 0;
else if (do_sqw_nommu == &do_sqw_nommu_area_3_nonvmem)
i = 1;
else if (do_sqw_nommu == &TAWriteSQ)
i = 2;
else if (do_sqw_nommu==&do_sqw_nommu_full)
i = 3;
ser << i;
ser << (*p_sh4rcb).sq_buffer;
ser << (*p_sh4rcb).cntx;
ser << sh4_sched_ffb;
std::array<int, 11> schedIds = getSchedulerIds();
if (sh4_sched_next_id == -1)
ser << sh4_sched_next_id;
else
for (u32 i = 0; i < schedIds.size(); i++)
if (schedIds[i] == sh4_sched_next_id)
ser << i;
for (u32 i = 0; i < schedIds.size() - 1; i++)
{
ser << sch_list[schedIds[i]].tag;
ser << sch_list[schedIds[i]].start;
ser << sch_list[schedIds[i]].end;
}
sh4::serialize(ser);
ser << config::EmulateBBA.get();
if (config::EmulateBBA)
{
bba_Serialize(ser);
}
else
{
ser << sch_list[modem_sched].tag;
ser << sch_list[modem_sched].start;
ser << sch_list[modem_sched].end;
}
ModemSerialize(ser);
ser << SCIF_SCFSR2;
ser << SCIF_SCSCR2;
ser << BSC_PDTRA;
ser << tmu_shift;
ser << tmu_mask;
ser << tmu_mask64;
ser << old_mode;
ser << tmu_ch_base;
ser << tmu_ch_base64;
ser << CCN_QACR_TR;
ser << UTLB;
ser << ITLB;
ser << sq_remap;
sh4::serialize2(ser);
ser << NullDriveDiscType;
ser << q_subchannel;
@ -251,11 +64,7 @@ static void dc_deserialize_libretro(Deserializer& deser)
{
aica::deserialize(deser);
register_deserialize(sb_regs, deser);
deser >> SB_ISTNRM;
deser.skip<u32>(); // SB_FFST_rc;
deser.skip<u32>(); // SB_FFST;
SB_ADST = 0;
sb_deserialize(deser);
nvmem::deserialize(deser);
@ -265,162 +74,15 @@ static void dc_deserialize_libretro(Deserializer& deser)
pvr::deserialize(deser);
deser >> OnChipRAM;
register_deserialize(CCN, deser);
register_deserialize(UBC, deser);
register_deserialize(BSC, deser);
register_deserialize(DMAC, deser);
register_deserialize(CPG, deser);
register_deserialize(RTC, deser);
register_deserialize(INTC, deser);
register_deserialize(TMU, deser);
register_deserialize(SCI, deser);
register_deserialize(SCIF, deser);
if (deser.version() >= Deserializer::V11_LIBRETRO) // FIXME was added in V11 fa49de29 24/12/2020 but ver not updated until V12 (13/4/2021)
icache.Deserialize(deser);
else
icache.Reset(true);
if (deser.version() >= Deserializer::V11_LIBRETRO) // FIXME was added in V11 2eb66879 27/12/2020 but ver not updated until V12 (13/4/2021)
ocache.Deserialize(deser);
else
ocache.Reset(true);
mem_b.deserialize(deser);
if (deser.version() < Deserializer::V9_LIBRETRO)
deser.skip<u16>();
deser >> InterruptEnvId;
deser >> InterruptBit;
deser >> InterruptLevelBit;
deser >> interrupt_vpend;
deser >> interrupt_vmask;
deser >> decoded_srimask;
int i;
deser >> i;
switch (i)
{
case 0:
case 1:
if (addrspace::virtmemEnabled())
do_sqw_nommu = &do_sqw_nommu_area_3;
else
do_sqw_nommu = &do_sqw_nommu_area_3_nonvmem;
break;
case 2:
do_sqw_nommu = &TAWriteSQ;
break;
case 3:
do_sqw_nommu = &do_sqw_nommu_full;
break;
default:
throw Deserializer::Exception("Invalid SQ handler index");
}
deser >> (*p_sh4rcb).sq_buffer;
deser >> (*p_sh4rcb).cntx;
p_sh4rcb->cntx.cycle_counter = SH4_TIMESLICE;
if (deser.version() < Deserializer::V9_LIBRETRO)
{
deser.skip<u32>(); // old_rm
deser.skip<u32>(); // old_dn
}
deser >> sh4_sched_ffb;
if (deser.version() < Deserializer::V9_LIBRETRO)
deser.skip<u32>(); // sh4_sched_intr
deser >> sch_list[aica::aica_schid].tag;
deser >> sch_list[aica::aica_schid].start;
deser >> sch_list[aica::aica_schid].end;
deser >> sch_list[aica::rtc_schid].tag;
deser >> sch_list[aica::rtc_schid].start;
deser >> sch_list[aica::rtc_schid].end;
deser >> sch_list[gdrom_schid].tag;
deser >> sch_list[gdrom_schid].start;
deser >> sch_list[gdrom_schid].end;
deser >> sch_list[maple_schid].tag;
deser >> sch_list[maple_schid].start;
deser >> sch_list[maple_schid].end;
deser >> sch_list[aica::dma_sched_id].tag;
deser >> sch_list[aica::dma_sched_id].start;
deser >> sch_list[aica::dma_sched_id].end;
for (int i = 0; i < 3; i++)
{
deser >> sch_list[tmu_sched[i]].tag;
deser >> sch_list[tmu_sched[i]].start;
deser >> sch_list[tmu_sched[i]].end;
}
deser >> sch_list[render_end_schid].tag;
deser >> sch_list[render_end_schid].start;
deser >> sch_list[render_end_schid].end;
deser >> sch_list[vblank_schid].tag;
deser >> sch_list[vblank_schid].start;
deser >> sch_list[vblank_schid].end;
if (deser.version() < Deserializer::V9_LIBRETRO)
{
deser.skip<u32>(); // sch_list[time_sync].tag
deser.skip<u32>(); // sch_list[time_sync].start
deser.skip<u32>(); // sch_list[time_sync].end
}
sh4::deserialize(deser);
if (deser.version() >= Deserializer::V13_LIBRETRO)
deser.skip<bool>(); // settings.network.EmulateBBA
config::EmulateBBA.override(false);
deser >> sch_list[modem_sched].tag;
deser >> sch_list[modem_sched].start;
deser >> sch_list[modem_sched].end;
ModemDeserialize(deser);
deser >> SCIF_SCFSR2;
if (deser.version() < Deserializer::V9_LIBRETRO)
{
deser.skip(1); // SCIF_SCFRDR2
deser.skip(4); // SCIF_SCFDR2
}
else if (deser.version() >= Deserializer::V11_LIBRETRO)
deser >> SCIF_SCSCR2;
deser >> BSC_PDTRA;
deser >> tmu_shift;
deser >> tmu_mask;
deser >> tmu_mask64;
deser >> old_mode;
deser >> tmu_ch_base;
deser >> tmu_ch_base64;
deser >> CCN_QACR_TR;
if (deser.version() < Deserializer::V6_LIBRETRO)
{
for (int i = 0; i < 64; i++)
{
deser >> UTLB[i].Address;
deser >> UTLB[i].Data;
}
for (int i = 0; i < 4; i++)
{
deser >> ITLB[i].Address;
deser >> ITLB[i].Data;
}
}
else
{
deser >> UTLB;
deser >> ITLB;
}
if (deser.version() >= Deserializer::V11_LIBRETRO)
deser >> sq_remap;
deser.skip(64 * 4); // ITLB_LRU_USE
sh4::deserialize2(deser);
deser >> NullDriveDiscType;
deser >> q_subchannel;
@ -468,7 +130,6 @@ static void dc_deserialize_libretro(Deserializer& deser)
CurrentCartridge->Deserialize(deser);
if (deser.version() >= Deserializer::V7_LIBRETRO)
gd_hle_state.Deserialize(deser);
config::EmulateBBA.override(false);
DEBUG_LOG(SAVESTATE, "Loaded %d bytes (libretro compat)", (u32)deser.size());
}
@ -478,27 +139,14 @@ void dc_deserialize(Deserializer& deser)
if (deser.version() >= Deserializer::V5_LIBRETRO && deser.version() <= Deserializer::VLAST_LIBRETRO)
{
dc_deserialize_libretro(deser);
sh4_sched_ffts();
return;
}
DEBUG_LOG(SAVESTATE, "Loading state version %d", deser.version());
aica::deserialize(deser);
register_deserialize(sb_regs, deser);
deser >> SB_ISTNRM;
if (deser.version() >= Deserializer::V24)
deser >> SB_ISTNRM1;
else
SB_ISTNRM1 = 0;
if (deser.version() < Deserializer::V30)
{
deser.skip<u32>(); // SB_FFST_rc;
deser.skip<u32>(); // SB_FFST;
}
if (deser.version() >= Deserializer::V15)
deser >> SB_ADST;
else
SB_ADST = 0;
sb_deserialize(deser);
nvmem::deserialize(deser);
@ -508,141 +156,17 @@ void dc_deserialize(Deserializer& deser)
pvr::deserialize(deser);
deser >> OnChipRAM;
register_deserialize(CCN, deser);
register_deserialize(UBC, deser);
register_deserialize(BSC, deser);
register_deserialize(DMAC, deser);
register_deserialize(CPG, deser);
register_deserialize(RTC, deser);
register_deserialize(INTC, deser);
register_deserialize(TMU, deser);
register_deserialize(SCI, deser);
register_deserialize(SCIF, deser);
if (deser.version() >= Deserializer::V9)
icache.Deserialize(deser);
else
icache.Reset(true);
if (deser.version() >= Deserializer::V10)
ocache.Deserialize(deser);
else
ocache.Reset(true);
if (!deser.rollback())
mem_b.deserialize(deser);
if (deser.version() < Deserializer::V5)
deser.skip(2);
deser >> InterruptEnvId;
deser >> InterruptBit;
deser >> InterruptLevelBit;
deser >> interrupt_vpend;
deser >> interrupt_vmask;
deser >> decoded_srimask;
int i;
deser >> i;
switch (i)
{
case 0:
case 1:
if (addrspace::virtmemEnabled())
do_sqw_nommu = &do_sqw_nommu_area_3;
else
do_sqw_nommu = &do_sqw_nommu_area_3_nonvmem;
break;
case 2:
do_sqw_nommu = &TAWriteSQ;
break;
case 3:
do_sqw_nommu = &do_sqw_nommu_full;
break;
default:
throw Deserializer::Exception("Invalid SQ handler index");
}
deser >> (*p_sh4rcb).sq_buffer;
deser >> (*p_sh4rcb).cntx;
if (deser.version() < Deserializer::V5)
{
deser.skip(4);
deser.skip(4);
}
if (deser.version() >= Deserializer::V19 && deser.version() < Deserializer::V21)
deser.skip<u32>(); // sh4InterpCycles
if (deser.version() < Deserializer::V21)
p_sh4rcb->cntx.cycle_counter = SH4_TIMESLICE;
deser >> sh4_sched_ffb;
std::array<int, 11> schedIds = getSchedulerIds();
if (deser.version() >= Deserializer::V19)
{
deser >> sh4_sched_next_id;
if (sh4_sched_next_id != -1)
sh4_sched_next_id = schedIds[sh4_sched_next_id];
}
if (deser.version() < Deserializer::V8)
deser.skip<u32>(); // sh4_sched_intr
for (u32 i = 0; i < schedIds.size() - 1; i++)
{
deser >> sch_list[schedIds[i]].tag;
deser >> sch_list[schedIds[i]].start;
deser >> sch_list[schedIds[i]].end;
}
if (deser.version() < Deserializer::V8)
{
deser.skip<u32>(); // sch_list[time_sync].tag
deser.skip<u32>(); // sch_list[time_sync].start
deser.skip<u32>(); // sch_list[time_sync].end
}
sh4::deserialize(deser);
if (deser.version() >= Deserializer::V13)
deser >> config::EmulateBBA.get();
else
config::EmulateBBA.override(false);
if (config::EmulateBBA)
{
bba_Deserialize(deser);
}
else
{
deser >> sch_list[modem_sched].tag;
deser >> sch_list[modem_sched].start;
deser >> sch_list[modem_sched].end;
}
if (deser.version() < Deserializer::V19)
sh4_sched_ffts();
ModemDeserialize(deser);
deser >> SCIF_SCFSR2;
if (deser.version() < Deserializer::V8)
{
deser.skip<bool>(); // SCIF_SCFRDR2
deser.skip<u32>(); // SCIF_SCFDR2
}
else if (deser.version() >= Deserializer::V11)
deser >> SCIF_SCSCR2;
deser >> BSC_PDTRA;
deser >> tmu_shift;
deser >> tmu_mask;
deser >> tmu_mask64;
deser >> old_mode;
deser >> tmu_ch_base;
deser >> tmu_ch_base64;
deser >> CCN_QACR_TR;
deser >> UTLB;
deser >> ITLB;
if (deser.version() >= Deserializer::V11)
deser >> sq_remap;
deser.skip(64 * 4, Deserializer::V23); // ITLB_LRU_USE
sh4::deserialize2(deser);
deser >> NullDriveDiscType;
deser >> q_subchannel;
@ -683,6 +207,7 @@ void dc_deserialize(Deserializer& deser)
CurrentCartridge->Deserialize(deser);
if (deser.version() >= Deserializer::V6)
gd_hle_state.Deserialize(deser);
sh4_sched_ffts();
DEBUG_LOG(SAVESTATE, "Loaded %d bytes", (u32)deser.size());
}

View File

@ -18,6 +18,7 @@
*/
#pragma once
#include "types.h"
#include "hw/hwreg.h"
#include <limits>
@ -67,7 +68,8 @@ public:
V29,
V30,
V31,
Current = V31,
V32,
Current = V32,
Next = Current + 1,
};
@ -216,3 +218,23 @@ Deserializer& operator>>(Deserializer& ctx, T& obj) {
void dc_serialize(Serializer& ctx);
void dc_deserialize(Deserializer& ctx);
template<typename T>
void register_serialize(const T& regs, Serializer& ser)
{
for (const auto& reg : regs)
ser << reg.data32;
}
template<typename T>
void register_deserialize(T& regs, Deserializer& deser)
{
for (auto& reg : regs)
{
if (deser.version() < Deserializer::V5)
deser.skip<u32>(); // regs.data[i].flags
if (!(reg.flags & REG_RF))
deser >> reg.data32;
else
deser.skip<u32>();
}
}

View File

@ -32,7 +32,7 @@ TEST_F(SerializeTest, SizeTest)
std::vector<char> data(30000000);
Serializer ser(data.data(), data.size());
dc_serialize(ser);
ASSERT_EQ(28191591u, ser.size());
ASSERT_EQ(28191583u, ser.size());
}