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()); _memoryManager->Initialize(shared_from_this());
_cpu.reset(new Cpu(_memoryManager)); _cpu.reset(new Cpu(_memoryManager.get()));
_memoryManager->IncrementMasterClockValue<160>(); _memoryManager->IncrementMasterClockValue<160>();
//if(_debugger) { //if(_debugger) {

View file

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

View file

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

View file

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

View file

@ -3,7 +3,7 @@
#include "Cpu.h" #include "Cpu.h"
#include "MemoryManager.h" #include "MemoryManager.h"
Cpu::Cpu(shared_ptr<MemoryManager> memoryManager) Cpu::Cpu(MemoryManager* memoryManager)
{ {
_memoryManager = memoryManager; _memoryManager = memoryManager;
_state = {}; _state = {};
@ -338,7 +338,9 @@ uint8_t Cpu::GetOpCode()
void Cpu::Idle() void Cpu::Idle()
{ {
#ifndef DUMMYCPU
_memoryManager->IncrementMasterClockValue<6>(); _memoryManager->IncrementMasterClockValue<6>();
#endif
} }
uint8_t Cpu::ReadOperandByte() uint8_t Cpu::ReadOperandByte()
@ -361,10 +363,22 @@ uint32_t Cpu::ReadOperandLong()
return (b3 << 16) | (b2 << 8) | b1; 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++; _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) 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) uint8_t Cpu::ReadData(uint32_t addr, MemoryOperationType type)
{ {
_state.CycleCount++; return Read(addr & 0xFFFFFF, type);
return _memoryManager->Read(addr & 0xFFFFFF, type);
} }
uint16_t Cpu::ReadDataWord(uint32_t addr, MemoryOperationType 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) void Cpu::Write(uint32_t addr, uint8_t value, MemoryOperationType type)
{ {
_state.CycleCount++; _state.CycleCount++;
#ifdef DUMMYCPU
LogWrite(addr, value);
#else
_memoryManager->Write(addr, value, type); _memoryManager->Write(addr, value, type);
#endif
} }
void Cpu::WriteWord(uint32_t addr, uint16_t value, MemoryOperationType type) 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 "stdafx.h"
#include "CpuTypes.h" #include "CpuTypes.h"
@ -25,7 +31,7 @@ private:
typedef void(Cpu::*Func)(); typedef void(Cpu::*Func)();
shared_ptr<MemoryManager> _memoryManager; MemoryManager* _memoryManager;
bool _immediateMode = false; bool _immediateMode = false;
@ -53,6 +59,8 @@ private:
uint16_t ReadOperandWord(); uint16_t ReadOperandWord();
uint32_t ReadOperandLong(); uint32_t ReadOperandLong();
uint8_t Read(uint32_t addr, MemoryOperationType type);
void SetSP(uint16_t sp); void SetSP(uint16_t sp);
void SetPS(uint8_t ps); void SetPS(uint8_t ps);
@ -285,7 +293,7 @@ private:
void AddrMode_StkRelIndIdxY(); void AddrMode_StkRelIndIdxY();
public: public:
Cpu(shared_ptr<MemoryManager> memoryManager); Cpu(MemoryManager* memoryManager);
~Cpu(); ~Cpu();
void Reset(); void Reset();
@ -295,4 +303,30 @@ public:
void SetIrqSource(IrqSource source); void SetIrqSource(IrqSource source);
bool CheckIrqSource(IrqSource source); bool CheckIrqSource(IrqSource source);
void ClearIrqSource(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; uint8_t Flags;
int32_t EffectiveAddress; int32_t EffectiveAddress;
int32_t Value; uint16_t Value;
uint8_t ValueSize;
uint8_t ByteCode[4]; uint8_t ByteCode[4];
char Text[1000]; char Text[1000];

View file

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

View file

@ -236,8 +236,12 @@ bool Disassembler::GetLineData(uint32_t lineIndex, CodeLineData &data)
GetSource(result.Address, &source, sourceLength, &cache); GetSource(result.Address, &source, sourceLength, &cache);
disInfo = (*cache)[result.Address.Address]; disInfo = (*cache)[result.Address.Address];
CpuState state = _console->GetCpu()->GetState();
state.PC = (uint16_t)result.CpuAddress;
state.K = (result.CpuAddress >> 16);
if(!disInfo) { if(!disInfo) {
disInfo.reset(new DisassemblyInfo(source + result.Address.Address, 0)); disInfo.reset(new DisassemblyInfo(source + result.Address.Address, state.PS));
} else { } else {
data.Flags |= (uint8_t)LineFlags::VerifiedCode; 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)); memcpy(data.Text, text.c_str(), std::min<int>((int)text.size(), 1000));
data.OpSize = disInfo->GetOperandSize() + 1; 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); disInfo->GetByteCode(data.ByteCode);
data.Comment[0] = 0; data.Comment[0] = 0;
@ -266,7 +276,7 @@ bool Disassembler::GetLineData(uint32_t lineIndex, CodeLineData &data)
return false; 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(); auto lock = _disassemblyLock.AcquireSafe();
int step = searchBackwards ? -1 : 1; int step = searchBackwards ? -1 : 1;

