Debugger: Show effective address/memory value in disassembly + update trace logger to use the same code

This commit is contained in:
Sour 2019-02-28 16:53:04 -05:00
parent 26e90e90a1
commit c9eb9cef52
20 changed files with 234 additions and 143 deletions

View file

@ -137,7 +137,7 @@ void Console::LoadRom(VirtualFile romFile, VirtualFile patchFile)
_memoryManager->Initialize(shared_from_this());
_cpu.reset(new Cpu(_memoryManager));
_cpu.reset(new Cpu(_memoryManager.get()));
_memoryManager->IncrementMasterClockValue<160>();
//if(_debugger) {

View file

@ -57,6 +57,7 @@
<ClInclude Include="ControlDeviceState.h" />
<ClInclude Include="ControlManager.h" />
<ClInclude Include="Cpu.h" />
<ClInclude Include="DummyCpu.h" />
<ClInclude Include="ExpressionEvaluator.h" />
<ClInclude Include="RegisterHandlerB.h" />
<ClInclude Include="CpuTypes.h" />

View file

@ -188,6 +188,9 @@
<ClInclude Include="ExpressionEvaluator.h">
<Filter>Debugger</Filter>
</ClInclude>
<ClInclude Include="DummyCpu.h">
<Filter>Debugger</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp" />

View file

@ -655,6 +655,7 @@ Move operations
****************/
void Cpu::MVN()
{
#ifndef DUMMYCPU
_state.DBR = _operand & 0xFF;
uint32_t destBank = _state.DBR << 16;
uint32_t srcBank = (_operand << 8) & 0xFF0000;
@ -671,15 +672,17 @@ void Cpu::MVN()
if(_state.A != 0xFFFF) {
//"Idle" cycles, instruction re-reads OP code and operands before every new byte
_memoryManager->Read((_state.K << 16) | (_state.PC - 3), MemoryOperationType::Read);
_memoryManager->Read((_state.K << 16) | (_state.PC - 2), MemoryOperationType::Read);
_memoryManager->Read((_state.K << 16) | (_state.PC - 1), MemoryOperationType::Read);
Read((_state.K << 16) | (_state.PC - 3), MemoryOperationType::Read);
Read((_state.K << 16) | (_state.PC - 2), MemoryOperationType::Read);
Read((_state.K << 16) | (_state.PC - 1), MemoryOperationType::Read);
}
} while(_state.A != 0xFFFF);
#endif
}
void Cpu::MVP()
{
#ifndef DUMMYCPU
_state.DBR = _operand & 0xFF;
uint32_t destBank = _state.DBR << 16;
uint32_t srcBank = (_operand << 8) & 0xFF0000;
@ -696,11 +699,12 @@ void Cpu::MVP()
if(_state.A != 0xFFFF) {
//"Idle" cycles, instruction re-reads OP code and operands before every new byte
_memoryManager->Read((_state.K << 16) | (_state.PC - 3), MemoryOperationType::Read);
_memoryManager->Read((_state.K << 16) | (_state.PC - 2), MemoryOperationType::Read);
_memoryManager->Read((_state.K << 16) | (_state.PC - 1), MemoryOperationType::Read);
Read((_state.K << 16) | (_state.PC - 3), MemoryOperationType::Read);
Read((_state.K << 16) | (_state.PC - 2), MemoryOperationType::Read);
Read((_state.K << 16) | (_state.PC - 1), MemoryOperationType::Read);
}
} while(_state.A != 0xFFFF);
#endif
}
/********************

View file

@ -3,7 +3,7 @@
#include "Cpu.h"
#include "MemoryManager.h"
Cpu::Cpu(shared_ptr<MemoryManager> memoryManager)
Cpu::Cpu(MemoryManager* memoryManager)
{
_memoryManager = memoryManager;
_state = {};
@ -338,7 +338,9 @@ uint8_t Cpu::GetOpCode()
void Cpu::Idle()
{
#ifndef DUMMYCPU
_memoryManager->IncrementMasterClockValue<6>();
#endif
}
uint8_t Cpu::ReadOperandByte()
@ -361,10 +363,22 @@ uint32_t Cpu::ReadOperandLong()
return (b3 << 16) | (b2 << 8) | b1;
}
uint8_t Cpu::ReadCode(uint16_t addr, MemoryOperationType type)
uint8_t Cpu::Read(uint32_t addr, MemoryOperationType type)
{
_state.CycleCount++;
return _memoryManager->Read((_state.K << 16) | addr, type);
#ifdef DUMMYCPU
uint8_t value = _memoryManager->Peek(addr);
LogRead(addr, value);
return value;
#else
return _memoryManager->Read(addr, type);
#endif
}
uint8_t Cpu::ReadCode(uint16_t addr, MemoryOperationType type)
{
return Read((_state.K << 16) | addr, type);
}
uint16_t Cpu::ReadCodeWord(uint16_t addr, MemoryOperationType type)
@ -376,8 +390,7 @@ uint16_t Cpu::ReadCodeWord(uint16_t addr, MemoryOperationType type)
uint8_t Cpu::ReadData(uint32_t addr, MemoryOperationType type)
{
_state.CycleCount++;
return _memoryManager->Read(addr & 0xFFFFFF, type);
return Read(addr & 0xFFFFFF, type);
}
uint16_t Cpu::ReadDataWord(uint32_t addr, MemoryOperationType type)
@ -398,7 +411,12 @@ uint32_t Cpu::ReadDataLong(uint32_t addr, MemoryOperationType type)
void Cpu::Write(uint32_t addr, uint8_t value, MemoryOperationType type)
{
_state.CycleCount++;
#ifdef DUMMYCPU
LogWrite(addr, value);
#else
_memoryManager->Write(addr, value, type);
#endif
}
void Cpu::WriteWord(uint32_t addr, uint16_t value, MemoryOperationType type)

View file

@ -1,4 +1,10 @@
#pragma once
#if (defined(DUMMYCPU) && !defined(__DUMMYCPU__H)) || (!defined(DUMMYCPU) && !defined(__CPU__H))
#ifdef DUMMYCPU
#define __DUMMYCPU__H
#else
#define __CPU__H
#endif
#include "stdafx.h"
#include "CpuTypes.h"
@ -25,7 +31,7 @@ private:
typedef void(Cpu::*Func)();
shared_ptr<MemoryManager> _memoryManager;
MemoryManager* _memoryManager;
bool _immediateMode = false;
@ -53,6 +59,8 @@ private:
uint16_t ReadOperandWord();
uint32_t ReadOperandLong();
uint8_t Read(uint32_t addr, MemoryOperationType type);
void SetSP(uint16_t sp);
void SetPS(uint8_t ps);
@ -285,7 +293,7 @@ private:
void AddrMode_StkRelIndIdxY();
public:
Cpu(shared_ptr<MemoryManager> memoryManager);
Cpu(MemoryManager* memoryManager);
~Cpu();
void Reset();
@ -295,4 +303,30 @@ public:
void SetIrqSource(IrqSource source);
bool CheckIrqSource(IrqSource source);
void ClearIrqSource(IrqSource source);
#ifdef DUMMYCPU
private:
uint32_t _writeCounter = 0;
uint32_t _writeAddresses[10];
uint8_t _writeValue[10];
uint32_t _readCounter = 0;
uint32_t _readAddresses[10];
uint8_t _readValue[10];
uint32_t _valueSize = 0;
void LogRead(uint32_t addr, uint8_t value);
void LogWrite(uint32_t addr, uint8_t value);
public:
void SetDummyState(CpuState &state);
uint32_t GetWriteCount();
uint32_t GetReadCount();
void GetWriteInfo(uint32_t index, uint32_t &addr, uint8_t &value);
void GetReadInfo(uint32_t index, uint32_t &addr, uint8_t &value);
#endif
};
#endif

View file

@ -107,7 +107,8 @@ struct CodeLineData
uint8_t Flags;
int32_t EffectiveAddress;
int32_t Value;
uint16_t Value;
uint8_t ValueSize;
uint8_t ByteCode[4];
char Text[1000];

View file

@ -71,7 +71,6 @@ void Debugger::ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType
DebugState debugState;
GetState(&debugState);
_traceLogger->LogEffectiveAddress(_cpu->GetLastOperand());
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo);
_traceLogger->Log(debugState, disInfo);

View file

@ -235,9 +235,13 @@ bool Disassembler::GetLineData(uint32_t lineIndex, CodeLineData &data)
vector<shared_ptr<DisassemblyInfo>> *cache;
GetSource(result.Address, &source, sourceLength, &cache);
disInfo = (*cache)[result.Address.Address];
CpuState state = _console->GetCpu()->GetState();
state.PC = (uint16_t)result.CpuAddress;
state.K = (result.CpuAddress >> 16);
if(!disInfo) {
disInfo.reset(new DisassemblyInfo(source + result.Address.Address, 0));
disInfo.reset(new DisassemblyInfo(source + result.Address.Address, state.PS));
} else {
data.Flags |= (uint8_t)LineFlags::VerifiedCode;
}
@ -247,8 +251,14 @@ bool Disassembler::GetLineData(uint32_t lineIndex, CodeLineData &data)
memcpy(data.Text, text.c_str(), std::min<int>((int)text.size(), 1000));
data.OpSize = disInfo->GetOperandSize() + 1;
data.EffectiveAddress = disInfo->GetEffectiveAddress();
data.Value = _memoryManager->Peek(result.CpuAddress);
MemoryManager *memoryManager = _console->GetMemoryManager().get();
data.EffectiveAddress = disInfo->GetEffectiveAddress(state, memoryManager);
if(data.EffectiveAddress >= 0) {
data.Value = disInfo->GetMemoryValue(data.EffectiveAddress, memoryManager, data.ValueSize);
} else {
data.ValueSize = 0;
}
disInfo->GetByteCode(data.ByteCode);
data.Comment[0] = 0;
@ -266,7 +276,7 @@ bool Disassembler::GetLineData(uint32_t lineIndex, CodeLineData &data)
return false;
}
int32_t Disassembler::SearchCode(const char *searchString, int32_t startPosition, int32_t endPosition, bool searchBackwards)
int32_t Disassembler::SearchDisassembly(const char *searchString, int32_t startPosition, int32_t endPosition, bool searchBackwards)
{
auto lock = _disassemblyLock.AcquireSafe();
int step = searchBackwards ? -1 : 1;

View file

@ -46,5 +46,5 @@ public:
uint32_t GetLineCount();
uint32_t GetLineIndex(uint32_t cpuAddress);
bool GetLineData(uint32_t lineIndex, CodeLineData &data);
int32_t SearchCode(const char* searchString, int32_t startPosition, int32_t endPosition, bool searchBackwards);
int32_t SearchDisassembly(const char* searchString, int32_t startPosition, int32_t endPosition, bool searchBackwards);
};

View file

@ -3,6 +3,7 @@
#include "DisassemblyInfo.h"
#include "CpuTypes.h"
#include "MemoryManager.h"
#include "DummyCpu.h"
#include "../Utilities/HexUtilities.h"
#include "../Utilities/FastString.h"
@ -17,8 +18,7 @@ DisassemblyInfo::DisassemblyInfo(uint8_t *opPointer, uint8_t cpuFlags)
void DisassemblyInfo::Initialize(uint8_t *opPointer, uint8_t cpuFlags)
{
_flags = cpuFlags;
_effectiveAddress = -1;
_flags = cpuFlags & (ProcFlags::MemoryMode8 | ProcFlags::IndexMode8);
_byteCode[0] = opPointer[0];
_addrMode = DisassemblyInfo::OpMode[_byteCode[0]];
@ -55,7 +55,7 @@ void DisassemblyInfo::GetDisassembly(string &out, uint32_t memoryAddr)
case AddrMode::AbsLng: str.Write(operand); break;
case AddrMode::AbsLngJmp: str.Write(operand); break;
case AddrMode::Acc: break;
case AddrMode::BlkMov: str.Write(operand[1], operand[2], " -> "); str.Write(operand[3], operand[4]); break;
case AddrMode::BlkMov: str.Write('$', operand[1], operand[2], " -> "); str.Write('$', operand[3], operand[4]); break;
case AddrMode::DirIdxIndX: str.Write('(', operand, ",X)"); break;
case AddrMode::DirIdxX: str.Write(operand, ",X"); break;
case AddrMode::DirIdxY: str.Write(operand, ",Y"); break;
@ -177,76 +177,36 @@ void DisassemblyInfo::GetByteCode(string &out)
out += str.ToString();
}
void DisassemblyInfo::GetEffectiveAddressString(string &out)
void DisassemblyInfo::GetEffectiveAddressString(string &out, CpuState &state, MemoryManager* memoryManager)
{
int32_t effectiveAddress = GetEffectiveAddress();
int32_t effectiveAddress = GetEffectiveAddress(state, memoryManager);
if(effectiveAddress >= 0) {
out += " [" + HexUtilities::ToHex24(effectiveAddress) + "]";
}
}
void DisassemblyInfo::SetEffectiveAddress(int32_t effectiveAddress)
int32_t DisassemblyInfo::GetEffectiveAddress(CpuState &state, MemoryManager *memoryManager)
{
_effectiveAddress = effectiveAddress;
}
int32_t DisassemblyInfo::GetEffectiveAddress()
{
if(_addrMode > AddrMode::ImmM && _addrMode != AddrMode::Acc && _addrMode != AddrMode::Imp && _addrMode != AddrMode::Stk) {
return _effectiveAddress;
if(_addrMode > AddrMode::ImmM && _addrMode != AddrMode::Acc && _addrMode != AddrMode::Imp && _addrMode != AddrMode::Stk && _addrMode != AddrMode::Rel && _addrMode != AddrMode::RelLng && _addrMode != AddrMode::BlkMov) {
DummyCpu cpu(memoryManager);
state.PS &= ~(ProcFlags::IndexMode8 | ProcFlags::MemoryMode8);
state.PS |= _flags;
cpu.SetDummyState(state);
cpu.Exec();
return cpu.GetLastOperand();
}
return -1;
}
/*auto getProgramAddress = [&state](uint16_t addr) { return (state.K << 16) | addr; };
auto getDataAddress = [&state](uint16_t addr) { return (state.DBR << 16) | addr; };
auto getDirectAddress = [&state](uint8_t baseAddress, uint16_t offset = 0, bool allowEmulationMode = true) {
if(allowEmulationMode && state.EmulationMode && (state.D & 0xFF) == 0) {
//TODO: Check if new instruction or not (PEI)
return (uint16_t)((state.D & 0xFF00) | ((baseAddress + offset) & 0xFF));
} else {
return (uint16_t)(state.D + baseAddress + offset);
}
};
auto getDirectAddressIndirectWord = [&state, mm, &getDirectAddress](uint8_t baseAddress, uint16_t offset = 0, bool allowEmulationMode = true) {
uint8_t b1 = mm->Peek(getDirectAddress(baseAddress, offset + 0));
uint8_t b2 = mm->Peek(getDirectAddress(baseAddress, offset + 1));
return (b2 << 8) | b1;
};
auto getDirectAddressIndirectLong = [&state, mm, &getDirectAddress](uint8_t baseAddress, uint16_t offset = 0, bool allowEmulationMode = true) {
uint8_t b1 = mm->Peek(getDirectAddress(baseAddress, offset + 0));
uint8_t b2 = mm->Peek(getDirectAddress(baseAddress, offset + 1));
uint8_t b3 = mm->Peek(getDirectAddress(baseAddress, offset + 2));
return (b3 << 16) | (b2 << 8) | b1;
};
uint32_t bank = (state.K << 16);
uint32_t opAddr = GetOperandAddress(bank | state.PC);
switch(_addrMode) {
case AddrMode::AbsIdxX: return opAddr + state.X;
case AddrMode::AbsIdxY: return opAddr + state.Y;
case AddrMode::AbsLngIdxX: return opAddr + state.X;
case AddrMode::AbsIdxXInd: return getProgramAddress(mm->PeekWord(getProgramAddress(opAddr + state.X)));
case AddrMode::AbsInd: return getProgramAddress(mm->PeekWord(opAddr));
case AddrMode::AbsIndLng: return mm->PeekLong(opAddr);
case AddrMode::BlkMov: break; //TODO
case AddrMode::Dir: return getDirectAddress(opAddr);
case AddrMode::DirIdxX: return getDirectAddress(opAddr, state.X);
case AddrMode::DirIdxY: return getDirectAddress(opAddr, state.Y);
case AddrMode::DirInd: return getDirectAddressIndirectWord(opAddr);
case AddrMode::DirIdxIndX: return getDirectAddressIndirectWord(opAddr, state.X);
case AddrMode::DirIndIdxY: return getDirectAddressIndirectWord(opAddr) + state.Y;
case AddrMode::DirIndLng: return getDirectAddressIndirectLong(opAddr);
case AddrMode::DirIndLngIdxY: return getDirectAddressIndirectLong(opAddr) + state.Y;
case AddrMode::StkRel: return opAddr + state.SP;
case AddrMode::StkRelIndIdxY: break;
}*/
uint16_t DisassemblyInfo::GetMemoryValue(uint32_t effectiveAddress, MemoryManager *memoryManager, uint8_t &valueSize)
{
if(_flags & ProcFlags::MemoryMode8) {
valueSize = 1;
return memoryManager->Peek(effectiveAddress);
} else {
valueSize = 2;
return memoryManager->PeekWord(effectiveAddress);
}
}
string DisassemblyInfo::OpName[256] = {

View file

@ -19,7 +19,6 @@ private:
uint8_t _opSize;
AddrMode _addrMode;
uint8_t _flags;
int32_t _effectiveAddress;
public:
DisassemblyInfo();
@ -37,13 +36,8 @@ public:
void GetByteCode(uint8_t copyBuffer[4]);
void GetByteCode(string &out);
void SetEffectiveAddress(int32_t effectiveAddress);
void GetEffectiveAddressString(string &out);
int32_t GetEffectiveAddress();
/*int32_t GetMemoryValue(CpuState& cpuState, MemoryManager* memoryManager);
uint16_t GetJumpDestination(uint16_t pc, MemoryManager* memoryManager);
uint16_t GetIndirectJumpDestination(MemoryManager* memoryManager);
*/
void GetEffectiveAddressString(string &out, CpuState &state, MemoryManager* memoryManager);
int32_t GetEffectiveAddress(CpuState &state, MemoryManager *memoryManager);
uint16_t GetMemoryValue(uint32_t effectiveAddress, MemoryManager *memoryManager, uint8_t &valueSize);
};

55
Core/DummyCpu.h Normal file
View file

@ -0,0 +1,55 @@
#pragma once
#include "stdafx.h"
#define DUMMYCPU
#define Cpu DummyCpu
#include "Cpu.h"
#include "Cpu.cpp"
#include "Cpu.Instructions.cpp"
#undef Cpu
#undef DUMMYCPU
void DummyCpu::SetDummyState(CpuState &state)
{
_state = state;
_writeCounter = 0;
_readCounter = 0;
}
uint32_t DummyCpu::GetWriteCount()
{
return _writeCounter;
}
uint32_t DummyCpu::GetReadCount()
{
return _readCounter;
}
void DummyCpu::LogRead(uint32_t addr, uint8_t value)
{
_readAddresses[_readCounter] = addr;
_readValue[_readCounter] = value;
_readCounter++;
}
void DummyCpu::LogWrite(uint32_t addr, uint8_t value)
{
_writeAddresses[_writeCounter] = addr;
_writeValue[_writeCounter] = value;
_writeCounter++;
}
void DummyCpu::GetWriteInfo(uint32_t index, uint32_t &addr, uint8_t &value)
{
addr = _writeAddresses[index];
value = _writeValue[index];
}
void DummyCpu::GetReadInfo(uint32_t index, uint32_t &addr, uint8_t &value)
{
addr = _readAddresses[index];
value = _readValue[index];
}

