From 0ebac3b4affa76238ecb35e49d52ef6421f633a3 Mon Sep 17 00:00:00 2001 From: gocha Date: Thu, 15 Oct 2009 04:58:17 +0000 Subject: [PATCH] Lua: add memory.registerwrite, memory.registerread, and memory.registerexec. --- desmume/src/MMU.h | 16 +++++++++ desmume/src/armcpu.cpp | 3 ++ desmume/src/lua-engine.cpp | 66 +++++++++++++++++--------------------- 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/desmume/src/MMU.h b/desmume/src/MMU.h index 6619c817b..d5585a5f4 100644 --- a/desmume/src/MMU.h +++ b/desmume/src/MMU.h @@ -30,6 +30,7 @@ #include "registers.h" #include "mc.h" #include "bits.h" +#include "lua-engine.h" #define ARMCPU_ARM7 1 #define ARMCPU_ARM9 0 @@ -549,6 +550,8 @@ FORCEINLINE u8 _MMU_read08(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u3 if((addr&(~0x3FFF)) == MMU.DTCMRegion) return 0; //dtcm } + CallRegisteredLuaMemHook(addr, 1, /*FIXME*/ 0, LUAMEMHOOK_READ); + if(PROCNUM==ARMCPU_ARM9) if((addr&(~0x3FFF)) == MMU.DTCMRegion) { @@ -572,6 +575,8 @@ FORCEINLINE u16 _MMU_read16(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u if((addr&(~0x3FFF)) == MMU.DTCMRegion) return 0; //dtcm } + CallRegisteredLuaMemHook(addr, 2, /*FIXME*/ 0, LUAMEMHOOK_READ); + //special handling for execution from arm9, since we spend so much time in there if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_CODE) { @@ -608,6 +613,8 @@ FORCEINLINE u32 _MMU_read32(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u if((addr&(~0x3FFF)) == MMU.DTCMRegion) return 0; //dtcm } + CallRegisteredLuaMemHook(addr, 4, /*FIXME*/ 0, LUAMEMHOOK_READ); + //special handling for execution from arm9, since we spend so much time in there if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_CODE) { @@ -663,16 +670,19 @@ FORCEINLINE void _MMU_write08(const int PROCNUM, const MMU_ACCESS_TYPE AT, const if((addr&(~0x3FFF)) == MMU.DTCMRegion) { T1WriteByte(MMU.ARM9_DTCM, addr & 0x3FFF, val); + CallRegisteredLuaMemHook(addr, 1, val, LUAMEMHOOK_WRITE); return; } if ( (addr & 0x0F000000) == 0x02000000) { T1WriteByte( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK, val); + CallRegisteredLuaMemHook(addr, 1, val, LUAMEMHOOK_WRITE); return; } if(PROCNUM==ARMCPU_ARM9) _MMU_ARM9_write08(addr,val); else _MMU_ARM7_write08(addr,val); + CallRegisteredLuaMemHook(addr, 1, val, LUAMEMHOOK_WRITE); } FORCEINLINE void _MMU_write16(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr, u16 val) @@ -688,16 +698,19 @@ FORCEINLINE void _MMU_write16(const int PROCNUM, const MMU_ACCESS_TYPE AT, const if((addr&(~0x3FFF)) == MMU.DTCMRegion) { T1WriteWord(MMU.ARM9_DTCM, addr & 0x3FFE, val); + CallRegisteredLuaMemHook(addr, 2, val, LUAMEMHOOK_WRITE); return; } if ( (addr & 0x0F000000) == 0x02000000) { T1WriteWord( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK16, val); + CallRegisteredLuaMemHook(addr, 2, val, LUAMEMHOOK_WRITE); return; } if(PROCNUM==ARMCPU_ARM9) _MMU_ARM9_write16(addr,val); else _MMU_ARM7_write16(addr,val); + CallRegisteredLuaMemHook(addr, 2, val, LUAMEMHOOK_WRITE); } FORCEINLINE void _MMU_write32(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr, u32 val) @@ -713,16 +726,19 @@ FORCEINLINE void _MMU_write32(const int PROCNUM, const MMU_ACCESS_TYPE AT, const if((addr&(~0x3FFF)) == MMU.DTCMRegion) { T1WriteLong(MMU.ARM9_DTCM, addr & 0x3FFC, val); + CallRegisteredLuaMemHook(addr, 4, val, LUAMEMHOOK_WRITE); return; } if ( (addr & 0x0F000000) == 0x02000000) { T1WriteLong( MMU.MAIN_MEM, addr & _MMU_MAIN_MEM_MASK32, val); + CallRegisteredLuaMemHook(addr, 4, val, LUAMEMHOOK_WRITE); return; } if(PROCNUM==ARMCPU_ARM9) _MMU_ARM9_write32(addr,val); else _MMU_ARM7_write32(addr,val); + CallRegisteredLuaMemHook(addr, 4, val, LUAMEMHOOK_WRITE); } diff --git a/desmume/src/armcpu.cpp b/desmume/src/armcpu.cpp index 38a4cb9c0..12db787d0 100644 --- a/desmume/src/armcpu.cpp +++ b/desmume/src/armcpu.cpp @@ -31,6 +31,7 @@ #include "Disassembler.h" #include "NDSSystem.h" #include "MMU_timing.h" +#include "lua-engine.h" template static u32 armcpu_prefetch(); @@ -540,6 +541,7 @@ u32 armcpu_exec() || (TEST_COND(CONDITION(ARMPROC.instruction), CODE(ARMPROC.instruction), ARMPROC.CPSR)) //handles any condition ) { + CallRegisteredLuaMemHook(ARMPROC.R[15], 4, ARMPROC.instruction, LUAMEMHOOK_EXEC); // should report even if condition=false? if(PROCNUM==0) { #ifdef DEVELOPER DEBUG_statistics.instructionHits[0].arm[INSTRUCTION_INDEX(ARMPROC.instruction)]++; @@ -566,6 +568,7 @@ u32 armcpu_exec() return MMU_fetchExecuteCycles(cExecute, cFetch); } + CallRegisteredLuaMemHook(ARMPROC.R[15], 2, ARMPROC.instruction, LUAMEMHOOK_EXEC); if(PROCNUM==0) { #ifdef DEVELOPER diff --git a/desmume/src/lua-engine.cpp b/desmume/src/lua-engine.cpp index f9701a676..b6ca7ad0c 100644 --- a/desmume/src/lua-engine.cpp +++ b/desmume/src/lua-engine.cpp @@ -158,7 +158,7 @@ static const char* luaCallIDStrings [] = }; static const int _makeSureWeHaveTheRightNumberOfStrings [sizeof(luaCallIDStrings)/sizeof(*luaCallIDStrings) == LUACALL_COUNT ? 1 : 0]; -/*static const char* luaMemHookTypeStrings [] = +static const char* luaMemHookTypeStrings [] = { "MEMHOOK_WRITE", "MEMHOOK_READ", @@ -169,7 +169,6 @@ static const int _makeSureWeHaveTheRightNumberOfStrings [sizeof(luaCallIDStrings "MEMHOOK_EXEC_SUB", }; static const int _makeSureWeHaveTheRightNumberOfStrings2 [sizeof(luaMemHookTypeStrings)/sizeof(*luaMemHookTypeStrings) == LUAMEMHOOK_COUNT ? 1 : 0]; -*/ void StopScriptIfFinished(int uid, bool justReturned = false); void SetSaveKey(LuaContextInfo& info, const char* key); @@ -180,17 +179,14 @@ void RefreshScriptSpeedStatus(); static char* rawToCString(lua_State* L, int idx=0); static const char* toCString(lua_State* L, int idx=0); -/* -// disabled, see comment above implementation of CalculateMemHookRegions - static void CalculateMemHookRegions(LuaMemHookType hookType); static int memory_registerHook(lua_State* L, LuaMemHookType hookType, int defaultSize) { // get first argument: address unsigned int addr = luaL_checkinteger(L,1); - if((addr & ~0xFFFFFF) == ~0xFFFFFF) - addr &= 0xFFFFFF; + //if((addr & ~0xFFFFFF) == ~0xFFFFFF) + // addr &= 0xFFFFFF; // get optional second argument: size int size = defaultSize; @@ -257,24 +253,24 @@ LuaMemHookType MatchHookTypeToCPU(lua_State* L, LuaMemHookType hookType) if(cpunameIndex) { const char* cpuName = lua_tostring(L, cpunameIndex); - if(!stricmp(cpuName, "sub") || !stricmp(cpuName, "s68k")) - cpuID = 1; +// if(!stricmp(cpuName, "sub") || !stricmp(cpuName, "s68k")) +// cpuID = 1; lua_remove(L, cpunameIndex); } - switch(cpuID) - { - case 0: // m68k: - return hookType; - - case 1: // s68k: - switch(hookType) - { - case LUAMEMHOOK_WRITE: return LUAMEMHOOK_WRITE_SUB; - case LUAMEMHOOK_READ: return LUAMEMHOOK_READ_SUB; - case LUAMEMHOOK_EXEC: return LUAMEMHOOK_EXEC_SUB; - } - } +// switch(cpuID) +// { +// case 0: // m68k: +// return hookType; +// +// case 1: // s68k: +// switch(hookType) +// { +// case LUAMEMHOOK_WRITE: return LUAMEMHOOK_WRITE_SUB; +// case LUAMEMHOOK_READ: return LUAMEMHOOK_READ_SUB; +// case LUAMEMHOOK_EXEC: return LUAMEMHOOK_EXEC_SUB; +// } +// } return hookType; } @@ -290,7 +286,6 @@ DEFINE_LUA_FUNCTION(memory_registerexec, "address,[size=2,][cpuname=\"main\",]fu { return memory_registerHook(L, MatchHookTypeToCPU(L,LUAMEMHOOK_EXEC), 2); } -*/ DEFINE_LUA_FUNCTION(emu_registerbefore, "func") { @@ -4139,13 +4134,13 @@ static const struct luaL_reg memorylib [] = {"writelong", memory_writedword}, // memory hooks -// {"registerwrite", memory_registerwrite}, -// {"registerread", memory_registerread}, -// {"registerexec", memory_registerexec}, + {"registerwrite", memory_registerwrite}, + {"registerread", memory_registerread}, + {"registerexec", memory_registerexec}, // alternate names -// {"register", memory_registerwrite}, -// {"registerrun", memory_registerexec}, -// {"registerexecute", memory_registerexec}, + {"register", memory_registerwrite}, + {"registerrun", memory_registerexec}, + {"registerexecute", memory_registerexec}, {NULL, NULL} }; @@ -4440,14 +4435,14 @@ void registerLibs(lua_State* L) } lua_pop(L,1); } -/* + // push arrays for storing hook functions in for(int i = 0; i < LUAMEMHOOK_COUNT; i++) { lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[i]); } -*/ + // register type luaL_newmetatable(L, "EMUFILE_MEMORY*"); lua_pushcfunction(L, gcEMUFILE_MEMORY); @@ -4844,10 +4839,8 @@ void StopLuaScript(int uid) info.started = false; info.numMemHooks = 0; -/* for(int i = 0; i < LUAMEMHOOK_COUNT; i++) CalculateMemHookRegions((LuaMemHookType)i); -*/ } RefreshScriptStartedStatus(); } @@ -4860,7 +4853,7 @@ void CloseLuaContext(int uid) luaContextInfo.erase(uid); } -/* + // the purpose of this structure is to provide a way of // QUICKLY determining whether a memory address range has a hook associated with it, // with a bias toward fast rejection because the majority of addresses will not be hooked. @@ -5049,13 +5042,12 @@ void CallRegisteredLuaMemHook(unsigned int address, int size, unsigned int value // (on my system that consistently took 200 ms total in the former case and 350 ms total in the latter case) if(hookedRegions[hookType].NotEmpty()) { - if((hookType <= LUAMEMHOOK_EXEC) && (address >= 0xE00000)) - address |= 0xFF0000; // account for mirroring of RAM + //if((hookType <= LUAMEMHOOK_EXEC) && (address >= 0xE00000)) + // address |= 0xFF0000; // gens: account for mirroring of RAM if(hookedRegions[hookType].Contains(address, size)) CallRegisteredLuaMemHook_LuaMatch(address, size, value, hookType); // something has hooked this specific address } } -*/ bool AnyLuaActive() {