mirror of https://github.com/snes9xgit/snes9x.git
Lua: add memory hook functions
This commit is contained in:
parent
f18ffa3b44
commit
6cd98accd9
|
@ -191,7 +191,7 @@ uint8 S9xGetByteFree (uint32 address)
|
||||||
uint8 byte;
|
uint8 byte;
|
||||||
|
|
||||||
CPU.NextEvent = 0x7FFFFFFF;
|
CPU.NextEvent = 0x7FFFFFFF;
|
||||||
byte = S9xGetByte(address);
|
byte = S9xGetByteQuiet(address);
|
||||||
CPU.NextEvent = NextEvent;
|
CPU.NextEvent = NextEvent;
|
||||||
CPU.Cycles = Cycles;
|
CPU.Cycles = Cycles;
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ void S9xSetByteFree (uint8 byte, uint32 address)
|
||||||
int32 NextEvent = CPU.NextEvent;
|
int32 NextEvent = CPU.NextEvent;
|
||||||
|
|
||||||
CPU.NextEvent = 0x7FFFFFFF;
|
CPU.NextEvent = 0x7FFFFFFF;
|
||||||
S9xSetByte(byte, address);
|
S9xSetByteQuiet(byte, address);
|
||||||
CPU.NextEvent = NextEvent;
|
CPU.NextEvent = NextEvent;
|
||||||
CPU.Cycles = Cycles;
|
CPU.Cycles = Cycles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,6 +297,10 @@ void S9xMainLoop (void)
|
||||||
Opcodes = S9xOpcodesSlow;
|
Opcodes = S9xOpcodesSlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LUA
|
||||||
|
CallRegisteredLuaMemHook(Registers.PBPC, ICPU.S9xOpLengths[Op], Op, LUAMEMHOOK_EXEC);
|
||||||
|
#endif
|
||||||
|
|
||||||
Registers.PCw++;
|
Registers.PCw++;
|
||||||
(*Opcodes[Op].S9xOpcode)();
|
(*Opcodes[Op].S9xOpcode)();
|
||||||
|
|
||||||
|
|
60
getset.h
60
getset.h
|
@ -188,6 +188,10 @@
|
||||||
#include "seta.h"
|
#include "seta.h"
|
||||||
#include "bsx.h"
|
#include "bsx.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_LUA
|
||||||
|
#include "lua-engine.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define addCyclesInMemoryAccess \
|
#define addCyclesInMemoryAccess \
|
||||||
if (!CPU.InDMAorHDMA) \
|
if (!CPU.InDMAorHDMA) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -229,7 +233,7 @@ static inline int32 memory_speed (uint32 address)
|
||||||
return (TWO_CYCLES);
|
return (TWO_CYCLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8 S9xGetByte (uint32 Address)
|
inline uint8 S9xGetByteQuiet (uint32 Address)
|
||||||
{
|
{
|
||||||
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
||||||
uint8 *GetAddress = Memory.Map[block];
|
uint8 *GetAddress = Memory.Map[block];
|
||||||
|
@ -332,30 +336,30 @@ inline uint8 S9xGetByte (uint32 Address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16 S9xGetWord (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
inline uint16 S9xGetWordQuiet (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
||||||
{
|
{
|
||||||
uint32 mask = MEMMAP_MASK & (w == WRAP_PAGE ? 0xff : (w == WRAP_BANK ? 0xffff : 0xffffff));
|
uint32 mask = MEMMAP_MASK & (w == WRAP_PAGE ? 0xff : (w == WRAP_BANK ? 0xffff : 0xffffff));
|
||||||
if ((Address & mask) == mask)
|
if ((Address & mask) == mask)
|
||||||
{
|
{
|
||||||
PC_t a;
|
PC_t a;
|
||||||
|
|
||||||
OpenBus = S9xGetByte(Address);
|
OpenBus = S9xGetByteQuiet(Address);
|
||||||
|
|
||||||
switch (w)
|
switch (w)
|
||||||
{
|
{
|
||||||
case WRAP_PAGE:
|
case WRAP_PAGE:
|
||||||
a.xPBPC = Address;
|
a.xPBPC = Address;
|
||||||
a.B.xPCl++;
|
a.B.xPCl++;
|
||||||
return (OpenBus | (S9xGetByte(a.xPBPC) << 8));
|
return (OpenBus | (S9xGetByteQuiet(a.xPBPC) << 8));
|
||||||
|
|
||||||
case WRAP_BANK:
|
case WRAP_BANK:
|
||||||
a.xPBPC = Address;
|
a.xPBPC = Address;
|
||||||
a.W.xPC++;
|
a.W.xPC++;
|
||||||
return (OpenBus | (S9xGetByte(a.xPBPC) << 8));
|
return (OpenBus | (S9xGetByteQuiet(a.xPBPC) << 8));
|
||||||
|
|
||||||
case WRAP_NONE:
|
case WRAP_NONE:
|
||||||
default:
|
default:
|
||||||
return (OpenBus | (S9xGetByte(Address + 1) << 8));
|
return (OpenBus | (S9xGetByteQuiet(Address + 1) << 8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,8 +387,8 @@ inline uint16 S9xGetWord (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
||||||
case CMemory::MAP_PPU:
|
case CMemory::MAP_PPU:
|
||||||
if (CPU.InDMAorHDMA)
|
if (CPU.InDMAorHDMA)
|
||||||
{
|
{
|
||||||
OpenBus = S9xGetByte(Address);
|
OpenBus = S9xGetByteQuiet(Address);
|
||||||
return (OpenBus | (S9xGetByte(Address + 1) << 8));
|
return (OpenBus | (S9xGetByteQuiet(Address + 1) << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
word = S9xGetPPU(Address & 0xffff);
|
word = S9xGetPPU(Address & 0xffff);
|
||||||
|
@ -491,7 +495,7 @@ inline uint16 S9xGetWord (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void S9xSetByte (uint8 Byte, uint32 Address)
|
inline void S9xSetByteQuiet (uint8 Byte, uint32 Address)
|
||||||
{
|
{
|
||||||
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
||||||
uint8 *SetAddress = Memory.WriteMap[block];
|
uint8 *SetAddress = Memory.WriteMap[block];
|
||||||
|
@ -597,7 +601,7 @@ inline void S9xSetByte (uint8 Byte, uint32 Address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NONE, enum s9xwriteorder_t o = WRITE_01)
|
inline void S9xSetWordQuiet (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NONE, enum s9xwriteorder_t o = WRITE_01)
|
||||||
{
|
{
|
||||||
uint32 mask = MEMMAP_MASK & (w == WRAP_PAGE ? 0xff : (w == WRAP_BANK ? 0xffff : 0xffffff));
|
uint32 mask = MEMMAP_MASK & (w == WRAP_PAGE ? 0xff : (w == WRAP_BANK ? 0xffff : 0xffffff));
|
||||||
if ((Address & mask) == mask)
|
if ((Address & mask) == mask)
|
||||||
|
@ -605,30 +609,30 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
||||||
PC_t a;
|
PC_t a;
|
||||||
|
|
||||||
if (!o)
|
if (!o)
|
||||||
S9xSetByte((uint8) Word, Address);
|
S9xSetByteQuiet((uint8) Word, Address);
|
||||||
|
|
||||||
switch (w)
|
switch (w)
|
||||||
{
|
{
|
||||||
case WRAP_PAGE:
|
case WRAP_PAGE:
|
||||||
a.xPBPC = Address;
|
a.xPBPC = Address;
|
||||||
a.B.xPCl++;
|
a.B.xPCl++;
|
||||||
S9xSetByte(Word >> 8, a.xPBPC);
|
S9xSetByteQuiet(Word >> 8, a.xPBPC);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WRAP_BANK:
|
case WRAP_BANK:
|
||||||
a.xPBPC = Address;
|
a.xPBPC = Address;
|
||||||
a.W.xPC++;
|
a.W.xPC++;
|
||||||
S9xSetByte(Word >> 8, a.xPBPC);
|
S9xSetByteQuiet(Word >> 8, a.xPBPC);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WRAP_NONE:
|
case WRAP_NONE:
|
||||||
default:
|
default:
|
||||||
S9xSetByte(Word >> 8, Address + 1);
|
S9xSetByteQuiet(Word >> 8, Address + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o)
|
if (o)
|
||||||
S9xSetByte((uint8) Word, Address);
|
S9xSetByteQuiet((uint8) Word, Address);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -868,6 +872,32 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint8 S9xGetByte (uint32 Address)
|
||||||
|
{
|
||||||
|
uint8 byte = S9xGetByteQuiet(Address);
|
||||||
|
CallRegisteredLuaMemHook(Address, 1, byte, LUAMEMHOOK_READ);
|
||||||
|
return (byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint16 S9xGetWord (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
||||||
|
{
|
||||||
|
uint16 word = S9xGetWordQuiet(Address, w);
|
||||||
|
CallRegisteredLuaMemHook(Address, 2, word, LUAMEMHOOK_READ);
|
||||||
|
return (word);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void S9xSetByte (uint8 Byte, uint32 Address)
|
||||||
|
{
|
||||||
|
S9xSetByteQuiet(Byte, Address);
|
||||||
|
CallRegisteredLuaMemHook(Address, 1, Byte, LUAMEMHOOK_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NONE, enum s9xwriteorder_t o = WRITE_01)
|
||||||
|
{
|
||||||
|
S9xSetWordQuiet(Word, Address, w, o);
|
||||||
|
CallRegisteredLuaMemHook(Address, 2, Word, LUAMEMHOOK_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
inline void S9xSetPCBase (uint32 Address)
|
inline void S9xSetPCBase (uint32 Address)
|
||||||
{
|
{
|
||||||
Registers.PBPC = Address & 0xffffff;
|
Registers.PBPC = Address & 0xffffff;
|
||||||
|
|
|
@ -284,23 +284,23 @@ LuaMemHookType MatchHookTypeToCPU(lua_State* L, LuaMemHookType hookType)
|
||||||
if(cpunameIndex)
|
if(cpunameIndex)
|
||||||
{
|
{
|
||||||
const char* cpuName = lua_tostring(L, cpunameIndex);
|
const char* cpuName = lua_tostring(L, cpunameIndex);
|
||||||
if(!stricmp(cpuName, "sub") || !stricmp(cpuName, "s68k"))
|
//if(stricmp(cpuName, "sa1") == 0)
|
||||||
cpuID = 1;
|
// cpuID = 1;
|
||||||
lua_remove(L, cpunameIndex);
|
lua_remove(L, cpunameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(cpuID)
|
switch(cpuID)
|
||||||
{
|
{
|
||||||
case 0: // m68k:
|
case 0: // 65c816:
|
||||||
return hookType;
|
return hookType;
|
||||||
|
|
||||||
case 1: // s68k:
|
// case 1: // sa1:
|
||||||
switch(hookType)
|
// switch(hookType)
|
||||||
{
|
// {
|
||||||
case LUAMEMHOOK_WRITE: return LUAMEMHOOK_WRITE_SUB;
|
// case LUAMEMHOOK_WRITE: return LUAMEMHOOK_WRITE_SUB;
|
||||||
case LUAMEMHOOK_READ: return LUAMEMHOOK_READ_SUB;
|
// case LUAMEMHOOK_READ: return LUAMEMHOOK_READ_SUB;
|
||||||
case LUAMEMHOOK_EXEC: return LUAMEMHOOK_EXEC_SUB;
|
// case LUAMEMHOOK_EXEC: return LUAMEMHOOK_EXEC_SUB;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
return hookType;
|
return hookType;
|
||||||
}
|
}
|
||||||
|
@ -4232,13 +4232,13 @@ static const struct luaL_reg memorylib [] =
|
||||||
{"writelong", memory_writedword},
|
{"writelong", memory_writedword},
|
||||||
|
|
||||||
// memory hooks
|
// memory hooks
|
||||||
// {"registerwrite", memory_registerwrite},
|
{"registerwrite", memory_registerwrite},
|
||||||
// {"registerread", memory_registerread},
|
{"registerread", memory_registerread},
|
||||||
// {"registerexec", memory_registerexec},
|
{"registerexec", memory_registerexec},
|
||||||
// alternate names
|
// alternate names
|
||||||
// {"register", memory_registerwrite},
|
{"register", memory_registerwrite},
|
||||||
// {"registerrun", memory_registerexec},
|
{"registerrun", memory_registerexec},
|
||||||
// {"registerexecute", memory_registerexec},
|
{"registerexecute", memory_registerexec},
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -5158,8 +5158,10 @@ 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)
|
// (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(hookedRegions[hookType].NotEmpty())
|
||||||
{
|
{
|
||||||
if((hookType <= LUAMEMHOOK_EXEC) && (address >= 0xE00000))
|
// TODO: add more mirroring
|
||||||
address |= 0xFF0000; // account for mirroring of RAM
|
if(address >= 0x0000 && address <= 0x1FFF)
|
||||||
|
address |= 0x7E0000; // account for mirroring of LowRAM
|
||||||
|
|
||||||
if(hookedRegions[hookType].Contains(address, size))
|
if(hookedRegions[hookType].Contains(address, size))
|
||||||
CallRegisteredLuaMemHook_LuaMatch(address, size, value, hookType); // something has hooked this specific address
|
CallRegisteredLuaMemHook_LuaMatch(address, size, value, hookType); // something has hooked this specific address
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,6 +179,10 @@
|
||||||
#include "snes9x.h"
|
#include "snes9x.h"
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_LUA
|
||||||
|
#include "lua-engine.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CPU SA1
|
#define CPU SA1
|
||||||
#define ICPU SA1
|
#define ICPU SA1
|
||||||
#define Registers SA1Registers
|
#define Registers SA1Registers
|
||||||
|
@ -327,6 +331,10 @@ void S9xSA1MainLoop (void)
|
||||||
Opcodes = S9xSA1OpcodesSlow;
|
Opcodes = S9xSA1OpcodesSlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LUA
|
||||||
|
CallRegisteredLuaMemHook(SA1Registers.PBPC, SA1.S9xOpLengths[Op], Op, LUAMEMHOOK_EXEC);
|
||||||
|
#endif
|
||||||
|
|
||||||
Registers.PCw++;
|
Registers.PCw++;
|
||||||
(*Opcodes[Op].S9xOpcode)();
|
(*Opcodes[Op].S9xOpcode)();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue