Debugger: Lua - Added API to access/reset memory access counters

This commit is contained in:
Sour 2018-03-30 19:54:47 -04:00
parent bf2e733cc3
commit 490ea3d5f6
3 changed files with 73 additions and 1 deletions

View File

@ -19,6 +19,7 @@
#include "PPU.h"
#include "CheatManager.h"
#include "KeyManager.h"
#include "MemoryAccessCounter.h"
#define lua_pushintvalue(name, value) lua_pushliteral(lua, #name); lua_pushinteger(lua, (int)value); lua_settable(lua, -3);
#define lua_pushdoublevalue(name, value) lua_pushliteral(lua, #name); lua_pushnumber(lua, (double)value); lua_settable(lua, -3);
@ -96,6 +97,8 @@ int LuaApi::GetLibrary(lua_State *lua)
{ "setInput", LuaApi::SetInput },
{ "addCheat", LuaApi::AddCheat },
{ "clearCheats", LuaApi::ClearCheats },
{ "getAccessCounters", LuaApi::GetAccessCounters },
{ "resetAccessCounters", LuaApi::ResetAccessCounters },
{ "setState", LuaApi::SetState },
{ "getState", LuaApi::GetState },
{ "getScriptDataFolder", LuaApi::GetScriptDataFolder },
@ -132,6 +135,21 @@ int LuaApi::GetLibrary(lua_State *lua)
lua_pushintvalue(ppuWrite, CallbackType::PpuWrite);
lua_settable(lua, -3);
lua_pushliteral(lua, "counterMemType");
lua_newtable(lua);
lua_pushintvalue(nesRam, AddressType::InternalRam);
lua_pushintvalue(prgRom, AddressType::PrgRom);
lua_pushintvalue(workRam, AddressType::WorkRam);
lua_pushintvalue(saveRam, AddressType::SaveRam);
lua_settable(lua, -3);
lua_pushliteral(lua, "counterOpType");
lua_newtable(lua);
lua_pushintvalue(read, MemoryOperationType::Read);
lua_pushintvalue(write, MemoryOperationType::Write);
lua_pushintvalue(exec, MemoryOperationType::ExecOpCode);
lua_settable(lua, -3);
lua_pushliteral(lua, "eventType");
lua_newtable(lua);
lua_pushintvalue(reset, EventType::Reset);
@ -367,7 +385,7 @@ int LuaApi::GetScreenBuffer(lua_State *lua)
lua_newtable(lua);
for(int y = 0; y < PPU::ScreenHeight; y++) {
for(int x = 0; x < PPU::ScreenWidth; x++) {
lua_pushnumber(lua, palette[PPU::GetPixel(x, y) & 0x3F] & 0xFFFFFF);
lua_pushinteger(lua, palette[PPU::GetPixel(x, y) & 0x3F] & 0xFFFFFF);
lua_rawseti(lua, -2, (y << 8) + x);
}
}
@ -657,6 +675,45 @@ int LuaApi::ClearCheats(lua_State *lua)
return l.ReturnCount();
}
int LuaApi::GetAccessCounters(lua_State *lua)
{
LuaCallHelper l(lua);
l.ForceParamCount(2);
MemoryOperationType operationType = (MemoryOperationType)l.ReadInteger();
AddressType memoryType = (AddressType)l.ReadInteger();
errorCond(operationType >= MemoryOperationType::ExecOperand, "Invalid operation type");
errorCond(memoryType >= AddressType::Register, "Invalid memory type");
checkparams();
uint32_t size = 0;
switch(memoryType) {
case AddressType::InternalRam: size = 0x2000; break;
case AddressType::PrgRom: size = _debugger->GetMemoryDumper()->GetMemorySize(DebugMemoryType::PrgRom); break;
case AddressType::WorkRam: size = _debugger->GetMemoryDumper()->GetMemorySize(DebugMemoryType::WorkRam); break;
case AddressType::SaveRam: size = _debugger->GetMemoryDumper()->GetMemorySize(DebugMemoryType::SaveRam); break;
}
vector<uint32_t> counts;
counts.resize(size, 0);
_debugger->GetMemoryAccessCounter()->GetAccessCounts(memoryType, operationType, counts.data(), false);
lua_newtable(lua);
for(uint32_t i = 0; i < size; i++) {
lua_pushinteger(lua, counts[i]);
lua_rawseti(lua, -2, i);
}
return 1;
}
int LuaApi::ResetAccessCounters(lua_State *lua)
{
LuaCallHelper l(lua);
checkparams();
_debugger->GetMemoryAccessCounter()->ResetCounts();
return l.ReturnCount();
}
int LuaApi::GetScriptDataFolder(lua_State *lua)
{
LuaCallHelper l(lua);

View File

@ -70,6 +70,9 @@ public:
static int SetState(lua_State *lua);
static int GetState(lua_State *lua);
static int GetAccessCounters(lua_State *lua);
static int ResetAccessCounters(lua_State *lua);
private:
static Debugger* _debugger;
static MemoryDumper* _memoryDumper;

View File

@ -484,6 +484,9 @@ namespace Mesen.GUI.Debugger
new List<string> {"func","emu.getScreenBuffer","emu.getScreenBuffer()","", "*Array* 32-bit integers in ARGB format", "Returns an array of ARGB values for the entire screen (256px by 240px) - can be used with emu.setScreenBuffer() to alter the frame."},
new List<string> {"func","emu.setScreenBuffer","emu.setScreenBuffer(screenBuffer)", "screenBuffer - *Array* An array of 32-bit integers in ARGB format", "","Replaces the current frame with the contents of the specified array."},
new List<string> {"func","emu.getAccessCounters","emu.getAccessCounters(counterMemType, counterOpType)", "counterMemType - *Enum* A value from the emu.counterMemType enum\ncounterOpType - *Enum* A value from the emu.counterOpType enum\n", "*Array* 32-bit integers", "Returns an array of counters for the specified memory and operation types."},
new List<string> {"func","emu.resetAccessCounters","emu.resetAccessCounters()", "", "", "Resets all access counters."},
new List<string> {"func","emu.saveSavestate","emu.saveSavestate()","","*String* A string containing a binary blob representing the emulation's current state.","Creates a savestate and returns it as a binary string. (The savestate is not saved on disk)\n Note: this can only be called from within a “startFrame” event callback or “cpuExec” memory callback."},
new List<string> {"func","emu.loadSavestate","emu.loadSavestate(savestate)","savestate - *String* A binary blob representing a savestate, as returned by saveSavestate()","","Loads the specified savestate.\nNote: this can only be called from within a “startFrame” event callback or “cpuExec” memory callback."},
new List<string> {"func","emu.saveSavestateAsync","emu.saveSavestateAsync()","slotNumber - *Integer* A slot number to which the savestate data will be stored (slotNumber must be >= 0)","","Queues a save savestate request. As soon at the emulator is able to process the request, it will be saved into the specified slot.\nThis API is asynchronous because save states can only be taken in-between 2 CPU instructions, not in the middle of an instruction.\nWhen called while the CPU is in-between 2 instructions (e.g: inside the callback of an cpuExec or startFrame event),\nthe save state will be taken immediately and its data will be available via getSavestateData right after the call to saveSavestateAsync.\nThe savestate can be loaded by calling the loadSavestateAsync function."},
@ -534,6 +537,15 @@ namespace Mesen.GUI.Debugger
new List<string> {"enum","emu.memType.saveRam","Save RAM - Range varies by game","","",""},
new List<string> {"enum","emu.memType.cpuDebug","CPU memory - $0000 to $FFFF","","","Same as \"memType.cpu\" but does NOT cause any side-effects."},
new List<string> {"enum","emu.memType.ppuDebug","PPU memory - $0000 to $3FFF","","","Same as \"memType.ppu\" but does NOT cause any side-effects."},
new List<string> {"enum","emu.counterMemType","emu.counterMemType.[value]","","","Values:\nnesRam = 0,\nprgRom = 1,\nworkRam = 2,\nsaveRam = 3\n\nUsed by getAccessCounters calls."},
new List<string> {"enum","emu.counterMemType.nesRam","Returns access counter data for the built-in 2 KB NES RAM","","",""},
new List<string> {"enum","emu.counterMemType.prgRom","Returns access counter data for PRG ROM","","",""},
new List<string> {"enum","emu.counterMemType.workRam", "Returns access counter data for Work RAM", "","",""},
new List<string> {"enum","emu.counterMemType.saveRam", "Returns access counter data for Save RAM", "","",""},
new List<string> {"enum","emu.counterOpType","emu.counterOpType.[value]","","","Values:\nread = 0,\nwrite = 1,\nexec = 2\n\nUsed by getAccessCounters calls."},
new List<string> {"enum","emu.counterOpType.read","Returns access counter data for reads","","",""},
new List<string> {"enum","emu.counterOpType.write","Returns access counter data for writes","","",""},
new List<string> {"enum","emu.counterOpType.exec", "Returns access counter data for executed bytes", "","",""},
};
}