Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/fceux.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorharry <hrosen2016@gmail.com>2024-01-15 17:31:53 +0300
committerharry <hrosen2016@gmail.com>2024-01-15 17:31:53 +0300
commit8e7e5e8c05d283b0caadc26e03303f209dd3d22a (patch)
tree40ca257242499c0c9eb37bad8ef14ab1b096db65
parentf90a269386f288df4696a028eb282090cf59abae (diff)
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.
-rw-r--r--src/lua-engine.cpp22
-rw-r--r--src/x6502.cpp155
-rw-r--r--src/x6502.h22
3 files changed, 176 insertions, 23 deletions
diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp
index 6ca7a4bb..d164d2db 100644
--- a/src/lua-engine.cpp
+++ b/src/lua-engine.cpp
@@ -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) {
diff --git a/src/x6502.cpp b/src/x6502.cpp
index 85c59362..74f008b6 100644
--- a/src/x6502.cpp
+++ b/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)
{
diff --git a/src/x6502.h b/src/x6502.h
index 460683d8..f1ba3519 100644
--- a/src/x6502.h
+++ b/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