View file

@ -46,5 +46,5 @@ public:
uint32_t GetLineCount(); uint32_t GetLineCount();
uint32_t GetLineIndex(uint32_t cpuAddress); uint32_t GetLineIndex(uint32_t cpuAddress);
bool GetLineData(uint32_t lineIndex, CodeLineData &data); 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 "DisassemblyInfo.h"
#include "CpuTypes.h" #include "CpuTypes.h"
#include "MemoryManager.h" #include "MemoryManager.h"
#include "DummyCpu.h"
#include "../Utilities/HexUtilities.h" #include "../Utilities/HexUtilities.h"
#include "../Utilities/FastString.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) void DisassemblyInfo::Initialize(uint8_t *opPointer, uint8_t cpuFlags)
{ {
_flags = cpuFlags; _flags = cpuFlags & (ProcFlags::MemoryMode8 | ProcFlags::IndexMode8);
_effectiveAddress = -1;
_byteCode[0] = opPointer[0]; _byteCode[0] = opPointer[0];
_addrMode = DisassemblyInfo::OpMode[_byteCode[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::AbsLng: str.Write(operand); break;
case AddrMode::AbsLngJmp: str.Write(operand); break; case AddrMode::AbsLngJmp: str.Write(operand); break;
case AddrMode::Acc: 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::DirIdxIndX: str.Write('(', operand, ",X)"); break;
case AddrMode::DirIdxX: str.Write(operand, ",X"); break; case AddrMode::DirIdxX: str.Write(operand, ",X"); break;
case AddrMode::DirIdxY: str.Write(operand, ",Y"); break; case AddrMode::DirIdxY: str.Write(operand, ",Y"); break;
@ -177,76 +177,36 @@ void DisassemblyInfo::GetByteCode(string &out)
out += str.ToString(); 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) { if(effectiveAddress >= 0) {
out += " [" + HexUtilities::ToHex24(effectiveAddress) + "]"; out += " [" + HexUtilities::ToHex24(effectiveAddress) + "]";
} }
} }
void DisassemblyInfo::SetEffectiveAddress(int32_t effectiveAddress) int32_t DisassemblyInfo::GetEffectiveAddress(CpuState &state, MemoryManager *memoryManager)
{ {
_effectiveAddress = 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);
int32_t DisassemblyInfo::GetEffectiveAddress() state.PS |= _flags;
{ cpu.SetDummyState(state);
if(_addrMode > AddrMode::ImmM && _addrMode != AddrMode::Acc && _addrMode != AddrMode::Imp && _addrMode != AddrMode::Stk) { cpu.Exec();
return _effectiveAddress; return cpu.GetLastOperand();
} }
return -1; return -1;
}
/*auto getProgramAddress = [&state](uint16_t addr) { return (state.K << 16) | addr; }; uint16_t DisassemblyInfo::GetMemoryValue(uint32_t effectiveAddress, MemoryManager *memoryManager, uint8_t &valueSize)
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(_flags & ProcFlags::MemoryMode8) {
if(allowEmulationMode && state.EmulationMode && (state.D & 0xFF) == 0) { valueSize = 1;
//TODO: Check if new instruction or not (PEI) return memoryManager->Peek(effectiveAddress);
return (uint16_t)((state.D & 0xFF00) | ((baseAddress + offset) & 0xFF));
} else { } else {
return (uint16_t)(state.D + baseAddress + offset); valueSize = 2;
return memoryManager->PeekWord(effectiveAddress);
} }
};
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;
}*/
} }
string DisassemblyInfo::OpName[256] = { string DisassemblyInfo::OpName[256] = {

View file

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

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; 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) void MemoryManager::Write(uint32_t addr, uint8_t value, MemoryOperationType type)
{ {
IncrementMasterClock(addr); IncrementMasterClock(addr);

View file

@ -51,6 +51,7 @@ public:
uint8_t Read(uint32_t addr, MemoryOperationType type); uint8_t Read(uint32_t addr, MemoryOperationType type);
uint8_t ReadDma(uint32_t addr); uint8_t ReadDma(uint32_t addr);
uint8_t Peek(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 Write(uint32_t addr, uint8_t value, MemoryOperationType type);
void WriteDma(uint32_t addr, uint8_t value); 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: case RowDataType::EffectiveAddress:
{ {
string effectiveAddress; string effectiveAddress;
disassemblyInfo.GetEffectiveAddressString(effectiveAddress); disassemblyInfo.GetEffectiveAddressString(effectiveAddress, cpuState, _memoryManager.get());
WriteValue(output, effectiveAddress, rowPart); WriteValue(output, effectiveAddress, rowPart);
break; break;
} }
case RowDataType::MemoryValue: case RowDataType::MemoryValue:
{ {
/*int32_t value = disassemblyInfo.GetMemoryValue(cpuState, _memoryManager.get()); int32_t address = disassemblyInfo.GetEffectiveAddress(cpuState, _memoryManager.get());
if(value >= 0) { if(address >= 0) {
output += rowPart.DisplayInHex ? "= $" : "= "; 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); WriteValue(output, (uint8_t)value, rowPart);
}*/ }
} else {
output += "= ";
}
}
break; break;
} }
@ -284,6 +294,14 @@ void TraceLogger::AddRow(DisassemblyInfo &disassemblyInfo, DebugState &state)
_logCount++; _logCount++;
} }
if(_logToFile) {
GetTraceRow(_outputBuffer, _cpuStateCache[_currentPos], _ppuStateCache[_currentPos], _disassemblyCache[_currentPos]);
if(_outputBuffer.size() > 32768) {
_outputFile << _outputBuffer;
_outputBuffer.clear();
}
}
_currentPos = (_currentPos + 1) % ExecutionLogSize; _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) void TraceLogger::Log(DebugState &state, DisassemblyInfo &disassemblyInfo)
{ {
auto lock = _lock.AcquireSafe(); auto lock = _lock.AcquireSafe();

View file

@ -97,8 +97,6 @@ public:
TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager); TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager);
~TraceLogger(); ~TraceLogger();
void LogEffectiveAddress(uint32_t effectiveAddress);
void Log(DebugState &state, DisassemblyInfo &disassemblyInfo); void Log(DebugState &state, DisassemblyInfo &disassemblyInfo);
//void LogNonExec(OperationInfo& operationInfo); //void LogNonExec(OperationInfo& operationInfo);
void SetOptions(TraceLoggerOptions options); 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 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 GetDisassemblyLineCount() { return GetDebugger()->GetDisassembler()->GetLineCount(); }
DllExport uint32_t __stdcall GetDisassemblyLineIndex(uint32_t cpuAddress) { return GetDebugger()->GetDisassembler()->GetLineIndex(cpuAddress); } 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 SetTraceOptions(TraceLoggerOptions options) { GetDebugger()->GetTraceLogger()->SetOptions(options); }
DllExport void __stdcall StartTraceLogger(char* filename) { GetDebugger()->GetTraceLogger()->StartLogging(filename); } DllExport void __stdcall StartTraceLogger(char* filename) { GetDebugger()->GetTraceLogger()->StartLogging(filename); }