View file

@ -185,6 +185,13 @@ uint8_t MemoryManager::Peek(uint32_t addr)
return value;
}
uint16_t MemoryManager::PeekWord(uint32_t addr)
{
uint8_t lsb = Peek(addr);
uint8_t msb = Peek((addr + 1) & 0xFFFFFF);
return (msb << 8) | lsb;
}
void MemoryManager::Write(uint32_t addr, uint8_t value, MemoryOperationType type)
{
IncrementMasterClock(addr);

View file

@ -51,6 +51,7 @@ public:
uint8_t Read(uint32_t addr, MemoryOperationType type);
uint8_t ReadDma(uint32_t addr);
uint8_t Peek(uint32_t addr);
uint16_t PeekWord(uint32_t addr);
void Write(uint32_t addr, uint8_t value, MemoryOperationType type);
void WriteDma(uint32_t addr, uint8_t value);

View file

@ -218,18 +218,28 @@ void TraceLogger::GetTraceRow(string &output, CpuState &cpuState, PpuState &ppuS
case RowDataType::EffectiveAddress:
{
string effectiveAddress;
disassemblyInfo.GetEffectiveAddressString(effectiveAddress);
disassemblyInfo.GetEffectiveAddressString(effectiveAddress, cpuState, _memoryManager.get());
WriteValue(output, effectiveAddress, rowPart);
break;
}
case RowDataType::MemoryValue:
{
/*int32_t value = disassemblyInfo.GetMemoryValue(cpuState, _memoryManager.get());
if(value >= 0) {
output += rowPart.DisplayInHex ? "= $" : "= ";
WriteValue(output, (uint8_t)value, rowPart);
}*/
int32_t address = disassemblyInfo.GetEffectiveAddress(cpuState, _memoryManager.get());
if(address >= 0) {
uint8_t valueSize;
uint16_t value = disassemblyInfo.GetMemoryValue(address, _memoryManager.get(), valueSize);
if(rowPart.DisplayInHex) {
output += "= $";
if(valueSize == 2) {
WriteValue(output, (uint16_t)value, rowPart);
} else {
WriteValue(output, (uint8_t)value, rowPart);
}
} else {
output += "= ";
}
}
break;
}
@ -284,6 +294,14 @@ void TraceLogger::AddRow(DisassemblyInfo &disassemblyInfo, DebugState &state)
_logCount++;
}
if(_logToFile) {
GetTraceRow(_outputBuffer, _cpuStateCache[_currentPos], _ppuStateCache[_currentPos], _disassemblyCache[_currentPos]);
if(_outputBuffer.size() > 32768) {
_outputFile << _outputBuffer;
_outputBuffer.clear();
}
}
_currentPos = (_currentPos + 1) % ExecutionLogSize;
}
/*
@ -297,25 +315,6 @@ void TraceLogger::LogNonExec(OperationInfo& operationInfo)
}
}*/
void TraceLogger::LogEffectiveAddress(uint32_t effectiveAddress)
{
uint32_t pos;
if(_currentPos > 0) {
pos = _currentPos - 1;
} else {
pos = ExecutionLogSize - 1;
}
_disassemblyCache[pos].SetEffectiveAddress(effectiveAddress);
if(_logToFile) {
GetTraceRow(_outputBuffer, _cpuStateCache[pos], _ppuStateCache[pos], _disassemblyCache[pos]);
if(_outputBuffer.size() > 32768) {
_outputFile << _outputBuffer;
_outputBuffer.clear();
}
}
}
void TraceLogger::Log(DebugState &state, DisassemblyInfo &disassemblyInfo)
{
auto lock = _lock.AcquireSafe();

View file

@ -97,8 +97,6 @@ public:
TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager);
~TraceLogger();
void LogEffectiveAddress(uint32_t effectiveAddress);
void Log(DebugState &state, DisassemblyInfo &disassemblyInfo);
//void LogNonExec(OperationInfo& operationInfo);
void SetOptions(TraceLoggerOptions options);

