diff --git a/Core/Cpu.cpp b/Core/Cpu.cpp index 43d9ffb..1d2d09c 100644 --- a/Core/Cpu.cpp +++ b/Core/Cpu.cpp @@ -117,3 +117,45 @@ void Cpu::Write(uint32_t addr, uint8_t value, MemoryOperationType type) UpdateIrqNmiFlags(); } #endif + +void Cpu::SetReg(CpuRegister reg, uint16_t value) +{ + switch (reg) { + case CpuRegister::CpuRegA: + { + _state.A = value; + } break; + case CpuRegister::CpuRegX: + { + _state.X = value; + } break; + case CpuRegister::CpuRegY: + { + _state.Y = value; + } break; + case CpuRegister::CpuRegSP: + { + _state.SP = value; + } break; + case CpuRegister::CpuRegD: + { + _state.D = value; + } break; + case CpuRegister::CpuRegPC: + { + _state.PC = value; + } break; + case CpuRegister::CpuRegK: + { + _state.K = value & 0xFF; + } break; + case CpuRegister::CpuRegDBR: + { + _state.DBR = value & 0xFF; + } break; + case CpuRegister::CpuRegPS: + { + _state.PS = value & 0xFF; + } break; + } +} diff --git a/Core/Cpu.h b/Core/Cpu.h index 22f999d..e636acd 100644 --- a/Core/Cpu.h +++ b/Core/Cpu.h @@ -7,6 +7,7 @@ #include "stdafx.h" #include "CpuTypes.h" +#include "DebugTypes.h" #include "../Utilities/ISerializable.h" class MemoryMappings; @@ -345,6 +346,8 @@ public: // Inherited via ISerializable void Serialize(Serializer &s) override; + void SetReg(CpuRegister reg, uint16_t value); + #ifdef DUMMYCPU private: MemoryMappings* _memoryMappings; @@ -370,6 +373,8 @@ public: #endif }; +void SetReg(CpuRegister reg, uint16_t value); + template void Cpu::IncreaseCycleCount() { diff --git a/Core/Cx4.cpp b/Core/Cx4.cpp index 0b276bc..bbbb369 100644 --- a/Core/Cx4.cpp +++ b/Core/Cx4.cpp @@ -478,4 +478,37 @@ uint32_t Cx4::DebugGetDataRamSize() Cx4State Cx4::GetState() { return _state; +} + +void Cx4::SetReg(Cx4Register reg, uint32_t value) +{ + switch (reg) + { + case Cx4Register::Cx4Reg0: case Cx4Register::Cx4Reg1: case Cx4Register::Cx4Reg2: case Cx4Register::Cx4Reg3: + case Cx4Register::Cx4Reg4: case Cx4Register::Cx4Reg5: case Cx4Register::Cx4Reg6: case Cx4Register::Cx4Reg7: + case Cx4Register::Cx4Reg8: case Cx4Register::Cx4Reg9: case Cx4Register::Cx4Reg10: case Cx4Register::Cx4Reg11: + case Cx4Register::Cx4Reg12: case Cx4Register::Cx4Reg13: case Cx4Register::Cx4Reg14: case Cx4Register::Cx4Reg15: + _state.Regs[(static_cast(reg) - static_cast(Cx4Register::Cx4Reg0)) & 0x0F] = value & 0xFFFFFF; // 24-bit + break; + case Cx4Register::Cx4RegPB: + { + _state.PB = value & 0xFFFF; + } break; + case Cx4Register::Cx4RegPC: + { + _state.PC = value & 0xFF; + } break; + case Cx4Register::Cx4RegA: + { + _state.A = value & 0xFFFFFF; // 24-bit + } break; + case Cx4Register::Cx4RegP: + { + _state.P = value & 0xFFFF; + } break; + case Cx4Register::Cx4RegSP: + { + _state.SP = value & 0xFF; + } break; + } } \ No newline at end of file diff --git a/Core/Cx4.h b/Core/Cx4.h index 678c3e9..d18e50c 100644 --- a/Core/Cx4.h +++ b/Core/Cx4.h @@ -129,4 +129,6 @@ public: uint8_t* DebugGetDataRam(); uint32_t DebugGetDataRamSize(); Cx4State GetState(); + + void SetReg(Cx4Register reg, uint32_t value); }; \ No newline at end of file diff --git a/Core/DebugTypes.h b/Core/DebugTypes.h index db0b474..5b1607f 100644 --- a/Core/DebugTypes.h +++ b/Core/DebugTypes.h @@ -284,3 +284,108 @@ enum class CpuType : uint8_t Cx4, Gameboy }; + +enum class CpuRegister : uint8_t +{ + CpuRegA, + CpuRegX, + CpuRegY, + CpuRegSP, + CpuRegD, + CpuRegPC, + CpuRegK, + CpuRegDBR, + CpuRegPS +}; + +enum class Cx4Register : uint8_t +{ + Cx4Reg0, + Cx4Reg1, + Cx4Reg2, + Cx4Reg3, + Cx4Reg4, + Cx4Reg5, + Cx4Reg6, + Cx4Reg7, + Cx4Reg8, + Cx4Reg9, + Cx4Reg10, + Cx4Reg11, + Cx4Reg12, + Cx4Reg13, + Cx4Reg14, + Cx4Reg15, + Cx4RegPB, + Cx4RegPC, + Cx4RegA, + Cx4RegP, + Cx4RegSP +}; + +enum class GbRegister : uint8_t +{ + GbRegPC, + GbRegSP, + GbRegA, + GbRegFlags, + GbRegB, + GbRegC, + GbRegD, + GbRegE, + GbRegH, + GbRegL +}; + +enum class GsuRegister : uint8_t +{ + GsuReg0, + GsuReg1, + GsuReg2, + GsuReg3, + GsuReg4, + GsuReg5, + GsuReg6, + GsuReg7, + GsuReg8, + GsuReg9, + GsuRegA, + GsuRegB, + GsuRegC, + GsuRegD, + GsuRegE, + GsuRegF, + GsuRegSFR +}; + +enum class NecDspRegister : uint8_t +{ + NecDspRegA, + NecDspRegFlagsA, + NecDspRegB, + NecDspRegFlagsB, + NecDspRegTR, + NecDspRegTRB, + NecDspRegPC, + NecDspRegRP, + NecDspRegDP, + NecDspRegDR, + NecDspRegSR, + NecDspRegK, + NecDspRegL, + NecDspRegM, + NecDspRegN, + NecDspRegSerialOut, + NecDspRegSerialIn, + NecDspRegSP +}; + +enum class SpcRegister : uint8_t +{ + SpcRegPC, + SpcRegA, + SpcRegX, + SpcRegY, + SpcRegSP, + SpcRegPS +}; diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index 35eb81a..b015c26 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -511,6 +511,41 @@ void Debugger::GetState(DebugState &state, bool partialPpuState) } } +void Debugger::SetCpuRegister(CpuRegister reg, uint16_t value) +{ + _cpu->SetReg(reg, value); +} + +void Debugger::SetCx4Register(Cx4Register reg, uint32_t value) +{ + _cart->GetCx4()->SetReg(reg, value); +} + +void Debugger::SetGameboyRegister(GbRegister reg, uint16_t value) +{ + _cart->GetGameboy()->SetReg(reg, value); +} + +void Debugger::SetGsuRegister(GsuRegister reg, uint16_t value) +{ + _cart->GetGsu()->SetReg(reg, value); +} + +void Debugger::SetNecDspRegister(NecDspRegister reg, uint16_t value) +{ + _cart->GetDsp()->SetReg(reg, value); +} + +void Debugger::SetSa1Register(CpuRegister reg, uint16_t value) +{ + _cart->GetSa1()->SetReg(reg, value); +} + +void Debugger::SetSpcRegister(SpcRegister reg, uint16_t value) +{ + _spc->SetReg(reg, value); +} + AddressInfo Debugger::GetAbsoluteAddress(AddressInfo relAddress) { if(relAddress.Type == SnesMemoryType::CpuMemory) { diff --git a/Core/Debugger.h b/Core/Debugger.h index b3d6ed2..df65147 100644 --- a/Core/Debugger.h +++ b/Core/Debugger.h @@ -127,7 +127,15 @@ public: void ProcessBreakConditions(bool needBreak, BreakpointManager *bpManager, MemoryOperationInfo &operation, AddressInfo &addressInfo, BreakSource source = BreakSource::Unspecified); void SleepUntilResume(BreakSource source, MemoryOperationInfo* operation = nullptr, int breakpointId = -1); - void GetState(DebugState &state, bool partialPpuState); + void GetState(DebugState& state, bool partialPpuState); + + void SetCpuRegister(CpuRegister reg, uint16_t value); + void SetCx4Register(Cx4Register reg, uint32_t value); + void SetGameboyRegister(GbRegister reg, uint16_t value); + void SetGsuRegister(GsuRegister reg, uint16_t value); + void SetNecDspRegister(NecDspRegister reg, uint16_t value); + void SetSa1Register(CpuRegister reg, uint16_t value); + void SetSpcRegister(SpcRegister reg, uint16_t value); AddressInfo GetAbsoluteAddress(AddressInfo relAddress); AddressInfo GetRelativeAddress(AddressInfo absAddress, CpuType cpuType); diff --git a/Core/Gameboy.cpp b/Core/Gameboy.cpp index 9d0b699..1625d06 100644 --- a/Core/Gameboy.cpp +++ b/Core/Gameboy.cpp @@ -364,3 +364,8 @@ void Gameboy::Serialize(Serializer& s) s.StreamArray(_spriteRam, Gameboy::SpriteRamSize); s.StreamArray(_highRam, Gameboy::HighRamSize); } + +void Gameboy::SetReg(GbRegister reg, uint16_t value) +{ + _cpu->SetReg(reg, value); +} diff --git a/Core/Gameboy.h b/Core/Gameboy.h index 927a5f0..518a940 100644 --- a/Core/Gameboy.h +++ b/Core/Gameboy.h @@ -92,4 +92,6 @@ public: uint64_t GetApuCycleCount(); void Serialize(Serializer& s) override; + + void SetReg(GbRegister reg, uint16_t value); }; \ No newline at end of file diff --git a/Core/GbCpu.cpp b/Core/GbCpu.cpp index 15d232e..a4b20f9 100644 --- a/Core/GbCpu.cpp +++ b/Core/GbCpu.cpp @@ -1389,3 +1389,50 @@ void GbCpu::Serialize(Serializer& s) _state.EiPending ); } + +void GbCpu::SetReg(GbRegister reg, uint16_t value) +{ + switch (reg) + { + case GbRegister::GbRegPC: + { + _state.PC = value; + } break; + case GbRegister::GbRegSP: + { + _state.SP = value; + } break; + case GbRegister::GbRegA: + { + _state.A = value & 0xFF; + } break; + case GbRegister::GbRegFlags: + { + _state.Flags = value & 0xFF; + } break; + case GbRegister::GbRegB: + { + _state.B = value & 0xFF; + } break; + case GbRegister::GbRegC: + { + _state.C = value & 0xFF; + } break; + case GbRegister::GbRegD: + { + _state.D = value & 0xFF; + } break; + case GbRegister::GbRegE: + { + _state.E = value & 0xFF; + } break; + case GbRegister::GbRegH: + { + _state.H = value & 0xFF; + } break; + case GbRegister::GbRegL: + { + _state.L = value & 0xFF; + } break; + } +} diff --git a/Core/GbCpu.h b/Core/GbCpu.h index 580fecb..474708c 100644 --- a/Core/GbCpu.h +++ b/Core/GbCpu.h @@ -150,4 +150,6 @@ public: void Exec(); void Serialize(Serializer& s) override; + + void SetReg(GbRegister reg, uint16_t value); }; diff --git a/Core/Gsu.cpp b/Core/Gsu.cpp index bb5e933..e3aca33 100644 --- a/Core/Gsu.cpp +++ b/Core/Gsu.cpp @@ -651,3 +651,33 @@ uint32_t Gsu::DebugGetWorkRamSize() { return _gsuRamSize; } + +void Gsu::SetReg(GsuRegister reg, uint16_t value) +{ + switch (reg) + { + case GsuRegister::GsuReg0: + case GsuRegister::GsuReg1: + case GsuRegister::GsuReg2: + case GsuRegister::GsuReg3: + case GsuRegister::GsuReg4: + case GsuRegister::GsuReg5: + case GsuRegister::GsuReg6: + case GsuRegister::GsuReg7: + case GsuRegister::GsuReg8: + case GsuRegister::GsuReg9: + case GsuRegister::GsuRegA: + case GsuRegister::GsuRegB: + case GsuRegister::GsuRegC: + case GsuRegister::GsuRegD: + case GsuRegister::GsuRegE: + case GsuRegister::GsuRegF: + { + _state.R[static_cast(reg) & 0xF] = value; + } break; + case GsuRegister::GsuRegSFR: + { + _state.SFR.SetFlags(value); + } break; + } +} diff --git a/Core/Gsu.h b/Core/Gsu.h index e8524d6..744760b 100644 --- a/Core/Gsu.h +++ b/Core/Gsu.h @@ -170,4 +170,6 @@ public: MemoryMappings* GetMemoryMappings(); uint8_t* DebugGetWorkRam(); uint32_t DebugGetWorkRamSize(); + + void SetReg(GsuRegister reg, uint16_t value); }; \ No newline at end of file diff --git a/Core/GsuTypes.h b/Core/GsuTypes.h index 98537a0..2dabec2 100644 --- a/Core/GsuTypes.h +++ b/Core/GsuTypes.h @@ -39,6 +39,27 @@ struct GsuFlags (Irq << 7) ); } + + void SetFlags(uint16_t flags) + { + // 0 bit is clear + Zero = flags & (1 << 1); + Carry = flags & (1 << 2); + Sign = flags & (1 << 3); + Overflow = flags & (1 << 4); + Running = flags & (1 << 5); + RomReadPending = flags & (1 << 6); + // 7 bit is clear + + Alt1 = flags & (1 << (8 + 0)); + Alt2 = flags & (1 << (8 + 1)); + ImmLow = flags & (1 << (8 + 2)); + ImmHigh = flags & (1 << (8 + 3)); + Prefix = flags & (1 << (8 + 4)); + // 5 bit is clear + // 6 bit is clear + Irq = flags & (1 << (8 + 7)); + } }; struct GsuPixelCache diff --git a/Core/NecDsp.cpp b/Core/NecDsp.cpp index ae89c8a..49b750c 100644 --- a/Core/NecDsp.cpp +++ b/Core/NecDsp.cpp @@ -586,3 +586,82 @@ void NecDsp::Serialize(Serializer &s) s.StreamArray(_stack, _stackSize); } +void NecDsp::SetReg(NecDspRegister reg, uint16_t value) +{ + switch (reg) + { + case NecDspRegister::NecDspRegA: + { + _state.A = value; + } break; + case NecDspRegister::NecDspRegFlagsA: + { + _state.FlagsA.SetFlags(value & 0xFF); + } break; + case NecDspRegister::NecDspRegB: + { + _state.B = value; + } break; + case NecDspRegister::NecDspRegFlagsB: + { + _state.FlagsB.SetFlags(value & 0xFF); + } break; + case NecDspRegister::NecDspRegTR: + { + _state.TR = value; + } break; + case NecDspRegister::NecDspRegTRB: + { + _state.TRB = value; + } break; + case NecDspRegister::NecDspRegPC: + { + _state.PC = value; + } break; + case NecDspRegister::NecDspRegRP: + { + _state.RP = value; + } break; + case NecDspRegister::NecDspRegDP: + { + _state.DP = value; + } break; + case NecDspRegister::NecDspRegDR: + { + _state.DR = value; + } break; + case NecDspRegister::NecDspRegSR: + { + _state.SR = value; + } break; + case NecDspRegister::NecDspRegK: + { + _state.K = value; + } break; + case NecDspRegister::NecDspRegL: + { + _state.L = value; + } break; + case NecDspRegister::NecDspRegM: + { + _state.M = value; + } break; + case NecDspRegister::NecDspRegN: + { + _state.N = value; + } break; + case NecDspRegister::NecDspRegSerialOut: + { + _state.SerialOut = value; + } break; + case NecDspRegister::NecDspRegSerialIn: + { + _state.SerialIn = value; + } break; + case NecDspRegister::NecDspRegSP: + { + _state.SP = value & 0xFF; + } break; + } +} + diff --git a/Core/NecDsp.h b/Core/NecDsp.h index 9b2cdd7..184356a 100644 --- a/Core/NecDsp.h +++ b/Core/NecDsp.h @@ -82,4 +82,6 @@ public: NecDspState GetState(); void Serialize(Serializer &s) override; + + void SetReg(NecDspRegister reg, uint16_t value); }; \ No newline at end of file diff --git a/Core/NecDspTypes.h b/Core/NecDspTypes.h index 57de3b2..0fd65e6 100644 --- a/Core/NecDspTypes.h +++ b/Core/NecDspTypes.h @@ -9,6 +9,16 @@ struct NecDspAccFlags bool Overflow1; bool Sign0; bool Sign1; + + void SetFlags(uint8_t flags) + { + Carry = flags & (1 << 0); + Zero = flags & (1 << 1); + Overflow0 = flags & (1 << 2); + Overflow1 = flags & (1 << 3); + Sign0 = flags & (1 << 4); + Sign1 = flags & (1 << 5); + } }; namespace NecDspStatusFlags diff --git a/Core/Ppu.cpp b/Core/Ppu.cpp index af496c8..5e3e55d 100644 --- a/Core/Ppu.cpp +++ b/Core/Ppu.cpp @@ -1723,7 +1723,7 @@ uint8_t Ppu::Read(uint16_t addr) if(_regs->GetIoPortOutput() & 0x80) { _locationLatched = false; - //"The high/low selector is reset to elowf when $213F is read" (the selector is NOT reset when the counter is latched) + //"The high/low selector is reset to ?elow?f when $213F is read" (the selector is NOT reset when the counter is latched) _horizontalLocToggle = false; _verticalLocationToggle = false; } @@ -1832,7 +1832,7 @@ void Ppu::Write(uint32_t addr, uint8_t value) _state.MosaicSize = ((value & 0xF0) >> 4) + 1; uint8_t mosaicEnabled = value & 0x0F; if(!_state.MosaicEnabled && mosaicEnabled) { - //"If this register is set during the frame, the starting scanline is the current scanline, otherwise it is the first visible scanline of the frame." + //"If this register is set during the frame, the ?starting scanline is the current scanline, otherwise it is the first visible scanline of the frame." //This is only done when mosaic is turned on from an off state (FF6 mosaic effect looks wrong otherwise) //FF6's mosaic effect is broken on some screens without this. _mosaicScanlineCounter = _state.MosaicSize + 1; @@ -2317,4 +2317,4 @@ void Ppu::RenderTilemapMode7() } else { RenderTilemapMode7(); } -} +} \ No newline at end of file diff --git a/Core/Sa1.cpp b/Core/Sa1.cpp index bc61b6c..1ec9a72 100644 --- a/Core/Sa1.cpp +++ b/Core/Sa1.cpp @@ -863,4 +863,9 @@ void Sa1::Serialize(Serializer &s) UpdateSaveRamMappings(); ProcessInterrupts(); } -} \ No newline at end of file +} + +void Sa1::SetReg(CpuRegister reg, uint16_t value) +{ + _cpu->SetReg(reg, value); +} diff --git a/Core/Sa1.h b/Core/Sa1.h index 4ffafd2..e709d48 100644 --- a/Core/Sa1.h +++ b/Core/Sa1.h @@ -95,4 +95,6 @@ public: MemoryMappings* GetMemoryMappings(); void LoadBattery() override; void SaveBattery() override; + + void SetReg(CpuRegister reg, uint16_t value); }; diff --git a/Core/Sa1Cpu.cpp b/Core/Sa1Cpu.cpp index 32c4b90..27b3b18 100644 --- a/Core/Sa1Cpu.cpp +++ b/Core/Sa1Cpu.cpp @@ -142,4 +142,46 @@ uint16_t Sa1Cpu::GetResetVector() void Sa1Cpu::IncreaseCycleCount(uint64_t cycleCount) { _state.CycleCount += cycleCount; -} \ No newline at end of file +} + +void Sa1Cpu::SetReg(CpuRegister reg, uint16_t value) +{ + switch (reg) { + case CpuRegister::CpuRegA: + { + _state.A = value; + } break; + case CpuRegister::CpuRegX: + { + _state.X = value; + } break; + case CpuRegister::CpuRegY: + { + _state.Y = value; + } break; + case CpuRegister::CpuRegSP: + { + _state.SP = value; + } break; + case CpuRegister::CpuRegD: + { + _state.D = value; + } break; + case CpuRegister::CpuRegPC: + { + _state.PC = value; + } break; + case CpuRegister::CpuRegK: + { + _state.K = value & 0xFF; + } break; + case CpuRegister::CpuRegDBR: + { + _state.DBR = value & 0xFF; + } break; + case CpuRegister::CpuRegPS: + { + _state.PS = value & 0xFF; + } break; + } +} diff --git a/Core/Sa1Cpu.h b/Core/Sa1Cpu.h index 9b86467..d8c6d1c 100644 --- a/Core/Sa1Cpu.h +++ b/Core/Sa1Cpu.h @@ -1,6 +1,7 @@ #pragma once #include "stdafx.h" #include "CpuTypes.h" +#include "DebugTypes.h" #include "../Utilities/ISerializable.h" class Sa1; @@ -333,6 +334,8 @@ public: // Inherited via ISerializable void Serialize(Serializer &s) override; + + void SetReg(CpuRegister reg, uint16_t value); }; template diff --git a/Core/Spc.cpp b/Core/Spc.cpp index d9110eb..06126ae 100644 --- a/Core/Spc.cpp +++ b/Core/Spc.cpp @@ -582,4 +582,35 @@ void Spc::LoadSpcFile(SpcFileData* data) _state.Timer0.SetOutput(data->TimerOutput[0]); _state.Timer1.SetOutput(data->TimerOutput[0]); _state.Timer2.SetOutput(data->TimerOutput[0]); -} \ No newline at end of file +} + +void Spc::SetReg(SpcRegister reg, uint16_t value) +{ + switch (reg) + { + case SpcRegister::SpcRegPC: + { + _state.PC = value; + } break; + case SpcRegister::SpcRegA: + { + _state.A = value & 0xFF; + } break; + case SpcRegister::SpcRegX: + { + _state.X = value & 0xFF; + } break; + case SpcRegister::SpcRegY: + { + _state.Y = value & 0xFF; + } break; + case SpcRegister::SpcRegSP: + { + _state.SP = value & 0xFF; + } break; + case SpcRegister::SpcRegPS: + { + _state.PS = value & 0xFF; + } break; + } +} diff --git a/Core/Spc.h b/Core/Spc.h index 8d65bcd..1d745dc 100644 --- a/Core/Spc.h +++ b/Core/Spc.h @@ -8,6 +8,7 @@ #include "stdafx.h" #include "SpcTypes.h" #include "CpuTypes.h" +#include "DebugTypes.h" #include "SpcTimer.h" #include "../Utilities/ISerializable.h" @@ -317,6 +318,8 @@ public: void Serialize(Serializer &s) override; + void SetReg(SpcRegister reg, uint16_t value); + #ifdef DUMMYSPC private: uint32_t _writeCounter = 0; diff --git a/InteropDLL/DebugApiWrapper.cpp b/InteropDLL/DebugApiWrapper.cpp index 45d2179..ba2d442 100644 --- a/InteropDLL/DebugApiWrapper.cpp +++ b/InteropDLL/DebugApiWrapper.cpp @@ -67,7 +67,15 @@ extern "C" DllExport void __stdcall ResetProfiler(CpuType cpuType) { GetDebugger()->GetCallstackManager(cpuType)->GetProfiler()->Reset(); } DllExport void __stdcall GetState(DebugState& state) { GetDebugger()->GetState(state, false); } - + + DllExport void __stdcall SetCpuRegister(CpuRegister reg, uint16_t value) { GetDebugger()->SetCpuRegister(reg, value); } + DllExport void __stdcall SetSpcRegister(SpcRegister reg, uint32_t value) { GetDebugger()->SetSpcRegister(reg, value); } + DllExport void __stdcall SetNecDspRegister(NecDspRegister reg, uint32_t value) { GetDebugger()->SetNecDspRegister(reg, value); } + DllExport void __stdcall SetSa1Register(CpuRegister reg, uint32_t value) { GetDebugger()->SetSa1Register(reg, value); } + DllExport void __stdcall SetGsuRegister(GsuRegister reg, uint32_t value) { GetDebugger()->SetGsuRegister(reg, value); } + DllExport void __stdcall SetCx4Register(Cx4Register reg, uint32_t value) { GetDebugger()->SetCx4Register(reg, value); } + DllExport void __stdcall SetGameboyRegister(GbRegister reg, uint32_t value) { GetDebugger()->SetGameboyRegister(reg, value); } + DllExport const char* __stdcall GetDebuggerLog() { _logString = GetDebugger()->GetLog();