View file

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

View file

@ -16,7 +16,7 @@ namespace Mesen.GUI.Debugger.Controls
{ {
public partial class ctrlTextbox : Control 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 ScrollPositionChanged;
public event EventHandler SelectedLineChanged; public event EventHandler SelectedLineChanged;
private bool _disableScrollPositionChangedEvent; 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) private void DrawLineText(Graphics g, int currentLine, int marginLeft, int positionY, CodeLineData lineData, float codeStringLength, Color? textColor, int lineHeight)
{ {
string codeString = lineData.Text; 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; string commentString = lineData.Comment;
DebugInfo info = ConfigManager.Config.Debug; DebugInfo info = ConfigManager.Config.Debug;
@ -962,24 +960,15 @@ namespace Mesen.GUI.Debugger.Controls
int codePartCount = colors.Count; int codePartCount = colors.Count;
List<string> parts = new List<string>() { padding, opcode, invalidStar, " ", paren1, operand, paren2, indirect, paren3 }; List<string> parts = new List<string>() { padding, opcode, invalidStar, " ", paren1, operand, paren2, indirect, paren3 };
string memoryAddress = "";
if(!string.IsNullOrWhiteSpace(addressString)) { if(lineData.EffectiveAddress >= 0) {
colors.Add(info.CodeEffectiveAddressColor); colors.Add(info.CodeEffectiveAddressColor);
parts.Add(addressString); parts.Add(" [" + lineData.EffectiveAddress.ToString("X6") + "]");
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(this.ShowMemoryValues && memoryAddress.Length > 0) { if(this.ShowMemoryValues && lineData.ValueSize > 0) {
if(lineData.Value >= 0) {
colors.Add(defaultColor); colors.Add(defaultColor);
parts.Add(" = $" + lineData.Value.ToString("X4")); parts.Add(lineData.GetValueString());
}
} }
//Display the rest of the line (used by trace logger) //Display the rest of the line (used by trace logger)