#include <stdlib.h>
#include <string.h>
#include "usf/usf.h"
#include "usf/usf_internal.h"
#define M64P_CORE_PROTOTYPES 1
#include "api/m64p_types.h"
#include "api/callbacks.h"
#include "savestates.h"
#include "main.h"
#include "rom.h"
#include "util.h"
#include "ai/ai_controller.h"
#include "memory/memory.h"
#include "r4300/tlb.h"
#include "r4300/cp0.h"
#include "r4300/cp1.h"
#include "r4300/r4300.h"
#include "r4300/r4300_core.h"
#include "r4300/cached_interp.h"
#include "r4300/interupt.h"
#include "pi/pi_controller.h"
#ifdef NEW_DYNAREC
#include "r4300/new_dynarec/new_dynarec.h"
#endif
#include "rdp/rdp_core.h"
#include "ri/ri_controller.h"
#include "rsp/rsp_core.h"
#include "si/si_controller.h"
#include "vi/vi_controller.h"
static const char* savestate_magic = "M64+SAVE";
static const int savestate_latest_version = 0x00010000;
static const unsigned char pj64_magic[4] = { 0xC8, 0xA6, 0xD8, 0x23 };
#define GETARRAY(buff, type, count) \
(to_little_endian_buffer(buff, sizeof(type),count), \
buff += count*sizeof(type), \
(type *)(buff-count*sizeof(type)))
#define COPYARRAY(dst, buff, type, count) \
memcpy(dst, GETARRAY(buff, type, count), sizeof(type)*count)
#define GETDATA(buff, type) *GETARRAY(buff, type, 1)
#define PUTARRAY(src, buff, type, count) \
memcpy(buff, src, sizeof(type)*count); \
to_little_endian_buffer(buff, sizeof(type), count); \
buff += count*sizeof(type);
#define PUTDATA(buff, type, value) \
do { type x = value; PUTARRAY(&x, buff, type, 1); } while(0)
#define read_bytes(ptr, size) \
{ \
if ((size) > state_size) \
{ \
if (savestateData) free(savestateData); \
return 0; \
} \
memcpy((ptr), state_ptr, (size)); \
state_ptr += (size); \
state_size -= (size); \
}
static int savestates_load_m64p(usf_state_t * state, unsigned char * ptr, unsigned int size)
{
unsigned char header[44];
int version;
int i;
unsigned char * state_ptr = ptr;
unsigned int state_size = size;
size_t savestateSize;
unsigned char *savestateData = 0, *curr;
char queue[1024];
read_bytes(header, 44);
curr = header;
if(strncmp((char *)curr, savestate_magic, 8)!=0)
return 0;
curr += 8;
version = *curr++;
version = (version << 8) | *curr++;
version = (version << 8) | *curr++;
version = (version << 8) | *curr++;
if(version != 0x00010000)
return 0;
curr += 32;
savestateSize = 16788244;
if (state_size < savestateSize + sizeof(queue))
return 0;
savestateData = curr = malloc(savestateSize);
if (!savestateData)
return 0;
read_bytes(savestateData, savestateSize);
read_bytes(queue, sizeof(queue));
state->g_ri.rdram.regs[RDRAM_CONFIG_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_DEVICE_ID_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_DELAY_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_MODE_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_REF_INTERVAL_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_REF_ROW_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_RAS_INTERVAL_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_MIN_INTERVAL_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_ADDR_SELECT_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_DEVICE_MANUF_REG] = GETDATA(curr, uint32_t);
curr += 4;
state->g_r4300.mi.regs[MI_INIT_MODE_REG] = GETDATA(curr, uint32_t);
curr += 4; state->g_r4300.mi.regs[MI_VERSION_REG] = GETDATA(curr, uint32_t);
state->g_r4300.mi.regs[MI_INTR_REG] = GETDATA(curr, uint32_t);
state->g_r4300.mi.regs[MI_INTR_MASK_REG] = GETDATA(curr, uint32_t);
curr += 4;
curr += 8;
state->g_pi.regs[PI_DRAM_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_CART_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_RD_LEN_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_WR_LEN_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_STATUS_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM1_LAT_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM1_PWD_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM1_PGS_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM1_RLS_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM2_LAT_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM2_PWD_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM2_PGS_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM2_RLS_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_MEM_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_DRAM_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_RD_LEN_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_WR_LEN_REG] = GETDATA(curr, uint32_t);
curr += 4;
state->g_sp.regs[SP_STATUS_REG] = GETDATA(curr, uint32_t);
curr += 16; state->g_sp.regs[SP_DMA_FULL_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_DMA_BUSY_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_SEMAPHORE_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs2[SP_PC_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs2[SP_IBIST_REG] = GETDATA(curr, uint32_t);
state->g_si.regs[SI_DRAM_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_si.regs[SI_PIF_ADDR_RD64B_REG] = GETDATA(curr, uint32_t);
state->g_si.regs[SI_PIF_ADDR_WR64B_REG] = GETDATA(curr, uint32_t);
state->g_si.regs[SI_STATUS_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_STATUS_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_ORIGIN_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_WIDTH_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_V_INTR_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_CURRENT_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_BURST_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_V_SYNC_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_H_SYNC_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_LEAP_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_H_START_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_V_START_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_V_BURST_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_X_SCALE_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_Y_SCALE_REG] = GETDATA(curr, uint32_t);
state->g_vi.delay = GETDATA(curr, unsigned int);
state->g_ri.regs[RI_MODE_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_CONFIG_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_CURRENT_LOAD_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_SELECT_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_REFRESH_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_LATENCY_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_ERROR_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_WERROR_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_DRAM_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_LEN_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_CONTROL_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_STATUS_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_DACRATE_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_BITRATE_REG] = GETDATA(curr, uint32_t);
state->g_ai.fifo[1].duration = GETDATA(curr, unsigned int);
state->g_ai.fifo[1].length = GETDATA(curr, uint32_t);
state->g_ai.fifo[0].duration = GETDATA(curr, unsigned int);
state->g_ai.fifo[0].length = GETDATA(curr, uint32_t);
state->g_ai.fifo[0].address = state->g_ai.regs[AI_DRAM_ADDR_REG];
state->g_ai.fifo[1].address = state->g_ai.regs[AI_DRAM_ADDR_REG];
state->g_ai.samples_format_changed = 1;
state->g_dp.dpc_regs[DPC_START_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_END_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_CURRENT_REG] = GETDATA(curr, uint32_t);
curr += 4; state->g_dp.dpc_regs[DPC_STATUS_REG] = GETDATA(curr, uint32_t);
curr += 12; state->g_dp.dpc_regs[DPC_CLOCK_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_BUFBUSY_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_PIPEBUSY_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_TMEM_REG] = GETDATA(curr, uint32_t);
state->g_dp.dps_regs[DPS_TBIST_REG] = GETDATA(curr, uint32_t);
state->g_dp.dps_regs[DPS_TEST_MODE_REG] = GETDATA(curr, uint32_t);
state->g_dp.dps_regs[DPS_BUFTEST_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_dp.dps_regs[DPS_BUFTEST_DATA_REG] = GETDATA(curr, uint32_t);
COPYARRAY(state->g_rdram, curr, uint32_t, RDRAM_MAX_SIZE/4);
COPYARRAY(state->g_sp.mem, curr, uint32_t, SP_MEM_SIZE/4);
COPYARRAY(state->g_si.pif.ram, curr, uint8_t, PIF_RAM_SIZE);
(void)GETDATA(curr, int);
(void)GETDATA(curr, int);
(void)GETDATA(curr, unsigned long long);
(void)GETDATA(curr, unsigned int);
(void)GETDATA(curr, unsigned int);
COPYARRAY(state->tlb_LUT_r, curr, unsigned int, 0x100000);
COPYARRAY(state->tlb_LUT_w, curr, unsigned int, 0x100000);
state->llbit = GETDATA(curr, unsigned int);
COPYARRAY(state->reg, curr, long long int, 32);
COPYARRAY(state->g_cp0_regs, curr, unsigned int, CP0_REGS_COUNT);
set_fpr_pointers(state, state->g_cp0_regs[CP0_STATUS_REG]);
state->lo = GETDATA(curr, long long int);
state->hi = GETDATA(curr, long long int);
COPYARRAY(state->reg_cop1_fgr_64, curr, long long int, 32);
if ((state->g_cp0_regs[CP0_STATUS_REG] & 0x04000000) == 0) shuffle_fpr_data(state, 0x04000000, 0);
state->FCR0 = GETDATA(curr, int);
state->FCR31 = GETDATA(curr, int);
for (i = 0; i < 32; i++)
{
state->tlb_e[i].mask = GETDATA(curr, short);
curr += 2;
state->tlb_e[i].vpn2 = GETDATA(curr, int);
state->tlb_e[i].g = GETDATA(curr, char);
state->tlb_e[i].asid = GETDATA(curr, unsigned char);
curr += 2;
state->tlb_e[i].pfn_even = GETDATA(curr, int);
state->tlb_e[i].c_even = GETDATA(curr, char);
state->tlb_e[i].d_even = GETDATA(curr, char);
state->tlb_e[i].v_even = GETDATA(curr, char);
curr++;
state->tlb_e[i].pfn_odd = GETDATA(curr, int);
state->tlb_e[i].c_odd = GETDATA(curr, char);
state->tlb_e[i].d_odd = GETDATA(curr, char);
state->tlb_e[i].v_odd = GETDATA(curr, char);
state->tlb_e[i].r = GETDATA(curr, char);
state->tlb_e[i].start_even = GETDATA(curr, unsigned int);
state->tlb_e[i].end_even = GETDATA(curr, unsigned int);
state->tlb_e[i].phys_even = GETDATA(curr, unsigned int);
state->tlb_e[i].start_odd = GETDATA(curr, unsigned int);
state->tlb_e[i].end_odd = GETDATA(curr, unsigned int);
state->tlb_e[i].phys_odd = GETDATA(curr, unsigned int);
}
#ifdef NEW_DYNAREC
if (state->r4300emu == CORE_DYNAREC) {
state->pcaddr = GETDATA(curr, unsigned int);
state->pending_exception = 1;
invalidate_all_pages(state);
} else {
if(state->r4300emu != CORE_PURE_INTERPRETER)
{
for (i = 0; i < 0x100000; i++)
state->invalid_code[i] = 1;
}
generic_jump_to(state, GETDATA(curr, unsigned int)); }
#else
if(state->r4300emu != CORE_PURE_INTERPRETER)
{
for (i = 0; i < 0x100000; i++)
state->invalid_code[i] = 1;
}
generic_jump_to(state, GETDATA(curr, unsigned int)); #endif
state->next_interupt = GETDATA(curr, unsigned int);
state->g_vi.next_vi = GETDATA(curr, unsigned int);
state->g_vi.field = GETDATA(curr, unsigned int);
free(savestateData);
to_little_endian_buffer(queue, 4, 256);
load_eventqueue_infos(state, queue);
#ifdef NEW_DYNAREC
if (state->r4300emu == CORE_DYNAREC)
state->last_addr = state->pcaddr;
else
state->last_addr = state->PC->addr;
#else
state->last_addr = state->PC->addr;
#endif
return 1;
}
static int savestates_load_pj64(usf_state_t * state, unsigned char * ptr, unsigned int size)
{
char buffer[1024];
unsigned int vi_timer, SaveRDRAMSize;
int i;
#ifdef DYNAREC
unsigned long long dummy;
#endif
unsigned char header[8];
unsigned char * state_ptr = ptr;
unsigned int state_size = size;
size_t savestateSize;
unsigned char *savestateData = 0, *curr;
read_bytes(header, 8);
curr = header;
if (memcmp(curr, pj64_magic, 4) != 0)
{
return 0;
}
curr += 4;
SaveRDRAMSize = GETDATA(curr, unsigned int);
savestateSize = SaveRDRAMSize + 0x2754;
savestateData = curr = malloc(savestateSize);
if (!savestateData)
return 0;
if (state_size < savestateSize)
{
free(savestateData);
return 0;
}
read_bytes(savestateData, savestateSize);
curr += 0x40;
vi_timer = GETDATA(curr, unsigned int);
state->last_addr = GETDATA(curr, unsigned int);
COPYARRAY(state->reg, curr, long long int, 32);
COPYARRAY(state->reg_cop1_fgr_64, curr, long long int, 32);
COPYARRAY(state->g_cp0_regs, curr, unsigned int, CP0_REGS_COUNT);
set_fpr_pointers(state, state->g_cp0_regs[CP0_STATUS_REG]);
if ((state->g_cp0_regs[CP0_STATUS_REG] & 0x04000000) == 0) shuffle_fpr_data(state, 0x04000000, 0);
vi_timer += state->g_cp0_regs[CP0_COUNT_REG];
state->next_interupt = (state->g_cp0_regs[CP0_COMPARE_REG] < vi_timer)
? state->g_cp0_regs[CP0_COMPARE_REG]
: vi_timer;
state->g_vi.next_vi = vi_timer;
state->g_vi.field = 0;
*((unsigned int*)&buffer[0]) = VI_INT;
*((unsigned int*)&buffer[4]) = vi_timer;
*((unsigned int*)&buffer[8]) = COMPARE_INT;
*((unsigned int*)&buffer[12]) = state->g_cp0_regs[CP0_COMPARE_REG];
*((unsigned int*)&buffer[16]) = 0xFFFFFFFF;
load_eventqueue_infos(state, buffer);
state->FCR0 = GETDATA(curr, int);
curr += 30 * 4; state->FCR31 = GETDATA(curr, int);
state->hi = GETDATA(curr, long long int);
state->lo = GETDATA(curr, long long int);
state->g_ri.rdram.regs[RDRAM_CONFIG_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_DEVICE_ID_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_DELAY_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_MODE_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_REF_INTERVAL_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_REF_ROW_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_RAS_INTERVAL_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_MIN_INTERVAL_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_ADDR_SELECT_REG] = GETDATA(curr, uint32_t);
state->g_ri.rdram.regs[RDRAM_DEVICE_MANUF_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_MEM_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_DRAM_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_RD_LEN_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_WR_LEN_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_STATUS_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_DMA_FULL_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_DMA_BUSY_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs[SP_SEMAPHORE_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs2[SP_PC_REG] = GETDATA(curr, uint32_t);
state->g_sp.regs2[SP_IBIST_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_START_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_END_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_CURRENT_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_STATUS_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_CLOCK_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_BUFBUSY_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_PIPEBUSY_REG] = GETDATA(curr, uint32_t);
state->g_dp.dpc_regs[DPC_TMEM_REG] = GETDATA(curr, uint32_t);
(void)GETDATA(curr, unsigned int); (void)GETDATA(curr, unsigned int);
state->g_r4300.mi.regs[MI_INIT_MODE_REG] = GETDATA(curr, uint32_t);
state->g_r4300.mi.regs[MI_VERSION_REG] = GETDATA(curr, uint32_t);
state->g_r4300.mi.regs[MI_INTR_REG] = GETDATA(curr, uint32_t);
state->g_r4300.mi.regs[MI_INTR_MASK_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_STATUS_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_ORIGIN_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_WIDTH_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_V_INTR_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_CURRENT_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_BURST_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_V_SYNC_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_H_SYNC_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_LEAP_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_H_START_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_V_START_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_V_BURST_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_X_SCALE_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_Y_SCALE_REG] = GETDATA(curr, uint32_t);
state->g_vi.delay = (state->g_vi.regs[VI_V_SYNC_REG] == 0)
? 500000
: (state->g_vi.regs[VI_V_SYNC_REG] + 1)*1500;
state->g_ai.regs[AI_DRAM_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_LEN_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_CONTROL_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_STATUS_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_DACRATE_REG] = GETDATA(curr, uint32_t);
state->g_ai.regs[AI_BITRATE_REG] = GETDATA(curr, uint32_t);
state->g_ai.samples_format_changed = 1;
state->g_ai.regs[AI_STATUS_REG] = 0;
state->g_pi.regs[PI_DRAM_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_CART_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_RD_LEN_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_WR_LEN_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_STATUS_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM1_LAT_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM1_PWD_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM1_PGS_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM1_RLS_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM2_LAT_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM2_PWD_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM2_PGS_REG] = GETDATA(curr, uint32_t);
state->g_pi.regs[PI_BSD_DOM2_RLS_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_MODE_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_CONFIG_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_CURRENT_LOAD_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_SELECT_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_REFRESH_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_LATENCY_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_ERROR_REG] = GETDATA(curr, uint32_t);
state->g_ri.regs[RI_WERROR_REG] = GETDATA(curr, uint32_t);
state->g_si.regs[SI_DRAM_ADDR_REG] = GETDATA(curr, uint32_t);
state->g_si.regs[SI_PIF_ADDR_RD64B_REG] = GETDATA(curr, uint32_t);
state->g_si.regs[SI_PIF_ADDR_WR64B_REG] = GETDATA(curr, uint32_t);
state->g_si.regs[SI_STATUS_REG] = GETDATA(curr, uint32_t);
memset(state->tlb_LUT_r, 0, 0x400000);
memset(state->tlb_LUT_w, 0, 0x400000);
for (i=0; i < 32; i++)
{
unsigned int MyPageMask, MyEntryHi, MyEntryLo0, MyEntryLo1;
(void)GETDATA(curr, unsigned int); MyPageMask = GETDATA(curr, unsigned int);
MyEntryHi = GETDATA(curr, unsigned int);
MyEntryLo0 = GETDATA(curr, unsigned int);
MyEntryLo1 = GETDATA(curr, unsigned int);
state->tlb_e[i].g = (MyEntryLo0 & MyEntryLo1 & 1);
state->tlb_e[i].pfn_even = (MyEntryLo0 & 0x3FFFFFC0) >> 6;
state->tlb_e[i].pfn_odd = (MyEntryLo1 & 0x3FFFFFC0) >> 6;
state->tlb_e[i].c_even = (MyEntryLo0 & 0x38) >> 3;
state->tlb_e[i].c_odd = (MyEntryLo1 & 0x38) >> 3;
state->tlb_e[i].d_even = (MyEntryLo0 & 0x4) >> 2;
state->tlb_e[i].d_odd = (MyEntryLo1 & 0x4) >> 2;
state->tlb_e[i].v_even = (MyEntryLo0 & 0x2) >> 1;
state->tlb_e[i].v_odd = (MyEntryLo1 & 0x2) >> 1;
state->tlb_e[i].asid = (MyEntryHi & 0xFF);
state->tlb_e[i].vpn2 = (MyEntryHi & 0xFFFFE000) >> 13;
state->tlb_e[i].mask = (MyPageMask & 0x1FFE000) >> 13;
state->tlb_e[i].start_even = state->tlb_e[i].vpn2 << 13;
state->tlb_e[i].end_even = state->tlb_e[i].start_even+
(state->tlb_e[i].mask << 12) + 0xFFF;
state->tlb_e[i].phys_even = state->tlb_e[i].pfn_even << 12;
state->tlb_e[i].start_odd = state->tlb_e[i].end_even+1;
state->tlb_e[i].end_odd = state->tlb_e[i].start_odd+
(state->tlb_e[i].mask << 12) + 0xFFF;
state->tlb_e[i].phys_odd = state->tlb_e[i].pfn_odd << 12;
tlb_map(state, &state->tlb_e[i]);
}
COPYARRAY(state->g_si.pif.ram, curr, uint8_t, PIF_RAM_SIZE);
memset(state->g_rdram, 0, RDRAM_MAX_SIZE);
COPYARRAY(state->g_rdram, curr, uint32_t, SaveRDRAMSize/4);
COPYARRAY(state->g_sp.mem, curr, uint32_t, SP_MEM_SIZE/4);
open_rom_header(state, savestateData, sizeof(m64p_rom_header));
#ifdef NEW_DYNAREC
if (state->r4300emu == CORE_DYNAREC) {
state->pcaddr = state->last_addr;
state->pending_exception = 1;
invalidate_all_pages(state);
} else {
if(state->r4300emu != CORE_PURE_INTERPRETER)
{
for (i = 0; i < 0x100000; i++)
state->invalid_code[i] = 1;
}
generic_jump_to(state, state->last_addr);
}
#else
if(state->r4300emu != CORE_PURE_INTERPRETER)
{
for (i = 0; i < 0x100000; i++)
state->invalid_code[i] = 1;
}
#ifdef DYNAREC
*(void **)&state->return_address = (void *)&dummy;
#endif
generic_jump_to(state, state->last_addr);
#ifdef DYNAREC
*(void **)&state->return_address = (void *)0;
#endif
#endif
free(savestateData);
return 1;
}
int savestates_load(usf_state_t * state, unsigned char * ptr, unsigned int size, unsigned int is_m64p)
{
if (is_m64p)
return savestates_load_m64p(state, ptr, size);
else
return savestates_load_pj64(state, ptr, size);
}