static void nmi_int_handler(void) { /* Non Maskable Interrupt -- remove interrupt event from queue */ remove_interrupt_event(); /* setup r4300 Status flags: reset TS and SR, set BEV, ERL, and SR */ g_cp0_regs[CP0_STATUS_REG] = (g_cp0_regs[CP0_STATUS_REG] & ~(CP0_STATUS_SR | CP0_STATUS_TS | UINT32_C(0x00080000))) | (CP0_STATUS_ERL | CP0_STATUS_BEV | CP0_STATUS_SR); g_cp0_regs[CP0_CAUSE_REG] = 0x00000000; /* simulate the soft reset code which would run from the PIF ROM */ pifbootrom_hle_execute(&g_dev); /* clear all interrupts, reset interrupt counters back to 0 */ g_cp0_regs[CP0_COUNT_REG] = 0; g_gs_vi_counter = 0; init_interrupt(); g_dev.vi.delay = g_dev.vi.next_vi = 5000; add_interrupt_event_count(VI_INT, g_dev.vi.next_vi); /* clear the audio status register so that subsequent write_ai() calls will work properly */ g_dev.ai.regs[AI_STATUS_REG] = 0; /* set ErrorEPC with the last instruction address */ g_cp0_regs[CP0_ERROREPC_REG] = PC->addr; /* reset the r4300 internal state */ if (r4300emu != CORE_PURE_INTERPRETER) { /* clear all the compiled instruction blocks and re-initialize */ free_blocks(); init_blocks(); } /* adjust ErrorEPC if we were in a delay slot, and clear the delay_slot and dyna_interp flags */ if(g_dev.r4300.delay_slot==1 || g_dev.r4300.delay_slot==3) { g_cp0_regs[CP0_ERROREPC_REG]-=4; } g_dev.r4300.delay_slot = 0; dyna_interp = 0; /* set next instruction address to reset vector */ last_addr = UINT32_C(0xa4000040); generic_jump_to(UINT32_C(0xa4000040)); #ifdef NEW_DYNAREC if (r4300emu == CORE_DYNAREC) { g_cp0_regs[CP0_ERROREPC_REG]=(pcaddr&~3)-(pcaddr&1)*4; pcaddr = 0xa4000040; pending_exception = 1; invalidate_all_pages(); } #endif }
int savestates_load_m64p(const unsigned char *data, size_t size) { unsigned char header[44]; int version; int i; unsigned char *curr = (unsigned char*)data; // < HACK char queue[1024]; /* Read and check Mupen64Plus magic number. */ 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; } if(memcmp((char *)curr, ROM_SETTINGS.MD5, 32)) { return 0; } curr += 32; // Parse savestate rdram_register.rdram_config = GETDATA(curr, unsigned int); rdram_register.rdram_device_id = GETDATA(curr, unsigned int); rdram_register.rdram_delay = GETDATA(curr, unsigned int); rdram_register.rdram_mode = GETDATA(curr, unsigned int); rdram_register.rdram_ref_interval = GETDATA(curr, unsigned int); rdram_register.rdram_ref_row = GETDATA(curr, unsigned int); rdram_register.rdram_ras_interval = GETDATA(curr, unsigned int); rdram_register.rdram_min_interval = GETDATA(curr, unsigned int); rdram_register.rdram_addr_select = GETDATA(curr, unsigned int); rdram_register.rdram_device_manuf = GETDATA(curr, unsigned int); MI_register.w_mi_init_mode_reg = GETDATA(curr, unsigned int); MI_register.mi_init_mode_reg = GETDATA(curr, unsigned int); curr += 4; // Duplicate MI init mode flags from old implementation MI_register.mi_version_reg = GETDATA(curr, unsigned int); MI_register.mi_intr_reg = GETDATA(curr, unsigned int); MI_register.mi_intr_mask_reg = GETDATA(curr, unsigned int); MI_register.w_mi_intr_mask_reg = GETDATA(curr, unsigned int); curr += 8; // Duplicated MI intr flags and padding from old implementation pi_register.pi_dram_addr_reg = GETDATA(curr, unsigned int); pi_register.pi_cart_addr_reg = GETDATA(curr, unsigned int); pi_register.pi_rd_len_reg = GETDATA(curr, unsigned int); pi_register.pi_wr_len_reg = GETDATA(curr, unsigned int); pi_register.read_pi_status_reg = GETDATA(curr, unsigned int); pi_register.pi_bsd_dom1_lat_reg = GETDATA(curr, unsigned int); pi_register.pi_bsd_dom1_pwd_reg = GETDATA(curr, unsigned int); pi_register.pi_bsd_dom1_pgs_reg = GETDATA(curr, unsigned int); pi_register.pi_bsd_dom1_rls_reg = GETDATA(curr, unsigned int); pi_register.pi_bsd_dom2_lat_reg = GETDATA(curr, unsigned int); pi_register.pi_bsd_dom2_pwd_reg = GETDATA(curr, unsigned int); pi_register.pi_bsd_dom2_pgs_reg = GETDATA(curr, unsigned int); pi_register.pi_bsd_dom2_rls_reg = GETDATA(curr, unsigned int); sp_register.sp_mem_addr_reg = GETDATA(curr, unsigned int); sp_register.sp_dram_addr_reg = GETDATA(curr, unsigned int); sp_register.sp_rd_len_reg = GETDATA(curr, unsigned int); sp_register.sp_wr_len_reg = GETDATA(curr, unsigned int); sp_register.w_sp_status_reg = GETDATA(curr, unsigned int); sp_register.sp_status_reg = GETDATA(curr, unsigned int); curr += 16; // Duplicated SP flags and padding from old implementation sp_register.sp_dma_full_reg = GETDATA(curr, unsigned int); sp_register.sp_dma_busy_reg = GETDATA(curr, unsigned int); sp_register.sp_semaphore_reg = GETDATA(curr, unsigned int); rsp_register.rsp_pc = GETDATA(curr, unsigned int); rsp_register.rsp_ibist = GETDATA(curr, unsigned int); si_register.si_dram_addr = GETDATA(curr, unsigned int); si_register.si_pif_addr_rd64b = GETDATA(curr, unsigned int); si_register.si_pif_addr_wr64b = GETDATA(curr, unsigned int); si_register.si_stat = GETDATA(curr, unsigned int); vi_register.vi_status = GETDATA(curr, unsigned int); vi_register.vi_origin = GETDATA(curr, unsigned int); vi_register.vi_width = GETDATA(curr, unsigned int); vi_register.vi_v_intr = GETDATA(curr, unsigned int); vi_register.vi_current = GETDATA(curr, unsigned int); vi_register.vi_burst = GETDATA(curr, unsigned int); vi_register.vi_v_sync = GETDATA(curr, unsigned int); vi_register.vi_h_sync = GETDATA(curr, unsigned int); vi_register.vi_leap = GETDATA(curr, unsigned int); vi_register.vi_h_start = GETDATA(curr, unsigned int); vi_register.vi_v_start = GETDATA(curr, unsigned int); vi_register.vi_v_burst = GETDATA(curr, unsigned int); vi_register.vi_x_scale = GETDATA(curr, unsigned int); vi_register.vi_y_scale = GETDATA(curr, unsigned int); vi_register.vi_delay = GETDATA(curr, unsigned int); update_vi_status(vi_register.vi_status); update_vi_width(vi_register.vi_width); ri_register.ri_mode = GETDATA(curr, unsigned int); ri_register.ri_config = GETDATA(curr, unsigned int); ri_register.ri_current_load = GETDATA(curr, unsigned int); ri_register.ri_select = GETDATA(curr, unsigned int); ri_register.ri_refresh = GETDATA(curr, unsigned int); ri_register.ri_latency = GETDATA(curr, unsigned int); ri_register.ri_error = GETDATA(curr, unsigned int); ri_register.ri_werror = GETDATA(curr, unsigned int); ai_register.ai_dram_addr = GETDATA(curr, unsigned int); ai_register.ai_len = GETDATA(curr, unsigned int); ai_register.ai_control = GETDATA(curr, unsigned int); ai_register.ai_status = GETDATA(curr, unsigned int); ai_register.ai_dacrate = GETDATA(curr, unsigned int); ai_register.ai_bitrate = GETDATA(curr, unsigned int); ai_register.next_delay = GETDATA(curr, unsigned int); ai_register.next_len = GETDATA(curr, unsigned int); ai_register.current_delay = GETDATA(curr, unsigned int); ai_register.current_len = GETDATA(curr, unsigned int); update_ai_dacrate(ai_register.ai_dacrate); dpc_register.dpc_start = GETDATA(curr, unsigned int); dpc_register.dpc_end = GETDATA(curr, unsigned int); dpc_register.dpc_current = GETDATA(curr, unsigned int); dpc_register.w_dpc_status = GETDATA(curr, unsigned int); dpc_register.dpc_status = GETDATA(curr, unsigned int); curr += 12; // Duplicated DPC flags and padding from old implementation dpc_register.dpc_clock = GETDATA(curr, unsigned int); dpc_register.dpc_bufbusy = GETDATA(curr, unsigned int); dpc_register.dpc_pipebusy = GETDATA(curr, unsigned int); dpc_register.dpc_tmem = GETDATA(curr, unsigned int); dps_register.dps_tbist = GETDATA(curr, unsigned int); dps_register.dps_test_mode = GETDATA(curr, unsigned int); dps_register.dps_buftest_addr = GETDATA(curr, unsigned int); dps_register.dps_buftest_data = GETDATA(curr, unsigned int); COPYARRAY(rdram, curr, unsigned int, 0x800000/4); COPYARRAY(SP_DMEM, curr, unsigned int, 0x1000/4); COPYARRAY(SP_IMEM, curr, unsigned int, 0x1000/4); COPYARRAY(PIF_RAM, curr, unsigned char, 0x40); flashram_info.use_flashram = GETDATA(curr, int); flashram_info.mode = GETDATA(curr, int); flashram_info.status = GETDATA(curr, unsigned long long); flashram_info.erase_offset = GETDATA(curr, unsigned int); flashram_info.write_pointer = GETDATA(curr, unsigned int); COPYARRAY(tlb_LUT_r, curr, unsigned int, 0x100000); COPYARRAY(tlb_LUT_w, curr, unsigned int, 0x100000); llbit = GETDATA(curr, unsigned int); COPYARRAY(reg, curr, long long int, 32); COPYARRAY(reg_cop0, curr, unsigned int, 32); set_fpr_pointers(Status); // Status is reg_cop0[12] lo = GETDATA(curr, long long int); hi = GETDATA(curr, long long int); COPYARRAY(reg_cop1_fgr_64, curr, long long int, 32); if ((Status & 0x04000000) == 0) // 32-bit FPR mode requires data shuffling because 64-bit layout is always stored in savestate file shuffle_fpr_data(0x04000000, 0); FCR0 = GETDATA(curr, int); FCR31 = GETDATA(curr, int); for (i = 0; i < 32; i++) { tlb_e[i].mask = GETDATA(curr, short); curr += 2; tlb_e[i].vpn2 = GETDATA(curr, int); tlb_e[i].g = GETDATA(curr, char); tlb_e[i].asid = GETDATA(curr, unsigned char); curr += 2; tlb_e[i].pfn_even = GETDATA(curr, int); tlb_e[i].c_even = GETDATA(curr, char); tlb_e[i].d_even = GETDATA(curr, char); tlb_e[i].v_even = GETDATA(curr, char); curr++; tlb_e[i].pfn_odd = GETDATA(curr, int); tlb_e[i].c_odd = GETDATA(curr, char); tlb_e[i].d_odd = GETDATA(curr, char); tlb_e[i].v_odd = GETDATA(curr, char); tlb_e[i].r = GETDATA(curr, char); tlb_e[i].start_even = GETDATA(curr, unsigned int); tlb_e[i].end_even = GETDATA(curr, unsigned int); tlb_e[i].phys_even = GETDATA(curr, unsigned int); tlb_e[i].start_odd = GETDATA(curr, unsigned int); tlb_e[i].end_odd = GETDATA(curr, unsigned int); tlb_e[i].phys_odd = GETDATA(curr, unsigned int); } #ifdef NEW_DYNAREC if (r4300emu == CORE_DYNAREC) { pcaddr = GETDATA(curr, unsigned int); pending_exception = 1; invalidate_all_pages(); } else {