Debugger: Fixes/improvements to CA65 .dbg file import

This commit is contained in:
Sour 2018-02-23 08:28:29 -05:00
parent c8cbbb5c41
commit feb4828a9b
7 changed files with 99 additions and 25 deletions

View file

@ -41,30 +41,42 @@ bool CodeDataLogger::LoadCdlFile(string cdlFilepath)
cdlFile.read((char*)_cdlData, _prgSize + _chrSize); cdlFile.read((char*)_cdlData, _prgSize + _chrSize);
cdlFile.close(); cdlFile.close();
for(int i = 0, len = _prgSize; i < len; i++) { CalculateStats();
if(IsCode(i)) {
_codeSize++;
} else if(IsData(i)) {
_dataSize++;
}
}
for(int i = 0, len = _chrSize; i < len; i++) {
if(IsDrawn(i) || IsRead(i)) {
_usedChrSize++;
if(IsDrawn(i)) {
_drawnChrSize++;
} else if(IsRead(i)) {
_readChrSize++;
}
}
}
return true; return true;
} }
} }
return false; return false;
} }
void CodeDataLogger::CalculateStats()
{
_codeSize = 0;
_dataSize = 0;
_usedChrSize = 0;
_drawnChrSize = 0;
_readChrSize = 0;
for(int i = 0, len = _prgSize; i < len; i++) {
if(IsCode(i)) {
_codeSize++;
} else if(IsData(i)) {
_dataSize++;
}
}
for(int i = 0, len = _chrSize; i < len; i++) {
if(IsDrawn(i) || IsRead(i)) {
_usedChrSize++;
if(IsDrawn(i)) {
_drawnChrSize++;
} else if(IsRead(i)) {
_readChrSize++;
}
}
}
}
bool CodeDataLogger::SaveCdlFile(string cdlFilepath) bool CodeDataLogger::SaveCdlFile(string cdlFilepath)
{ {
ofstream cdlFile(cdlFilepath, ios::out | ios::binary); ofstream cdlFile(cdlFilepath, ios::out | ios::binary);
@ -159,6 +171,14 @@ bool CodeDataLogger::IsDrawn(uint32_t absoluteAddr)
return (_cdlData[absoluteAddr + _prgSize] & (uint8_t)CdlChrFlags::Drawn) == (uint8_t)CdlChrFlags::Drawn; return (_cdlData[absoluteAddr + _prgSize] & (uint8_t)CdlChrFlags::Drawn) == (uint8_t)CdlChrFlags::Drawn;
} }
void CodeDataLogger::SetCdlData(uint8_t *cdlData, uint32_t length)
{
if(length <= _prgSize + _chrSize) {
memcpy(_cdlData, cdlData, length);
CalculateStats();
}
}
void CodeDataLogger::GetCdlData(uint32_t offset, uint32_t length, DebugMemoryType memoryType, uint8_t * cdlData) void CodeDataLogger::GetCdlData(uint32_t offset, uint32_t length, DebugMemoryType memoryType, uint8_t * cdlData)
{ {
if(memoryType == DebugMemoryType::PrgRom) { if(memoryType == DebugMemoryType::PrgRom) {

View file

@ -57,6 +57,8 @@ private:
SimpleLock _lock; SimpleLock _lock;
void CalculateStats();
public: public:
CodeDataLogger(Debugger *debugger, uint32_t prgSize, uint32_t chrSize); CodeDataLogger(Debugger *debugger, uint32_t prgSize, uint32_t chrSize);
~CodeDataLogger(); ~CodeDataLogger();
@ -77,6 +79,7 @@ public:
bool IsRead(uint32_t absoluteAddr); bool IsRead(uint32_t absoluteAddr);
bool IsDrawn(uint32_t absoluteAddr); bool IsDrawn(uint32_t absoluteAddr);
void SetCdlData(uint8_t *cdlData, uint32_t length);
void GetCdlData(uint32_t offset, uint32_t length, DebugMemoryType memoryType, uint8_t* cdlData); void GetCdlData(uint32_t offset, uint32_t length, DebugMemoryType memoryType, uint8_t* cdlData);
void StripData(uint8_t* romBuffer, CdlStripFlag flag); void StripData(uint8_t* romBuffer, CdlStripFlag flag);

View file

@ -178,6 +178,13 @@ bool Debugger::LoadCdlFile(string cdlFilepath)
return false; return false;
} }
void Debugger::SetCdlData(uint8_t* cdlData, uint32_t length)
{
DebugBreakHelper helper(this);
_codeDataLogger->SetCdlData(cdlData, length);
UpdateCdlCache();
}
void Debugger::ResetCdl() void Debugger::ResetCdl()
{ {
DebugBreakHelper helper(this); DebugBreakHelper helper(this);

View file

@ -173,6 +173,7 @@ public:
void Run(); void Run();
bool LoadCdlFile(string cdlFilepath); bool LoadCdlFile(string cdlFilepath);
void SetCdlData(uint8_t* cdlData, uint32_t length);
void ResetCdl(); void ResetCdl();
void UpdateCdlCache(); void UpdateCdlCache();
bool IsMarkedAsCode(uint16_t relativeAddress); bool IsMarkedAsCode(uint16_t relativeAddress);

View file

@ -28,11 +28,11 @@ namespace Mesen.GUI.Debugger
private HashSet<string> _filesNotFound = new HashSet<string>(); private HashSet<string> _filesNotFound = new HashSet<string>();
private int _errorCount = 0; private int _errorCount = 0;
private static Regex _segmentRegex = new Regex("seg\tid=([0-9]+),.*start=0x([0-9a-fA-F]+)", RegexOptions.Compiled); private static Regex _segmentRegex = new Regex("seg\tid=([0-9]+),.*start=0x([0-9a-fA-F]+),.*size=0x([0-9A-Fa-f]+)", RegexOptions.Compiled);
private static Regex _segmentPrgRomRegex = new Regex("seg\tid=([0-9]+),.*start=0x([0-9a-fA-F]+),.*ooffs=([0-9]+)", RegexOptions.Compiled); private static Regex _segmentPrgRomRegex = new Regex("seg\tid=([0-9]+),.*start=0x([0-9a-fA-F]+),.*size=0x([0-9A-Fa-f]+),.*ooffs=([0-9]+)", RegexOptions.Compiled);
private static Regex _lineRegex = new Regex("line\tid=([0-9]+),.*file=([0-9]+),.*line=([0-9]+),.*span=([0-9]+)", RegexOptions.Compiled); private static Regex _lineRegex = new Regex("line\tid=([0-9]+),.*file=([0-9]+),.*line=([0-9]+),.*span=([0-9]+)", RegexOptions.Compiled);
private static Regex _fileRegex = new Regex("file\tid=([0-9]+),.*name=\"([^\"]+)\"", RegexOptions.Compiled); private static Regex _fileRegex = new Regex("file\tid=([0-9]+),.*name=\"([^\"]+)\"", RegexOptions.Compiled);
private static Regex _spanRegex = new Regex("span\tid=([0-9]+),.*seg=([0-9]+),.*start=([0-9]+)", RegexOptions.Compiled); private static Regex _spanRegex = new Regex("span\tid=([0-9]+),.*seg=([0-9]+),.*start=([0-9]+),.*size=([0-9]+)(,.*type=([0-9]+)){0,1}", RegexOptions.Compiled);
private static Regex _symbolRegex = new Regex("sym\tid=([0-9]+).*name=\"([0-9a-zA-Z@_]+)\",.*val=0x([0-9a-fA-F]+),.*seg=([0-9a-zA-Z]+)", RegexOptions.Compiled); private static Regex _symbolRegex = new Regex("sym\tid=([0-9]+).*name=\"([0-9a-zA-Z@_]+)\",.*val=0x([0-9a-fA-F]+),.*seg=([0-9a-zA-Z]+)", RegexOptions.Compiled);
private static Regex _asmFirstLineRegex = new Regex(";(.*)", RegexOptions.Compiled); private static Regex _asmFirstLineRegex = new Regex(";(.*)", RegexOptions.Compiled);
@ -46,13 +46,14 @@ namespace Mesen.GUI.Debugger
if(match.Success) { if(match.Success) {
SegmentInfo segment = new SegmentInfo() { SegmentInfo segment = new SegmentInfo() {
ID = Int32.Parse(match.Groups[1].Value), ID = Int32.Parse(match.Groups[1].Value),
Start = Int32.Parse(match.Groups[2].Value, System.Globalization.NumberStyles.HexNumber), Start = Int32.Parse(match.Groups[2].Value, NumberStyles.HexNumber),
Size = Int32.Parse(match.Groups[3].Value, NumberStyles.HexNumber),
IsRam = true IsRam = true
}; };
match = _segmentPrgRomRegex.Match(row); match = _segmentPrgRomRegex.Match(row);
if(match.Success) { if(match.Success) {
segment.FileOffset = Int32.Parse(match.Groups[3].Value); segment.FileOffset = Int32.Parse(match.Groups[4].Value);
segment.IsRam = false; segment.IsRam = false;
} }
@ -123,8 +124,10 @@ namespace Mesen.GUI.Debugger
SpanInfo span = new SpanInfo() { SpanInfo span = new SpanInfo() {
ID = Int32.Parse(match.Groups[1].Value), ID = Int32.Parse(match.Groups[1].Value),
SegmentID = Int32.Parse(match.Groups[2].Value), SegmentID = Int32.Parse(match.Groups[2].Value),
Offset = Int32.Parse(match.Groups[3].Value) Offset = Int32.Parse(match.Groups[3].Value),
Size = Int32.Parse(match.Groups[4].Value)
}; };
span.IsData = match.Groups[6].Success;
_spans.Add(span.ID, span); _spans.Add(span.ID, span);
return true; return true;
@ -197,7 +200,8 @@ namespace Mesen.GUI.Debugger
continue; continue;
} }
bool isAsm = Path.GetExtension(_files[line.FileID].Name).StartsWith(".s"); string ext = Path.GetExtension(_files[line.FileID].Name).ToLower();
bool isAsm = ext != ".c" && ext != ".h";
string comment = ""; string comment = "";
for(int i = line.LineNumber; i >= 0; i--) { for(int i = line.LineNumber; i >= 0; i--) {
@ -268,6 +272,30 @@ namespace Mesen.GUI.Debugger
LoadLabels(); LoadLabels();
LoadComments(); LoadComments();
int prgSize = InteropEmu.DebugGetMemorySize(DebugMemoryType.PrgRom);
if(prgSize > 0) {
byte[] cdlFile = new byte[prgSize];
foreach(KeyValuePair<int, SpanInfo> kvp in _spans) {
SegmentInfo segment;
if(_segments.TryGetValue(kvp.Value.SegmentID, out segment)) {
if(!segment.IsRam && kvp.Value.Size != segment.Size) {
int prgAddress = kvp.Value.Offset + segment.FileOffset - iNesHeaderSize;
if(prgAddress >= 0 && prgAddress < prgSize) {
for(int i = 0; i < kvp.Value.Size; i++) {
if(cdlFile[prgAddress + i] == 0 && !kvp.Value.IsData && kvp.Value.Size <= 3) {
cdlFile[prgAddress + i] = (byte)0x01;
} else if(kvp.Value.IsData) {
cdlFile[prgAddress + i] = (byte)0x02;
}
}
}
}
}
}
InteropEmu.DebugSetCdlData(cdlFile);
}
LabelManager.SetLabels(_romLabels.Values); LabelManager.SetLabels(_romLabels.Values);
LabelManager.SetLabels(_ramLabels.Values); LabelManager.SetLabels(_ramLabels.Values);
@ -296,6 +324,7 @@ namespace Mesen.GUI.Debugger
{ {
public int ID; public int ID;
public int Start; public int Start;
public int Size;
public int FileOffset; public int FileOffset;
public bool IsRam; public bool IsRam;
} }
@ -321,6 +350,8 @@ namespace Mesen.GUI.Debugger
public int ID; public int ID;
public int SegmentID; public int SegmentID;
public int Offset; public int Offset;
public int Size;
public bool IsData;
} }
private class SymbolInfo private class SymbolInfo

View file

@ -549,6 +549,17 @@ namespace Mesen.GUI
return freezeState; return freezeState;
} }
[DllImport(DLLPath, EntryPoint = "DebugSetCdlData")] private static extern void DebugSetCdlDataWrapper(IntPtr cdlData, UInt32 length);
public static void DebugSetCdlData(byte[] cdlData)
{
GCHandle hResult = GCHandle.Alloc(cdlData, GCHandleType.Pinned);
try {
InteropEmu.DebugSetCdlDataWrapper(hResult.AddrOfPinnedObject(), (UInt32)cdlData.Length);
} finally {
hResult.Free();
}
}
[DllImport(DLLPath, EntryPoint = "DebugGetCdlData")] private static extern void DebugGetCdlDataWrapper(UInt32 offset, UInt32 length, DebugMemoryType type, IntPtr counts); [DllImport(DLLPath, EntryPoint = "DebugGetCdlData")] private static extern void DebugGetCdlDataWrapper(UInt32 offset, UInt32 length, DebugMemoryType type, IntPtr counts);
public static byte[] DebugGetCdlData(UInt32 offset, UInt32 length, DebugMemoryType type) public static byte[] DebugGetCdlData(UInt32 offset, UInt32 length, DebugMemoryType type)
{ {

View file

@ -76,6 +76,7 @@ extern "C"
DllExport bool __stdcall DebugSaveCdlFile(char* cdlFilepath) { return GetDebugger()->GetCodeDataLogger()->SaveCdlFile(cdlFilepath); } DllExport bool __stdcall DebugSaveCdlFile(char* cdlFilepath) { return GetDebugger()->GetCodeDataLogger()->SaveCdlFile(cdlFilepath); }
DllExport void __stdcall DebugGetCdlRatios(CdlRatios* cdlRatios) { *cdlRatios = GetDebugger()->GetCodeDataLogger()->GetRatios(); } DllExport void __stdcall DebugGetCdlRatios(CdlRatios* cdlRatios) { *cdlRatios = GetDebugger()->GetCodeDataLogger()->GetRatios(); }
DllExport void __stdcall DebugResetCdlLog() { GetDebugger()->ResetCdl(); } DllExport void __stdcall DebugResetCdlLog() { GetDebugger()->ResetCdl(); }
DllExport void __stdcall DebugSetCdlData(uint8_t* cdlData, uint32_t length) { GetDebugger()->SetCdlData(cdlData, length); }
DllExport void __stdcall DebugGetCdlData(uint32_t offset, uint32_t length, DebugMemoryType memoryType, uint8_t* cdlData) { GetDebugger()->GetCodeDataLogger()->GetCdlData(offset, length, memoryType, cdlData); } DllExport void __stdcall DebugGetCdlData(uint32_t offset, uint32_t length, DebugMemoryType memoryType, uint8_t* cdlData) { GetDebugger()->GetCodeDataLogger()->GetCdlData(offset, length, memoryType, cdlData); }
DllExport void __stdcall DebugMarkPrgBytesAs(uint32_t start, uint32_t end, CdlPrgFlags type) { GetDebugger()->GetCodeDataLogger()->MarkPrgBytesAs(start, end, type); } DllExport void __stdcall DebugMarkPrgBytesAs(uint32_t start, uint32_t end, CdlPrgFlags type) { GetDebugger()->GetCodeDataLogger()->MarkPrgBytesAs(start, end, type); }