2013-12-19 17:10:14 +00:00
|
|
|
|
#include "types.h"
|
|
|
|
|
|
|
|
|
|
#if HOST_OS==OS_WINDOWS
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#elif HOST_OS==OS_LINUX
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "../sh4_interpreter.h"
|
|
|
|
|
#include "../sh4_opcode_list.h"
|
|
|
|
|
#include "../sh4_core.h"
|
|
|
|
|
#include "../sh4_if.h"
|
|
|
|
|
#include "hw/sh4/sh4_interrupts.h"
|
|
|
|
|
|
|
|
|
|
#include "hw/sh4/sh4_mem.h"
|
|
|
|
|
#include "hw/pvr/pvr_mem.h"
|
|
|
|
|
#include "hw/aica/aica_if.h"
|
|
|
|
|
#include "hw/gdrom/gdrom_if.h"
|
|
|
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <float.h>
|
|
|
|
|
|
|
|
|
|
#include "blockmanager.h"
|
|
|
|
|
#include "ngen.h"
|
|
|
|
|
#include "decoder.h"
|
|
|
|
|
|
2015-07-25 06:39:35 +00:00
|
|
|
|
#if FEAT_SHREC != DYNAREC_NONE
|
2013-12-19 17:10:14 +00:00
|
|
|
|
//uh uh
|
|
|
|
|
|
2015-08-07 13:54:51 +00:00
|
|
|
|
#if !defined(_WIN64)
|
|
|
|
|
u8 SH4_TCB[CODE_SIZE+4096]
|
2015-07-28 16:10:31 +00:00
|
|
|
|
#if HOST_OS == OS_WINDOWS || FEAT_SHREC != DYNAREC_JIT
|
|
|
|
|
;
|
2013-12-19 17:10:14 +00:00
|
|
|
|
#elif HOST_OS == OS_LINUX
|
2015-07-28 16:10:31 +00:00
|
|
|
|
__attribute__((section(".text")));
|
2015-05-16 05:12:19 +00:00
|
|
|
|
#elif HOST_OS==OS_DARWIN
|
2015-07-28 16:10:31 +00:00
|
|
|
|
__attribute__((section("__TEXT,.text")));
|
Partially working dyna for iOS. Very few games working atm.
This works, but is extremelly hacky. Must be started without attached debugger, lldb doesn't want to let go of EXC_BAD_ADDRESS, but reicast really depends on it getting delivered as SIGSEGV/SIGBUS. Also xcode has a really bad day upon seeing the jit code. Oh well.
There's some dynarec bug that causes color corruption on bios logo/boot triagles, TA crash on ikaruga and infinitive loop on crazy taxi. I'd guess some fp-memory-write thingy, abi, or smth. Too bad.
- Force code to compile in arm mode (arm jit -> thumb mem functions is complicated)
- SIGILL, SIGBUS. Works w/o Mach exceptions and EXC_BAD_ADDRESS
- Code buffers move to __TEXT, munmapped && memmapped to actually work
- Primitive input. Button + start, or left (works to get out of bios date screen)
- Fixup emitter for thumb2/interworking (didn't work though, reverted to arm cc)
- Block Manager: Disable mem saving / page fault alloc-on-demand logic
- Move cycle counter to r11, r9 is not clean on iOS. Remove r11 from reg alloc list
- Cache flushes for iOS
- log to log.txt
- load game.chd
2015-01-19 07:52:12 +00:00
|
|
|
|
#else
|
2015-05-16 05:12:19 +00:00
|
|
|
|
#error SH4_TCB ALLOC
|
2013-12-19 17:10:14 +00:00
|
|
|
|
#endif
|
2015-08-07 13:54:51 +00:00
|
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
u8* CodeCache;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
u32 LastAddr;
|
|
|
|
|
u32 LastAddr_min;
|
|
|
|
|
u32* emit_ptr=0;
|
|
|
|
|
|
|
|
|
|
void* emit_GetCCPtr() { return emit_ptr==0?(void*)&CodeCache[LastAddr]:(void*)emit_ptr; }
|
|
|
|
|
void emit_SetBaseAddr() { LastAddr_min = LastAddr; }
|
|
|
|
|
void emit_WriteCodeCache()
|
|
|
|
|
{
|
|
|
|
|
wchar path[512];
|
2015-08-17 11:59:39 +00:00
|
|
|
|
sprintf(path,"/code_cache_%8p.bin",CodeCache);
|
2015-08-28 23:28:51 +00:00
|
|
|
|
string pt2=get_writable_data_path(path);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
printf("Writing code cache to %s\n",pt2.c_str());
|
|
|
|
|
FILE*f=fopen(pt2.c_str(),"wb");
|
|
|
|
|
if (f)
|
|
|
|
|
{
|
|
|
|
|
fwrite(CodeCache,LastAddr,1,f);
|
|
|
|
|
fclose(f);
|
2018-03-05 00:29:19 +00:00
|
|
|
|
printf("Written!\n");
|
2013-12-19 17:10:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bm_WriteBlockMap(pt2+".map");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RASDASD()
|
|
|
|
|
{
|
|
|
|
|
LastAddr=LastAddr_min;
|
|
|
|
|
memset(emit_GetCCPtr(),0xCC,emit_FreeSpace());
|
|
|
|
|
}
|
|
|
|
|
void recSh4_ClearCache()
|
|
|
|
|
{
|
|
|
|
|
LastAddr=LastAddr_min;
|
|
|
|
|
bm_Reset();
|
|
|
|
|
|
|
|
|
|
printf("recSh4:Dynarec Cache clear at %08X\n",curr_pc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void recSh4_Run()
|
|
|
|
|
{
|
|
|
|
|
sh4_int_bCpuRun=true;
|
|
|
|
|
|
|
|
|
|
sh4_dyna_rcb=(u8*)&Sh4cntx + sizeof(Sh4cntx);
|
|
|
|
|
printf("cntx // fpcb offset: %d // pc offset: %d // pc %08X\n",(u8*)&sh4rcb.fpcb-sh4_dyna_rcb,(u8*)&sh4rcb.cntx.pc-sh4_dyna_rcb,sh4rcb.cntx.pc);
|
|
|
|
|
|
|
|
|
|
verify(rcb_noffs(&next_pc)==-184);
|
|
|
|
|
ngen_mainloop(sh4_dyna_rcb);
|
|
|
|
|
|
2015-07-29 04:45:02 +00:00
|
|
|
|
#if !defined(TARGET_BOUNDED_EXECUTION)
|
2013-12-19 17:10:14 +00:00
|
|
|
|
sh4_int_bCpuRun=false;
|
2015-07-29 04:45:02 +00:00
|
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void emit_Write32(u32 data)
|
|
|
|
|
{
|
|
|
|
|
if (emit_ptr)
|
|
|
|
|
{
|
|
|
|
|
*emit_ptr=data;
|
|
|
|
|
emit_ptr++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*(u32*)&CodeCache[LastAddr]=data;
|
|
|
|
|
LastAddr+=4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void emit_Skip(u32 sz)
|
|
|
|
|
{
|
|
|
|
|
LastAddr+=sz;
|
|
|
|
|
}
|
|
|
|
|
u32 emit_FreeSpace()
|
|
|
|
|
{
|
|
|
|
|
return CODE_SIZE-LastAddr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool DoCheck(u32 pc)
|
|
|
|
|
{
|
|
|
|
|
if (IsOnRam(pc))
|
|
|
|
|
{
|
2014-01-20 23:04:58 +00:00
|
|
|
|
if (!settings.dynarec.unstable_opt)
|
2014-01-20 21:10:00 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
|
pc&=0xFFFFFF;
|
|
|
|
|
switch(pc)
|
|
|
|
|
{
|
|
|
|
|
//DOA2LE
|
|
|
|
|
case 0x3DAFC6:
|
|
|
|
|
case 0x3C83F8:
|
2013-12-24 00:56:44 +00:00
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
|
//Shenmue 2
|
|
|
|
|
case 0x348000:
|
2014-01-20 21:10:00 +00:00
|
|
|
|
|
|
|
|
|
//Shenmue
|
|
|
|
|
case 0x41860e:
|
|
|
|
|
|
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AnalyseBlock(RuntimeBlockInfo* blk);
|
|
|
|
|
|
|
|
|
|
char block_hash[1024];
|
|
|
|
|
|
|
|
|
|
#include "deps/crypto/sha1.h"
|
|
|
|
|
|
|
|
|
|
const char* RuntimeBlockInfo::hash(bool full, bool relocable)
|
|
|
|
|
{
|
|
|
|
|
sha1_ctx ctx;
|
|
|
|
|
sha1_init(&ctx);
|
|
|
|
|
|
|
|
|
|
u8* ptr = GetMemPtr(this->addr,this->guest_opcodes*2);
|
|
|
|
|
|
|
|
|
|
if (ptr)
|
|
|
|
|
{
|
|
|
|
|
if (relocable)
|
|
|
|
|
{
|
2013-12-25 17:47:51 +00:00
|
|
|
|
for (u32 i=0; i<this->guest_opcodes; i++)
|
2013-12-19 17:10:14 +00:00
|
|
|
|
{
|
|
|
|
|
u16 data=ptr[i];
|
|
|
|
|
//Do not count PC relative loads (relocated code)
|
|
|
|
|
if ((ptr[i]>>12)==0xD)
|
|
|
|
|
data=0xD000;
|
|
|
|
|
|
|
|
|
|
sha1_update(&ctx,2,(u8*)&data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sha1_update(&ctx,this->guest_opcodes*2,ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sha1_final(&ctx);
|
|
|
|
|
|
|
|
|
|
if (full)
|
|
|
|
|
sprintf(block_hash,">:%d:%08X:%02X:%08X:%08X:%08X:%08X:%08X",relocable,this->addr,this->guest_opcodes,ctx.digest[0],ctx.digest[1],ctx.digest[2],ctx.digest[3],ctx.digest[4]);
|
|
|
|
|
else
|
|
|
|
|
sprintf(block_hash,">:%d:%02X:%08X:%08X:%08X:%08X:%08X",relocable,this->guest_opcodes,ctx.digest[0],ctx.digest[1],ctx.digest[2],ctx.digest[3],ctx.digest[4]);
|
|
|
|
|
|
|
|
|
|
//return ctx
|
|
|
|
|
return block_hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg)
|
|
|
|
|
{
|
|
|
|
|
staging_runs=addr=lookups=runs=host_code_size=0;
|
|
|
|
|
guest_cycles=guest_opcodes=host_opcodes=0;
|
|
|
|
|
pBranchBlock=pNextBlock=0;
|
|
|
|
|
code=0;
|
|
|
|
|
has_jcond=false;
|
|
|
|
|
BranchBlock=NextBlock=csc_RetCache=0xFFFFFFFF;
|
|
|
|
|
BlockType=BET_SCL_Intr;
|
|
|
|
|
|
|
|
|
|
addr=rpc;
|
|
|
|
|
fpu_cfg=rfpu_cfg;
|
|
|
|
|
|
|
|
|
|
oplist.clear();
|
|
|
|
|
|
|
|
|
|
dec_DecodeBlock(this,SH4_TIMESLICE/2);
|
|
|
|
|
AnalyseBlock(this);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-08 16:59:20 +00:00
|
|
|
|
DynarecCodeEntryPtr rdv_CompilePC()
|
2013-12-19 17:10:14 +00:00
|
|
|
|
{
|
|
|
|
|
u32 pc=next_pc;
|
|
|
|
|
|
2015-02-25 18:30:08 +00:00
|
|
|
|
if (emit_FreeSpace()<16*1024 || pc==0x8c0000e0 || pc==0xac010000 || pc==0xac008300)
|
2013-12-19 17:10:14 +00:00
|
|
|
|
recSh4_ClearCache();
|
|
|
|
|
|
|
|
|
|
RuntimeBlockInfo* rv=0;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
RuntimeBlockInfo* rbi = ngen_AllocateBlock();
|
|
|
|
|
if (rv==0) rv=rbi;
|
|
|
|
|
|
|
|
|
|
rbi->Setup(pc,fpscr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool do_opts=((rbi->addr&0x3FFFFFFF)>0x0C010100);
|
|
|
|
|
rbi->staging_runs=do_opts?100:-100;
|
|
|
|
|
ngen_Compile(rbi,DoCheck(rbi->addr),(pc&0xFFFFFF)==0x08300 || (pc&0xFFFFFF)==0x10000,false,do_opts);
|
|
|
|
|
verify(rbi->code!=0);
|
|
|
|
|
|
|
|
|
|
bm_AddBlock(rbi);
|
|
|
|
|
|
|
|
|
|
if (rbi->BlockType==BET_Cond_0 || rbi->BlockType==BET_Cond_1)
|
|
|
|
|
pc=rbi->NextBlock;
|
|
|
|
|
else
|
|
|
|
|
pc=0;
|
|
|
|
|
} while(false && pc);
|
|
|
|
|
|
|
|
|
|
return rv->code;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-08 16:59:20 +00:00
|
|
|
|
DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc)
|
2013-12-19 17:10:14 +00:00
|
|
|
|
{
|
|
|
|
|
//printf("rdv_FailedToFindBlock ~ %08X\n",pc);
|
|
|
|
|
next_pc=pc;
|
|
|
|
|
|
|
|
|
|
return rdv_CompilePC();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern u32 rebuild_counter;
|
|
|
|
|
|
2015-07-13 21:56:42 +00:00
|
|
|
|
|
|
|
|
|
u32 DYNACALL rdv_DoInterrupts_pc(u32 pc) {
|
|
|
|
|
next_pc = pc;
|
2013-12-19 17:10:14 +00:00
|
|
|
|
UpdateINTC();
|
|
|
|
|
|
|
|
|
|
//We can only safely relocate/etc stuff here, as in other generic update cases
|
|
|
|
|
//There's a RET, meaning the code can't move around
|
|
|
|
|
//Interrupts happen at least 50 times/second, so its not a problem ..
|
2015-07-13 21:56:42 +00:00
|
|
|
|
if (rebuild_counter == 0)
|
2013-12-19 17:10:14 +00:00
|
|
|
|
{
|
2013-12-24 00:56:44 +00:00
|
|
|
|
// TODO: Why is this commented, etc.
|
|
|
|
|
//bm_Rebuild();
|
2013-12-19 17:10:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return next_pc;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-13 21:56:42 +00:00
|
|
|
|
void bm_Rebuild();
|
|
|
|
|
u32 DYNACALL rdv_DoInterrupts(void* block_cpde)
|
|
|
|
|
{
|
|
|
|
|
RuntimeBlockInfo* rbi = bm_GetBlock(block_cpde);
|
|
|
|
|
return rdv_DoInterrupts_pc(rbi->addr);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-08 16:59:20 +00:00
|
|
|
|
DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc)
|
2013-12-19 17:10:14 +00:00
|
|
|
|
{
|
|
|
|
|
next_pc=pc;
|
|
|
|
|
recSh4_ClearCache();
|
|
|
|
|
return rdv_CompilePC();
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-08 16:59:20 +00:00
|
|
|
|
DynarecCodeEntryPtr rdv_FindCode()
|
2013-12-19 17:10:14 +00:00
|
|
|
|
{
|
2015-05-08 16:59:20 +00:00
|
|
|
|
DynarecCodeEntryPtr rv=bm_GetCode(next_pc);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
if (rv==ngen_FailedToFindBlock)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-08 16:59:20 +00:00
|
|
|
|
DynarecCodeEntryPtr rdv_FindOrCompile()
|
2013-12-19 17:10:14 +00:00
|
|
|
|
{
|
2015-05-08 16:59:20 +00:00
|
|
|
|
DynarecCodeEntryPtr rv=bm_GetCode(next_pc);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
if (rv==ngen_FailedToFindBlock)
|
|
|
|
|
rv=rdv_CompilePC();
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* DYNACALL rdv_LinkBlock(u8* code,u32 dpc)
|
|
|
|
|
{
|
|
|
|
|
RuntimeBlockInfo* rbi=bm_GetBlock(code);
|
|
|
|
|
|
|
|
|
|
if (!rbi)
|
|
|
|
|
{
|
|
|
|
|
printf("Stale block ..");
|
|
|
|
|
rbi=bm_GetStaleBlock(code);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-31 18:37:39 +00:00
|
|
|
|
verify(rbi != NULL);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
u32 bcls=BET_GET_CLS(rbi->BlockType);
|
|
|
|
|
|
|
|
|
|
if (bcls==BET_CLS_Static)
|
|
|
|
|
{
|
|
|
|
|
next_pc=rbi->BranchBlock;
|
|
|
|
|
}
|
|
|
|
|
else if (bcls==BET_CLS_Dynamic)
|
|
|
|
|
{
|
|
|
|
|
next_pc=dpc;
|
|
|
|
|
}
|
|
|
|
|
else if (bcls==BET_CLS_COND)
|
|
|
|
|
{
|
|
|
|
|
if (dpc)
|
|
|
|
|
next_pc=rbi->BranchBlock;
|
|
|
|
|
else
|
|
|
|
|
next_pc=rbi->NextBlock;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-08 16:59:20 +00:00
|
|
|
|
DynarecCodeEntryPtr rv=rdv_FindOrCompile();
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
bool do_link=bm_GetBlock(code)==rbi;
|
|
|
|
|
|
|
|
|
|
if (do_link)
|
|
|
|
|
{
|
|
|
|
|
if (bcls==BET_CLS_Dynamic)
|
|
|
|
|
{
|
|
|
|
|
verify(rbi->relink_data==0 || rbi->pBranchBlock==0);
|
|
|
|
|
|
|
|
|
|
if (rbi->pBranchBlock!=0)
|
|
|
|
|
{
|
|
|
|
|
rbi->pBranchBlock->RemRef(rbi);
|
|
|
|
|
rbi->pBranchBlock=0;
|
|
|
|
|
rbi->relink_data=1;
|
|
|
|
|
}
|
|
|
|
|
else if (rbi->relink_data==0)
|
|
|
|
|
{
|
|
|
|
|
rbi->pBranchBlock=bm_GetBlock(next_pc);
|
|
|
|
|
rbi->pBranchBlock->AddRef(rbi);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
RuntimeBlockInfo* nxt=bm_GetBlock(next_pc);
|
|
|
|
|
|
|
|
|
|
if (rbi->BranchBlock==next_pc)
|
|
|
|
|
rbi->pBranchBlock=nxt;
|
|
|
|
|
if (rbi->NextBlock==next_pc)
|
|
|
|
|
rbi->pNextBlock=nxt;
|
|
|
|
|
|
|
|
|
|
nxt->AddRef(rbi);
|
|
|
|
|
}
|
|
|
|
|
u32 ncs=rbi->relink_offset+rbi->Relink();
|
|
|
|
|
verify(rbi->host_code_size>=ncs);
|
|
|
|
|
rbi->host_code_size=ncs;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf(" .. null RBI: %08X -- unlinked stale block\n",next_pc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (void*)rv;
|
|
|
|
|
}
|
|
|
|
|
void recSh4_Stop()
|
|
|
|
|
{
|
|
|
|
|
Sh4_int_Stop();
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-02 13:49:23 +00:00
|
|
|
|
void recSh4_Start()
|
|
|
|
|
{
|
|
|
|
|
Sh4_int_Start();
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
|
void recSh4_Step()
|
|
|
|
|
{
|
|
|
|
|
Sh4_int_Step();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void recSh4_Skip()
|
|
|
|
|
{
|
|
|
|
|
Sh4_int_Skip();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void recSh4_Reset(bool Manual)
|
|
|
|
|
{
|
|
|
|
|
Sh4_int_Reset(Manual);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-16 05:12:19 +00:00
|
|
|
|
#if HOST_OS == OS_DARWIN
|
Partially working dyna for iOS. Very few games working atm.
This works, but is extremelly hacky. Must be started without attached debugger, lldb doesn't want to let go of EXC_BAD_ADDRESS, but reicast really depends on it getting delivered as SIGSEGV/SIGBUS. Also xcode has a really bad day upon seeing the jit code. Oh well.
There's some dynarec bug that causes color corruption on bios logo/boot triagles, TA crash on ikaruga and infinitive loop on crazy taxi. I'd guess some fp-memory-write thingy, abi, or smth. Too bad.
- Force code to compile in arm mode (arm jit -> thumb mem functions is complicated)
- SIGILL, SIGBUS. Works w/o Mach exceptions and EXC_BAD_ADDRESS
- Code buffers move to __TEXT, munmapped && memmapped to actually work
- Primitive input. Button + start, or left (works to get out of bios date screen)
- Fixup emitter for thumb2/interworking (didn't work though, reverted to arm cc)
- Block Manager: Disable mem saving / page fault alloc-on-demand logic
- Move cycle counter to r11, r9 is not clean on iOS. Remove r11 from reg alloc list
- Cache flushes for iOS
- log to log.txt
- load game.chd
2015-01-19 07:52:12 +00:00
|
|
|
|
#include <sys/mman.h>
|
2015-05-16 05:12:19 +00:00
|
|
|
|
#endif
|
Partially working dyna for iOS. Very few games working atm.
This works, but is extremelly hacky. Must be started without attached debugger, lldb doesn't want to let go of EXC_BAD_ADDRESS, but reicast really depends on it getting delivered as SIGSEGV/SIGBUS. Also xcode has a really bad day upon seeing the jit code. Oh well.
There's some dynarec bug that causes color corruption on bios logo/boot triagles, TA crash on ikaruga and infinitive loop on crazy taxi. I'd guess some fp-memory-write thingy, abi, or smth. Too bad.
- Force code to compile in arm mode (arm jit -> thumb mem functions is complicated)
- SIGILL, SIGBUS. Works w/o Mach exceptions and EXC_BAD_ADDRESS
- Code buffers move to __TEXT, munmapped && memmapped to actually work
- Primitive input. Button + start, or left (works to get out of bios date screen)
- Fixup emitter for thumb2/interworking (didn't work though, reverted to arm cc)
- Block Manager: Disable mem saving / page fault alloc-on-demand logic
- Move cycle counter to r11, r9 is not clean on iOS. Remove r11 from reg alloc list
- Cache flushes for iOS
- log to log.txt
- load game.chd
2015-01-19 07:52:12 +00:00
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
|
void recSh4_Init()
|
|
|
|
|
{
|
|
|
|
|
printf("recSh4 Init\n");
|
|
|
|
|
Sh4_int_Init();
|
|
|
|
|
bm_Init();
|
|
|
|
|
bm_Reset();
|
|
|
|
|
|
2015-08-11 17:07:23 +00:00
|
|
|
|
verify(rcb_noffs(p_sh4rcb->fpcb) == FPCB_OFFSET);
|
2015-07-13 21:56:42 +00:00
|
|
|
|
|
|
|
|
|
verify(rcb_noffs(p_sh4rcb->sq_buffer) == -512);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
2015-07-13 21:56:42 +00:00
|
|
|
|
verify(rcb_noffs(&p_sh4rcb->cntx.sh4_sched_next) == -152);
|
|
|
|
|
verify(rcb_noffs(&p_sh4rcb->cntx.interrupt_pend) == -148);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
2015-08-11 22:58:50 +00:00
|
|
|
|
if (_nvmem_enabled()) {
|
|
|
|
|
verify(mem_b.data==((u8*)p_sh4rcb->sq_buffer+512+0x0C000000));
|
|
|
|
|
}
|
2015-07-28 15:28:53 +00:00
|
|
|
|
|
2015-08-07 13:54:51 +00:00
|
|
|
|
#if defined(_WIN64)
|
2018-09-25 12:09:07 +00:00
|
|
|
|
#ifdef _MSC_VER
|
2015-08-07 13:54:51 +00:00
|
|
|
|
for (int i = 10; i < 1300; i++) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//align to next page ..
|
|
|
|
|
u8* ptr = (u8*)recSh4_Init - i * 1024 * 1024;
|
|
|
|
|
|
|
|
|
|
CodeCache = (u8*)VirtualAlloc(ptr, CODE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);//; (u8*)(((unat)SH4_TCB+4095)& ~4095);
|
|
|
|
|
|
|
|
|
|
if (CodeCache)
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-09-25 10:27:37 +00:00
|
|
|
|
#else
|
|
|
|
|
CodeCache = (u8*)VirtualAlloc(NULL, CODE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
|
|
|
#endif
|
|
|
|
|
verify(CodeCache != NULL);
|
2015-08-07 13:54:51 +00:00
|
|
|
|
#else
|
|
|
|
|
CodeCache = (u8*)(((unat)SH4_TCB+4095)& ~4095);
|
|
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
2015-05-16 05:12:19 +00:00
|
|
|
|
#if HOST_OS == OS_DARWIN
|
2015-08-07 13:54:51 +00:00
|
|
|
|
munmap(CodeCache, CODE_SIZE);
|
|
|
|
|
CodeCache = (u8*)mmap(CodeCache, CODE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0);
|
2015-05-16 05:12:19 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
|
#if HOST_OS == OS_WINDOWS
|
|
|
|
|
DWORD old;
|
2015-08-07 13:54:51 +00:00
|
|
|
|
VirtualProtect(CodeCache,CODE_SIZE,PAGE_EXECUTE_READWRITE,&old);
|
Partially working dyna for iOS. Very few games working atm.
This works, but is extremelly hacky. Must be started without attached debugger, lldb doesn't want to let go of EXC_BAD_ADDRESS, but reicast really depends on it getting delivered as SIGSEGV/SIGBUS. Also xcode has a really bad day upon seeing the jit code. Oh well.
There's some dynarec bug that causes color corruption on bios logo/boot triagles, TA crash on ikaruga and infinitive loop on crazy taxi. I'd guess some fp-memory-write thingy, abi, or smth. Too bad.
- Force code to compile in arm mode (arm jit -> thumb mem functions is complicated)
- SIGILL, SIGBUS. Works w/o Mach exceptions and EXC_BAD_ADDRESS
- Code buffers move to __TEXT, munmapped && memmapped to actually work
- Primitive input. Button + start, or left (works to get out of bios date screen)
- Fixup emitter for thumb2/interworking (didn't work though, reverted to arm cc)
- Block Manager: Disable mem saving / page fault alloc-on-demand logic
- Move cycle counter to r11, r9 is not clean on iOS. Remove r11 from reg alloc list
- Cache flushes for iOS
- log to log.txt
- load game.chd
2015-01-19 07:52:12 +00:00
|
|
|
|
#elif HOST_OS == OS_LINUX || HOST_OS == OS_DARWIN
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
Partially working dyna for iOS. Very few games working atm.
This works, but is extremelly hacky. Must be started without attached debugger, lldb doesn't want to let go of EXC_BAD_ADDRESS, but reicast really depends on it getting delivered as SIGSEGV/SIGBUS. Also xcode has a really bad day upon seeing the jit code. Oh well.
There's some dynarec bug that causes color corruption on bios logo/boot triagles, TA crash on ikaruga and infinitive loop on crazy taxi. I'd guess some fp-memory-write thingy, abi, or smth. Too bad.
- Force code to compile in arm mode (arm jit -> thumb mem functions is complicated)
- SIGILL, SIGBUS. Works w/o Mach exceptions and EXC_BAD_ADDRESS
- Code buffers move to __TEXT, munmapped && memmapped to actually work
- Primitive input. Button + start, or left (works to get out of bios date screen)
- Fixup emitter for thumb2/interworking (didn't work though, reverted to arm cc)
- Block Manager: Disable mem saving / page fault alloc-on-demand logic
- Move cycle counter to r11, r9 is not clean on iOS. Remove r11 from reg alloc list
- Cache flushes for iOS
- log to log.txt
- load game.chd
2015-01-19 07:52:12 +00:00
|
|
|
|
printf("\n\t CodeCache addr: %p | from: %p | addr here: %p\n", CodeCache, CodeCache, recSh4_Init);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
2015-07-29 02:58:41 +00:00
|
|
|
|
#if FEAT_SHREC == DYNAREC_JIT
|
2015-08-07 13:54:51 +00:00
|
|
|
|
if (mprotect(CodeCache, CODE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC))
|
2015-07-28 15:28:53 +00:00
|
|
|
|
{
|
|
|
|
|
perror("\n\tError,Couldn’t mprotect CodeCache!");
|
|
|
|
|
die("Couldn’t mprotect CodeCache");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
2015-08-19 19:32:07 +00:00
|
|
|
|
#if TARGET_IPHONE
|
|
|
|
|
memset((u8*)mmap(CodeCache, CODE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0),0xFF,CODE_SIZE);
|
|
|
|
|
#else
|
2015-08-07 13:54:51 +00:00
|
|
|
|
memset(CodeCache,0xFF,CODE_SIZE);
|
2015-08-19 19:32:07 +00:00
|
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
ngen_init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void recSh4_Term()
|
|
|
|
|
{
|
|
|
|
|
printf("recSh4 Term\n");
|
|
|
|
|
bm_Term();
|
|
|
|
|
Sh4_int_Term();
|
|
|
|
|
|
|
|
|
|
#if HOST_OS == OS_LINUX
|
|
|
|
|
//hum ?
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool recSh4_IsCpuRunning()
|
|
|
|
|
{
|
|
|
|
|
return Sh4_int_IsCpuRunning();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Get_Sh4Recompiler(sh4_if* rv)
|
|
|
|
|
{
|
2015-07-25 06:39:35 +00:00
|
|
|
|
rv->Run = recSh4_Run;
|
|
|
|
|
rv->Stop = recSh4_Stop;
|
2018-09-02 13:49:23 +00:00
|
|
|
|
rv->Start = recSh4_Start;
|
2015-07-25 06:39:35 +00:00
|
|
|
|
rv->Step = recSh4_Step;
|
|
|
|
|
rv->Skip = recSh4_Skip;
|
|
|
|
|
rv->Reset = recSh4_Reset;
|
|
|
|
|
rv->Init = recSh4_Init;
|
|
|
|
|
rv->Term = recSh4_Term;
|
|
|
|
|
rv->IsCpuRunning = recSh4_IsCpuRunning;
|
2013-12-19 17:10:14 +00:00
|
|
|
|
//rv->GetRegister=Sh4_int_GetRegister;
|
|
|
|
|
//rv->SetRegister=Sh4_int_SetRegister;
|
2015-07-25 06:39:35 +00:00
|
|
|
|
rv->ResetCache = recSh4_ClearCache;
|
2013-12-19 17:10:14 +00:00
|
|
|
|
}
|
2015-07-25 06:39:35 +00:00
|
|
|
|
#endif
|