#ifdef _3DS
#include <3ds_utils.h>
#endif
-#ifdef VITA
-#include <psp2/kernel/sysmem.h>
-static int sceBlock;
-#endif
#include "new_dynarec_config.h"
#include "../psxhle.h"
static void *copy;
static int expirep;
static u_int stop_after_jal;
- static u_int f1_hack; // 0 - off, ~0 - capture address, else addr
+ static u_int f1_hack;
int new_dynarec_hacks;
int new_dynarec_hacks_pergame;
static void emit_far_jump(const void *f);
static void emit_far_call(const void *f);
+#ifdef VITA
+#include <psp2/kernel/sysmem.h>
+static int sceBlock;
+// note: this interacts with RetroArch's Vita bootstrap code: bootstrap/vita/sbrk.c
+extern int getVMBlock();
+int _newlib_vm_size_user = sizeof(*ndrc);
+#endif
+
static void mprotect_w_x(void *start, void *end, int is_x)
{
#ifdef NO_WRITE_EXEC
SysPrintf("linkage_arm* miscompilation/breakage detected.\n");
}
- SysPrintf("testing if we can run recompiled code...\n");
+ SysPrintf("testing if we can run recompiled code @%p...\n", out);
((volatile u_int *)out)[0]++; // make cache dirty
for (i = 0; i < ARRAY_SIZE(ret); i++) {
literalcount=0;
stop_after_jal=0;
inv_code_start=inv_code_end=~0;
+ hack_addr=0;
f1_hack=0;
// TLB
for(n=0;n<4096;n++) ll_clear(jump_in+n);
#else
#ifndef NO_WRITE_EXEC
// not all systems allow execute in data segment by default
- if (mprotect(ndrc, sizeof(ndrc->translation_cache) + sizeof(ndrc->tramp.ops),
+ // size must be 4K aligned for 3DS?
+ if (mprotect(ndrc, sizeof(*ndrc),
PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
SysPrintf("mprotect() failed: %s\n", strerror(errno));
#endif
int n;
#ifdef BASE_ADDR_DYNAMIC
#ifdef VITA
- sceKernelFreeMemBlock(sceBlock);
- sceBlock = -1;
+ //sceKernelFreeMemBlock(sceBlock);
+ //sceBlock = -1;
#else
if (munmap(ndrc, sizeof(*ndrc)) < 0)
SysPrintf("munmap() failed\n");
memcpy(&psxRegs.GPR, regs_save, sizeof(regs_save));
}
-static void apply_hacks(void)
+static int apply_hacks(void)
{
int i;
if (HACK_ENABLED(NDHACK_NO_COMPAT_HACKS))
- return;
+ return 0;
/* special hack(s) */
for (i = 0; i < slen - 4; i++)
{
if (dops[i].itype == STORELR && dops[i].rs1 == 6
&& dops[i-1].itype == STORELR && dops[i-1].rs1 == 6)
{
- SysPrintf("F1 hack from %08x\n", start);
- if (f1_hack == 0)
- f1_hack = ~0u;
+ SysPrintf("F1 hack from %08x, old dst %08x\n", start, hack_addr);
+ f1_hack = 1;
+ return 1;
}
}
+ return 0;
}
int new_recompile_block(u_int addr)
ll_add_flags(jump_in+page,start,state_rflags,(void *)beginning);
return 0;
}
- else if (f1_hack == ~0u || (f1_hack != 0 && start == f1_hack)) {
+ else if (f1_hack && hack_addr == 0) {
void *beginning = start_block();
u_int page = get_page(start);
+ emit_movimm(start, 0);
+ emit_writeword(0, &hack_addr);
emit_readword(&psxRegs.GPR.n.sp, 0);
emit_readptr(&mem_rtab, 1);
emit_shrimm(0, 12, 2);
ll_add_flags(jump_in + page, start, state_rflags, beginning);
SysPrintf("F1 hack to %08x\n", start);
- f1_hack = start;
return 0;
}
/* Pass 1 disassembly */
- for(i=0;!done;i++) {
- dops[i].bt=0;
- dops[i].ooo=0;
+ for (i = 0; !done; i++)
+ {
+ memset(&dops[i], 0, sizeof(dops[i]));
op2=0;
minimum_free_regs[i]=0;
dops[i].opcode=op=source[i]>>26;
do_in_intrp=1;
}
}
- if(do_in_intrp) {
- dops[i-1].rs1=CCREG;
- dops[i-1].rs2=dops[i-1].rt1=dops[i-1].rt2=0;
- ba[i-1]=-1;
- dops[i-1].itype=INTCALL;
- done=2;
+ if (do_in_intrp) {
+ memset(&dops[i-1], 0, sizeof(dops[i-1]));
+ dops[i-1].itype = INTCALL;
+ dops[i-1].rs1 = CCREG;
+ ba[i-1] = -1;
+ done = 2;
i--; // don't compile the DS
}
}
}
assert(slen>0);
- apply_hacks();
+ int clear_hack_addr = apply_hacks();
/* Pass 2 - Register dependencies and branch targets */
current.u=branch_unneeded_reg[i]&~((1LL<<dops[i+1].rs1)|(1LL<<dops[i+1].rs2));
current.u&=~((1LL<<dops[i].rs1)|(1LL<<dops[i].rs2));
current.u|=1;
- } else { SysPrintf("oops, branch at end of block with no delay slot\n");abort(); }
+ } else {
+ SysPrintf("oops, branch at end of block with no delay slot @%08x\n", start + i*4);
+ abort();
+ }
}
dops[i].is_ds=ds;
if(ds) {
instr_addr[i] = out;
assem_debug("<->\n");
drc_dbg_emit_do_cmp(i, ccadj[i]);
+ if (clear_hack_addr) {
+ emit_movimm(0, 0);
+ emit_writeword(0, &hack_addr);
+ clear_hack_addr = 0;
+ }
// load regs
if(regs[i].regmap_entry[HOST_CCREG]==CCREG&®s[i].regmap[HOST_CCREG]!=CCREG)