Minor refactor of script memory hook interface so that both lua and js script can coexist nicely. Script engines now register themselves with the CPU module for their functions to be called.
This commit is contained in:
parent
f90a269386
commit
8e7e5e8c05
|
@ -118,6 +118,19 @@ bool DemandLua()
|
|||
#endif
|
||||
}
|
||||
|
||||
static void luaReadMemHook(unsigned int address, unsigned int value)
|
||||
{
|
||||
CallRegisteredLuaMemHook(address, 1, value, LUAMEMHOOK_READ);
|
||||
}
|
||||
static void luaWriteMemHook(unsigned int address, unsigned int value)
|
||||
{
|
||||
CallRegisteredLuaMemHook(address, 1, value, LUAMEMHOOK_WRITE);
|
||||
}
|
||||
static void luaExecMemHook(unsigned int address, unsigned int value)
|
||||
{
|
||||
CallRegisteredLuaMemHook(address, 1, value, LUAMEMHOOK_EXEC);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <lua.h>
|
||||
|
@ -6378,6 +6391,7 @@ void FCEU_LuaFrameBoundary()
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads and runs the given Lua script.
|
||||
* The emulator MUST be paused for this function to be
|
||||
|
@ -6486,6 +6500,10 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg)
|
|||
lua_newtable(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[i]);
|
||||
}
|
||||
|
||||
X6502_MemHook::Add( X6502_MemHook::Read , luaReadMemHook );
|
||||
X6502_MemHook::Add( X6502_MemHook::Write, luaWriteMemHook );
|
||||
X6502_MemHook::Add( X6502_MemHook::Exec , luaExecMemHook );
|
||||
}
|
||||
|
||||
// We make our thread NOW because we want it at the bottom of the stack.
|
||||
|
@ -6601,6 +6619,10 @@ void FCEU_LuaStop() {
|
|||
//already killed
|
||||
if (!L) return;
|
||||
|
||||
X6502_MemHook::Remove( X6502_MemHook::Read , luaReadMemHook );
|
||||
X6502_MemHook::Remove( X6502_MemHook::Write, luaWriteMemHook );
|
||||
X6502_MemHook::Remove( X6502_MemHook::Exec , luaExecMemHook );
|
||||
|
||||
// Since the script is exiting, we want to prevent an infinite loop.
|
||||
// CallExitFunction() > HandleCallbackError() > FCEU_LuaStop() > CallExitFunction() ...
|
||||
if (luaexiterrorcount > 0) {
|
||||
|
|
155
src/x6502.cpp
155
src/x6502.cpp
|
@ -44,13 +44,116 @@ void (*MapIRQHook)(int a);
|
|||
if(!overclocking) soundtimestamp+=__x; \
|
||||
}
|
||||
|
||||
static X6502_MemHook* readMemHook = nullptr;
|
||||
static X6502_MemHook* writeMemHook = nullptr;
|
||||
static X6502_MemHook* execMemHook = nullptr;
|
||||
|
||||
void X6502_MemHook::Add(enum X6502_MemHook::Type type, void (*func)(unsigned int address, unsigned int value) )
|
||||
{
|
||||
X6502_MemHook** hookStart = nullptr;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Read:
|
||||
hookStart = &readMemHook;
|
||||
break;
|
||||
case Write:
|
||||
hookStart = &writeMemHook;
|
||||
break;
|
||||
case Exec:
|
||||
hookStart = &execMemHook;
|
||||
break;
|
||||
}
|
||||
if (hookStart == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (*hookStart != nullptr)
|
||||
{
|
||||
X6502_MemHook* hook = *hookStart;
|
||||
|
||||
while (hook->next != nullptr)
|
||||
{
|
||||
if (hook->func == func)
|
||||
{
|
||||
// Already registered
|
||||
//printf("LUA MemHook Already Registered\n");
|
||||
return;
|
||||
}
|
||||
hook = hook->next;
|
||||
}
|
||||
X6502_MemHook* newHook = new X6502_MemHook();
|
||||
newHook->type = type;
|
||||
newHook->func = func;
|
||||
hook->next = newHook;
|
||||
}
|
||||
else
|
||||
{
|
||||
X6502_MemHook* newHook = new X6502_MemHook();
|
||||
newHook->type = type;
|
||||
newHook->func = func;
|
||||
*hookStart = newHook;
|
||||
}
|
||||
//printf("LUA MemHook Added: %p\n", func);
|
||||
}
|
||||
|
||||
void X6502_MemHook::Remove(enum X6502_MemHook::Type type, void (*func)(unsigned int address, unsigned int value) )
|
||||
{
|
||||
X6502_MemHook** hookStart = nullptr;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Read:
|
||||
hookStart = &readMemHook;
|
||||
break;
|
||||
case Write:
|
||||
hookStart = &writeMemHook;
|
||||
break;
|
||||
case Exec:
|
||||
hookStart = &execMemHook;
|
||||
break;
|
||||
}
|
||||
if (hookStart == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (*hookStart != nullptr)
|
||||
{
|
||||
X6502_MemHook* hook = *hookStart;
|
||||
X6502_MemHook* prev = nullptr;
|
||||
|
||||
while (hook != nullptr)
|
||||
{
|
||||
if (hook->func == func)
|
||||
{
|
||||
if (prev != nullptr)
|
||||
{
|
||||
prev->next = hook->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
*hookStart = hook->next;
|
||||
}
|
||||
delete hook;
|
||||
//printf("LUA MemHook Removed: %p\n", func);
|
||||
return;
|
||||
}
|
||||
prev = hook;
|
||||
hook = hook->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//normal memory read
|
||||
static INLINE uint8 RdMem(unsigned int A)
|
||||
{
|
||||
_DB=ARead[A](A);
|
||||
#ifdef _S9XLUA_H
|
||||
CallRegisteredLuaMemHook(A, 1, _DB, LUAMEMHOOK_READ);
|
||||
#endif
|
||||
if (readMemHook)
|
||||
{
|
||||
readMemHook->call(A, _DB);
|
||||
}
|
||||
return(_DB);
|
||||
}
|
||||
|
||||
|
@ -58,18 +161,20 @@ static INLINE uint8 RdMem(unsigned int A)
|
|||
static INLINE void WrMem(unsigned int A, uint8 V)
|
||||
{
|
||||
BWrite[A](A,V);
|
||||
#ifdef _S9XLUA_H
|
||||
CallRegisteredLuaMemHook(A, 1, V, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
_DB = V;
|
||||
if (writeMemHook)
|
||||
{
|
||||
writeMemHook->call(A, V);
|
||||
}
|
||||
_DB = V;
|
||||
}
|
||||
|
||||
static INLINE uint8 RdRAM(unsigned int A)
|
||||
{
|
||||
_DB=ARead[A](A);
|
||||
#ifdef _S9XLUA_H
|
||||
CallRegisteredLuaMemHook(A, 1, _DB, LUAMEMHOOK_READ);
|
||||
#endif
|
||||
if (readMemHook)
|
||||
{
|
||||
readMemHook->call(A, _DB);
|
||||
}
|
||||
//bbit edited: this was changed so cheat substituion would work
|
||||
// return(_DB=RAM[A]);
|
||||
return(_DB);
|
||||
|
@ -78,19 +183,21 @@ static INLINE uint8 RdRAM(unsigned int A)
|
|||
static INLINE void WrRAM(unsigned int A, uint8 V)
|
||||
{
|
||||
RAM[A]=V;
|
||||
#ifdef _S9XLUA_H
|
||||
CallRegisteredLuaMemHook(A, 1, V, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
_DB = V;
|
||||
if (writeMemHook)
|
||||
{
|
||||
writeMemHook->call(A, V);
|
||||
}
|
||||
_DB = V;
|
||||
}
|
||||
|
||||
uint8 X6502_DMR(uint32 A)
|
||||
{
|
||||
ADDCYC(1);
|
||||
_DB=ARead[A](A);
|
||||
#ifdef _S9XLUA_H
|
||||
CallRegisteredLuaMemHook(A, 1, _DB, LUAMEMHOOK_READ);
|
||||
#endif
|
||||
if (readMemHook)
|
||||
{
|
||||
readMemHook->call(A, _DB);
|
||||
}
|
||||
return(_DB);
|
||||
}
|
||||
|
||||
|
@ -98,9 +205,10 @@ void X6502_DMW(uint32 A, uint8 V)
|
|||
{
|
||||
ADDCYC(1);
|
||||
BWrite[A](A,V);
|
||||
#ifdef _S9XLUA_H
|
||||
CallRegisteredLuaMemHook(A, 1, V, LUAMEMHOOK_WRITE);
|
||||
#endif
|
||||
if (writeMemHook)
|
||||
{
|
||||
writeMemHook->call(A, V);
|
||||
}
|
||||
_DB = V;
|
||||
}
|
||||
|
||||
|
@ -520,9 +628,10 @@ extern int test; test++;
|
|||
|
||||
if (!overclocking)
|
||||
FCEU_SoundCPUHook(temp);
|
||||
#ifdef _S9XLUA_H
|
||||
CallRegisteredLuaMemHook(_PC, 1, 0, LUAMEMHOOK_EXEC);
|
||||
#endif
|
||||
if (execMemHook)
|
||||
{
|
||||
execMemHook->call(_PC, 0);
|
||||
}
|
||||
_PC++;
|
||||
switch(b1)
|
||||
{
|
||||
|
|
22
src/x6502.h
22
src/x6502.h
|
@ -92,5 +92,27 @@ void X6502_IRQEnd(int w);
|
|||
|
||||
int X6502_GetOpcodeCycles( int op );
|
||||
|
||||
class X6502_MemHook
|
||||
{
|
||||
public:
|
||||
enum Type { Read = 0, Write, Exec } type;
|
||||
|
||||
static void Add(enum Type type, void (*func)(unsigned int address, unsigned int value) );
|
||||
static void Remove(enum Type type, void (*func)(unsigned int address, unsigned int value) );
|
||||
|
||||
inline void call( unsigned int address, unsigned int value )
|
||||
{
|
||||
func(address, value);
|
||||
|
||||
if (next != nullptr)
|
||||
{
|
||||
next->call(address, value);
|
||||
}
|
||||
}
|
||||
private:
|
||||
void (*func)(unsigned int address, unsigned int value) = nullptr;
|
||||
X6502_MemHook* next = nullptr;
|
||||
};
|
||||
|
||||
#define _X6502H
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue