X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Flightrec%2Fplugin.c;h=2648cc30306674941abc71aa8f7686e2c894e76b;hb=7baee56f47d66a45c3a04ec0c97164a837a34cf0;hp=8c64c67ffd6b83dac1a8173752fe171904f657ab;hpb=3eb073975e1816abadd8b15f53fe62f74ee1c7a8;p=pcsx_rearmed.git diff --git a/libpcsxcore/lightrec/plugin.c b/libpcsxcore/lightrec/plugin.c index 8c64c67f..2648cc30 100644 --- a/libpcsxcore/lightrec/plugin.c +++ b/libpcsxcore/lightrec/plugin.c @@ -37,27 +37,20 @@ # define unlikely(x) (x) #endif +psxRegisters psxRegs; +Rcnt rcnts[4]; + static struct lightrec_state *lightrec_state; static char *name = "retroarch.exe"; static bool use_lightrec_interpreter; +static bool use_pcsx_interpreter; static bool lightrec_debug; static bool lightrec_very_debug; +static bool booting; static u32 lightrec_begin_cycles; -int stop; -u32 cycle_multiplier; -int new_dynarec_hacks; - -/* Unused for now */ -u32 event_cycles[PSXINT_COUNT]; -u32 next_interupt; - -void new_dyna_before_save() {} -void new_dyna_after_save() {} -void new_dyna_freeze(void *f, int i) {} - enum my_cp2_opcodes { OP_CP2_RTPS = 0x01, OP_CP2_NCLIP = 0x06, @@ -111,7 +104,7 @@ static void (*cp2_ops[])(struct psxCP2Regs *) = { static char cache_buf[64 * 1024]; -static u32 cop0_mfc(struct lightrec_state *state, u8 reg) +static u32 cop0_mfc(struct lightrec_state *state, u32 op, u8 reg) { return psxRegs.CP0.r[reg]; } @@ -124,19 +117,38 @@ static u32 cop2_mfc_cfc(struct lightrec_state *state, u8 reg, bool cfc) return MFC2(reg); } -static u32 cop2_mfc(struct lightrec_state *state, u8 reg) +static u32 cop2_mfc(struct lightrec_state *state, u32 op, u8 reg) { return cop2_mfc_cfc(state, reg, false); } -static u32 cop2_cfc(struct lightrec_state *state, u8 reg) +static u32 cop2_cfc(struct lightrec_state *state, u32 op, u8 reg) { return cop2_mfc_cfc(state, reg, true); } +static bool has_interrupt(void) +{ + return ((psxHu32(0x1070) & psxHu32(0x1074)) && + (psxRegs.CP0.n.Status & 0x401) == 0x401) || + (psxRegs.CP0.n.Status & psxRegs.CP0.n.Cause & 0x0300); +} + +static void lightrec_restore_state(struct lightrec_state *state) +{ + lightrec_reset_cycle_count(state, psxRegs.cycle); + + if (booting || has_interrupt()) + lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); + else + lightrec_set_target_cycle_count(state, next_interupt); +} + static void cop0_mtc_ctc(struct lightrec_state *state, u8 reg, u32 value, bool ctc) { + psxRegs.cycle = lightrec_current_cycle_count(state); + switch (reg) { case 1: case 4: @@ -154,17 +166,17 @@ static void cop0_mtc_ctc(struct lightrec_state *state, } psxRegs.CP0.n.Status = value; - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); break; case 13: /* Cause */ psxRegs.CP0.n.Cause &= ~0x0300; psxRegs.CP0.n.Cause |= value & 0x0300; - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); break; default: psxRegs.CP0.r[reg] = value; break; } + + lightrec_restore_state(state); } static void cop2_mtc_ctc(struct lightrec_state *state, @@ -176,22 +188,22 @@ static void cop2_mtc_ctc(struct lightrec_state *state, MTC2(value, reg); } -static void cop0_mtc(struct lightrec_state *state, u8 reg, u32 value) +static void cop0_mtc(struct lightrec_state *state, u32 op, u8 reg, u32 value) { cop0_mtc_ctc(state, reg, value, false); } -static void cop0_ctc(struct lightrec_state *state, u8 reg, u32 value) +static void cop0_ctc(struct lightrec_state *state, u32 op, u8 reg, u32 value) { cop0_mtc_ctc(state, reg, value, true); } -static void cop2_mtc(struct lightrec_state *state, u8 reg, u32 value) +static void cop2_mtc(struct lightrec_state *state, u32 op, u8 reg, u32 value) { cop2_mtc_ctc(state, reg, value, false); } -static void cop2_ctc(struct lightrec_state *state, u8 reg, u32 value) +static void cop2_ctc(struct lightrec_state *state, u32 op, u8 reg, u32 value) { cop2_mtc_ctc(state, reg, value, true); } @@ -211,71 +223,73 @@ static void cop2_op(struct lightrec_state *state, u32 func) cp2_ops[func & 0x3f](&psxRegs.CP2); } -static void hw_write_byte(struct lightrec_state *state, u32 mem, u8 val) +static void hw_write_byte(struct lightrec_state *state, + u32 op, void *host, u32 mem, u8 val) { psxRegs.cycle = lightrec_current_cycle_count(state); psxHwWrite8(mem, val); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); - lightrec_reset_cycle_count(state, psxRegs.cycle); + lightrec_restore_state(state); } -static void hw_write_half(struct lightrec_state *state, u32 mem, u16 val) +static void hw_write_half(struct lightrec_state *state, + u32 op, void *host, u32 mem, u16 val) { psxRegs.cycle = lightrec_current_cycle_count(state); psxHwWrite16(mem, val); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); - lightrec_reset_cycle_count(state, psxRegs.cycle); + lightrec_restore_state(state); } -static void hw_write_word(struct lightrec_state *state, u32 mem, u32 val) +static void hw_write_word(struct lightrec_state *state, + u32 op, void *host, u32 mem, u32 val) { psxRegs.cycle = lightrec_current_cycle_count(state); psxHwWrite32(mem, val); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); - lightrec_reset_cycle_count(state, psxRegs.cycle); + lightrec_restore_state(state); } -static u8 hw_read_byte(struct lightrec_state *state, u32 mem) +static u8 hw_read_byte(struct lightrec_state *state, u32 op, void *host, u32 mem) { u8 val; psxRegs.cycle = lightrec_current_cycle_count(state); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); val = psxHwRead8(mem); - lightrec_reset_cycle_count(state, psxRegs.cycle); + + lightrec_restore_state(state); return val; } -static u16 hw_read_half(struct lightrec_state *state, u32 mem) +static u16 hw_read_half(struct lightrec_state *state, + u32 op, void *host, u32 mem) { u16 val; psxRegs.cycle = lightrec_current_cycle_count(state); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); val = psxHwRead16(mem); - lightrec_reset_cycle_count(state, psxRegs.cycle); + + lightrec_restore_state(state); return val; } -static u32 hw_read_word(struct lightrec_state *state, u32 mem) +static u32 hw_read_word(struct lightrec_state *state, + u32 op, void *host, u32 mem) { u32 val; psxRegs.cycle = lightrec_current_cycle_count(state); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); val = psxHwRead32(mem); - lightrec_reset_cycle_count(state, psxRegs.cycle); + + lightrec_restore_state(state); return val; } @@ -291,12 +305,14 @@ static struct lightrec_mem_map_ops hw_regs_ops = { static u32 cache_ctrl; -static void cache_ctrl_write_word(struct lightrec_state *state, u32 mem, u32 val) +static void cache_ctrl_write_word(struct lightrec_state *state, + u32 op, void *host, u32 mem, u32 val) { cache_ctrl = val; } -static u32 cache_ctrl_read_word(struct lightrec_state *state, u32 mem) +static u32 cache_ctrl_read_word(struct lightrec_state *state, + u32 op, void *host, u32 mem) { return cache_ctrl; } @@ -393,11 +409,11 @@ static int lightrec_plugin_init(void) lightrec_map, ARRAY_SIZE(lightrec_map), &lightrec_ops); - fprintf(stderr, "M=0x%lx, P=0x%lx, R=0x%lx, H=0x%lx\n", - (uintptr_t) psxM, - (uintptr_t) psxP, - (uintptr_t) psxR, - (uintptr_t) psxH); + // fprintf(stderr, "M=0x%lx, P=0x%lx, R=0x%lx, H=0x%lx\n", + // (uintptr_t) psxM, + // (uintptr_t) psxP, + // (uintptr_t) psxR, + // (uintptr_t) psxH); #ifndef _WIN32 signal(SIGPIPE, exit); @@ -489,6 +505,10 @@ static void print_for_big_ass_debugger(void) printf("\n"); } + +extern void intExecuteBlock(); +extern void gen_interupt(); + static u32 old_cycle_counter; static void lightrec_plugin_execute_block(void) @@ -496,30 +516,43 @@ static void lightrec_plugin_execute_block(void) u32 old_pc = psxRegs.pc; u32 flags; - lightrec_reset_cycle_count(lightrec_state, psxRegs.cycle); - lightrec_restore_registers(lightrec_state, psxRegs.GPR.r); - - if (use_lightrec_interpreter) - psxRegs.pc = lightrec_run_interpreter(lightrec_state, psxRegs.pc); - else - psxRegs.pc = lightrec_execute_one(lightrec_state, psxRegs.pc); - - psxRegs.cycle = lightrec_current_cycle_count(lightrec_state); + gen_interupt(); + + if (use_pcsx_interpreter) { + intExecuteBlock(); + } else { + lightrec_reset_cycle_count(lightrec_state, psxRegs.cycle); + lightrec_restore_registers(lightrec_state, psxRegs.GPR.r); + + if (unlikely(use_lightrec_interpreter)) + psxRegs.pc = lightrec_run_interpreter(lightrec_state, + psxRegs.pc); + // step during early boot so that 0x80030000 fastboot hack works + else if (unlikely(booting)) + psxRegs.pc = lightrec_execute_one(lightrec_state, + psxRegs.pc); + else + psxRegs.pc = lightrec_execute(lightrec_state, + psxRegs.pc, next_interupt); + + psxRegs.cycle = lightrec_current_cycle_count(lightrec_state); + + lightrec_dump_registers(lightrec_state, psxRegs.GPR.r); + flags = lightrec_exit_flags(lightrec_state); + + if (flags & LIGHTREC_EXIT_SEGFAULT) { + fprintf(stderr, "Exiting at cycle 0x%08x\n", + psxRegs.cycle); + exit(1); + } - lightrec_dump_registers(lightrec_state, psxRegs.GPR.r); - flags = lightrec_exit_flags(lightrec_state); + if (flags & LIGHTREC_EXIT_SYSCALL) + psxException(0x20, 0); - if (flags & LIGHTREC_EXIT_SEGFAULT) { - fprintf(stderr, "Exiting at cycle 0x%08x\n", - psxRegs.cycle); - exit(1); + if (booting && (psxRegs.pc & 0xff800000) == 0x80000000) + booting = false; } - if (flags & LIGHTREC_EXIT_SYSCALL) - psxException(0x20, 0); - - psxBranchTest(); - if (lightrec_debug && psxRegs.cycle >= lightrec_begin_cycles && psxRegs.pc != old_pc) print_for_big_ass_debugger(); @@ -532,8 +565,9 @@ static void lightrec_plugin_execute_block(void) } if ((psxRegs.cycle & ~0xfffffff) != old_cycle_counter) { - printf("RAM usage: IR %u KiB, CODE %u KiB, " + SysDLog("RAM usage: Lightrec %u KiB, IR %u KiB, CODE %u KiB, " "MIPS %u KiB, TOTAL %u KiB, avg. IPI %f\n", + lightrec_get_mem_usage(MEM_FOR_LIGHTREC) / 1024, lightrec_get_mem_usage(MEM_FOR_IR) / 1024, lightrec_get_mem_usage(MEM_FOR_CODE) / 1024, lightrec_get_mem_usage(MEM_FOR_MIPS_CODE) / 1024, @@ -560,6 +594,27 @@ static void lightrec_plugin_clear(u32 addr, u32 size) lightrec_invalidate(lightrec_state, addr, size * 4); } +static void lightrec_plugin_notify(int note, void *data) +{ + /* + To change once proper icache emulation is emulated + switch (note) + { + case R3000ACPU_NOTIFY_CACHE_UNISOLATED: + lightrec_plugin_clear(0, 0x200000/4); + break; + case R3000ACPU_NOTIFY_CACHE_ISOLATED: + // Sent from psxDma3(). + case R3000ACPU_NOTIFY_DMA3_EXE_LOAD: + default: + break; + }*/ +} + +static void lightrec_plugin_apply_config() +{ +} + static void lightrec_plugin_shutdown(void) { lightrec_destroy(lightrec_state); @@ -569,6 +624,7 @@ static void lightrec_plugin_reset(void) { lightrec_plugin_shutdown(); lightrec_plugin_init(); + booting = true; } R3000Acpu psxRec = @@ -578,5 +634,7 @@ R3000Acpu psxRec = lightrec_plugin_execute, lightrec_plugin_execute_block, lightrec_plugin_clear, + lightrec_plugin_notify, + lightrec_plugin_apply_config, lightrec_plugin_shutdown, };