From 6969caa1b83a3d993090cb6f65305748e935c13d Mon Sep 17 00:00:00 2001 From: Souryo Date: Fri, 8 Sep 2017 17:20:40 -0400 Subject: [PATCH] Debugger: Lua memory callback fixes + allow lua script to change read/written value --- Core/Debugger.cpp | 14 ++++++------ Core/Debugger.h | 12 +++++------ Core/LuaApi.cpp | 12 +++++------ Core/LuaScriptingContext.cpp | 14 +++++++++--- Core/LuaScriptingContext.h | 2 +- Core/MemoryDumper.cpp | 40 +++++++++++++++++++++-------------- Core/ScriptHost.cpp | 4 ++-- Core/ScriptHost.h | 4 ++-- Core/ScriptingContext.h | 2 +- GUI.NET/Debugger/frmScript.cs | 1 + 10 files changed, 61 insertions(+), 44 deletions(-) diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index 652edf0a..ea5c95a5 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -594,7 +594,7 @@ bool Debugger::SleepUntilResume() return false; } -void Debugger::PrivateProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t value) +void Debugger::PrivateProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t &value) { int32_t absoluteAddr = _mapper->ToAbsoluteChrAddress(addr); _codeDataLogger->SetFlag(absoluteAddr, type == MemoryOperationType::Read ? CdlChrFlags::Read : CdlChrFlags::Drawn); @@ -611,7 +611,7 @@ void Debugger::PrivateProcessVramReadOperation(MemoryOperationType type, uint16_ ProcessPpuOperation(addr, value, MemoryOperationType::Read); } -void Debugger::PrivateProcessVramWriteOperation(uint16_t addr, uint8_t value) +void Debugger::PrivateProcessVramWriteOperation(uint16_t addr, uint8_t &value) { if(_hasBreakpoint[BreakpointType::WriteVram]) { OperationInfo operationInfo{ addr, value, MemoryOperationType::Write }; @@ -813,14 +813,14 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin return true; } -void Debugger::ProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t value) +void Debugger::ProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t &value) { if(Debugger::Instance) { Debugger::Instance->PrivateProcessVramReadOperation(type, addr, value); } } -void Debugger::ProcessVramWriteOperation(uint16_t addr, uint8_t value) +void Debugger::ProcessVramWriteOperation(uint16_t addr, uint8_t &value) { if(Debugger::Instance) { Debugger::Instance->PrivateProcessVramWriteOperation(addr, value); @@ -1078,7 +1078,7 @@ const char* Debugger::GetScriptLog(int32_t scriptId) return ""; } -void Debugger::ProcessCpuOperation(uint16_t addr, uint8_t value, MemoryOperationType type) +void Debugger::ProcessCpuOperation(uint16_t addr, uint8_t &value, MemoryOperationType type) { if(_hasScript) { for(shared_ptr &script : _scripts) { @@ -1087,11 +1087,11 @@ void Debugger::ProcessCpuOperation(uint16_t addr, uint8_t value, MemoryOperation } } -void Debugger::ProcessPpuOperation(uint16_t addr, uint8_t value, MemoryOperationType type) +void Debugger::ProcessPpuOperation(uint16_t addr, uint8_t &value, MemoryOperationType type) { if(_hasScript) { for(shared_ptr &script : _scripts) { - script->ProcessPpuOperation(addr, value, MemoryOperationType::Write); + script->ProcessPpuOperation(addr, value, type); } } } diff --git a/Core/Debugger.h b/Core/Debugger.h index 1d8d9390..d0e71003 100644 --- a/Core/Debugger.h +++ b/Core/Debugger.h @@ -121,8 +121,8 @@ private: void PrivateProcessPpuCycle(); bool PrivateProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t &value); - void PrivateProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t value); - void PrivateProcessVramWriteOperation(uint16_t addr, uint8_t value); + void PrivateProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t &value); + void PrivateProcessVramWriteOperation(uint16_t addr, uint8_t &value); bool HasMatchingBreakpoint(BreakpointType type, OperationInfo &operationInfo); void UpdateCallstack(uint32_t addr); @@ -192,8 +192,8 @@ public: int32_t EvaluateExpression(string expression, EvalResultType &resultType); static bool ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t &value); - static void ProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t value); - static void ProcessVramWriteOperation(uint16_t addr, uint8_t value); + static void ProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t &value); + static void ProcessVramWriteOperation(uint16_t addr, uint8_t &value); static void ProcessPpuCycle(); static void SetLastFramePpuScroll(uint16_t x, uint16_t y); @@ -224,7 +224,7 @@ public: int32_t LoadScript(string content, int32_t scriptId); void RemoveScript(int32_t scriptId); const char* GetScriptLog(int32_t scriptId); - void ProcessCpuOperation(uint16_t addr, uint8_t value, MemoryOperationType type); - void ProcessPpuOperation(uint16_t addr, uint8_t value, MemoryOperationType type); + void ProcessCpuOperation(uint16_t addr, uint8_t &value, MemoryOperationType type); + void ProcessPpuOperation(uint16_t addr, uint8_t &value, MemoryOperationType type); void ProcessEvent(EventType type); }; \ No newline at end of file diff --git a/Core/LuaApi.cpp b/Core/LuaApi.cpp index 919152a6..215c08a4 100644 --- a/Core/LuaApi.cpp +++ b/Core/LuaApi.cpp @@ -160,7 +160,7 @@ int LuaApi::WriteMemory(lua_State *lua) checkparams(); errorCond(value > 255 || value < -128, "value out of range"); errorCond(address < 0, "address must be >= 0"); - _memoryDumper->SetMemoryValue(type, address, value, false); + _memoryDumper->SetMemoryValue(type, address, value, false, false); return l.ReturnCount(); } @@ -171,7 +171,7 @@ int LuaApi::DebugReadMemory(lua_State *lua) int address = l.ReadInteger(); checkparams(); errorCond(address < 0, "address must be >= 0"); - l.Return(_memoryDumper->GetMemoryValue(type, address)); + l.Return(_memoryDumper->GetMemoryValue(type, address, true)); return l.ReturnCount(); } @@ -184,7 +184,7 @@ int LuaApi::DebugWriteMemory(lua_State *lua) checkparams(); errorCond(value > 255 || value < -128, "value out of range"); errorCond(address < 0, "address must be >= 0"); - _memoryDumper->SetMemoryValue(type, address, value); + _memoryDumper->SetMemoryValue(type, address, value, false, true); return l.ReturnCount(); } @@ -208,7 +208,7 @@ int LuaApi::WriteMemoryWord(lua_State *lua) checkparams(); errorCond(value > 65535 || value < -32768, "value out of range"); errorCond(address < 0, "address must be >= 0"); - _memoryDumper->SetMemoryValueWord(type, address, value, false); + _memoryDumper->SetMemoryValueWord(type, address, value, false, false); return l.ReturnCount(); } @@ -219,7 +219,7 @@ int LuaApi::DebugReadMemoryWord(lua_State *lua) int address = l.ReadInteger(); checkparams(); errorCond(address < 0, "address must be >= 0"); - l.Return(_memoryDumper->GetMemoryValueWord(type, address)); + l.Return(_memoryDumper->GetMemoryValueWord(type, address, true)); return l.ReturnCount(); } @@ -232,7 +232,7 @@ int LuaApi::DebugWriteMemoryWord(lua_State *lua) checkparams(); errorCond(value > 65535 || value < -32768, "value out of range"); errorCond(address < 0, "address must be >= 0"); - _memoryDumper->SetMemoryValueWord(type, address, value); + _memoryDumper->SetMemoryValueWord(type, address, value, false, true); return l.ReturnCount(); } diff --git a/Core/LuaScriptingContext.cpp b/Core/LuaScriptingContext.cpp index e0a468c3..6a914409 100644 --- a/Core/LuaScriptingContext.cpp +++ b/Core/LuaScriptingContext.cpp @@ -40,15 +40,23 @@ bool LuaScriptingContext::LoadScript(string scriptContent, Debugger* debugger) return false; } -void LuaScriptingContext::CallMemoryCallback(int addr, int value, CallbackType type) +void LuaScriptingContext::CallMemoryCallback(uint16_t addr, uint8_t &value, CallbackType type) { LuaApi::SetContext(this); for(int &ref : _callbacks[(int)type][addr]) { + int top = lua_gettop(_lua); lua_rawgeti(_lua, LUA_REGISTRYINDEX, ref); lua_pushinteger(_lua, addr); - lua_pushinteger(_lua, value); - if(lua_pcall(_lua, 2, 0, 0) != 0) { + lua_pushinteger(_lua, value); + if(lua_pcall(_lua, 2, LUA_MULTRET, 0) != 0) { Log(lua_tostring(_lua, -1)); + } else { + int returnParamCount = lua_gettop(_lua) - top; + if(returnParamCount && lua_isinteger(_lua, -1)) { + int newValue = (int)lua_tointeger(_lua, -1); + value = (uint8_t)newValue; + } + lua_settop(_lua, top); } } } diff --git a/Core/LuaScriptingContext.h b/Core/LuaScriptingContext.h index 6dea6061..db415dd5 100644 --- a/Core/LuaScriptingContext.h +++ b/Core/LuaScriptingContext.h @@ -15,6 +15,6 @@ public: ~LuaScriptingContext(); bool LoadScript(string scriptContent, Debugger* debugger); - void CallMemoryCallback(int addr, int value, CallbackType type); + void CallMemoryCallback(uint16_t addr, uint8_t &value, CallbackType type); int InternalCallEventCallback(EventType type); }; diff --git a/Core/MemoryDumper.cpp b/Core/MemoryDumper.cpp index d5879a49..a4770fc3 100644 --- a/Core/MemoryDumper.cpp +++ b/Core/MemoryDumper.cpp @@ -130,15 +130,19 @@ void MemoryDumper::SetMemoryValue(DebugMemoryType memoryType, uint32_t address, { switch(memoryType) { case DebugMemoryType::CpuMemory: - AddressTypeInfo info; - _debugger->GetAbsoluteAddressAndType(address, &info); - if(info.Address >= 0) { - switch(info.Type) { - case AddressType::InternalRam: SetMemoryValue(DebugMemoryType::InternalRam, info.Address, value, preventRebuildCache, disableSideEffects); break; - case AddressType::PrgRom: SetMemoryValue(DebugMemoryType::PrgRom, info.Address, value, preventRebuildCache, disableSideEffects); break; - case AddressType::WorkRam: SetMemoryValue(DebugMemoryType::WorkRam, info.Address, value, preventRebuildCache, disableSideEffects); break; - case AddressType::SaveRam: SetMemoryValue(DebugMemoryType::SaveRam, info.Address, value, preventRebuildCache, disableSideEffects); break; + if(disableSideEffects) { + AddressTypeInfo info; + _debugger->GetAbsoluteAddressAndType(address, &info); + if(info.Address >= 0) { + switch(info.Type) { + case AddressType::InternalRam: SetMemoryValue(DebugMemoryType::InternalRam, info.Address, value, preventRebuildCache, true); break; + case AddressType::PrgRom: SetMemoryValue(DebugMemoryType::PrgRom, info.Address, value, preventRebuildCache, true); break; + case AddressType::WorkRam: SetMemoryValue(DebugMemoryType::WorkRam, info.Address, value, preventRebuildCache, true); break; + case AddressType::SaveRam: SetMemoryValue(DebugMemoryType::SaveRam, info.Address, value, preventRebuildCache, true); break; + } } + } else { + _memoryManager->DebugWrite(address, value, false); } break; @@ -181,15 +185,19 @@ uint8_t MemoryDumper::GetMemoryValue(DebugMemoryType memoryType, uint32_t addres { switch(memoryType) { case DebugMemoryType::CpuMemory: - AddressTypeInfo info; - _debugger->GetAbsoluteAddressAndType(address, &info); - if(info.Address >= 0) { - switch(info.Type) { - case AddressType::InternalRam: return GetMemoryValue(DebugMemoryType::InternalRam, info.Address, disableSideEffects); - case AddressType::PrgRom: return GetMemoryValue(DebugMemoryType::PrgRom, info.Address, disableSideEffects); - case AddressType::WorkRam: return GetMemoryValue(DebugMemoryType::WorkRam, info.Address, disableSideEffects); - case AddressType::SaveRam: return GetMemoryValue(DebugMemoryType::SaveRam, info.Address, disableSideEffects); + if(disableSideEffects) { + AddressTypeInfo info; + _debugger->GetAbsoluteAddressAndType(address, &info); + if(info.Address >= 0) { + switch(info.Type) { + case AddressType::InternalRam: return GetMemoryValue(DebugMemoryType::InternalRam, info.Address, true); + case AddressType::PrgRom: return GetMemoryValue(DebugMemoryType::PrgRom, info.Address, true); + case AddressType::WorkRam: return GetMemoryValue(DebugMemoryType::WorkRam, info.Address, true); + case AddressType::SaveRam: return GetMemoryValue(DebugMemoryType::SaveRam, info.Address, true); + } } + } else { + return _memoryManager->DebugRead(address, false); } break; diff --git a/Core/ScriptHost.cpp b/Core/ScriptHost.cpp index fd6a7b6d..aa7b00b5 100644 --- a/Core/ScriptHost.cpp +++ b/Core/ScriptHost.cpp @@ -31,7 +31,7 @@ bool ScriptHost::LoadScript(string scriptContent, Debugger* debugger) return true; } -void ScriptHost::ProcessCpuOperation(uint16_t addr, uint8_t value, MemoryOperationType type) +void ScriptHost::ProcessCpuOperation(uint16_t addr, uint8_t &value, MemoryOperationType type) { if(_context) { switch(type) { @@ -42,7 +42,7 @@ void ScriptHost::ProcessCpuOperation(uint16_t addr, uint8_t value, MemoryOperati } } -void ScriptHost::ProcessPpuOperation(uint16_t addr, uint8_t value, MemoryOperationType type) +void ScriptHost::ProcessPpuOperation(uint16_t addr, uint8_t &value, MemoryOperationType type) { if(_context) { switch(type) { diff --git a/Core/ScriptHost.h b/Core/ScriptHost.h index 5bf36ffd..b14c7648 100644 --- a/Core/ScriptHost.h +++ b/Core/ScriptHost.h @@ -19,7 +19,7 @@ public: bool LoadScript(string scriptContent, Debugger* debugger); - void ProcessCpuOperation(uint16_t addr, uint8_t value, MemoryOperationType type); - void ProcessPpuOperation(uint16_t addr, uint8_t value, MemoryOperationType type); + void ProcessCpuOperation(uint16_t addr, uint8_t &value, MemoryOperationType type); + void ProcessPpuOperation(uint16_t addr, uint8_t &value, MemoryOperationType type); void ProcessEvent(EventType eventType); }; \ No newline at end of file diff --git a/Core/ScriptingContext.h b/Core/ScriptingContext.h index 3db38672..85f36bac 100644 --- a/Core/ScriptingContext.h +++ b/Core/ScriptingContext.h @@ -33,7 +33,7 @@ public: void Log(string message); const char* GetLog(); - virtual void CallMemoryCallback(int addr, int value, CallbackType type) = 0; + virtual void CallMemoryCallback(uint16_t addr, uint8_t &value, CallbackType type) = 0; virtual int InternalCallEventCallback(EventType type) = 0; int CallEventCallback(EventType type); diff --git a/GUI.NET/Debugger/frmScript.cs b/GUI.NET/Debugger/frmScript.cs index 1392210b..c5bdd3bd 100644 --- a/GUI.NET/Debugger/frmScript.cs +++ b/GUI.NET/Debugger/frmScript.cs @@ -82,6 +82,7 @@ namespace Mesen.GUI.Debugger using(StreamReader reader = new StreamReader(stream)) { txtScriptContent.Text = reader.ReadToEnd(); _originalText = txtScriptContent.Text; + txtScriptContent.ClearUndo(); } } }