mirror of
https://github.com/libretro/Mu.git
synced 2026-02-15 21:27:08 +00:00
Add sandbox frame callback, make memory alignment test
This commit is contained in:
14
src/armv5.c
14
src/armv5.c
@@ -19,14 +19,14 @@ static ArmCpu armv5Cpu;
|
||||
|
||||
|
||||
static Boolean armv5MemoryAccess(ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 size, Boolean write, Boolean privileged, UInt8* fsr){
|
||||
//just gonna have ARM and m68k share the same bus for now, ARM may want fonts/bitmaps from ROM
|
||||
//just gonna have ARM and 68k share the same bus for now, ARM may want fonts/bitmaps from ROM
|
||||
|
||||
//Fake ARM 32 bit alignment convention
|
||||
//0x00000000<->0x7FFFFFFF Normal memory access
|
||||
//0x80000000<->0xFFFFFFFF Mirrored range, realAddress = address - 0x80000000 + 0x00000002
|
||||
//0x0XXXXXXX<->0x1XXXXXXX Normal memory access
|
||||
//0x20000000<->0x3XXXXXXX Mirrored range, realAddress = address - 0x20000000 + 0x00000002
|
||||
|
||||
//this will still fail if ARM allocates a 16 bit aligned buffer and passes it to the m68k,
|
||||
//but it allows 16 bit aligned data to be executed from the m68k stack and works as a
|
||||
//but it allows 16 bit aligned data to be executed from the 68k stack and works as a
|
||||
//temporary measure until I get MemChunkNew patched correctly
|
||||
|
||||
//while executing wont support non 32 bit alignment regular accesses can for now
|
||||
@@ -40,8 +40,8 @@ static Boolean armv5MemoryAccess(ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 siz
|
||||
#endif
|
||||
*/
|
||||
|
||||
if(vaddr & 0x80000000)
|
||||
vaddr ^= 0x80000002;
|
||||
if(vaddr & 0x20000000)
|
||||
vaddr ^= 0x20000002;
|
||||
|
||||
if(write){
|
||||
switch(size){
|
||||
@@ -97,7 +97,7 @@ static void armv5SetFaultAddr(struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus)
|
||||
}
|
||||
|
||||
void armv5Reset(void){
|
||||
cpuInit(&armv5Cpu, 0x00000000/*PC, set by m68k while emulating*/, armv5MemoryAccess, armv5EmulErr, armv5Hypercall, armv5SetFaultAddr);
|
||||
cpuInit(&armv5Cpu, 0x00000000/*PC, set by 68k while emulating*/, armv5MemoryAccess, armv5EmulErr, armv5Hypercall, armv5SetFaultAddr);
|
||||
armv5ServiceRequest = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
#if defined(EMU_DEBUG) && defined(EMU_SANDBOX)
|
||||
//this wrappers m68k code and allows calling it for tests, this should be useful for determining if hardware accesses are correct
|
||||
//this wrappers 68k code and allows calling it for tests, this should be useful for determining if hardware accesses are correct
|
||||
//Note: when running a test the emulator runs at native speed and no clocks are emulated
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -25,6 +25,8 @@
|
||||
#define SANDBOX_MAX_UNLOGGED_JUMP_SIZE 0xFFFFFFFF
|
||||
#define SANDBOX_MAX_WATCH_REGIONS 1000
|
||||
|
||||
#define SANDBOX_SECONDS_TO_FRAMES(x) ((x) * EMU_FPS)
|
||||
|
||||
|
||||
typedef struct{
|
||||
void* hostPointer;
|
||||
@@ -51,7 +53,8 @@ static bool sandboxActive;//used to "log out" of the emulator once
|
||||
static bool sandboxControlHandoff;//used for functions that depend on timing, hands full control to the m68k
|
||||
static uint8_t sandboxCurrentCpuArch;
|
||||
static local_cpu_state_t sandboxOldFunctionCpuState;
|
||||
static mem_region_t sandboxWatchRegions[SANDBOX_MAX_WATCH_REGIONS];//code locations in m68k address space to be sandboxed
|
||||
static uint64_t sandboxFramesRan;
|
||||
static mem_region_t sandboxWatchRegions[SANDBOX_MAX_WATCH_REGIONS];//code locations in 68k address space to be sandboxed
|
||||
static uint16_t sandboxWatchRegionsActive;//number of used sandboxWatchRegions entrys
|
||||
|
||||
|
||||
@@ -69,6 +72,17 @@ static uint32_t getCurrentCpuPreviousPc(void){
|
||||
return sandboxCurrentCpuArch == SANDBOX_CPU_ARCH_M68K ? m68k_get_reg(NULL, M68K_REG_PPC) : armv5GetRegister(15) & 0xFFFFFFFE;
|
||||
}
|
||||
|
||||
uint32_t getRandomRange(uint32_t start, uint32_t end){
|
||||
static bool seeded = false;
|
||||
|
||||
if(!seeded){
|
||||
srand(time(NULL));
|
||||
seeded = true;
|
||||
}
|
||||
|
||||
return (uint32_t)rand() % (end + 1 - start) + start;
|
||||
}
|
||||
|
||||
static char* takeStackDump(uint32_t bytes){
|
||||
char* textBytes = malloc(bytes * 2);
|
||||
uint32_t textBytesOffset = 0;
|
||||
@@ -166,6 +180,8 @@ bool validExecutionAddress(uint32_t address){
|
||||
return true;
|
||||
if(address >= chips[CHIP_DX_RAM].start && address < chips[CHIP_DX_RAM].start + chips[CHIP_DX_RAM].lineSize)
|
||||
return true;
|
||||
if(sandboxActive && address >= 0xFFFFFE00)//used to run custom code when in sandbox mode
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -401,6 +417,72 @@ static bool installResourceToDevice(buffer_t resourceBuffer){
|
||||
return true;
|
||||
}
|
||||
|
||||
static void checkMemoryAlignment(uint16_t heap){
|
||||
uint32_t memPtrs[100];
|
||||
uint8_t index;
|
||||
uint16_t error;
|
||||
|
||||
memset(memPtrs, 0x00, sizeof(memPtrs));
|
||||
|
||||
//get randomly sized memory regions
|
||||
for(index = 0; index < 100; index++){
|
||||
memPtrs[index] = sandboxCallGuestFunction(false, 0x00000000, MemChunkNew, "p(wlw)", heap, getRandomRange(1, 100), 0x0200/*memNewChunkFlagNonMovable*/);
|
||||
if(!memPtrs[index]){
|
||||
debugLog("Memory test: Failed to allocate memory\n");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
//check alignment
|
||||
for(index = 0; index < 100; index++){
|
||||
if(memPtrs[index] & 0x00000003){
|
||||
debugLog("Memory test: Memory allocations are not 32 bit aligned:0x%08X\n", memPtrs[index]);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
//resize memory
|
||||
for(index = 0; index < 100; index++){
|
||||
error = sandboxCallGuestFunction(false, 0x00000000, MemPtrResize, "w(pl)", memPtrs[index], getRandomRange(1, 100));
|
||||
if(error != 0x0000/*errNone*/){
|
||||
debugLog("Memory test: Failed to resize memory:0x%04X\n", error);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
//check alignment again
|
||||
for(index = 0; index < 100; index++){
|
||||
if(memPtrs[index] & 0x00000003){
|
||||
debugLog("Memory test: Memory misaligned by resize:0x%08X\n", memPtrs[index]);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
//shuffle memory
|
||||
error = sandboxCallGuestFunction(false, 0x00000000, MemHeapScramble, "w(w)", heap);
|
||||
if(error != 0x0000/*errNone*/){
|
||||
debugLog("Memory test: Unable to scramble heap:0x%04X\n", error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
//check alignment again
|
||||
for(index = 0; index < 100; index++){
|
||||
if(memPtrs[index] & 0x00000003){
|
||||
debugLog("Memory test: Memory misaligned by defragment:0x%08X\n", memPtrs[index]);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
debugLog("Memory test: Memory aligned correctly\n");
|
||||
|
||||
failed:
|
||||
|
||||
//free pointers
|
||||
for(index = 0; index < 100; index++)
|
||||
if(memPtrs[index])
|
||||
sandboxCallGuestFunction(false, 0x00000000, MemChunkFree, "w(p)", memPtrs[index]);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t sandboxGetStackFrameSize(const char* prototype){
|
||||
const char* params = prototype + 2;
|
||||
@@ -607,28 +689,17 @@ void sandboxInit(void){
|
||||
void sandboxReset(void){
|
||||
sandboxActive = false;
|
||||
sandboxControlHandoff = false;
|
||||
sandboxFramesRan = 0;
|
||||
|
||||
memset(sandboxWatchRegions, 0x00, sizeof(sandboxWatchRegions));
|
||||
sandboxWatchRegionsActive = 0;
|
||||
|
||||
//patch OS here if needed
|
||||
//debug patches
|
||||
//sandboxCommand(SANDBOX_PATCH_OS, NULL);
|
||||
|
||||
//add memory region monitors
|
||||
/*
|
||||
if(pc >= 0x100A07DC && pc <= 0x100ADB3C){
|
||||
//the SD slot driver
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
sandboxCommand(SANDBOX_CMD_PATCH_OS, NULL);
|
||||
|
||||
//log all register accesses
|
||||
//sandboxCommand(SANDBOX_CMD_REGISTER_WATCH_ENABLE, NULL);
|
||||
|
||||
//patch OS
|
||||
sandboxCommand(SANDBOX_CMD_PATCH_OS, NULL);
|
||||
|
||||
//monitor for strange jumps
|
||||
sandboxSetWatchRegion(0x00000000, 0xFFFFFFFE, SANDBOX_WATCH_CODE);
|
||||
}
|
||||
@@ -639,6 +710,7 @@ uint32_t sandboxStateSize(void){
|
||||
size += sizeof(uint8_t) * 3;//sandboxActive / sandboxControlHandoff / sandboxCurrentCpuArch
|
||||
size += sizeof(uint32_t) * 4;//sandboxOldFunctionCpuState.(sp/pc/a0/d0)
|
||||
size += sizeof(uint16_t);//sandboxOldFunctionCpuState.sr
|
||||
size += sizeof(uint64_t);//sandboxFramesRan
|
||||
size += sizeof(uint32_t) * 2 * SANDBOX_MAX_WATCH_REGIONS;//sandboxWatchRegions.(address/size)
|
||||
size += sizeof(uint8_t) * SANDBOX_MAX_WATCH_REGIONS;//sandboxWatchRegions.type
|
||||
size += sizeof(uint16_t);//sandboxWatchRegionsActive
|
||||
@@ -666,6 +738,8 @@ void sandboxSaveState(uint8_t* data){
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValue32(data + offset, sandboxOldFunctionCpuState.d0);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValue64(data + offset, sandboxFramesRan);
|
||||
offset += sizeof(uint64_t);
|
||||
for(index = 0; index < SANDBOX_MAX_WATCH_REGIONS; index++){
|
||||
writeStateValue32(data + offset, sandboxWatchRegions[index].address);
|
||||
offset += sizeof(uint32_t);
|
||||
@@ -698,6 +772,8 @@ void sandboxLoadState(uint8_t* data){
|
||||
offset += sizeof(uint32_t);
|
||||
sandboxOldFunctionCpuState.d0 = readStateValue32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
sandboxFramesRan = readStateValue64(data + offset);
|
||||
offset += sizeof(uint64_t);
|
||||
for(index = 0; index < SANDBOX_MAX_WATCH_REGIONS; index++){
|
||||
sandboxWatchRegions[index].address = readStateValue32(data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
@@ -721,20 +797,6 @@ uint32_t sandboxCommand(uint32_t command, void* data){
|
||||
|
||||
switch(command){
|
||||
case SANDBOX_CMD_PATCH_OS:{
|
||||
//this will not be in the v1.0 release
|
||||
//remove parts of the OS that cause lockups, yeah its bad
|
||||
|
||||
//remove ErrDisplayFileLineMsg from HwrIRQ2Handler, device locks on USB polling without this
|
||||
//this is fixed, leaving it here for reference
|
||||
//patchOsRom(0x83652, "4E714E71");//nop; nop
|
||||
|
||||
//make SysSetTrapAddress/SysGetTrapAddress support traps > ScrDefaultPaletteState 0xA459
|
||||
//up to final OS 5.3 trap DmSyncDatabase 0xA476
|
||||
//SysSetTrapAddress_1001AE36:
|
||||
//SysGetTrapAddress_1001AE7C:
|
||||
//patchOsRom(0x1AE42, "0C410477");//cmpi.w 0x477, d1
|
||||
//patchOsRom(0x1AE8A, "0C42A477");//cmpi.w 0xA477, d2
|
||||
|
||||
//double dynamic heap size, verified working
|
||||
//HwrCalcDynamicRAMSize_10005CC6:
|
||||
//HwrCalcDynamicRAMSize_10083B0A:
|
||||
@@ -881,6 +943,12 @@ uint32_t sandboxCommand(uint32_t command, void* data){
|
||||
}
|
||||
break;
|
||||
|
||||
case SANDBOX_CMD_TEST_MEMORY_ALIGNMENT:{
|
||||
checkMemoryAlignment(0);//RAM heap
|
||||
checkMemoryAlignment(1);//storage heap
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -890,6 +958,15 @@ uint32_t sandboxCommand(uint32_t command, void* data){
|
||||
return result;
|
||||
}
|
||||
|
||||
void sandboxOnFrameRun(void){
|
||||
//run at the end of every frame
|
||||
sandboxFramesRan++;
|
||||
|
||||
if(sandboxFramesRan == SANDBOX_SECONDS_TO_FRAMES(10)){
|
||||
sandboxCommand(SANDBOX_CMD_TEST_MEMORY_ALIGNMENT, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void sandboxOnOpcodeRun(void){
|
||||
if(sandboxRunning()){
|
||||
#if defined(EMU_SANDBOX_LOG_JUMPS)
|
||||
@@ -1135,6 +1212,7 @@ uint32_t sandboxStateSize(void){return 0;}
|
||||
void sandboxSaveState(uint8_t* data){}
|
||||
void sandboxLoadState(uint8_t* data){}
|
||||
uint32_t sandboxCommand(uint32_t command, void* data){return 0;}
|
||||
void sandboxOnFrameRun(void){}
|
||||
void sandboxOnOpcodeRun(void){}
|
||||
void sandboxOnMemoryAccess(uint32_t address, uint8_t size, bool write, uint32_t value){}
|
||||
bool sandboxRunning(void){return false;}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
enum{
|
||||
SANDBOX_CMD_PATCH_OS = 0,
|
||||
SANDBOX_CMD_DEBUG_INSTALL_APP,
|
||||
SANDBOX_CMD_REGISTER_WATCH_ENABLE
|
||||
SANDBOX_CMD_REGISTER_WATCH_ENABLE,
|
||||
SANDBOX_CMD_TEST_MEMORY_ALIGNMENT
|
||||
};
|
||||
|
||||
enum{
|
||||
@@ -29,10 +30,11 @@ uint32_t sandboxStateSize(void);
|
||||
void sandboxSaveState(uint8_t* data);
|
||||
void sandboxLoadState(uint8_t* data);
|
||||
uint32_t sandboxCommand(uint32_t command, void* data);
|
||||
void sandboxOnFrameRun(void);
|
||||
void sandboxOnOpcodeRun(void);
|
||||
void sandboxOnMemoryAccess(uint32_t address, uint8_t size, bool write, uint32_t value);
|
||||
bool sandboxRunning(void);
|
||||
void sandboxReturn(void);//should only be called called by m68k code
|
||||
void sandboxReturn(void);//should only be called called by 68k code
|
||||
uint16_t sandboxSetWatchRegion(uint32_t address, uint32_t size, uint8_t type);
|
||||
void sandboxClearWatchRegion(uint16_t index);
|
||||
void sandboxSetCpuArch(uint8_t arch);
|
||||
|
||||
@@ -733,4 +733,8 @@ void emulatorRunFrame(void){
|
||||
memcpy(palmFramebuffer, sed1376Framebuffer, 160 * 160 * sizeof(uint16_t));
|
||||
memcpy(palmFramebuffer + 160 * 160, silkscreen160x60, 160 * 60 * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
#if defined(EMU_SANDBOX)
|
||||
sandboxOnFrameRun();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ void flx68000PcLongJump(uint32_t newPc){
|
||||
memBase = dataBufferHost - dataBufferGuest - windowSize * ((newPc - dataBufferGuest) / windowSize);
|
||||
}
|
||||
|
||||
//everything must be 16 bit aligned(accept 8 bit accesses) due to m68k unaligned access rules,
|
||||
//everything must be 16 bit aligned(accept 8 bit accesses) due to 68k unaligned access rules,
|
||||
//32 bit reads are 2 16 bit reads because on some platforms 32 bit reads that arnt on 32 bit boundrys will crash the program
|
||||
#if defined(EMU_BIG_ENDIAN)
|
||||
uint16_t m68k_read_immediate_16(uint32_t address){
|
||||
@@ -279,7 +279,7 @@ bool flx68000IsSupervisor(void){
|
||||
void flx68000BusError(uint32_t address, bool isWrite){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
if(!(palmEmuFeatures.info & FEATURE_DURABLE)){
|
||||
//never call outsize of a m68k opcode, behavior is undefined due to longjmp
|
||||
//never call outsize of a 68k opcode, behavior is undefined due to longjmp
|
||||
m68ki_trigger_bus_error(address, isWrite ? MODE_WRITE : MODE_READ, FLAG_S | m68ki_get_address_space());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -53,7 +53,7 @@ These registers will do nothing if their corresponding feature bit is not set on
|
||||
#define CMD_DEBUG_WATCH 0x0000FFF9/*EMU_VALUE = 0/clear watch reference or 1/make code watch reference or 2/make data watch reference, EMU_SRC = address of area(or watch area reference number), EMU_SIZE = size of area(unused if clear operation), EMU_VALUE is set to the watch areas reference number after a set operation*/
|
||||
#define CMD_SOUND 0x0000FFFA/*needed for OS 5 advanced sound*/
|
||||
#define CMD_DEBUG_EXEC_END 0x0000FFFB/*terminates execution, used when a function is called from outside the emulator*/
|
||||
#define CMD_ARM_SERVICE 0x0000FFFC/*EMU_VALUE is set to 1 if ARM wants service from m68k routines*/
|
||||
#define CMD_ARM_SERVICE 0x0000FFFC/*EMU_VALUE is set to 1 if ARM wants service from 68k routines*/
|
||||
#define CMD_ARM_SET_REG 0x0000FFFD/*EMU_DST = register number, EMU_VALUE = new value*/
|
||||
#define CMD_ARM_GET_REG 0x0000FFFE/*EMU_SRC = register number, EMU_VALUE is set to register value*/
|
||||
#define CMD_ARM_RUN 0x0000FFFF/*EMU_VALUE = cycles, EMU_VALUE is set to cycles not used on return, 0 if all are used*/
|
||||
|
||||
@@ -17,9 +17,16 @@ void armv5SetStack(uint8_t* location, uint32_t size){
|
||||
}
|
||||
|
||||
uint32_t* armv5ValidatePointer(uint32_t* address){
|
||||
/*patches 16 bit alignment to 32 bit alignment using a special memory range*/
|
||||
/*patches 16 bit alignment to 32 bit alignment using a special address bit*/
|
||||
if((uint32_t)address & 0x00000002)
|
||||
return (uint32_t*)((uint32_t)address ^ 0x80000002);
|
||||
return (uint32_t*)((uint32_t)address ^ 0x20000002);
|
||||
return address;
|
||||
}
|
||||
|
||||
uint32_t* armv5InvalidatePointer(uint32_t* address){
|
||||
/*puts address bits back to normal*/
|
||||
if((uint32_t)address & 0x20000000)
|
||||
return (uint32_t*)((uint32_t)address ^ 0x20000002);
|
||||
return address;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
void armv5SetStack(uint8_t* location, uint32_t size);
|
||||
uint32_t* armv5ValidatePointer(uint32_t* address);
|
||||
uint32_t* armv5InvalidatePointer(uint32_t* address);
|
||||
void armv5StackPush(uint32_t value);
|
||||
uint32_t armv5StackPop(void);
|
||||
void armv5SetRegister(uint8_t reg, uint32_t value);
|
||||
|
||||
@@ -12,20 +12,35 @@
|
||||
/*cant use normal global variables in this file!!!*/
|
||||
/*functions in this file are called directly by the Palm OS trap dispatch, this means they can be called when the app isnt loaded and the globals are just a random data buffer*/
|
||||
|
||||
#if 0
|
||||
static const SECTION(".text") ALIGN(2) uint32_t armExitFunc[] = {0x0000A0E3, 0xBBBBBBF7};/*ARM asm blob*/
|
||||
static const SECTION(".text") ALIGN(2) uint32_t armCall68kFunc[] = {0x0100A0E3, 0xBBBBBBF7, 0x0EF0A0E1};/*ARM asm blob*/
|
||||
static const SECTION(".text") ALIGN(2) uint8_t m68kCallWithBlobFunc[] = {
|
||||
0x4E, 0x56, 0x00, 0x00, 0x48, 0xE7, 0x60, 0x70, 0x26, 0x6E, 0x00, 0x08,
|
||||
0x22, 0x6E, 0x00, 0x0C, 0x22, 0x2E, 0x00, 0x10, 0x34, 0x2E, 0x00, 0x14,
|
||||
0x24, 0x4F, 0x95, 0xC1, 0xBF, 0xCA, 0x67, 0x00, 0x00, 0x0A, 0x34, 0x91,
|
||||
0x54, 0x89, 0x54, 0x8A, 0x60, 0xF2, 0x9F, 0xC1, 0x4E, 0x93, 0xDF, 0xC1,
|
||||
0x4A, 0x42, 0x67, 0x00, 0x00, 0x04, 0x20, 0x08, 0x4C, 0xDF, 0x0E, 0x06,
|
||||
0x4E, 0x5E, 0x4E, 0x75
|
||||
|
||||
};/*68k asm blob*/
|
||||
#endif
|
||||
|
||||
UInt32 emuPceNativeCall(NativeFuncType* nativeFuncP, void* userDataP){
|
||||
/*these arnt set as "static" because the globals dont work here*/
|
||||
#if 1
|
||||
const ALIGN(2) uint32_t armExitFunc[] = {0x0000A0E3, 0xBBBBBBF7};/*ARM asm blob*/
|
||||
const ALIGN(2) uint32_t armCall68kFunc[] = {0x0100A0E3, 0xBBBBBBF7, 0x0EF0A0E1};/*ARM asm blob*/
|
||||
const ALIGN(2) uint8_t m68kCallWithBlobFunc[] = {
|
||||
0x4e, 0x56, 0x00, 0x00, 0x48, 0xe7, 0x60, 0x70, 0x26, 0x6e, 0x00, 0x08,
|
||||
0x22, 0x6e, 0x00, 0x0c, 0x22, 0x2e, 0x00, 0x10, 0x34, 0x2e, 0x00, 0x14,
|
||||
0x24, 0x4f, 0x95, 0xc1, 0xbf, 0xca, 0x67, 0x00, 0x00, 0x0a, 0x34, 0x91,
|
||||
0x54, 0x89, 0x54, 0x8a, 0x60, 0xf2, 0x9f, 0xc1, 0x4e, 0x93, 0xdf, 0xc1,
|
||||
0x4a, 0x42, 0x67, 0x00, 0x00, 0x04, 0x20, 0x08, 0x4c, 0xdf, 0x0e, 0x06,
|
||||
0x4e, 0x5e, 0x4e, 0x75
|
||||
0x4E, 0x56, 0x00, 0x00, 0x48, 0xE7, 0x60, 0x70, 0x26, 0x6E, 0x00, 0x08,
|
||||
0x22, 0x6E, 0x00, 0x0C, 0x22, 0x2E, 0x00, 0x10, 0x34, 0x2E, 0x00, 0x14,
|
||||
0x24, 0x4F, 0x95, 0xC1, 0xBF, 0xCA, 0x67, 0x00, 0x00, 0x0A, 0x34, 0x91,
|
||||
0x54, 0x89, 0x54, 0x8A, 0x60, 0xF2, 0x9F, 0xC1, 0x4E, 0x93, 0xDF, 0xC1,
|
||||
0x4A, 0x42, 0x67, 0x00, 0x00, 0x04, 0x20, 0x08, 0x4C, 0xDF, 0x0E, 0x06,
|
||||
0x4E, 0x5E, 0x4E, 0x75
|
||||
|
||||
};/*m68k asm blob*/
|
||||
};/*68k asm blob*/
|
||||
#endif
|
||||
uint32_t oldArmRegisters[5];
|
||||
uint32_t returnValue;
|
||||
|
||||
@@ -40,11 +55,11 @@ UInt32 emuPceNativeCall(NativeFuncType* nativeFuncP, void* userDataP){
|
||||
/*when R0 = 1, R1 = function to execute, R2 = stack blob, R3 = stack blob size and want A0*/
|
||||
|
||||
/*Fake ARM 32 bit alignment convention*/
|
||||
/*0x00000000<->0x7FFFFFFF Normal memory access*/
|
||||
/*0x80000000<->0xFFFFFFFF Mirrored range, realAddress = address - 0x80000000 + 0x00000002*/
|
||||
/*0x0XXXXXXX<->0x1XXXXXXX Normal memory access*/
|
||||
/*0x20000000<->0x3XXXXXXX Mirrored range, realAddress = address - 0x20000000 + 0x00000002*/
|
||||
|
||||
/*this will still fail if ARM allocates a 16 bit aligned buffer and passes it to the m68k,*/
|
||||
/*but it allows 16 bit aligned data to be executed from the m68k stack and works as a*/
|
||||
/*this will still fail if ARM allocates a 16 bit aligned buffer and passes it to the 68k,*/
|
||||
/*but it allows 16 bit aligned data to be executed from the 68k stack and works as a*/
|
||||
/*temporary measure until I get MemChunkNew patched correctly*/
|
||||
|
||||
debugLog("Called ARM function:0x%08lX\n", (uint32_t)nativeFuncP);
|
||||
@@ -70,28 +85,12 @@ UInt32 emuPceNativeCall(NativeFuncType* nativeFuncP, void* userDataP){
|
||||
/*ARM tried to call a 68k function or has finished executing*/
|
||||
if(armv5GetRegister(0)){
|
||||
/*call function*/
|
||||
uint32_t emulStateP = armv5GetRegister(0);
|
||||
uint32_t function = armv5GetRegister(1);
|
||||
uint32_t stackBlob = armv5GetRegister(2);
|
||||
uint32_t stackBlobSizeAndWantA0 = armv5GetRegister(3);
|
||||
uint32_t (*m68kCallWithBlobFuncPtr)(uint32_t functionAddress, uint32_t stackBlob, uint32_t stackBlobSize, uint16_t returnA0) = (uint32_t (*)(uint32_t, uint32_t, uint32_t, uint16_t))m68kCallWithBlobFunc;
|
||||
|
||||
/*debug checks, I think these where preventing the callback to 68k code MemPtrNew???*/
|
||||
/*
|
||||
if(true){
|
||||
uint32_t index;
|
||||
uint32_t end = stackBlobSizeAndWantA0 & ~kPceNativeWantA0;
|
||||
|
||||
debugLog("ARM calling 68k function:0x%08lX, stackBlob:0x%08lX, stackBlobSize:0x%08lX, wantA0:%d\n", function, stackBlob, stackBlobSizeAndWantA0 & ~kPceNativeWantA0, !!(stackBlobSizeAndWantA0 & kPceNativeWantA0));
|
||||
for(index = 0; index < end; index++)
|
||||
debugLog("Stack byte:0x%02X\n", ((uint8_t*)stackBlob)[index]);
|
||||
}
|
||||
*/
|
||||
/*debugLog("Called 68k function:0x%08lX\n", function);*/
|
||||
debugLog("ARM calling 68k: emulStateP:0x%08lX, function:0x%08lX, stackBlob:0x%08lX, stackBlobSize:0x%08lX, wantA0:%d\n", emulStateP, function, stackBlob, stackBlobSizeAndWantA0 & ~kPceNativeWantA0, !!(stackBlobSizeAndWantA0 & kPceNativeWantA0));
|
||||
/*
|
||||
debugLog("ARM calling 68k function:0x%08lX, stackBlob:0x%08lX, stackBlobSize:0x%08lX, wantA0:%d\n", function, stackBlob, stackBlobSizeAndWantA0 & ~kPceNativeWantA0, !!(stackBlobSizeAndWantA0 & kPceNativeWantA0));
|
||||
*/
|
||||
debugLog("ARM calling 68k: function:0x%08lX, stackBlob:0x%08lX, stackBlobSize:0x%08lX, wantA0:%d\n", function, stackBlob, stackBlobSizeAndWantA0 & ~kPceNativeWantA0, !!(stackBlobSizeAndWantA0 & kPceNativeWantA0));
|
||||
|
||||
/*API call, convert to address first*/
|
||||
if(function <= kPceNativeTrapNoMask)
|
||||
|
||||
Reference in New Issue
Block a user