mirror of
https://github.com/libretro/Mesen.git
synced 2025-03-02 21:47:59 +00:00
Debugger: Trace Logger improvements (Last 30k instructions visible, performance fixes, options are saved)
This commit is contained in:
parent
4f6776f30b
commit
312a07bbdd
21
Core/CPU.h
21
Core/CPU.h
@ -5,6 +5,7 @@
|
||||
#include "Snapshotable.h"
|
||||
#include "TraceLogger.h"
|
||||
#include "EmulationSettings.h"
|
||||
#include "CpuState.h"
|
||||
|
||||
namespace PSFlags
|
||||
{
|
||||
@ -24,9 +25,9 @@ namespace PSFlags
|
||||
enum AddrMode
|
||||
{
|
||||
None, Acc, Imp, Imm, Rel,
|
||||
Zero, ZeroX, ZeroY,
|
||||
Zero, Abs, ZeroX, ZeroY,
|
||||
Ind, IndX, IndY, IndYW,
|
||||
Abs, AbsX, AbsXW, AbsY, AbsYW
|
||||
AbsX, AbsXW, AbsY, AbsYW
|
||||
};
|
||||
|
||||
enum class IRQSource
|
||||
@ -37,22 +38,6 @@ enum class IRQSource
|
||||
FdsDisk = 8,
|
||||
};
|
||||
|
||||
struct State
|
||||
{
|
||||
uint16_t PC = 0;
|
||||
uint8_t SP = 0;
|
||||
uint8_t A = 0;
|
||||
uint8_t X = 0;
|
||||
uint8_t Y = 0;
|
||||
uint8_t PS = 0;
|
||||
uint32_t IRQFlag = 0;
|
||||
int32_t CycleCount = 0;
|
||||
bool NMIFlag = false;
|
||||
|
||||
//Used by debugger
|
||||
uint16_t DebugPC = 0;
|
||||
};
|
||||
|
||||
class CPU : public Snapshotable
|
||||
{
|
||||
public:
|
||||
|
@ -321,7 +321,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
@ -333,6 +333,11 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ShowIncludes>
|
||||
</ShowIncludes>
|
||||
<BufferSecurityCheck>
|
||||
</BufferSecurityCheck>
|
||||
<ControlFlowGuard>false</ControlFlowGuard>
|
||||
<RuntimeTypeInfo>
|
||||
</RuntimeTypeInfo>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -435,6 +440,7 @@
|
||||
<ClInclude Include="Caltron41.h" />
|
||||
<ClInclude Include="Cc21.h" />
|
||||
<ClInclude Include="ColorDreams46.h" />
|
||||
<ClInclude Include="CpuState.h" />
|
||||
<ClInclude Include="CrossFeedFilter.h" />
|
||||
<ClInclude Include="DaouInfosys.h" />
|
||||
<ClInclude Include="DebugBreakHelper.h" />
|
||||
@ -583,6 +589,7 @@
|
||||
<ClInclude Include="OekaKids.h" />
|
||||
<ClInclude Include="OekaKidsTablet.h" />
|
||||
<ClInclude Include="PlayerListMessage.h" />
|
||||
<ClInclude Include="PpuState.h" />
|
||||
<ClInclude Include="Profiler.h" />
|
||||
<ClInclude Include="Racermate.h" />
|
||||
<ClInclude Include="ReverbFilter.h" />
|
||||
|
@ -1117,6 +1117,12 @@
|
||||
<ClInclude Include="Eh8813A.h">
|
||||
<Filter>Nes\Mappers\Unif</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PpuState.h">
|
||||
<Filter>Nes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CpuState.h">
|
||||
<Filter>Nes</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
18
Core/CpuState.h
Normal file
18
Core/CpuState.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
struct State
|
||||
{
|
||||
uint16_t PC = 0;
|
||||
uint8_t SP = 0;
|
||||
uint8_t A = 0;
|
||||
uint8_t X = 0;
|
||||
uint8_t Y = 0;
|
||||
uint8_t PS = 0;
|
||||
uint32_t IRQFlag = 0;
|
||||
int32_t CycleCount = 0;
|
||||
bool NMIFlag = false;
|
||||
|
||||
//Used by debugger
|
||||
uint16_t DebugPC = 0;
|
||||
};
|
@ -33,6 +33,7 @@ Debugger::Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<
|
||||
_memoryDumper.reset(new MemoryDumper(_ppu, _memoryManager, _mapper, _codeDataLogger, this));
|
||||
_memoryAccessCounter.reset(new MemoryAccessCounter(this));
|
||||
_profiler.reset(new Profiler(this));
|
||||
_traceLogger.reset(new TraceLogger(memoryManager, _labelManager));
|
||||
|
||||
_stepOut = false;
|
||||
_stepCount = -1;
|
||||
@ -381,12 +382,8 @@ bool Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &ad
|
||||
|
||||
breakDone = SleepUntilResume();
|
||||
|
||||
shared_ptr<TraceLogger> logger = _traceLogger;
|
||||
if(logger) {
|
||||
DebugState state;
|
||||
GetState(&state);
|
||||
logger->Log(state, _disassembler->GetDisassemblyInfo(absoluteAddr, absoluteRamAddr, addr));
|
||||
}
|
||||
GetState(&_debugState, false);
|
||||
_traceLogger->Log(_debugState.CPU, _debugState.PPU, _disassembler->GetDisassemblyInfo(absoluteAddr, absoluteRamAddr, addr));
|
||||
} else {
|
||||
_profiler->ProcessCycle();
|
||||
}
|
||||
@ -623,17 +620,6 @@ void Debugger::SetNextStatement(uint16_t addr)
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::StartTraceLogger(TraceLoggerOptions options)
|
||||
{
|
||||
string traceFilepath = FolderUtilities::CombinePath(FolderUtilities::GetDebuggerFolder(), "Trace - " + FolderUtilities::GetFilename(_romName, false) + ".log");
|
||||
_traceLogger.reset(new TraceLogger(traceFilepath, _memoryManager, options));
|
||||
}
|
||||
|
||||
void Debugger::StopTraceLogger()
|
||||
{
|
||||
_traceLogger.reset();
|
||||
}
|
||||
|
||||
void Debugger::ProcessPpuCycle()
|
||||
{
|
||||
if(Debugger::Instance) {
|
||||
@ -682,6 +668,11 @@ void Debugger::GetFunctionEntryPoints(int32_t* entryPoints)
|
||||
entryPoints[i] = -1;
|
||||
}
|
||||
|
||||
shared_ptr<TraceLogger> Debugger::GetTraceLogger()
|
||||
{
|
||||
return _traceLogger;
|
||||
}
|
||||
|
||||
shared_ptr<MemoryDumper> Debugger::GetMemoryDumper()
|
||||
{
|
||||
return _memoryDumper;
|
||||
|
@ -155,7 +155,7 @@ public:
|
||||
void StopTraceLogger();
|
||||
|
||||
shared_ptr<Profiler> GetProfiler();
|
||||
|
||||
shared_ptr<TraceLogger> GetTraceLogger();
|
||||
shared_ptr<MemoryDumper> GetMemoryDumper();
|
||||
shared_ptr<MemoryAccessCounter> GetMemoryAccessCounter();
|
||||
|
||||
|
@ -78,9 +78,9 @@ void Disassembler::BuildOpCodeTables(bool useLowerCase)
|
||||
if(useLowerCase) {
|
||||
string name = opName[i];
|
||||
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
||||
DisassemblyInfo::OPName[i] = name;
|
||||
DisassemblyInfo::OPName[i] = name + " ";
|
||||
} else {
|
||||
DisassemblyInfo::OPName[i] = opName[i];
|
||||
DisassemblyInfo::OPName[i] = opName[i] + " ";
|
||||
}
|
||||
|
||||
DisassemblyInfo::OPMode[i] = opMode[i];
|
||||
@ -341,8 +341,11 @@ string Disassembler::GetCode(uint32_t startAddr, uint32_t endAddr, uint16_t memo
|
||||
output += commentLines;
|
||||
output += labelLine;
|
||||
|
||||
string effectiveAddress = showEffectiveAddresses ? info->GetEffectiveAddressString(cpuState, memoryManager, labelManager) : "";
|
||||
output += GetLine(" " + info->ToString(memoryAddr, memoryManager, labelManager), commentString, memoryAddr, source != _internalRam ? addr : -1, info->GetByteCode(), effectiveAddress, speculativeCode);
|
||||
char* effectiveAddress = info->GetEffectiveAddressString(cpuState, memoryManager.get(), labelManager.get());
|
||||
if(!effectiveAddress) {
|
||||
effectiveAddress = "";
|
||||
}
|
||||
output += GetLine(" " + string(info->ToString(memoryAddr, memoryManager.get(), labelManager.get())), commentString, memoryAddr, source != _internalRam ? addr : -1, info->GetByteCode(), effectiveAddress, speculativeCode);
|
||||
|
||||
if(info->IsSubExitPoint()) {
|
||||
output += GetLine("__sub end__") + GetLine();
|
||||
|
@ -8,69 +8,112 @@ string DisassemblyInfo::OPName[256];
|
||||
AddrMode DisassemblyInfo::OPMode[256];
|
||||
uint32_t DisassemblyInfo::OPSize[256];
|
||||
|
||||
string DisassemblyInfo::ToString(uint32_t memoryAddr, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager)
|
||||
static const char* hexTable[256] = {
|
||||
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
|
||||
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
|
||||
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
|
||||
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
|
||||
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
|
||||
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
|
||||
"60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
|
||||
"70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
|
||||
"80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
|
||||
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
|
||||
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
|
||||
"B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
|
||||
"C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
|
||||
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
|
||||
"E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
|
||||
"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
|
||||
};
|
||||
|
||||
char* DisassemblyInfo::ToString(uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager)
|
||||
{
|
||||
string out;
|
||||
out.reserve(25);
|
||||
uint16_t length;
|
||||
return ToString(memoryAddr, memoryManager, labelManager, length);
|
||||
}
|
||||
|
||||
char* DisassemblyInfo::ToString(uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager, uint16_t &length)
|
||||
{
|
||||
uint8_t opCode = *_opPointer;
|
||||
|
||||
if(DisassemblyInfo::OPName[opCode].empty()) {
|
||||
out = "invalid opcode";
|
||||
} else {
|
||||
out = DisassemblyInfo::OPName[opCode];
|
||||
}
|
||||
memcpy(_toStringBuffer, DisassemblyInfo::OPName[opCode].c_str(), 4);
|
||||
|
||||
length = 4;
|
||||
uint16_t* ptrPos = &length;
|
||||
|
||||
uint16_t opAddr = GetOpAddr(memoryAddr);
|
||||
|
||||
string operandValue;
|
||||
if(labelManager && _opMode != AddrMode::Imm) {
|
||||
operandValue = labelManager->GetLabel(opAddr, true);
|
||||
}
|
||||
|
||||
if(operandValue.empty()) {
|
||||
if(_opSize == 2 && _opMode != AddrMode::Rel) {
|
||||
operandValue += "$" + HexUtilities::ToHex((uint8_t)opAddr);
|
||||
} else {
|
||||
operandValue += "$" + HexUtilities::ToHex((uint16_t)opAddr);
|
||||
}
|
||||
uint8_t operandLength = 0;
|
||||
char operandBuffer[7];
|
||||
char* opBuffer = operandBuffer;
|
||||
|
||||
operandBuffer[0] = '$';
|
||||
if(_opSize == 2 && _opMode != AddrMode::Rel) {
|
||||
memcpy(operandBuffer + 1, hexTable[opAddr], 2);
|
||||
operandLength = 3;
|
||||
} else {
|
||||
memcpy(operandBuffer + 1, hexTable[opAddr >> 8], 2);
|
||||
memcpy(operandBuffer + 3, hexTable[opAddr & 0xFF], 2);
|
||||
operandLength = 5;
|
||||
}
|
||||
|
||||
out += " ";
|
||||
auto writeChar = [=](char c) -> void {
|
||||
_toStringBuffer[(*ptrPos)++] = c;
|
||||
};
|
||||
|
||||
auto copyOperand = [=]() -> void {
|
||||
if(labelManager && _opMode != AddrMode::Imm) {
|
||||
string label = labelManager->GetLabel(opAddr, true);
|
||||
if(!label.empty()) {
|
||||
memcpy(_toStringBuffer + (*ptrPos), label.c_str(), label.size());
|
||||
(*ptrPos) += (uint16_t)label.size();
|
||||
return;
|
||||
}
|
||||
}
|
||||
memcpy(_toStringBuffer + (*ptrPos), opBuffer, operandLength);
|
||||
(*ptrPos) += operandLength;
|
||||
};
|
||||
|
||||
switch(_opMode) {
|
||||
case AddrMode::Acc: out += "A"; break;
|
||||
case AddrMode::Imm: out += "#" + operandValue; break;
|
||||
case AddrMode::Ind: out += "(" + operandValue + ")"; break;
|
||||
case AddrMode::IndX: out += "(" + operandValue + ",X)"; break;
|
||||
case AddrMode::Acc: writeChar('A'); break;
|
||||
case AddrMode::Imm: writeChar('#'); copyOperand(); break;
|
||||
case AddrMode::Ind: writeChar('('); copyOperand(); writeChar(')'); break;
|
||||
case AddrMode::IndX: writeChar('('); copyOperand(); memcpy(_toStringBuffer + length, ",X)", 3); length += 3; break;
|
||||
|
||||
case AddrMode::IndY:
|
||||
case AddrMode::IndYW:
|
||||
out += "(" + operandValue + "),Y";
|
||||
writeChar('(');
|
||||
copyOperand();
|
||||
memcpy(_toStringBuffer + length, "),Y", 3);
|
||||
length += 3;
|
||||
break;
|
||||
|
||||
case AddrMode::Abs:
|
||||
case AddrMode::Rel:
|
||||
case AddrMode::Zero:
|
||||
out += operandValue;
|
||||
copyOperand();
|
||||
break;
|
||||
|
||||
case AddrMode::AbsX:
|
||||
case AddrMode::AbsXW:
|
||||
case AddrMode::ZeroX:
|
||||
out += operandValue + ",X";
|
||||
copyOperand();
|
||||
memcpy(_toStringBuffer + length, ",X", 2);
|
||||
length += 2;
|
||||
break;
|
||||
|
||||
case AddrMode::AbsY:
|
||||
case AddrMode::AbsYW:
|
||||
case AddrMode::ZeroY:
|
||||
out += operandValue + ",Y";
|
||||
copyOperand();
|
||||
memcpy(_toStringBuffer + length, ",Y", 2);
|
||||
length += 2;
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return out;
|
||||
_toStringBuffer[length] = 0;
|
||||
return _toStringBuffer;
|
||||
}
|
||||
|
||||
uint16_t DisassemblyInfo::GetOpAddr(uint16_t memoryAddr)
|
||||
@ -105,32 +148,53 @@ void DisassemblyInfo::SetSubEntryPoint()
|
||||
_isSubEntryPoint = true;
|
||||
}
|
||||
|
||||
string DisassemblyInfo::GetEffectiveAddressString(State& cpuState, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager)
|
||||
char* DisassemblyInfo::GetEffectiveAddressString(State& cpuState, MemoryManager* memoryManager, LabelManager* labelManager)
|
||||
{
|
||||
int32_t effectiveAddress = GetEffectiveAddress(cpuState, memoryManager);
|
||||
if(effectiveAddress < 0) {
|
||||
return "";
|
||||
uint16_t length;
|
||||
return GetEffectiveAddressString(cpuState, memoryManager, labelManager, length);
|
||||
}
|
||||
|
||||
char* DisassemblyInfo::GetEffectiveAddressString(State& cpuState, MemoryManager* memoryManager, LabelManager* labelManager, uint16_t& length)
|
||||
{
|
||||
if(_opMode <= AddrMode::Abs) {
|
||||
length = 0;
|
||||
return nullptr;
|
||||
} else {
|
||||
int32_t effectiveAddress = GetEffectiveAddress(cpuState, memoryManager);
|
||||
|
||||
_effectiveAddressBuffer[0] = ' ';
|
||||
_effectiveAddressBuffer[1] = '@';
|
||||
_effectiveAddressBuffer[2] = ' ';
|
||||
|
||||
if(labelManager) {
|
||||
string label = labelManager->GetLabel(effectiveAddress, true);
|
||||
if(!label.empty()) {
|
||||
return " @ " + label;
|
||||
memcpy(_effectiveAddressBuffer + 3, label.c_str(), label.size());
|
||||
length = (uint16_t)label.size() + 3;
|
||||
_effectiveAddressBuffer[length] = 0;
|
||||
|
||||
return _effectiveAddressBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
string output;
|
||||
output = " @ $";
|
||||
|
||||
_effectiveAddressBuffer[3] = '$';
|
||||
|
||||
if(_opMode == AddrMode::ZeroX || _opMode == AddrMode::ZeroY) {
|
||||
output += HexUtilities::ToHex((uint8_t)effectiveAddress);
|
||||
memcpy(_effectiveAddressBuffer + 4, hexTable[effectiveAddress], 2);
|
||||
_effectiveAddressBuffer[6] = 0;
|
||||
length = 6;
|
||||
} else {
|
||||
output += HexUtilities::ToHex((uint16_t)effectiveAddress);
|
||||
memcpy(_effectiveAddressBuffer + 4, hexTable[effectiveAddress >> 8], 2);
|
||||
memcpy(_effectiveAddressBuffer + 6, hexTable[effectiveAddress & 0xFF], 2);
|
||||
_effectiveAddressBuffer[8] = 0;
|
||||
length = 8;
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
return _effectiveAddressBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t DisassemblyInfo::GetEffectiveAddress(State& cpuState, shared_ptr<MemoryManager> memoryManager)
|
||||
int32_t DisassemblyInfo::GetEffectiveAddress(State& cpuState, MemoryManager* memoryManager)
|
||||
{
|
||||
switch(_opMode) {
|
||||
case AddrMode::ZeroX: return (uint8_t)(*(_opPointer + 1) + cpuState.X); break;
|
||||
|
@ -20,15 +20,21 @@ private:
|
||||
uint32_t _opSize = 0;
|
||||
AddrMode _opMode;
|
||||
|
||||
char _toStringBuffer[1000];
|
||||
char _effectiveAddressBuffer[1000];
|
||||
|
||||
public:
|
||||
DisassemblyInfo(uint8_t* opPointer, bool isSubEntryPoint);
|
||||
|
||||
void SetSubEntryPoint();
|
||||
|
||||
int32_t GetEffectiveAddress(State& cpuState, shared_ptr<MemoryManager> memoryManager);
|
||||
string GetEffectiveAddressString(State& cpuState, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
|
||||
int32_t GetEffectiveAddress(State& cpuState, MemoryManager* memoryManager);
|
||||
|
||||
char* GetEffectiveAddressString(State& cpuState, MemoryManager* memoryManager, LabelManager* labelManager);
|
||||
char* GetEffectiveAddressString(State& cpuState, MemoryManager* memoryManager, LabelManager* labelManager, uint16_t &length);
|
||||
|
||||
string ToString(uint32_t memoryAddr, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
|
||||
char* ToString(uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager);
|
||||
char* ToString(uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager, uint16_t &length);
|
||||
string GetByteCode();
|
||||
uint32_t GetSize();
|
||||
uint16_t GetOpAddr(uint16_t memoryAddr);
|
||||
|
@ -24,6 +24,10 @@ void LabelManager::SetLabel(uint32_t address, AddressType addressType, string la
|
||||
|
||||
_codeLabels.erase(address);
|
||||
if(!label.empty()) {
|
||||
if(label.size() > 400) {
|
||||
//Restrict labels to 400 bytes
|
||||
label = label.substr(0, 400);
|
||||
}
|
||||
_codeLabels.emplace(address, label);
|
||||
_codeLabelReverseLookup.emplace(label, address);
|
||||
}
|
||||
|
70
Core/PPU.h
70
Core/PPU.h
@ -4,6 +4,7 @@
|
||||
#include "Snapshotable.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "EmulationSettings.h"
|
||||
#include "PpuState.h"
|
||||
|
||||
enum class NesModel;
|
||||
|
||||
@ -20,75 +21,6 @@ enum PPURegisters
|
||||
SpriteDMA = 0x4014,
|
||||
};
|
||||
|
||||
struct PPUControlFlags
|
||||
{
|
||||
bool VerticalWrite;
|
||||
uint16_t SpritePatternAddr;
|
||||
uint16_t BackgroundPatternAddr;
|
||||
bool LargeSprites;
|
||||
bool VBlank;
|
||||
|
||||
bool Grayscale;
|
||||
bool BackgroundMask;
|
||||
bool SpriteMask;
|
||||
bool BackgroundEnabled;
|
||||
bool SpritesEnabled;
|
||||
bool IntensifyRed;
|
||||
bool IntensifyGreen;
|
||||
bool IntensifyBlue;
|
||||
};
|
||||
|
||||
struct PPUStatusFlags
|
||||
{
|
||||
bool SpriteOverflow;
|
||||
bool Sprite0Hit;
|
||||
bool VerticalBlank;
|
||||
};
|
||||
|
||||
struct PPUState
|
||||
{
|
||||
uint8_t Control;
|
||||
uint8_t Mask;
|
||||
uint8_t Status;
|
||||
uint32_t SpriteRamAddr;
|
||||
uint16_t VideoRamAddr;
|
||||
uint8_t XScroll;
|
||||
uint16_t TmpVideoRamAddr;
|
||||
bool WriteToggle;
|
||||
|
||||
uint16_t HighBitShift;
|
||||
uint16_t LowBitShift;
|
||||
};
|
||||
|
||||
struct TileInfo
|
||||
{
|
||||
uint8_t LowByte;
|
||||
uint8_t HighByte;
|
||||
uint32_t PaletteOffset;
|
||||
|
||||
uint16_t TileAddr; //used by HD ppu
|
||||
uint8_t OffsetY; //used by HD ppu
|
||||
};
|
||||
|
||||
struct SpriteInfo : TileInfo
|
||||
{
|
||||
bool HorizontalMirror;
|
||||
bool BackgroundPriority;
|
||||
uint8_t SpriteX;
|
||||
|
||||
bool VerticalMirror; //used by HD ppu
|
||||
};
|
||||
|
||||
struct PPUDebugState
|
||||
{
|
||||
PPUControlFlags ControlFlags;
|
||||
PPUStatusFlags StatusFlags;
|
||||
PPUState State;
|
||||
int32_t Scanline;
|
||||
uint32_t Cycle;
|
||||
uint32_t FrameCount;
|
||||
};
|
||||
|
||||
class PPU : public IMemoryHandler, public Snapshotable
|
||||
{
|
||||
protected:
|
||||
|
71
Core/PpuState.h
Normal file
71
Core/PpuState.h
Normal file
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
struct PPUControlFlags
|
||||
{
|
||||
bool VerticalWrite;
|
||||
uint16_t SpritePatternAddr;
|
||||
uint16_t BackgroundPatternAddr;
|
||||
bool LargeSprites;
|
||||
bool VBlank;
|
||||
|
||||
bool Grayscale;
|
||||
bool BackgroundMask;
|
||||
bool SpriteMask;
|
||||
bool BackgroundEnabled;
|
||||
bool SpritesEnabled;
|
||||
bool IntensifyRed;
|
||||
bool IntensifyGreen;
|
||||
bool IntensifyBlue;
|
||||
};
|
||||
|
||||
struct PPUStatusFlags
|
||||
{
|
||||
bool SpriteOverflow;
|
||||
bool Sprite0Hit;
|
||||
bool VerticalBlank;
|
||||
};
|
||||
|
||||
struct PPUState
|
||||
{
|
||||
uint8_t Control;
|
||||
uint8_t Mask;
|
||||
uint8_t Status;
|
||||
uint32_t SpriteRamAddr;
|
||||
uint16_t VideoRamAddr;
|
||||
uint8_t XScroll;
|
||||
uint16_t TmpVideoRamAddr;
|
||||
bool WriteToggle;
|
||||
|
||||
uint16_t HighBitShift;
|
||||
uint16_t LowBitShift;
|
||||
};
|
||||
|
||||
struct TileInfo
|
||||
{
|
||||
uint8_t LowByte;
|
||||
uint8_t HighByte;
|
||||
uint32_t PaletteOffset;
|
||||
|
||||
uint16_t TileAddr; //used by HD ppu
|
||||
uint8_t OffsetY; //used by HD ppu
|
||||
};
|
||||
|
||||
struct SpriteInfo : TileInfo
|
||||
{
|
||||
bool HorizontalMirror;
|
||||
bool BackgroundPriority;
|
||||
uint8_t SpriteX;
|
||||
|
||||
bool VerticalMirror; //used by HD ppu
|
||||
};
|
||||
|
||||
struct PPUDebugState
|
||||
{
|
||||
PPUControlFlags ControlFlags;
|
||||
PPUStatusFlags StatusFlags;
|
||||
PPUState State;
|
||||
int32_t Scanline;
|
||||
uint32_t Cycle;
|
||||
uint32_t FrameCount;
|
||||
};
|
@ -4,38 +4,58 @@
|
||||
#include "DebugState.h"
|
||||
#include "Console.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "LabelManager.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
#include "../Utilities/FolderUtilities.h"
|
||||
|
||||
TraceLogger *TraceLogger::_instance = nullptr;
|
||||
|
||||
TraceLogger::TraceLogger(string outputFilepath, shared_ptr<MemoryManager> memoryManager, TraceLoggerOptions options)
|
||||
TraceLogger::TraceLogger(shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager)
|
||||
{
|
||||
_memoryManager = memoryManager;
|
||||
_outputFile.open(outputFilepath, ios::out | ios::binary);
|
||||
_options = options;
|
||||
_firstLine = true;
|
||||
_labelManager = labelManager;
|
||||
_instance = this;
|
||||
_currentPos = 0;
|
||||
_logToFile = false;
|
||||
}
|
||||
|
||||
TraceLogger::~TraceLogger()
|
||||
{
|
||||
Console::Pause();
|
||||
if(_instance == this) {
|
||||
_instance = nullptr;
|
||||
}
|
||||
|
||||
if(_outputFile) {
|
||||
if(!_outputBuffer.empty()) {
|
||||
_outputFile << _outputBuffer;
|
||||
}
|
||||
_outputFile.close();
|
||||
}
|
||||
Console::Resume();
|
||||
StopLogging();
|
||||
_instance = nullptr;
|
||||
}
|
||||
|
||||
void TraceLogger::SetOptions(TraceLoggerOptions options)
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
|
||||
void TraceLogger::StartLogging(string filename)
|
||||
{
|
||||
_outputFile.open(filename, ios::out | ios::binary);
|
||||
_logToFile = true;
|
||||
_firstLine = true;
|
||||
}
|
||||
|
||||
void TraceLogger::StopLogging()
|
||||
{
|
||||
if(_logToFile) {
|
||||
Console::Pause();
|
||||
if(_outputFile) {
|
||||
if(!_outputBuffer.empty()) {
|
||||
_outputFile << _outputBuffer;
|
||||
}
|
||||
_outputFile.close();
|
||||
}
|
||||
Console::Resume();
|
||||
_logToFile = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TraceLogger::LogStatic(string log)
|
||||
{
|
||||
if(_instance && _instance->_options.ShowExtraInfo) {
|
||||
if(_instance && _instance->_logToFile && _instance->_options.ShowExtraInfo && !_instance->_firstLine) {
|
||||
//Flush current buffer
|
||||
_instance->_outputFile << _instance->_outputBuffer;
|
||||
_instance->_outputBuffer.clear();
|
||||
@ -44,75 +64,108 @@ void TraceLogger::LogStatic(string log)
|
||||
}
|
||||
}
|
||||
|
||||
void TraceLogger::Log(DebugState &state, shared_ptr<DisassemblyInfo> disassemblyInfo)
|
||||
void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, shared_ptr<DisassemblyInfo> &disassemblyInfo, bool firstLine)
|
||||
{
|
||||
//Roughly adjust PPU cycle & scanline to take into account the PPU already ran 3 cycles by the time we get here
|
||||
short ppuCycle = (short)ppuState.Cycle - 3;
|
||||
short scanline = (short)ppuState.Scanline;
|
||||
if(ppuCycle < 0) {
|
||||
ppuCycle = 341 + ppuCycle;
|
||||
scanline--;
|
||||
if(scanline < -1) {
|
||||
scanline = EmulationSettings::GetNesModel() == NesModel::NTSC ? 260 : 310;
|
||||
}
|
||||
}
|
||||
|
||||
if(!firstLine) {
|
||||
output += "\n";
|
||||
}
|
||||
|
||||
output += HexUtilities::ToHex(cpuState.DebugPC) + " ";
|
||||
|
||||
if(_options.ShowByteCode) {
|
||||
output += disassemblyInfo->GetByteCode() + std::string(13 - disassemblyInfo->GetByteCode().size(), ' ');
|
||||
}
|
||||
|
||||
int indentLevel = 0;
|
||||
if(_options.IndentCode) {
|
||||
indentLevel = 0xFF - cpuState.SP;
|
||||
output += std::string(indentLevel, ' ');
|
||||
}
|
||||
|
||||
uint16_t disassemblyLength = 0;
|
||||
uint16_t effectiveAddressLength = 0;
|
||||
LabelManager* labelManager = _options.UseLabels ? _labelManager.get() : nullptr;
|
||||
char* disassembly = disassemblyInfo->ToString(cpuState.DebugPC, _memoryManager.get(), labelManager, disassemblyLength);
|
||||
char* effectiveAddress = (_options.ShowEffectiveAddresses ? disassemblyInfo->GetEffectiveAddressString(cpuState, _memoryManager.get(), labelManager, effectiveAddressLength) : nullptr);
|
||||
|
||||
output += disassembly;
|
||||
if(effectiveAddress) {
|
||||
output += effectiveAddress;
|
||||
}
|
||||
output += std::string(32 - disassemblyLength - effectiveAddressLength, ' ');
|
||||
|
||||
if(_options.ShowRegisters) {
|
||||
output += " A:" + HexUtilities::ToHex(cpuState.A) +
|
||||
" X:" + HexUtilities::ToHex(cpuState.X) +
|
||||
" Y:" + HexUtilities::ToHex(cpuState.Y) +
|
||||
" P:" + HexUtilities::ToHex(cpuState.PS) +
|
||||
" SP:" + HexUtilities::ToHex(cpuState.SP);
|
||||
}
|
||||
|
||||
if(_options.ShowPpuCycles) {
|
||||
string str = std::to_string(ppuCycle);
|
||||
output += " CYC:" + std::string(3 - str.size(), ' ') + str;
|
||||
}
|
||||
|
||||
if(_options.ShowPpuScanline) {
|
||||
string str = std::to_string(scanline);
|
||||
output += " SL:" + std::string(3 - str.size(), ' ') + str;
|
||||
}
|
||||
|
||||
if(_options.ShowPpuFrames) {
|
||||
output += " FC:" + std::to_string(ppuState.FrameCount);
|
||||
}
|
||||
|
||||
if(_options.ShowCpuCycles) {
|
||||
output += " CPU Cycle:" + std::to_string(cpuState.CycleCount);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleLock _lock;
|
||||
void TraceLogger::Log(State &cpuState, PPUDebugState &ppuState, shared_ptr<DisassemblyInfo> disassemblyInfo)
|
||||
{
|
||||
if(disassemblyInfo) {
|
||||
State &cpuState = state.CPU;
|
||||
PPUDebugState &ppuState = state.PPU;
|
||||
|
||||
string disassembly = disassemblyInfo->ToString(cpuState.DebugPC, _memoryManager, nullptr);
|
||||
|
||||
//Roughly adjust PPU cycle & scanline to take into account the PPU already ran 3 cycles by the time we get here
|
||||
short ppuCycle = (short)ppuState.Cycle - 3;
|
||||
short scanline = (short)ppuState.Scanline;
|
||||
if(ppuCycle < 0) {
|
||||
ppuCycle = 341 + ppuCycle;
|
||||
scanline--;
|
||||
if(scanline < -1) {
|
||||
scanline = EmulationSettings::GetNesModel() == NesModel::NTSC ? 260 : 310;
|
||||
auto lock = _lock.AcquireSafe();
|
||||
_disassemblyCache[_currentPos] = disassemblyInfo;
|
||||
_cpuStateCache[_currentPos] = cpuState;
|
||||
_ppuStateCache[_currentPos] = ppuState;
|
||||
_currentPos = (_currentPos + 1) % ExecutionLogSize;
|
||||
|
||||
if(_logToFile) {
|
||||
GetTraceRow(_outputBuffer, cpuState, ppuState, disassemblyInfo, _firstLine);
|
||||
if(_outputBuffer.size() > 32768) {
|
||||
_outputFile << _outputBuffer;
|
||||
_outputBuffer.clear();
|
||||
}
|
||||
|
||||
_firstLine = false;
|
||||
}
|
||||
|
||||
if(!_firstLine) {
|
||||
_outputBuffer += "\n";
|
||||
}
|
||||
|
||||
_outputBuffer += HexUtilities::ToHex(cpuState.DebugPC) + " ";
|
||||
|
||||
if(_options.ShowByteCode) {
|
||||
_outputBuffer += disassemblyInfo->GetByteCode() + std::string(13 - disassemblyInfo->GetByteCode().size(), ' ');
|
||||
}
|
||||
|
||||
int indentLevel = 0;
|
||||
if(_options.IndentCode) {
|
||||
indentLevel = 0xFF - state.CPU.SP;
|
||||
_outputBuffer += std::string(indentLevel, ' ');
|
||||
}
|
||||
|
||||
string codeString = disassembly + (_options.ShowEffectiveAddresses ? disassemblyInfo->GetEffectiveAddressString(state.CPU, _memoryManager, nullptr) : "");
|
||||
_outputBuffer += codeString + std::string(32 - codeString.size(), ' ');
|
||||
|
||||
if(_options.ShowRegisters) {
|
||||
_outputBuffer += " A:" + HexUtilities::ToHex(cpuState.A) +
|
||||
" X:" + HexUtilities::ToHex(cpuState.X) +
|
||||
" Y:" + HexUtilities::ToHex(cpuState.Y) +
|
||||
" P:" + HexUtilities::ToHex(cpuState.PS) +
|
||||
" SP:" + HexUtilities::ToHex(cpuState.SP);
|
||||
}
|
||||
|
||||
if(_options.ShowPpuCycles) {
|
||||
string str = std::to_string(ppuCycle);
|
||||
_outputBuffer += " CYC:" + std::string(3 - str.size(), ' ') + str;
|
||||
}
|
||||
|
||||
if(_options.ShowPpuScanline) {
|
||||
string str = std::to_string(scanline);
|
||||
_outputBuffer += " SL:" + std::string(3 - str.size(), ' ') + str;
|
||||
}
|
||||
|
||||
if(_options.ShowPpuFrames) {
|
||||
_outputBuffer += " FC:" + std::to_string(ppuState.FrameCount);
|
||||
}
|
||||
|
||||
if(_options.ShowCpuCycles) {
|
||||
_outputBuffer += " CPU Cycle:" + std::to_string(cpuState.CycleCount);
|
||||
}
|
||||
|
||||
if(_outputBuffer.size() > 32768) {
|
||||
_outputFile << _outputBuffer;
|
||||
_outputBuffer.clear();
|
||||
}
|
||||
|
||||
_firstLine = false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* TraceLogger::GetExecutionTrace(uint32_t lineCount)
|
||||
{
|
||||
_executionTrace.clear();
|
||||
auto lock = _lock.AcquireSafe();
|
||||
int startPos = _currentPos + ExecutionLogSize - lineCount;
|
||||
bool firstLine = true;
|
||||
for(int i = 0; i < (int)lineCount; i++) {
|
||||
int index = (startPos + i) % ExecutionLogSize;
|
||||
if(_disassemblyCache[index]) {
|
||||
GetTraceRow(_executionTrace, _cpuStateCache[index], _ppuStateCache[index], _disassemblyCache[index], firstLine);
|
||||
firstLine = false;
|
||||
}
|
||||
}
|
||||
return _executionTrace.c_str();
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "CpuState.h"
|
||||
#include "PpuState.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class MemoryManager;
|
||||
struct DebugState;
|
||||
class LabelManager;
|
||||
|
||||
struct TraceLoggerOptions
|
||||
{
|
||||
@ -16,6 +18,7 @@ struct TraceLoggerOptions
|
||||
bool ShowExtraInfo;
|
||||
bool IndentCode;
|
||||
bool ShowEffectiveAddresses;
|
||||
bool UseLabels;
|
||||
};
|
||||
|
||||
class TraceLogger
|
||||
@ -28,12 +31,30 @@ private:
|
||||
ofstream _outputFile;
|
||||
bool _firstLine;
|
||||
shared_ptr<MemoryManager> _memoryManager;
|
||||
shared_ptr<LabelManager> _labelManager;
|
||||
|
||||
constexpr static int ExecutionLogSize = 30000;
|
||||
bool _logToFile;
|
||||
uint16_t _currentPos;
|
||||
State _cpuStateCache[ExecutionLogSize] = {};
|
||||
PPUDebugState _ppuStateCache[ExecutionLogSize] = {};
|
||||
int _memoryAddrCache[ExecutionLogSize] = {};
|
||||
shared_ptr<DisassemblyInfo> _disassemblyCache[ExecutionLogSize] = {};
|
||||
|
||||
string _executionTrace;
|
||||
|
||||
public:
|
||||
TraceLogger(string outputFilepath, shared_ptr<MemoryManager> memoryManager, TraceLoggerOptions options);
|
||||
TraceLogger(shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
|
||||
~TraceLogger();
|
||||
|
||||
void Log(DebugState &state, shared_ptr<DisassemblyInfo> disassemblyInfo);
|
||||
void Log(State &cpuState, PPUDebugState &ppuState, shared_ptr<DisassemblyInfo> disassemblyInfo);
|
||||
void SetOptions(TraceLoggerOptions options);
|
||||
void StartLogging(string filename);
|
||||
void StopLogging();
|
||||
|
||||
void GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, shared_ptr<DisassemblyInfo> &disassemblyInfo, bool firstLine);
|
||||
const char* GetExecutionTrace(uint32_t lineCount);
|
||||
|
||||
static void LogStatic(string log);
|
||||
|
||||
};
|
@ -144,6 +144,19 @@ namespace Mesen.GUI.Config
|
||||
public bool BreakOnOpen = true;
|
||||
public bool BreakOnReset = true;
|
||||
|
||||
public bool TraceAutoRefresh = true;
|
||||
public int TraceLineCount = 1000;
|
||||
public bool TraceIndentCode = false;
|
||||
public bool TraceShowByteCode = true;
|
||||
public bool TraceShowCpuCycles = false;
|
||||
public bool TraceShowEffectiveAddresses = true;
|
||||
public bool TraceShowExtraInfo = true;
|
||||
public bool TraceShowFrameCount = false;
|
||||
public bool TraceShowPpuCycles = true;
|
||||
public bool TraceShowPpuScanline = true;
|
||||
public bool TraceShowRegisters = true;
|
||||
internal bool TraceUseLabels;
|
||||
|
||||
public DebugInfo()
|
||||
{
|
||||
LeftView = new DebugViewInfo();
|
||||
|
331
GUI.NET/Debugger/frmTraceLogger.Designer.cs
generated
331
GUI.NET/Debugger/frmTraceLogger.Designer.cs
generated
@ -27,24 +27,43 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.btnOpenTrace = new System.Windows.Forms.Button();
|
||||
this.btnStartLogging = new System.Windows.Forms.Button();
|
||||
this.btnStopLogging = new System.Windows.Forms.Button();
|
||||
this.grpLogOptions = new System.Windows.Forms.GroupBox();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.chkShowCpuCycles = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowEffectiveAddresses = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowPpuCycles = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowRegisters = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowPpuScanline = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowFrameCount = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowExtraInfo = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowByteCode = new System.Windows.Forms.CheckBox();
|
||||
this.chkIndentCode = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowEffectiveAddresses = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowByteCode = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowFrameCount = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowPpuScanline = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowCpuCycles = new System.Windows.Forms.CheckBox();
|
||||
this.chkUseLabels = new System.Windows.Forms.CheckBox();
|
||||
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.grpExecutionLog = new System.Windows.Forms.GroupBox();
|
||||
this.txtTraceLog = new System.Windows.Forms.TextBox();
|
||||
this.tmrUpdateLog = new System.Windows.Forms.Timer(this.components);
|
||||
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
|
||||
this.showToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.logLinesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnu100Lines = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnu1000Lines = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnu10000Lines = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnu30000Lines = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuAutoRefresh = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.grpLogOptions.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
this.tableLayoutPanel3.SuspendLayout();
|
||||
this.grpExecutionLog.SuspendLayout();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
@ -57,23 +76,21 @@
|
||||
this.tableLayoutPanel1.Controls.Add(this.btnStartLogging, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.btnStopLogging, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.grpLogOptions, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkIndentCode, 0, 2);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 314);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 3;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(339, 193);
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(442, 206);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// btnOpenTrace
|
||||
//
|
||||
this.btnOpenTrace.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnOpenTrace.Enabled = false;
|
||||
this.btnOpenTrace.Location = new System.Drawing.Point(241, 3);
|
||||
this.btnOpenTrace.Location = new System.Drawing.Point(344, 3);
|
||||
this.btnOpenTrace.Name = "btnOpenTrace";
|
||||
this.btnOpenTrace.Size = new System.Drawing.Size(95, 23);
|
||||
this.btnOpenTrace.TabIndex = 2;
|
||||
@ -107,52 +124,55 @@
|
||||
//
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.grpLogOptions, 3);
|
||||
this.grpLogOptions.Controls.Add(this.tableLayoutPanel2);
|
||||
this.grpLogOptions.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpLogOptions.Location = new System.Drawing.Point(3, 32);
|
||||
this.grpLogOptions.Name = "grpLogOptions";
|
||||
this.grpLogOptions.Size = new System.Drawing.Size(333, 132);
|
||||
this.grpLogOptions.Size = new System.Drawing.Size(436, 168);
|
||||
this.grpLogOptions.TabIndex = 3;
|
||||
this.grpLogOptions.TabStop = false;
|
||||
this.grpLogOptions.Text = "Log Contents";
|
||||
this.grpLogOptions.Text = "Log Options";
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.ColumnCount = 3;
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33332F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F));
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowEffectiveAddresses, 0, 3);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowCpuCycles, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowPpuCycles, 0, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowRegisters, 0, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowPpuScanline, 1, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowFrameCount, 2, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowExtraInfo, 0, 4);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkIndentCode, 0, 6);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowByteCode, 0, 2);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowFrameCount, 2, 2);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowPpuScanline, 2, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowCpuCycles, 2, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkUseLabels, 2, 6);
|
||||
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 16);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.RowCount = 6;
|
||||
this.tableLayoutPanel2.RowCount = 7;
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(327, 113);
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(430, 149);
|
||||
this.tableLayoutPanel2.TabIndex = 0;
|
||||
//
|
||||
// chkShowCpuCycles
|
||||
// chkShowEffectiveAddresses
|
||||
//
|
||||
this.chkShowCpuCycles.AutoSize = true;
|
||||
this.chkShowCpuCycles.Checked = true;
|
||||
this.chkShowCpuCycles.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowCpuCycles.Location = new System.Drawing.Point(111, 3);
|
||||
this.chkShowCpuCycles.Name = "chkShowCpuCycles";
|
||||
this.chkShowCpuCycles.Size = new System.Drawing.Size(82, 17);
|
||||
this.chkShowCpuCycles.TabIndex = 3;
|
||||
this.chkShowCpuCycles.Text = "CPU Cycles";
|
||||
this.chkShowCpuCycles.UseVisualStyleBackColor = true;
|
||||
this.chkShowEffectiveAddresses.AutoSize = true;
|
||||
this.chkShowEffectiveAddresses.Checked = true;
|
||||
this.chkShowEffectiveAddresses.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.chkShowEffectiveAddresses, 2);
|
||||
this.chkShowEffectiveAddresses.Location = new System.Drawing.Point(3, 72);
|
||||
this.chkShowEffectiveAddresses.Name = "chkShowEffectiveAddresses";
|
||||
this.chkShowEffectiveAddresses.Size = new System.Drawing.Size(150, 17);
|
||||
this.chkShowEffectiveAddresses.TabIndex = 10;
|
||||
this.chkShowEffectiveAddresses.Text = "Show Effective Addresses";
|
||||
this.chkShowEffectiveAddresses.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowPpuCycles
|
||||
//
|
||||
@ -178,28 +198,6 @@
|
||||
this.chkShowRegisters.Text = "Registers";
|
||||
this.chkShowRegisters.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowPpuScanline
|
||||
//
|
||||
this.chkShowPpuScanline.AutoSize = true;
|
||||
this.chkShowPpuScanline.Checked = true;
|
||||
this.chkShowPpuScanline.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowPpuScanline.Location = new System.Drawing.Point(111, 26);
|
||||
this.chkShowPpuScanline.Name = "chkShowPpuScanline";
|
||||
this.chkShowPpuScanline.Size = new System.Drawing.Size(92, 17);
|
||||
this.chkShowPpuScanline.TabIndex = 6;
|
||||
this.chkShowPpuScanline.Text = "PPU Scanline";
|
||||
this.chkShowPpuScanline.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowFrameCount
|
||||
//
|
||||
this.chkShowFrameCount.AutoSize = true;
|
||||
this.chkShowFrameCount.Location = new System.Drawing.Point(220, 26);
|
||||
this.chkShowFrameCount.Name = "chkShowFrameCount";
|
||||
this.chkShowFrameCount.Size = new System.Drawing.Size(86, 17);
|
||||
this.chkShowFrameCount.TabIndex = 7;
|
||||
this.chkShowFrameCount.Text = "Frame Count";
|
||||
this.chkShowFrameCount.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowExtraInfo
|
||||
//
|
||||
this.chkShowExtraInfo.AutoSize = true;
|
||||
@ -213,6 +211,17 @@
|
||||
this.chkShowExtraInfo.Text = "Additional information (IRQ, NMI, etc.)";
|
||||
this.chkShowExtraInfo.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkIndentCode
|
||||
//
|
||||
this.chkIndentCode.AutoSize = true;
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.chkIndentCode, 2);
|
||||
this.chkIndentCode.Location = new System.Drawing.Point(3, 129);
|
||||
this.chkIndentCode.Name = "chkIndentCode";
|
||||
this.chkIndentCode.Size = new System.Drawing.Size(194, 17);
|
||||
this.chkIndentCode.TabIndex = 8;
|
||||
this.chkIndentCode.Text = "Indent code based on stack pointer";
|
||||
this.chkIndentCode.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowByteCode
|
||||
//
|
||||
this.chkShowByteCode.AutoSize = true;
|
||||
@ -225,48 +234,201 @@
|
||||
this.chkShowByteCode.Text = "Byte Code";
|
||||
this.chkShowByteCode.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkIndentCode
|
||||
// chkShowFrameCount
|
||||
//
|
||||
this.chkIndentCode.AutoSize = true;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.chkIndentCode, 3);
|
||||
this.chkIndentCode.Location = new System.Drawing.Point(3, 170);
|
||||
this.chkIndentCode.Name = "chkIndentCode";
|
||||
this.chkIndentCode.Size = new System.Drawing.Size(194, 17);
|
||||
this.chkIndentCode.TabIndex = 8;
|
||||
this.chkIndentCode.Text = "Indent code based on stack pointer";
|
||||
this.chkIndentCode.UseVisualStyleBackColor = true;
|
||||
this.chkShowFrameCount.AutoSize = true;
|
||||
this.chkShowFrameCount.Location = new System.Drawing.Point(289, 49);
|
||||
this.chkShowFrameCount.Name = "chkShowFrameCount";
|
||||
this.chkShowFrameCount.Size = new System.Drawing.Size(86, 17);
|
||||
this.chkShowFrameCount.TabIndex = 7;
|
||||
this.chkShowFrameCount.Text = "Frame Count";
|
||||
this.chkShowFrameCount.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowEffectiveAddresses
|
||||
// chkShowPpuScanline
|
||||
//
|
||||
this.chkShowEffectiveAddresses.AutoSize = true;
|
||||
this.chkShowEffectiveAddresses.Checked = true;
|
||||
this.chkShowEffectiveAddresses.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.chkShowEffectiveAddresses, 2);
|
||||
this.chkShowEffectiveAddresses.Location = new System.Drawing.Point(3, 72);
|
||||
this.chkShowEffectiveAddresses.Name = "chkShowEffectiveAddresses";
|
||||
this.chkShowEffectiveAddresses.Size = new System.Drawing.Size(150, 17);
|
||||
this.chkShowEffectiveAddresses.TabIndex = 10;
|
||||
this.chkShowEffectiveAddresses.Text = "Show Effective Addresses";
|
||||
this.chkShowEffectiveAddresses.UseVisualStyleBackColor = true;
|
||||
this.chkShowPpuScanline.AutoSize = true;
|
||||
this.chkShowPpuScanline.Checked = true;
|
||||
this.chkShowPpuScanline.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowPpuScanline.Location = new System.Drawing.Point(289, 26);
|
||||
this.chkShowPpuScanline.Name = "chkShowPpuScanline";
|
||||
this.chkShowPpuScanline.Size = new System.Drawing.Size(92, 17);
|
||||
this.chkShowPpuScanline.TabIndex = 6;
|
||||
this.chkShowPpuScanline.Text = "PPU Scanline";
|
||||
this.chkShowPpuScanline.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowCpuCycles
|
||||
//
|
||||
this.chkShowCpuCycles.AutoSize = true;
|
||||
this.chkShowCpuCycles.Checked = true;
|
||||
this.chkShowCpuCycles.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowCpuCycles.Location = new System.Drawing.Point(289, 3);
|
||||
this.chkShowCpuCycles.Name = "chkShowCpuCycles";
|
||||
this.chkShowCpuCycles.Size = new System.Drawing.Size(82, 17);
|
||||
this.chkShowCpuCycles.TabIndex = 3;
|
||||
this.chkShowCpuCycles.Text = "CPU Cycles";
|
||||
this.chkShowCpuCycles.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkUseLabels
|
||||
//
|
||||
this.chkUseLabels.AutoSize = true;
|
||||
this.chkUseLabels.Location = new System.Drawing.Point(289, 129);
|
||||
this.chkUseLabels.Name = "chkUseLabels";
|
||||
this.chkUseLabels.Size = new System.Drawing.Size(79, 17);
|
||||
this.chkUseLabels.TabIndex = 11;
|
||||
this.chkUseLabels.Text = "Use Labels";
|
||||
this.chkUseLabels.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tableLayoutPanel3
|
||||
//
|
||||
this.tableLayoutPanel3.ColumnCount = 2;
|
||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel3.Controls.Add(this.tableLayoutPanel1, 0, 1);
|
||||
this.tableLayoutPanel3.Controls.Add(this.grpExecutionLog, 0, 0);
|
||||
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 24);
|
||||
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
|
||||
this.tableLayoutPanel3.RowCount = 2;
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel3.Size = new System.Drawing.Size(808, 523);
|
||||
this.tableLayoutPanel3.TabIndex = 1;
|
||||
//
|
||||
// grpExecutionLog
|
||||
//
|
||||
this.tableLayoutPanel3.SetColumnSpan(this.grpExecutionLog, 2);
|
||||
this.grpExecutionLog.Controls.Add(this.txtTraceLog);
|
||||
this.grpExecutionLog.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpExecutionLog.Location = new System.Drawing.Point(3, 3);
|
||||
this.grpExecutionLog.Name = "grpExecutionLog";
|
||||
this.grpExecutionLog.Size = new System.Drawing.Size(802, 305);
|
||||
this.grpExecutionLog.TabIndex = 2;
|
||||
this.grpExecutionLog.TabStop = false;
|
||||
this.grpExecutionLog.Text = "Execution Log";
|
||||
//
|
||||
// txtTraceLog
|
||||
//
|
||||
this.txtTraceLog.BackColor = System.Drawing.SystemColors.Window;
|
||||
this.txtTraceLog.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtTraceLog.Location = new System.Drawing.Point(3, 16);
|
||||
this.txtTraceLog.Multiline = true;
|
||||
this.txtTraceLog.Name = "txtTraceLog";
|
||||
this.txtTraceLog.ReadOnly = true;
|
||||
this.txtTraceLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.txtTraceLog.Size = new System.Drawing.Size(796, 286);
|
||||
this.txtTraceLog.TabIndex = 1;
|
||||
//
|
||||
// tmrUpdateLog
|
||||
//
|
||||
this.tmrUpdateLog.Interval = 150;
|
||||
this.tmrUpdateLog.Tick += new System.EventHandler(this.tmrUpdateLog_Tick);
|
||||
//
|
||||
// menuStrip1
|
||||
//
|
||||
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.showToolStripMenuItem});
|
||||
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
|
||||
this.menuStrip1.Name = "menuStrip1";
|
||||
this.menuStrip1.Size = new System.Drawing.Size(808, 24);
|
||||
this.menuStrip1.TabIndex = 2;
|
||||
this.menuStrip1.Text = "menuStrip1";
|
||||
//
|
||||
// showToolStripMenuItem
|
||||
//
|
||||
this.showToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.logLinesToolStripMenuItem,
|
||||
this.mnuAutoRefresh,
|
||||
this.toolStripMenuItem1,
|
||||
this.mnuRefresh});
|
||||
this.showToolStripMenuItem.Name = "showToolStripMenuItem";
|
||||
this.showToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
|
||||
this.showToolStripMenuItem.Text = "View";
|
||||
//
|
||||
// logLinesToolStripMenuItem
|
||||
//
|
||||
this.logLinesToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnu100Lines,
|
||||
this.mnu1000Lines,
|
||||
this.mnu10000Lines,
|
||||
this.mnu30000Lines});
|
||||
this.logLinesToolStripMenuItem.Name = "logLinesToolStripMenuItem";
|
||||
this.logLinesToolStripMenuItem.Size = new System.Drawing.Size(141, 22);
|
||||
this.logLinesToolStripMenuItem.Text = "Line Count";
|
||||
//
|
||||
// mnu100Lines
|
||||
//
|
||||
this.mnu100Lines.Name = "mnu100Lines";
|
||||
this.mnu100Lines.Size = new System.Drawing.Size(104, 22);
|
||||
this.mnu100Lines.Text = "100";
|
||||
this.mnu100Lines.Click += new System.EventHandler(this.mnu100Lines_Click);
|
||||
//
|
||||
// mnu1000Lines
|
||||
//
|
||||
this.mnu1000Lines.Checked = true;
|
||||
this.mnu1000Lines.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.mnu1000Lines.Name = "mnu1000Lines";
|
||||
this.mnu1000Lines.Size = new System.Drawing.Size(104, 22);
|
||||
this.mnu1000Lines.Text = "1000";
|
||||
this.mnu1000Lines.Click += new System.EventHandler(this.mnu1000Lines_Click);
|
||||
//
|
||||
// mnu10000Lines
|
||||
//
|
||||
this.mnu10000Lines.Name = "mnu10000Lines";
|
||||
this.mnu10000Lines.Size = new System.Drawing.Size(104, 22);
|
||||
this.mnu10000Lines.Text = "10000";
|
||||
this.mnu10000Lines.Click += new System.EventHandler(this.mnu10000Lines_Click);
|
||||
//
|
||||
// mnu30000Lines
|
||||
//
|
||||
this.mnu30000Lines.Name = "mnu30000Lines";
|
||||
this.mnu30000Lines.Size = new System.Drawing.Size(104, 22);
|
||||
this.mnu30000Lines.Text = "30000";
|
||||
this.mnu30000Lines.Click += new System.EventHandler(this.mnu30000Lines_Click);
|
||||
//
|
||||
// mnuAutoRefresh
|
||||
//
|
||||
this.mnuAutoRefresh.Checked = true;
|
||||
this.mnuAutoRefresh.CheckOnClick = true;
|
||||
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
|
||||
this.mnuAutoRefresh.Size = new System.Drawing.Size(141, 22);
|
||||
this.mnuAutoRefresh.Text = "Auto-refresh";
|
||||
//
|
||||
// toolStripMenuItem1
|
||||
//
|
||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(138, 6);
|
||||
//
|
||||
// mnuRefresh
|
||||
//
|
||||
this.mnuRefresh.Name = "mnuRefresh";
|
||||
this.mnuRefresh.ShortcutKeys = System.Windows.Forms.Keys.F5;
|
||||
this.mnuRefresh.Size = new System.Drawing.Size(141, 22);
|
||||
this.mnuRefresh.Text = "Refresh";
|
||||
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
|
||||
//
|
||||
// frmTraceLogger
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(339, 193);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.ClientSize = new System.Drawing.Size(808, 547);
|
||||
this.Controls.Add(this.tableLayoutPanel3);
|
||||
this.Controls.Add(this.menuStrip1);
|
||||
this.Name = "frmTraceLogger";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Trace Logger";
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.grpLogOptions.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.PerformLayout();
|
||||
this.tableLayoutPanel3.ResumeLayout(false);
|
||||
this.grpExecutionLog.ResumeLayout(false);
|
||||
this.grpExecutionLog.PerformLayout();
|
||||
this.menuStrip1.ResumeLayout(false);
|
||||
this.menuStrip1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
@ -287,5 +449,20 @@
|
||||
private System.Windows.Forms.CheckBox chkIndentCode;
|
||||
private System.Windows.Forms.Button btnOpenTrace;
|
||||
private System.Windows.Forms.CheckBox chkShowEffectiveAddresses;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
|
||||
private System.Windows.Forms.TextBox txtTraceLog;
|
||||
private System.Windows.Forms.Timer tmrUpdateLog;
|
||||
private System.Windows.Forms.GroupBox grpExecutionLog;
|
||||
private System.Windows.Forms.MenuStrip menuStrip1;
|
||||
private System.Windows.Forms.ToolStripMenuItem showToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem logLinesToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefresh;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuRefresh;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnu100Lines;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnu1000Lines;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnu10000Lines;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnu30000Lines;
|
||||
private System.Windows.Forms.CheckBox chkUseLabels;
|
||||
}
|
||||
}
|
@ -9,29 +9,65 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Mesen.GUI.Config;
|
||||
using Mesen.GUI.Controls;
|
||||
using Mesen.GUI.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class frmTraceLogger : BaseForm
|
||||
{
|
||||
private int _lineCount;
|
||||
private bool _loggingEnabled = false;
|
||||
private string _lastFilename;
|
||||
|
||||
public frmTraceLogger()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
DebugInfo debugInfo = ConfigManager.Config.DebugInfo;
|
||||
mnuAutoRefresh.Checked = debugInfo.TraceAutoRefresh;
|
||||
_lineCount = debugInfo.TraceLineCount;
|
||||
chkIndentCode.Checked = debugInfo.TraceIndentCode;
|
||||
chkShowByteCode.Checked = debugInfo.TraceShowByteCode;
|
||||
chkShowCpuCycles.Checked = debugInfo.TraceShowCpuCycles;
|
||||
chkShowEffectiveAddresses.Checked = debugInfo.TraceShowEffectiveAddresses;
|
||||
chkShowExtraInfo.Checked = debugInfo.TraceShowExtraInfo;
|
||||
chkShowFrameCount.Checked = debugInfo.TraceShowFrameCount;
|
||||
chkShowPpuCycles.Checked = debugInfo.TraceShowPpuCycles;
|
||||
chkShowPpuScanline.Checked = debugInfo.TraceShowPpuScanline;
|
||||
chkShowRegisters.Checked = debugInfo.TraceShowRegisters;
|
||||
chkUseLabels.Checked = debugInfo.TraceUseLabels;
|
||||
|
||||
UpdateMenu();
|
||||
txtTraceLog.Font = new Font(BaseControl.MonospaceFontFamily, 10);
|
||||
tmrUpdateLog.Start();
|
||||
}
|
||||
|
||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||
{
|
||||
base.OnFormClosing(e);
|
||||
|
||||
DebugInfo debugInfo = ConfigManager.Config.DebugInfo;
|
||||
debugInfo.TraceAutoRefresh = mnuAutoRefresh.Checked;
|
||||
debugInfo.TraceLineCount = _lineCount;
|
||||
debugInfo.TraceIndentCode = chkIndentCode.Checked;
|
||||
debugInfo.TraceShowByteCode = chkShowByteCode.Checked;
|
||||
debugInfo.TraceShowCpuCycles = chkShowCpuCycles.Checked;
|
||||
debugInfo.TraceShowEffectiveAddresses = chkShowEffectiveAddresses.Checked;
|
||||
debugInfo.TraceShowExtraInfo = chkShowExtraInfo.Checked;
|
||||
debugInfo.TraceShowFrameCount = chkShowFrameCount.Checked;
|
||||
debugInfo.TraceShowPpuCycles = chkShowPpuCycles.Checked;
|
||||
debugInfo.TraceShowPpuScanline = chkShowPpuScanline.Checked;
|
||||
debugInfo.TraceShowRegisters = chkShowRegisters.Checked;
|
||||
debugInfo.TraceUseLabels = chkUseLabels.Checked;
|
||||
ConfigManager.ApplyChanges();
|
||||
|
||||
if(_loggingEnabled) {
|
||||
InteropEmu.DebugStopTraceLogger();
|
||||
}
|
||||
}
|
||||
|
||||
private void btnStartLogging_Click(object sender, EventArgs e)
|
||||
private void SetOptions()
|
||||
{
|
||||
TraceLoggerOptions options = new TraceLoggerOptions() {
|
||||
ShowByteCode = chkShowByteCode.Checked,
|
||||
@ -42,16 +78,31 @@ namespace Mesen.GUI.Debugger
|
||||
ShowPpuScanline = chkShowPpuScanline.Checked,
|
||||
ShowRegisters = chkShowRegisters.Checked,
|
||||
IndentCode = chkIndentCode.Checked,
|
||||
ShowEffectiveAddresses = chkShowEffectiveAddresses.Checked
|
||||
ShowEffectiveAddresses = chkShowEffectiveAddresses.Checked,
|
||||
UseLabels = chkUseLabels.Checked
|
||||
};
|
||||
|
||||
InteropEmu.DebugStartTraceLogger(options);
|
||||
InteropEmu.DebugSetTraceOptions(options);
|
||||
}
|
||||
|
||||
btnStartLogging.Enabled = false;
|
||||
btnStopLogging.Enabled = true;
|
||||
btnOpenTrace.Enabled = true;
|
||||
private void btnStartLogging_Click(object sender, EventArgs e)
|
||||
{
|
||||
using(SaveFileDialog sfd = new SaveFileDialog()) {
|
||||
sfd.FileName = "Trace logs (*.txt)|*.txt";
|
||||
sfd.FileName = "Trace - " + InteropEmu.GetRomInfo().GetRomName() + ".txt";
|
||||
sfd.InitialDirectory = ConfigManager.DebuggerFolder;
|
||||
if(sfd.ShowDialog() == DialogResult.OK) {
|
||||
_lastFilename = sfd.FileName;
|
||||
SetOptions();
|
||||
InteropEmu.DebugStartTraceLogger(sfd.FileName);
|
||||
|
||||
_loggingEnabled = true;
|
||||
btnStartLogging.Enabled = false;
|
||||
btnStopLogging.Enabled = true;
|
||||
btnOpenTrace.Enabled = false;
|
||||
|
||||
_loggingEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnStopLogging_Click(object sender, EventArgs e)
|
||||
@ -59,13 +110,80 @@ namespace Mesen.GUI.Debugger
|
||||
InteropEmu.DebugStopTraceLogger();
|
||||
btnStartLogging.Enabled = true;
|
||||
btnStopLogging.Enabled = false;
|
||||
btnOpenTrace.Enabled = true;
|
||||
}
|
||||
|
||||
private void btnOpenTrace_Click(object sender, EventArgs e)
|
||||
{
|
||||
try {
|
||||
System.Diagnostics.Process.Start(Path.Combine(ConfigManager.DebuggerFolder, "Trace - " + InteropEmu.GetRomInfo().GetRomName() + ".log"));
|
||||
System.Diagnostics.Process.Start(_lastFilename);
|
||||
} catch { }
|
||||
}
|
||||
|
||||
private void RefreshLog()
|
||||
{
|
||||
SetOptions();
|
||||
string newTrace = InteropEmu.DebugGetExecutionTrace((UInt32)_lineCount).Replace("\n", Environment.NewLine);
|
||||
|
||||
if(newTrace != txtTraceLog.Text) {
|
||||
txtTraceLog.Text = newTrace;
|
||||
txtTraceLog.SelectionStart = txtTraceLog.TextLength;
|
||||
txtTraceLog.ScrollToCaret();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMenu()
|
||||
{
|
||||
mnu30000Lines.Checked = _lineCount == 30000;
|
||||
mnu10000Lines.Checked = _lineCount == 10000;
|
||||
mnu1000Lines.Checked = _lineCount == 1000;
|
||||
mnu100Lines.Checked = _lineCount == 100;
|
||||
|
||||
if(_lineCount >= 10000) {
|
||||
mnuAutoRefresh.Checked = false;
|
||||
} else if(_lineCount == 1000) {
|
||||
tmrUpdateLog.Interval = 250;
|
||||
} else {
|
||||
tmrUpdateLog.Interval = 150;
|
||||
}
|
||||
|
||||
mnuAutoRefresh.Enabled = _lineCount < 10000;
|
||||
}
|
||||
|
||||
private void tmrUpdateLog_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if(mnuAutoRefresh.Checked) {
|
||||
RefreshLog();
|
||||
}
|
||||
}
|
||||
|
||||
private void mnu30000Lines_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lineCount = 30000;
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
private void mnu10000Lines_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lineCount = 10000;
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
private void mnu1000Lines_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lineCount = 1000;
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
private void mnu100Lines_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lineCount = 100;
|
||||
UpdateMenu();
|
||||
}
|
||||
|
||||
private void mnuRefresh_Click(object sender, EventArgs e)
|
||||
{
|
||||
RefreshLog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,4 +120,10 @@
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="tmrUpdateLog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>107, 17</value>
|
||||
</metadata>
|
||||
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>238, 17</value>
|
||||
</metadata>
|
||||
</root>
|
@ -195,10 +195,13 @@ namespace Mesen.GUI
|
||||
|
||||
[DllImport(DLLPath)] public static extern void DebugSetNextStatement(UInt16 addr);
|
||||
[DllImport(DLLPath)] public static extern Int32 DebugEvaluateExpression([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string expression, out EvalResultType resultType);
|
||||
|
||||
[DllImport(DLLPath)] public static extern void DebugStartTraceLogger(TraceLoggerOptions options);
|
||||
[DllImport(DLLPath)] public static extern void DebugStopTraceLogger();
|
||||
|
||||
[DllImport(DLLPath)] public static extern void DebugStartTraceLogger([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename);
|
||||
[DllImport(DLLPath)] public static extern void DebugStopTraceLogger();
|
||||
[DllImport(DLLPath)] public static extern void DebugSetTraceOptions(TraceLoggerOptions options);
|
||||
[DllImport(DLLPath, EntryPoint = "DebugGetExecutionTrace")] private static extern IntPtr DebugGetExecutionTraceWrapper(UInt32 lineCount);
|
||||
public static string DebugGetExecutionTrace(UInt32 lineCount) { return PtrToStringUtf8(InteropEmu.DebugGetExecutionTraceWrapper(lineCount)); }
|
||||
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool DebugLoadCdlFile([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string cdlFilepath);
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool DebugSaveCdlFile([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string cdlFilepath);
|
||||
[DllImport(DLLPath)] public static extern void DebugGetCdlRatios(ref CdlRatios ratios);
|
||||
@ -806,6 +809,7 @@ namespace Mesen.GUI
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowExtraInfo;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool IndentCode;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowEffectiveAddresses;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool UseLabels;
|
||||
}
|
||||
|
||||
public enum ProfilerDataType
|
||||
|
@ -74,8 +74,10 @@ extern "C"
|
||||
|
||||
DllExport int32_t __stdcall DebugEvaluateExpression(char* expression, EvalResultType *resultType) { return GetDebugger()->EvaluateExpression(expression, *resultType); }
|
||||
|
||||
DllExport void __stdcall DebugStartTraceLogger(TraceLoggerOptions options) { GetDebugger()->StartTraceLogger(options); }
|
||||
DllExport void __stdcall DebugStopTraceLogger() { GetDebugger()->StopTraceLogger(); }
|
||||
DllExport void __stdcall DebugSetTraceOptions(TraceLoggerOptions options) { GetDebugger()->GetTraceLogger()->SetOptions(options); }
|
||||
DllExport void __stdcall DebugStartTraceLogger(char* filename) { GetDebugger()->GetTraceLogger()->StartLogging(filename); }
|
||||
DllExport void __stdcall DebugStopTraceLogger() { GetDebugger()->GetTraceLogger()->StopLogging(); }
|
||||
DllExport const char* DebugGetExecutionTrace(uint32_t lineCount) { return GetDebugger()->GetTraceLogger()->GetExecutionTrace(lineCount); }
|
||||
|
||||
DllExport void __stdcall DebugSetMemoryValue(DebugMemoryType type, uint32_t address, uint8_t value) { return GetDebugger()->GetMemoryDumper()->SetMemoryValue(type, address, value); }
|
||||
DllExport int32_t __stdcall DebugGetMemorySize(DebugMemoryType type) { return GetDebugger()->GetMemorySize(type); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user