View file

@ -39,7 +39,7 @@ extern "C"
DllExport void __stdcall GetDisassemblyLineData(uint32_t lineIndex, CodeLineData &data) { GetDebugger()->GetDisassembler()->GetLineData(lineIndex, data); }
DllExport uint32_t __stdcall GetDisassemblyLineCount() { return GetDebugger()->GetDisassembler()->GetLineCount(); }
DllExport uint32_t __stdcall GetDisassemblyLineIndex(uint32_t cpuAddress) { return GetDebugger()->GetDisassembler()->GetLineIndex(cpuAddress); }
DllExport int32_t __stdcall SearchDisassembly(const char* searchString, int32_t startPosition, int32_t endPosition, bool searchBackwards) { return GetDebugger()->GetDisassembler()->SearchCode(searchString, startPosition, endPosition, searchBackwards); }
DllExport int32_t __stdcall SearchDisassembly(const char* searchString, int32_t startPosition, int32_t endPosition, bool searchBackwards) { return GetDebugger()->GetDisassembler()->SearchDisassembly(searchString, startPosition, endPosition, searchBackwards); }
DllExport void __stdcall SetTraceOptions(TraceLoggerOptions options) { GetDebugger()->GetTraceLogger()->SetOptions(options); }
DllExport void __stdcall StartTraceLogger(char* filename) { GetDebugger()->GetTraceLogger()->StartLogging(filename); }

