diff --git a/Core/BaseMapper.cpp b/Core/BaseMapper.cpp index c3ffcaaf..df17ec5f 100644 --- a/Core/BaseMapper.cpp +++ b/Core/BaseMapper.cpp @@ -1133,6 +1133,29 @@ int32_t BaseMapper::FromAbsoluteAddress(uint32_t addr, AddressType type) return -1; } +int32_t BaseMapper::FromAbsolutePpuAddress(uint32_t addr, PpuAddressType type) +{ + uint8_t* ptrAddress; + + switch(type) { + case PpuAddressType::ChrRom: ptrAddress = _chrRom; break; + case PpuAddressType::ChrRam: ptrAddress = _chrRam; break; + case PpuAddressType::NametableRam: ptrAddress = _nametableRam; break; + default: return -1; + } + ptrAddress += addr; + + for(int i = 0; i < 0x40; i++) { + uint8_t* pageAddress = _chrPages[i]; + if(pageAddress != nullptr && ptrAddress >= pageAddress && ptrAddress <= pageAddress + 0xFF) { + return (i << 8) + (uint32_t)(ptrAddress - pageAddress); + } + } + + //Address is currently not mapped + return -1; +} + bool BaseMapper::IsWriteRegister(uint16_t addr) { return _isWriteRegisterAddr[addr]; diff --git a/Core/BaseMapper.h b/Core/BaseMapper.h index 6e7c42c7..12af8492 100644 --- a/Core/BaseMapper.h +++ b/Core/BaseMapper.h @@ -226,6 +226,7 @@ public: int32_t ToAbsoluteChrRomAddress(uint16_t addr); int32_t FromAbsoluteChrAddress(uint32_t addr); int32_t FromAbsoluteAddress(uint32_t addr, AddressType type = AddressType::PrgRom); + int32_t FromAbsolutePpuAddress(uint32_t addr, PpuAddressType type); bool IsWriteRegister(uint16_t addr); bool IsReadRegister(uint16_t addr); diff --git a/Core/Breakpoint.cpp b/Core/Breakpoint.cpp index e15e0b3b..77f945db 100644 --- a/Core/Breakpoint.cpp +++ b/Core/Breakpoint.cpp @@ -50,7 +50,8 @@ bool Breakpoint::Matches(uint32_t memoryAddr, PpuAddressTypeInfo &info) } else if( (_memoryType == DebugMemoryType::ChrRam && info.Type == PpuAddressType::ChrRam) || (_memoryType == DebugMemoryType::ChrRom && info.Type == PpuAddressType::ChrRom) || - (_memoryType == DebugMemoryType::PaletteMemory && info.Type == PpuAddressType::PaletteRam) + (_memoryType == DebugMemoryType::PaletteMemory && info.Type == PpuAddressType::PaletteRam) || + (_memoryType == DebugMemoryType::NametableRam && info.Type == PpuAddressType::NametableRam) ) { if(_startAddr == -1) { return true; diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index 0cec8bf7..aa66ec6b 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -1178,6 +1178,14 @@ int32_t Debugger::GetRelativeAddress(uint32_t addr, AddressType type) return -1; } +int32_t Debugger::GetRelativePpuAddress(uint32_t addr, PpuAddressType type) +{ + if(type == PpuAddressType::PaletteRam) { + return 0x3F00 | (addr & 0x1F); + } + return _mapper->FromAbsolutePpuAddress(addr, type); +} + int32_t Debugger::GetAbsoluteAddress(uint32_t addr) { return _mapper->ToAbsoluteAddress(addr); @@ -1188,11 +1196,6 @@ int32_t Debugger::GetAbsoluteChrAddress(uint32_t addr) return _mapper->ToAbsoluteChrAddress(addr); } -int32_t Debugger::GetRelativeChrAddress(uint32_t absoluteAddr) -{ - return _mapper->FromAbsoluteChrAddress(absoluteAddr); -} - void Debugger::SetNextStatement(uint16_t addr) { if(_currentReadAddr) { diff --git a/Core/Debugger.h b/Core/Debugger.h index a54e38ff..4d06ee47 100644 --- a/Core/Debugger.h +++ b/Core/Debugger.h @@ -221,9 +221,9 @@ public: const char* GetCode(uint32_t &length); int32_t GetRelativeAddress(uint32_t addr, AddressType type); + int32_t GetRelativePpuAddress(uint32_t addr, PpuAddressType type); int32_t GetAbsoluteAddress(uint32_t addr); int32_t GetAbsoluteChrAddress(uint32_t addr); - int32_t GetRelativeChrAddress(uint32_t addr); void GetAbsoluteAddressAndType(uint32_t relativeAddr, AddressTypeInfo* info); void GetPpuAbsoluteAddressAndType(uint32_t relativeAddr, PpuAddressTypeInfo* info); diff --git a/GUI.NET/Debugger/Breakpoint.cs b/GUI.NET/Debugger/Breakpoint.cs index de9a109e..54fea24e 100644 --- a/GUI.NET/Debugger/Breakpoint.cs +++ b/GUI.NET/Debugger/Breakpoint.cs @@ -123,7 +123,7 @@ namespace Mesen.GUI.Debugger string type; switch(MemoryType) { - default: + default: throw new Exception("invalid type"); case DebugMemoryType.CpuMemory: type = "CPU"; break; case DebugMemoryType.PpuMemory: type = "PPU"; break; case DebugMemoryType.PrgRom: type = "PRG"; break; @@ -131,6 +131,7 @@ namespace Mesen.GUI.Debugger case DebugMemoryType.SaveRam: type = "SRAM"; break; case DebugMemoryType.ChrRam: type = "CHR"; break; case DebugMemoryType.ChrRom: type = "CHR"; break; + case DebugMemoryType.NametableRam: type = "NT"; break; case DebugMemoryType.PaletteMemory: type = "PAL"; break; } @@ -167,8 +168,8 @@ namespace Mesen.GUI.Debugger if(this.IsAbsoluteAddress) { if(IsCpuBreakpoint) { return InteropEmu.DebugGetRelativeAddress(address, this.MemoryType.ToAddressType()); - } else if(_memoryType == DebugMemoryType.ChrRam || _memoryType == DebugMemoryType.ChrRom) { - return InteropEmu.DebugGetRelativeChrAddress(address); + } else { + return InteropEmu.DebugGetRelativePpuAddress(address, this.MemoryType.ToPpuAddressType()); } } return -1; @@ -179,8 +180,8 @@ namespace Mesen.GUI.Debugger if(this.AddressType == BreakpointAddressType.AddressRange && this.IsAbsoluteAddress) { if(IsCpuBreakpoint) { return InteropEmu.DebugGetRelativeAddress(this.EndAddress, this.MemoryType.ToAddressType()); - } else if(_memoryType == DebugMemoryType.ChrRam || _memoryType == DebugMemoryType.ChrRom) { - return InteropEmu.DebugGetRelativeChrAddress(this.EndAddress); + } else { + return InteropEmu.DebugGetRelativePpuAddress(this.EndAddress, this.MemoryType.ToPpuAddressType()); } } return -1; diff --git a/GUI.NET/Debugger/frmBreakpoint.cs b/GUI.NET/Debugger/frmBreakpoint.cs index bb89aff9..c2371226 100644 --- a/GUI.NET/Debugger/frmBreakpoint.cs +++ b/GUI.NET/Debugger/frmBreakpoint.cs @@ -65,6 +65,7 @@ namespace Mesen.GUI.Debugger cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.ChrRam)); } + cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.NametableRam)); cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.PaletteMemory)); this.toolTip.SetToolTip(this.picExpressionWarning, "Condition contains invalid syntax or symbols."); diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index ed0667aa..eef22cf0 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -245,7 +245,7 @@ namespace Mesen.GUI [DllImport(DLLPath)] public static extern Int32 DebugFindSubEntryPoint(UInt16 relativeAddr); [DllImport(DLLPath)] public static extern Int32 DebugGetAbsoluteAddress(UInt32 relativeAddr); [DllImport(DLLPath)] public static extern Int32 DebugGetAbsoluteChrAddress(UInt32 relativeAddr); - [DllImport(DLLPath)] public static extern Int32 DebugGetRelativeChrAddress(UInt32 absoluteAddr); + [DllImport(DLLPath)] public static extern Int32 DebugGetRelativePpuAddress(UInt32 absoluteAddr, PpuAddressType type); [DllImport(DLLPath)] public static extern Int32 DebugGetMemorySize(DebugMemoryType type); [DllImport(DLLPath)] public static extern Byte DebugGetMemoryValue(DebugMemoryType type, UInt32 address); [DllImport(DLLPath)] public static extern void DebugSetMemoryValue(DebugMemoryType type, UInt32 address, byte value); @@ -280,6 +280,15 @@ namespace Mesen.GUI } [DllImport(DLLPath)] public static extern void DebugGetAbsoluteAddressAndType(UInt32 relativeAddr, AddressTypeInfo addressTypeInfo); + + [DllImport(DLLPath, EntryPoint = "DebugGetPpuAbsoluteAddressAndType")] private static extern void DebugGetPpuAbsoluteAddressAndTypeWrapper(UInt32 relativeAddr, PpuAddressTypeInfo addressTypeInfo); + public static PpuAddressTypeInfo DebugGetPpuAbsoluteAddressAndType(UInt32 relativeAddr) + { + PpuAddressTypeInfo addressTypeInfo = new PpuAddressTypeInfo(); + InteropEmu.DebugGetPpuAbsoluteAddressAndTypeWrapper(relativeAddr, addressTypeInfo); + return addressTypeInfo; + } + [DllImport(DLLPath)] public static extern void DebugSetPpuViewerScanlineCycle(Int32 ppuViewerId, Int32 scanline, Int32 cycle); [DllImport(DLLPath)] public static extern void DebugClearPpuViewerSettings(Int32 ppuViewerId); @@ -2329,6 +2338,14 @@ namespace Mesen.GUI Pause = 10, BreakAfterSuspend = 11, } + + public enum PpuAddressType + { + ChrRom = 0, + ChrRam = 1, + PaletteRam = 2, + NametableRam = 3 + } public enum AddressType { @@ -2338,7 +2355,7 @@ namespace Mesen.GUI SaveRam = 3, Register = 4 } - + public static class AddressTypeExtensions { public static DebugMemoryType ToMemoryType(this AddressType type) @@ -2353,6 +2370,17 @@ namespace Mesen.GUI return DebugMemoryType.CpuMemory; } + public static DebugMemoryType ToMemoryType(this PpuAddressType type) + { + switch(type) { + case PpuAddressType.ChrRom: return DebugMemoryType.ChrRom; + case PpuAddressType.ChrRam: return DebugMemoryType.ChrRam; + case PpuAddressType.NametableRam: return DebugMemoryType.NametableRam; + case PpuAddressType.PaletteRam: return DebugMemoryType.PaletteMemory; + } + throw new Exception("Invalid memory type"); + } + public static AddressType ToAddressType(this DebugMemoryType type) { switch(type) { @@ -2364,6 +2392,17 @@ namespace Mesen.GUI } return AddressType.Register; } + + public static PpuAddressType ToPpuAddressType(this DebugMemoryType type) + { + switch(type) { + case DebugMemoryType.ChrRom: return PpuAddressType.ChrRom; + case DebugMemoryType.ChrRam: return PpuAddressType.ChrRam; + case DebugMemoryType.NametableRam: return PpuAddressType.NametableRam; + case DebugMemoryType.PaletteMemory: return PpuAddressType.PaletteRam; + } + throw new Exception("Invalid memory type"); + } } public enum InteropMemoryOperationType @@ -2402,7 +2441,14 @@ namespace Mesen.GUI public Int32 Address; public AddressType Type; } - + + [StructLayout(LayoutKind.Sequential)] + public class PpuAddressTypeInfo + { + public Int32 Address; + public PpuAddressType Type; + } + public class MD5Helper { public static string GetMD5Hash(string filename) diff --git a/InteropDLL/DebugWrapper.cpp b/InteropDLL/DebugWrapper.cpp index d40383cc..f8a81ca9 100644 --- a/InteropDLL/DebugWrapper.cpp +++ b/InteropDLL/DebugWrapper.cpp @@ -85,10 +85,11 @@ extern "C" DllExport void __stdcall DebugGetFunctionEntryPoints(int32_t *entryPoints, int32_t maxCount) { GetDebugger()->GetFunctionEntryPoints(entryPoints, maxCount); } DllExport int32_t __stdcall DebugGetRelativeAddress(uint32_t addr, AddressType type) { return GetDebugger()->GetRelativeAddress(addr, type); } + DllExport int32_t __stdcall DebugGetRelativePpuAddress(uint32_t addr, PpuAddressType type) { return GetDebugger()->GetRelativePpuAddress(addr, type); } DllExport int32_t __stdcall DebugGetAbsoluteAddress(uint32_t addr) { return GetDebugger()->GetAbsoluteAddress(addr); } DllExport int32_t __stdcall DebugGetAbsoluteChrAddress(uint32_t addr) { return GetDebugger()->GetAbsoluteChrAddress(addr); } - DllExport int32_t __stdcall DebugGetRelativeChrAddress(uint32_t addr) { return GetDebugger()->GetRelativeChrAddress(addr); } DllExport void __stdcall DebugGetAbsoluteAddressAndType(uint32_t relativeAddr, AddressTypeInfo* info) { return GetDebugger()->GetAbsoluteAddressAndType(relativeAddr, info); } + DllExport void __stdcall DebugGetPpuAbsoluteAddressAndType(uint32_t relativeAddr, PpuAddressTypeInfo* info) { return GetDebugger()->GetPpuAbsoluteAddressAndType(relativeAddr, info); } DllExport bool __stdcall DebugLoadCdlFile(char* cdlFilepath) { return GetDebugger()->LoadCdlFile(cdlFilepath); } DllExport bool __stdcall DebugSaveCdlFile(char* cdlFilepath) { return GetDebugger()->GetCodeDataLogger()->SaveCdlFile(cdlFilepath); }