From cc8bab249f0b9b6ffd6101b16e214e8c45945beb Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 19 Aug 2019 18:19:27 +0300 Subject: [PATCH] reios: serialize hle bios state. Fix save state compat with upstream and libretro --- core/hw/pvr/ta_ctx.cpp | 9 +++--- core/reios/gdrom_hle.cpp | 22 +------------- core/reios/gdrom_hle.h | 63 ++++++++++++++++++++++++++++++++++++++++ core/serialize.cpp | 56 ++++++++++++++++++----------------- 4 files changed, 99 insertions(+), 51 deletions(-) diff --git a/core/hw/pvr/ta_ctx.cpp b/core/hw/pvr/ta_ctx.cpp index bb3dafd24..d30bb4b6a 100644 --- a/core/hw/pvr/ta_ctx.cpp +++ b/core/hw/pvr/ta_ctx.cpp @@ -127,7 +127,7 @@ TA_context* rqueue; cResetEvent frame_finished; double last_frame = 0; -u64 last_cyces = 0; +u64 last_cycles = 0; bool QueueRender(TA_context* ctx) { @@ -143,8 +143,8 @@ bool QueueRender(TA_context* ctx) //Try to limit speed to a "sane" level //Speed is also limited via audio, but audio //is sometimes not accurate enough (android, vista+) - u32 cycle_span = sh4_sched_now64() - last_cyces; - last_cyces = sh4_sched_now64(); + u32 cycle_span = (u32)(sh4_sched_now64() - last_cycles); + last_cycles = sh4_sched_now64(); double time_span = os_GetSeconds() - last_frame; last_frame = os_GetSeconds(); @@ -158,7 +158,8 @@ bool QueueRender(TA_context* ctx) frame_finished.Wait(); } - if (rqueue) { + if (rqueue) + { // FIXME if the discarded render is a RTT we'll have a texture missing. But waiting for the current frame to finish kills performance... tactx_Recycle(ctx); fskip++; diff --git a/core/reios/gdrom_hle.cpp b/core/reios/gdrom_hle.cpp index 8255098e4..219fa138f 100644 --- a/core/reios/gdrom_hle.cpp +++ b/core/reios/gdrom_hle.cpp @@ -20,26 +20,6 @@ #define debugf(...) DEBUG_LOG(REIOS, __VA_ARGS__) -// FIXME Serialize -typedef enum { BIOS_ERROR = -1, BIOS_INACTIVE, BIOS_ACTIVE, BIOS_COMPLETED, BIOS_DATA_AVAIL } gd_bios_status; -struct gdrom_hle_state_t -{ - u32 last_request_id; - u32 next_request_id; - gd_bios_status status; - u32 command; - u32 params[4]; - u32 result[4]; - u32 cur_sector; - u32 multi_read_sector; - u32 multi_read_offset; - u32 multi_read_count; - u32 multi_read_total; - u32 multi_callback; - u32 multi_callback_arg; - bool dma_trans_ended; - u64 xfer_end_time; -}; gdrom_hle_state_t gd_hle_state = { 0xffffffff, 2, BIOS_INACTIVE }; static void GDROM_HLE_ReadSES() @@ -238,7 +218,7 @@ static void multi_xfer() if (!dma) { gd_hle_state.result[2] = gd_hle_state.multi_read_total - gd_hle_state.multi_read_count; - gd_hle_state.result[3] = 0; + gd_hle_state.result[3] = 0; // 1 hangs Bust-a-Move-4 if (gd_hle_state.multi_callback != 0) { Sh4cntx.r[4] = gd_hle_state.multi_callback_arg; diff --git a/core/reios/gdrom_hle.h b/core/reios/gdrom_hle.h index a620a0e9a..9d35fa76c 100644 --- a/core/reios/gdrom_hle.h +++ b/core/reios/gdrom_hle.h @@ -50,3 +50,66 @@ #define CTOC_TRACK(n) (n<<16) void gdrom_hle_op(); + +typedef enum { BIOS_ERROR = -1, BIOS_INACTIVE, BIOS_ACTIVE, BIOS_COMPLETED, BIOS_DATA_AVAIL } gd_bios_status; +struct gdrom_hle_state_t +{ + u32 last_request_id; + u32 next_request_id; + gd_bios_status status; + u32 command; + u32 params[4]; + u32 result[4]; + u32 cur_sector; + u32 multi_read_sector; + u32 multi_read_offset; + u32 multi_read_count; + u32 multi_read_total; + u32 multi_callback; + u32 multi_callback_arg; + bool dma_trans_ended; + u64 xfer_end_time; + + bool Serialize(void **data, unsigned int *total_size) + { + REICAST_S(last_request_id); + REICAST_S(next_request_id); + REICAST_S(status); + REICAST_S(command); + REICAST_S(params); + REICAST_S(result); + REICAST_S(cur_sector); + REICAST_S(multi_read_sector); + REICAST_S(multi_read_offset); + REICAST_S(multi_read_count); + REICAST_S(multi_read_total); + REICAST_S(multi_callback); + REICAST_S(multi_callback_arg); + REICAST_S(dma_trans_ended); + REICAST_S(xfer_end_time); + + return true; + } + bool Unserialize(void **data, unsigned int *total_size) + { + REICAST_US(last_request_id); + REICAST_US(next_request_id); + REICAST_US(status); + REICAST_US(command); + REICAST_US(params); + REICAST_US(result); + REICAST_US(cur_sector); + REICAST_US(multi_read_sector); + REICAST_US(multi_read_offset); + REICAST_US(multi_read_count); + REICAST_US(multi_read_total); + REICAST_US(multi_callback); + REICAST_US(multi_callback_arg); + REICAST_US(dma_trans_ended); + REICAST_US(xfer_end_time); + + return true; + } +}; +extern gdrom_hle_state_t gd_hle_state; + diff --git a/core/serialize.cpp b/core/serialize.cpp index a92a58068..c9ac5bdb1 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -17,6 +17,7 @@ #include "hw/sh4/modules/mmu.h" #include "imgread/common.h" #include "reios/reios.h" +#include "reios/gdrom_hle.h" #include #include #include "rend/gles/gles.h" @@ -24,7 +25,7 @@ #include "hw/sh4/dyna/ngen.h" #include "hw/naomi/naomi_cart.h" -#define REICAST_SKIP(size) do { *(u8**)data += size; *total_size += size; } while (false) +#define REICAST_SKIP(size) do { *(u8**)data += (size); *total_size += (size); } while (false) extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb); @@ -34,9 +35,11 @@ enum serialize_version_enum { V3, V4, V5_LIBRETRO_UNSUPPORTED, - V6_LIBRETRO, + V6_LIBRETRO_UNSUPPORTED, + V7_LIBRETRO, V5 = 800, + V6 = 801, } ; //./core/hw/arm7/arm_mem.cpp @@ -313,7 +316,7 @@ bool dc_serialize(void **data, unsigned int *total_size) { int i = 0; int j = 0; - serialize_version_enum version = V5; + serialize_version_enum version = V6; *total_size = 0 ; @@ -570,6 +573,8 @@ bool dc_serialize(void **data, unsigned int *total_size) if (CurrentCartridge != NULL) CurrentCartridge->Serialize(data, total_size); + + gd_hle_state.Serialize(data, total_size); DEBUG_LOG(SAVESTATE, "Saved %d bytes", *total_size); @@ -613,15 +618,6 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_USA(aica_reg,0x8000); - u16 dummyshort; - - REICAST_SKIP(4 * 16); // volume_lut - REICAST_SKIP(4 * 256 + 768); // tl_lut. Due to a previous bug this is not 4 * (256 + 768) - REICAST_SKIP(4 * 64); // AEG_ATT_SPS - REICAST_SKIP(4 * 64); // AEG_DSR_SPS - REICAST_US(dummyshort); // pl - REICAST_US(dummyshort); // pr - channel_unserialize(data, total_size) ; REICAST_USA(cdda_sector,CDDA_SIZE); @@ -629,7 +625,7 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_SKIP(4 * 64); // mxlr REICAST_US(i); // samples_gen - register_unserialize(sb_regs, data, total_size, V6_LIBRETRO) ; + register_unserialize(sb_regs, data, total_size, V7_LIBRETRO) ; REICAST_US(SB_ISTNRM); REICAST_US(SB_FFST_rc); REICAST_US(SB_FFST); @@ -740,17 +736,19 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_USA(vram.data, vram.size); REICAST_USA(OnChipRAM.data,OnChipRAM_SIZE); - register_unserialize(CCN, data, total_size, V6_LIBRETRO) ; - register_unserialize(UBC, data, total_size, V6_LIBRETRO) ; - register_unserialize(BSC, data, total_size, V6_LIBRETRO) ; - register_unserialize(DMAC, data, total_size, V6_LIBRETRO) ; - register_unserialize(CPG, data, total_size, V6_LIBRETRO) ; - register_unserialize(RTC, data, total_size, V6_LIBRETRO) ; - register_unserialize(INTC, data, total_size, V6_LIBRETRO) ; - register_unserialize(TMU, data, total_size, V6_LIBRETRO) ; - register_unserialize(SCI, data, total_size, V6_LIBRETRO) ; - register_unserialize(SCIF, data, total_size, V6_LIBRETRO) ; + register_unserialize(CCN, data, total_size, V7_LIBRETRO) ; + register_unserialize(UBC, data, total_size, V7_LIBRETRO) ; + register_unserialize(BSC, data, total_size, V7_LIBRETRO) ; + register_unserialize(DMAC, data, total_size, V7_LIBRETRO) ; + register_unserialize(CPG, data, total_size, V7_LIBRETRO) ; + register_unserialize(RTC, data, total_size, V7_LIBRETRO) ; + register_unserialize(INTC, data, total_size, V7_LIBRETRO) ; + register_unserialize(TMU, data, total_size, V7_LIBRETRO) ; + register_unserialize(SCI, data, total_size, V7_LIBRETRO) ; + register_unserialize(SCIF, data, total_size, V7_LIBRETRO) ; + u16 dummyshort; + REICAST_USA(mem_b.data, mem_b.size); REICAST_US(dummyshort); // IRLPriority REICAST_USA(InterruptEnvId,32); @@ -851,7 +849,6 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_USA(sq_remap,64); #else REICAST_USA(ITLB_LRU_USE,64); - REICAST_US(i); // mmu_error_TT #endif REICAST_US(NullDriveDiscType); REICAST_USA(q_subchannel,96); @@ -926,6 +923,7 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) if (CurrentCartridge != NULL) CurrentCartridge->Unserialize(data, total_size); + gd_hle_state.Unserialize(data, total_size); DEBUG_LOG(SAVESTATE, "Loaded %d bytes (libretro compat)", *total_size); @@ -941,13 +939,17 @@ bool dc_unserialize(void **data, unsigned int *total_size) *total_size = 0 ; REICAST_US(version) ; - if (version == V6_LIBRETRO) + if (version == V7_LIBRETRO) return dc_unserialize_libretro(data, total_size); - if (version != V4 && version != V5) + if (version != V4 && version < V5) { WARN_LOG(SAVESTATE, "Save State version not supported: %d", version); return false; } + else + { + DEBUG_LOG(SAVESTATE, "Loading state version %d", version); + } REICAST_US(aica_interr) ; REICAST_US(aica_reg_L) ; REICAST_US(e68k_out) ; @@ -1275,6 +1277,8 @@ bool dc_unserialize(void **data, unsigned int *total_size) if (CurrentCartridge != NULL) CurrentCartridge->Unserialize(data, total_size); + if (version >= V6) + gd_hle_state.Unserialize(data, total_size); DEBUG_LOG(SAVESTATE, "Loaded %d bytes", *total_size);