serialize: move code out of serialize.cpp and into modules
This commit is contained in:
parent
27ea6ca092
commit
04c418d02a
|
@ -2,6 +2,8 @@
|
|||
#include "types.h"
|
||||
#include "stdclass.h"
|
||||
|
||||
extern u32 SB_ADST;
|
||||
|
||||
namespace aica
|
||||
{
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue