X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Flightrec%2Fplugin.c;h=2a46942b7327099328b52512eabe0793604cd1b4;hb=12742a5c7b839a9fad2ef87c1bd681b09ab86906;hp=64b353dd4a1ed7d19580aa3dc452b7ee73454fb0;hpb=f2100c3de4f1a2fcf86fb458b56d5c2978f1692f;p=pcsx_rearmed.git diff --git a/libpcsxcore/lightrec/plugin.c b/libpcsxcore/lightrec/plugin.c index 64b353dd..2a46942b 100644 --- a/libpcsxcore/lightrec/plugin.c +++ b/libpcsxcore/lightrec/plugin.c @@ -1,8 +1,14 @@ #include +#include #include #include #include #include +#include + +#if P_HAVE_MMAP +#include +#endif #include "../cdrom.h" #include "../gpu.h" @@ -49,6 +55,8 @@ psxRegisters psxRegs; Rcnt rcnts[4]; +void* code_buffer; + static struct lightrec_state *lightrec_state; static char *name = "retroarch.exe"; @@ -134,55 +142,62 @@ static bool has_interrupt(void) (regs->cp0[12] & regs->cp0[13] & 0x0300); } -static void lightrec_restore_state(struct lightrec_state *state) +static void lightrec_tansition_to_pcsx(struct lightrec_state *state) +{ + psxRegs.cycle += lightrec_current_cycle_count(state) / 1024; + lightrec_reset_cycle_count(state, 0); +} + +static void lightrec_tansition_from_pcsx(struct lightrec_state *state) { - lightrec_reset_cycle_count(state, psxRegs.cycle); + s32 cycles_left = next_interupt - psxRegs.cycle; - if (block_stepping || has_interrupt()) + if (block_stepping || cycles_left <= 0 || has_interrupt()) lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); - else - lightrec_set_target_cycle_count(state, next_interupt); + else { + lightrec_set_target_cycle_count(state, cycles_left * 1024); + } } static void hw_write_byte(struct lightrec_state *state, u32 op, void *host, u32 mem, u8 val) { - psxRegs.cycle = lightrec_current_cycle_count(state); + lightrec_tansition_to_pcsx(state); psxHwWrite8(mem, val); - lightrec_restore_state(state); + lightrec_tansition_from_pcsx(state); } static void hw_write_half(struct lightrec_state *state, u32 op, void *host, u32 mem, u16 val) { - psxRegs.cycle = lightrec_current_cycle_count(state); + lightrec_tansition_to_pcsx(state); psxHwWrite16(mem, val); - lightrec_restore_state(state); + lightrec_tansition_from_pcsx(state); } static void hw_write_word(struct lightrec_state *state, u32 op, void *host, u32 mem, u32 val) { - psxRegs.cycle = lightrec_current_cycle_count(state); + lightrec_tansition_to_pcsx(state); psxHwWrite32(mem, val); - lightrec_restore_state(state); + lightrec_tansition_from_pcsx(state); } 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_tansition_to_pcsx(state); val = psxHwRead8(mem); - lightrec_restore_state(state); + lightrec_tansition_from_pcsx(state); return val; } @@ -192,11 +207,11 @@ static u16 hw_read_half(struct lightrec_state *state, { u16 val; - psxRegs.cycle = lightrec_current_cycle_count(state); + lightrec_tansition_to_pcsx(state); val = psxHwRead16(mem); - lightrec_restore_state(state); + lightrec_tansition_from_pcsx(state); return val; } @@ -206,11 +221,11 @@ static u32 hw_read_word(struct lightrec_state *state, { u32 val; - psxRegs.cycle = lightrec_current_cycle_count(state); + lightrec_tansition_to_pcsx(state); val = psxHwRead32(mem); - lightrec_restore_state(state); + lightrec_tansition_from_pcsx(state); return val; } @@ -267,7 +282,7 @@ static struct lightrec_mem_map lightrec_map[] = { [PSX_MAP_HW_REGISTERS] = { /* Hardware registers */ .pc = 0x1f801000, - .length = 0x2000, + .length = 0x8000, .ops = &hw_regs_ops, }, [PSX_MAP_CACHE_CONTROL] = { @@ -293,6 +308,15 @@ static struct lightrec_mem_map lightrec_map[] = { .length = 0x200000, .mirror_of = &lightrec_map[PSX_MAP_KERNEL_USER_RAM], }, + + /* Mirror of the parallel port. Only used by the PS2/PS3 BIOS */ + [PSX_MAP_PPORT_MIRROR] = { + .pc = 0x1fa00000, + .length = 0x10000, + .mirror_of = &lightrec_map[PSX_MAP_PARALLEL_PORT], + }, + + /* Code buffer */ [PSX_MAP_CODE_BUFFER] = { .length = CODE_BUFFER_SIZE, }, @@ -382,10 +406,29 @@ static bool lightrec_can_hw_direct(u32 kaddr, bool is_write, u8 size) } } +#if defined(HW_DOL) || defined(HW_RVL) +static void lightrec_code_inv(void *ptr, uint32_t len) +{ + extern void DCFlushRange(void *ptr, u32 len); + extern void ICInvalidateRange(void *ptr, u32 len); + + DCFlushRange(ptr, len); + ICInvalidateRange(ptr, len); +} +#elif defined(HW_WUP) +static void lightrec_code_inv(void *ptr, uint32_t len) +{ + wiiu_clear_cache(ptr, (void *)((uintptr_t)ptr + len)); +} +#endif + static const struct lightrec_ops lightrec_ops = { .cop2_op = cop2_op, .enable_ram = lightrec_enable_ram, .hw_direct = lightrec_can_hw_direct, +#if defined(HW_DOL) || defined(HW_RVL) || defined(HW_WUP) + .code_inv = lightrec_code_inv, +#endif }; static int lightrec_plugin_init(void) @@ -396,13 +439,28 @@ static int lightrec_plugin_init(void) lightrec_map[PSX_MAP_HW_REGISTERS].address = psxH + 0x1000; lightrec_map[PSX_MAP_PARALLEL_PORT].address = psxP; + if (!LIGHTREC_CUSTOM_MAP) { +#if P_HAVE_MMAP + code_buffer = mmap(0, CODE_BUFFER_SIZE, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (code_buffer == MAP_FAILED) + return -ENOMEM; +#else + code_buffer = malloc(CODE_BUFFER_SIZE); + if (!code_buffer) + return -ENOMEM; +#endif + } + if (LIGHTREC_CUSTOM_MAP) { lightrec_map[PSX_MAP_MIRROR1].address = psxM + 0x200000; lightrec_map[PSX_MAP_MIRROR2].address = psxM + 0x400000; lightrec_map[PSX_MAP_MIRROR3].address = psxM + 0x600000; - lightrec_map[PSX_MAP_CODE_BUFFER].address = code_buffer; } + lightrec_map[PSX_MAP_CODE_BUFFER].address = code_buffer; + use_lightrec_interpreter = !!getenv("LIGHTREC_INTERPRETER"); lightrec_state = lightrec_init(name, @@ -424,31 +482,32 @@ static int lightrec_plugin_init(void) static void lightrec_plugin_execute_internal(bool block_only) { struct lightrec_registers *regs; - u32 flags; + u32 flags, cycles_pcsx; regs = lightrec_get_registers(lightrec_state); gen_interupt((psxCP0Regs *)regs->cp0); + cycles_pcsx = next_interupt - psxRegs.cycle; + assert((s32)cycles_pcsx > 0); // step during early boot so that 0x80030000 fastboot hack works block_stepping = block_only; if (block_only) - next_interupt = psxRegs.cycle; + cycles_pcsx = 0; if (use_pcsx_interpreter) { intExecuteBlock(0); } else { - lightrec_reset_cycle_count(lightrec_state, psxRegs.cycle); - + u32 cycles_lightrec = cycles_pcsx * 1024; if (unlikely(use_lightrec_interpreter)) { psxRegs.pc = lightrec_run_interpreter(lightrec_state, psxRegs.pc, - next_interupt); + cycles_lightrec); } else { psxRegs.pc = lightrec_execute(lightrec_state, - psxRegs.pc, next_interupt); + psxRegs.pc, cycles_lightrec); } - psxRegs.cycle = lightrec_current_cycle_count(lightrec_state); + lightrec_tansition_to_pcsx(lightrec_state); flags = lightrec_exit_flags(lightrec_state); @@ -513,11 +572,24 @@ static void lightrec_plugin_notify(enum R3000Anote note, void *data) static void lightrec_plugin_apply_config() { + u32 cycle_mult = Config.cycle_multiplier_override && Config.cycle_multiplier == CYCLE_MULT_DEFAULT + ? Config.cycle_multiplier_override : Config.cycle_multiplier; + assert(cycle_mult); + + lightrec_set_cycles_per_opcode(lightrec_state, cycle_mult * 1024 / 100); } static void lightrec_plugin_shutdown(void) { lightrec_destroy(lightrec_state); + + if (!LIGHTREC_CUSTOM_MAP) { +#if P_HAVE_MMAP + munmap(code_buffer, CODE_BUFFER_SIZE); +#else + free(code_buffer); +#endif + } } static void lightrec_plugin_reset(void)