Skip to content

Commit

Permalink
Minor refactor of script memory hook interface so that both lua and j…
Browse files Browse the repository at this point in the history
…s script can coexist nicely. Script engines now register themselves with the CPU module for their functions to be called.
  • Loading branch information
thor2016 committed Jan 15, 2024
1 parent f90a269 commit 8e7e5e8
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 23 deletions.
22 changes: 22 additions & 0 deletions src/lua-engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand Down
155 changes: 132 additions & 23 deletions src/x6502.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,32 +44,137 @@ 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);
}

//normal memory write
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);
Expand All @@ -78,29 +183,32 @@ 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);
}

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;
}

Expand Down Expand Up @@ -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)
{
Expand Down
22 changes: 22 additions & 0 deletions src/x6502.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 8e7e5e8

Please sign in to comment.