View file

@ -21,11 +21,27 @@ namespace Mesen.GUI.Debugger
public string Comment;
public Int32 EffectiveAddress;
public Int32 Value;
public UInt16 Value;
public byte ValueSize;
public string GetEffectiveAddressString()
{
return "[" + EffectiveAddress.ToString("X6") + "]";
if(EffectiveAddress >= 0) {
return "[" + EffectiveAddress.ToString("X6") + "]";
} else {
return "";
}
}
public string GetValueString()
{
if(ValueSize == 1) {
return " = $" + Value.ToString("X2");
} else if(ValueSize == 2) {
return " = $" + Value.ToString("X4");
} else {
return "";
}
}
public int Indentation
@ -58,6 +74,7 @@ namespace Mesen.GUI.Debugger
this.EffectiveAddress = data.EffectiveAddress;
this.Flags = (LineFlags)data.Flags;
this.Value = data.Value;
this.ValueSize = data.ValueSize;
}
private string ConvertString(byte[] stringArray)
@ -81,7 +98,8 @@ namespace Mesen.GUI.Debugger
public byte Flags;
public Int32 EffectiveAddress;
public Int32 Value;
public UInt16 Value;
public byte ValueSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] ByteCode;

View file

@ -16,7 +16,7 @@ namespace Mesen.GUI.Debugger.Controls
{
public partial class ctrlTextbox : Control
{
private Regex _codeRegex = new Regex("^(\\s*)([a-z]{3})([*]{0,1})($|[ ]){1}([(]{0,1})(([$][0-9a-f]*)|(#[@$:_0-9a-z]*)|([@_a-z]([@_a-z0-9])*){0,1}(\\+(\\d+)){0,1}){0,1}([)]{0,1})(,X|,Y){0,1}([)]{0,1})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private Regex _codeRegex = new Regex("^(\\s*)([a-z]{3})([*]{0,1})($|[ ]){1}([(\\[]{0,1})(([$][0-9a-f]*)|(#[@$:_0-9a-z]*)|([@_a-z]([@_a-z0-9])*){0,1}(\\+(\\d+)){0,1}){0,1}([)\\]]{0,1})(,X|,Y){0,1}([)\\]]{0,1})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
public event EventHandler ScrollPositionChanged;
public event EventHandler SelectedLineChanged;
private bool _disableScrollPositionChangedEvent;
@ -902,8 +902,6 @@ namespace Mesen.GUI.Debugger.Controls
private void DrawLineText(Graphics g, int currentLine, int marginLeft, int positionY, CodeLineData lineData, float codeStringLength, Color? textColor, int lineHeight)
{
string codeString = lineData.Text;
string addressString = lineData.EffectiveAddress>= 0 ? (" [" + lineData.EffectiveAddress.ToString("X6") + "]") : "";
float addressStringLength = g.MeasureString(addressString, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width;
string commentString = lineData.Comment;
DebugInfo info = ConfigManager.Config.Debug;
@ -962,24 +960,15 @@ namespace Mesen.GUI.Debugger.Controls
int codePartCount = colors.Count;
List<string> parts = new List<string>() { padding, opcode, invalidStar, " ", paren1, operand, paren2, indirect, paren3 };
string memoryAddress = "";
if(!string.IsNullOrWhiteSpace(addressString)) {
colors.Add(info.CodeEffectiveAddressColor);
parts.Add(addressString);
memoryAddress = addressString.Substring(3).Trim();
//Update the contents of "arrayPosition" based on the address string, rather than use the one from the original address
int plusIndex = memoryAddress.IndexOf("+");
arrayPosition = plusIndex >= 0 ? memoryAddress.Substring(plusIndex+1) : "";
} else if(operand.Length > 0 && operand[0] != '#') {
memoryAddress = operand.Trim();
if(lineData.EffectiveAddress >= 0) {
colors.Add(info.CodeEffectiveAddressColor);
parts.Add(" [" + lineData.EffectiveAddress.ToString("X6") + "]");
}
if(this.ShowMemoryValues && memoryAddress.Length > 0) {
if(lineData.Value >= 0) {
colors.Add(defaultColor);
parts.Add(" = $" + lineData.Value.ToString("X4"));
}
if(this.ShowMemoryValues && lineData.ValueSize > 0) {
colors.Add(defaultColor);
parts.Add(lineData.GetValueString());
}
//Display the rest of the line (used by trace logger)