From 4fd456e1583a4c8686c8de87c2aeb1eb78125be1 Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Wed, 5 May 2021 02:20:00 +0200 Subject: Adding Code Breaker cheat support This works on both interpreter and dynarec. Tested in MIPS, ARM and x86, still needs some more testing, some edge cases can be buggy. --- arm/arm_emit.h | 8 ++++++++ arm/arm_stub.S | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'arm') diff --git a/arm/arm_emit.h b/arm/arm_emit.h index 1432617..4368a80 100644 --- a/arm/arm_emit.h +++ b/arm/arm_emit.h @@ -31,6 +31,8 @@ u32 prepare_store_reg(u32 scratch_reg, u32 reg_index); void generate_load_reg(u32 ireg, u32 reg_index); void complete_store_reg(u32 scratch_reg, u32 reg_index); void complete_store_reg_pc_no_flags(u32 scratch_reg, u32 reg_index); +void thumb_cheat_hook(); +void arm_cheat_hook(); u32 arm_update_gba_arm(u32 pc); u32 arm_update_gba_thumb(u32 pc); @@ -1876,6 +1878,12 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address) generate_indirect_branch_cycle_update(dual_thumb); \ } \ +#define thumb_process_cheats() \ + generate_function_call(thumb_cheat_hook); + +#define arm_process_cheats() \ + generate_function_call(arm_cheat_hook); + #define thumb_swi() \ generate_swi_hle_handler(opcode & 0xFF, thumb); \ generate_function_call(execute_swi_thumb); \ diff --git a/arm/arm_stub.S b/arm/arm_stub.S index 944d36a..222bb21 100644 --- a/arm/arm_stub.S +++ b/arm/arm_stub.S @@ -288,6 +288,22 @@ arm_update_gba_builder(idle_arm, arm, add) arm_update_gba_builder(idle_thumb, thumb, add) +@ Cheat hooks for master function +@ This is called whenever PC == cheats-master-function +@ Just calls the C function to process cheats + +#define cheat_hook_builder(mode) ;\ +defsymbl(mode##_cheat_hook) ;\ + save_flags() ;\ + store_registers_##mode() ;\ + call_c_function(process_cheats) ;\ + load_registers_##mode() ;\ + restore_flags() ;\ + bx lr ;\ + +cheat_hook_builder(arm) +cheat_hook_builder(thumb) + @ These are b stubs for performing indirect branches. They are not @ linked to and don't return, instead they link elsewhere. -- cgit v1.2.3 From 883f07f487ecd2e803cf2f924ab1e9a51e5f4fa9 Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Wed, 5 May 2021 18:07:55 +0200 Subject: Fix small buf and add cheat error messages Some minor formating too --- arm/arm_emit.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arm') diff --git a/arm/arm_emit.h b/arm/arm_emit.h index 4368a80..1b6b251 100644 --- a/arm/arm_emit.h +++ b/arm/arm_emit.h @@ -31,8 +31,8 @@ u32 prepare_store_reg(u32 scratch_reg, u32 reg_index); void generate_load_reg(u32 ireg, u32 reg_index); void complete_store_reg(u32 scratch_reg, u32 reg_index); void complete_store_reg_pc_no_flags(u32 scratch_reg, u32 reg_index); -void thumb_cheat_hook(); -void arm_cheat_hook(); +void thumb_cheat_hook(void); +void arm_cheat_hook(void); u32 arm_update_gba_arm(u32 pc); u32 arm_update_gba_thumb(u32 pc); -- cgit v1.2.3 From 37430f22c5234cb09f2325575806b830f947bf8a Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Fri, 7 May 2021 20:41:54 +0200 Subject: Small optimization (~2-4%) and whitespace cleanup! Cleans up a ton of whitespace in cpu.c (like 100KB!) and improves readability of some massive decode statements. Added an optimization for PC-relative loads (pool load) in ROM (since it's read only and cannot possibily change) that directly emits an immediate load. This is way faster, specially in MIPS/x86, ARM can be even faster if we rewrite the immediate load macros to also use a pool. --- arm/arm_emit.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arm') diff --git a/arm/arm_emit.h b/arm/arm_emit.h index 1b6b251..4516404 100644 --- a/arm/arm_emit.h +++ b/arm/arm_emit.h @@ -319,7 +319,7 @@ u32 arm_disect_imm_32bit(u32 imm, u32 *stores, u32 *rotations) #define generate_load_pc(ireg, new_pc) \ - arm_load_imm_32bit(ireg, new_pc) \ + arm_load_imm_32bit(ireg, (new_pc)) \ #define generate_load_imm(ireg, imm, imm_ror) \ ARM_MOV_REG_IMM(0, ireg, imm, imm_ror) \ @@ -1658,6 +1658,10 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address) /* Operation types: imm, mem_reg, mem_imm */ +#define thumb_load_pc_pool_const(reg_rd, value) \ + generate_load_pc(reg_a0, (value)); \ + generate_store_reg(reg_a0, reg_rd) + #define thumb_access_memory_load(mem_type, _rd) \ cycle_count += 2; \ generate_function_call(execute_load_##mem_type); \ -- cgit v1.2.3 From 2877886ff1217d214dcb052457714ed05e00e02d Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Sat, 15 May 2021 21:43:10 +0200 Subject: Fix ARM dynarec unaligned 32 bit loads This might make a handful games slightly slower (but on the upper side they work now instead of crashing or restarting). Also while at it, fix some minor stuff in arm stubs for speed. --- arm/arm_stub.S | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'arm') diff --git a/arm/arm_stub.S b/arm/arm_stub.S index 222bb21..d7203f8 100644 --- a/arm/arm_stub.S +++ b/arm/arm_stub.S @@ -67,14 +67,8 @@ _##symbol: #define MODE_SUPERVISOR 3 -#ifdef __ARM_ARCH_7A__ - #define extract_u16(rd, rs) \ - uxth rd, rs -#else - #define extract_u16(rd, rs) \ - bic rd, rs, #0xff000000 ;\ - bic rd, rd, #0x00ff0000 -#endif +#define extract_u16(rd, rs) \ + uxth rd, rs @ Will load the register set from memory into the appropriate cached registers. @ See arm_emit.h for listing explanation. @@ -777,12 +771,10 @@ lookup_pc: #define sign_extend_u32(reg) #define sign_extend_s8(reg) ;\ - mov reg, reg, lsl #24 /* shift reg into upper 8bits */;\ - mov reg, reg, asr #24 /* shift down, sign extending */;\ + sxtb reg, reg #define sign_extend_s16(reg) ;\ - mov reg, reg, lsl #16 /* shift reg into upper 16bits */;\ - mov reg, reg, asr #16 /* shift down, sign extending */;\ + sxth reg, reg #define execute_load_op_u8(load_op) ;\ mov r0, r0, lsl #17 ;\ @@ -836,11 +828,11 @@ ext_load_##load_type: ;\ .pool -execute_load_builder(u8, 8, ldrneb, #0xF0000000) -execute_load_builder(s8, 8, ldrnesb, #0xF0000000) -execute_load_builder(u16, 16, ldrneh, #0xF0000001) -execute_load_builder(s16, 16_signed, ldrnesh, #0xF0000001) -execute_load_builder(u32, 32, ldrne, #0xF0000000) +execute_load_builder(u8, 8, ldrb, #0xF0000000) +execute_load_builder(s8, 8, ldrsb, #0xF0000000) +execute_load_builder(u16, 16, ldrh, #0xF0000001) +execute_load_builder(s16, 16_signed, ldrsh, #0xF0000001) +execute_load_builder(u32, 32, ldr, #0xF0000003) .data -- cgit v1.2.3 From aafde6de7b2a28c1684c0e9fa62fee9a2a5398dd Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Mon, 17 May 2021 01:14:46 +0200 Subject: Add ROM mirroring and fix mult. cycle count This should correct some minor issues in some games. --- arm/arm_emit.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arm') diff --git a/arm/arm_emit.h b/arm/arm_emit.h index 4516404..4198c7d 100644 --- a/arm/arm_emit.h +++ b/arm/arm_emit.h @@ -1239,12 +1239,10 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address) #define emit_trace_instruction(pc) \ generate_save_flags(); \ - ARM_LDR_IMM(0, ARMREG_SP, reg_base, 34*4); \ ARM_STMDB_WB(0, ARMREG_SP, 0x500C); \ arm_load_imm_32bit(reg_a0, pc); \ generate_function_call(trace_instruction); \ ARM_LDMIA_WB(0, ARMREG_SP, 0x500C); \ - arm_load_imm_32bit(ARMREG_SP, (u32)reg); \ generate_restore_flags(); #define emit_trace_thumb_instruction(pc) \ emit_trace_instruction(pc) -- cgit v1.2.3 From ea2608812f157007e4b0ba8f86913eb4e780122b Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Wed, 19 May 2021 20:09:28 +0200 Subject: Minor optimization --- arm/arm_emit.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arm') diff --git a/arm/arm_emit.h b/arm/arm_emit.h index 4198c7d..22ca763 100644 --- a/arm/arm_emit.h +++ b/arm/arm_emit.h @@ -1657,8 +1657,9 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address) /* Operation types: imm, mem_reg, mem_imm */ #define thumb_load_pc_pool_const(reg_rd, value) \ - generate_load_pc(reg_a0, (value)); \ - generate_store_reg(reg_a0, reg_rd) + u32 rgdst = prepare_store_reg(reg_a0, reg_rd); \ + generate_load_pc(rgdst, (value)); \ + complete_store_reg(rgdst, reg_rd) #define thumb_access_memory_load(mem_type, _rd) \ cycle_count += 2; \ -- cgit v1.2.3