Debugger: General speed optimizations

This commit is contained in:
Souryo 2017-08-05 17:18:09 -04:00
parent ce3e4d7c80
commit 4e14a83625
15 changed files with 151 additions and 110 deletions

View File

@ -800,7 +800,7 @@ void BaseMapper::InternalWriteVRAM(uint16_t addr, uint8_t value)
void BaseMapper::WriteVRAM(uint16_t addr, uint8_t value) void BaseMapper::WriteVRAM(uint16_t addr, uint8_t value)
{ {
ProcessVramAccess(addr); ProcessVramAccess(addr);
Debugger::ProcessVramOperation(MemoryOperationType::Write, addr, value); Debugger::ProcessVramWriteOperation(addr, value);
NotifyVRAMAddressChange(addr); NotifyVRAMAddressChange(addr);
if(_chrPageAccessType[addr >> 8] & MemoryAccessType::Write) { if(_chrPageAccessType[addr >> 8] & MemoryAccessType::Write) {

View File

@ -179,7 +179,7 @@ public:
NotifyVRAMAddressChange(addr); NotifyVRAMAddressChange(addr);
uint8_t value = MapperReadVRAM(addr, type); uint8_t value = MapperReadVRAM(addr, type);
Debugger::ProcessVramOperation(type, addr, value); Debugger::ProcessVramReadOperation(type, addr, value);
return value; return value;
} }

View File

@ -34,24 +34,25 @@ CPU::CPU(MemoryManager *memoryManager)
&CPU::BEQ, &CPU::SBC, &CPU::HLT, &CPU::ISB, &CPU::NOP, &CPU::SBC, &CPU::INC, &CPU::ISB, &CPU::SED, &CPU::SBC, &CPU::NOP, &CPU::ISB, &CPU::NOP, &CPU::SBC, &CPU::INC, &CPU::ISB //F &CPU::BEQ, &CPU::SBC, &CPU::HLT, &CPU::ISB, &CPU::NOP, &CPU::SBC, &CPU::INC, &CPU::ISB, &CPU::SED, &CPU::SBC, &CPU::NOP, &CPU::ISB, &CPU::NOP, &CPU::SBC, &CPU::INC, &CPU::ISB //F
}; };
typedef AddrMode M;
AddrMode addrMode[] = { AddrMode addrMode[] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F // 0 1 2 3 4 5 6 7 8 9 A B C D E F
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //0 M::Imp, M::IndX, M::None, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Acc, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //0
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //1 M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//1
Abs, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //2 M::Abs, M::IndX, M::None, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Acc, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //2
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //3 M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//3
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //4 M::Imp, M::IndX, M::None, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Acc, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //4
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //5 M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//5
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //6 M::Imp, M::IndX, M::None, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Acc, M::Imm, M::Ind, M::Abs, M::Abs, M::Abs, //6
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //7 M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//7
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //8 M::Imm, M::IndX, M::Imm, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Imp, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //8
Rel, IndYW, None, IndYW, ZeroX, ZeroX, ZeroY, ZeroY, Imp, AbsYW, Imp, AbsYW, AbsXW, AbsXW, AbsYW, AbsYW, //9 M::Rel, M::IndYW, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroY, M::ZeroY, M::Imp, M::AbsYW,M::Imp, M::AbsYW,M::AbsXW,M::AbsXW,M::AbsYW,M::AbsYW,//9
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //A M::Imm, M::IndX, M::Imm, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Imp, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //A
Rel, IndY, None, IndY, ZeroX, ZeroX, ZeroY, ZeroY, Imp, AbsY, Imp, AbsY, AbsX, AbsX, AbsY, AbsY, //B M::Rel, M::IndY, M::None, M::IndY, M::ZeroX, M::ZeroX, M::ZeroY, M::ZeroY, M::Imp, M::AbsY, M::Imp, M::AbsY, M::AbsX, M::AbsX, M::AbsY, M::AbsY, //B
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //C M::Imm, M::IndX, M::Imm, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Imp, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //C
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //D M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//D
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //E M::Imm, M::IndX, M::Imm, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Imp, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //E
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //F M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//F
}; };
memcpy(_opTable, opTable, sizeof(opTable)); memcpy(_opTable, opTable, sizeof(opTable));

View File

@ -22,7 +22,7 @@ namespace PSFlags
}; };
} }
enum AddrMode enum class AddrMode
{ {
None, Acc, Imp, Imm, Rel, None, Acc, Imp, Imm, Rel,
Zero, Abs, ZeroX, ZeroY, Zero, Abs, ZeroX, ZeroY,

View File

@ -42,7 +42,7 @@ void CodeRunner::WriteRAM(uint16_t addr, uint8_t value)
} }
} }
shared_ptr<DisassemblyInfo> CodeRunner::GetDisassemblyInfo(uint16_t cpuAddress) DisassemblyInfo CodeRunner::GetDisassemblyInfo(uint16_t cpuAddress)
{ {
return shared_ptr<DisassemblyInfo>(new DisassemblyInfo(_byteCode.data() + cpuAddress - CodeRunner::BaseAddress, false)); return DisassemblyInfo(_byteCode.data() + cpuAddress - CodeRunner::BaseAddress, false);
} }

View File

@ -18,7 +18,7 @@ public:
CodeRunner(vector<uint8_t> byteCode, Debugger *debugger); CodeRunner(vector<uint8_t> byteCode, Debugger *debugger);
bool IsRunning(); bool IsRunning();
shared_ptr<DisassemblyInfo> GetDisassemblyInfo(uint16_t cpuAddress); DisassemblyInfo GetDisassemblyInfo(uint16_t cpuAddress);
void GetMemoryRanges(MemoryRanges &ranges) override; void GetMemoryRanges(MemoryRanges &ranges) override;
uint8_t ReadRAM(uint16_t addr) override; uint8_t ReadRAM(uint16_t addr) override;

View File

@ -213,28 +213,26 @@ void Debugger::SetBreakpoints(Breakpoint breakpoints[], uint32_t length)
void Debugger::UpdateBreakpoints() void Debugger::UpdateBreakpoints()
{ {
if(_bpUpdateNeeded) { _bpUpdateLock.AcquireSafe();
_bpUpdateLock.AcquireSafe();
for(int i = 0; i < Debugger::BreakpointTypeCount; i++) {
_breakpoints[i].clear();
_breakpointRpnList[i].clear();
_hasBreakpoint[i] = false;
}
ExpressionEvaluator expEval(this);
for(Breakpoint &bp : _newBreakpoints) {
for(int i = 0; i < Debugger::BreakpointTypeCount; i++) { for(int i = 0; i < Debugger::BreakpointTypeCount; i++) {
_breakpoints[i].clear(); if(bp.HasBreakpointType((BreakpointType)i)) {
_breakpointRpnList[i].clear(); _breakpoints[i].push_back(bp);
_hasBreakpoint[i] = false; _breakpointRpnList[i].push_back(*expEval.GetRpnList(bp.GetCondition()));
} _hasBreakpoint[i] = true;
ExpressionEvaluator expEval(this);
for(Breakpoint &bp : _newBreakpoints) {
for(int i = 0; i < Debugger::BreakpointTypeCount; i++) {
if(bp.HasBreakpointType((BreakpointType)i)) {
_breakpoints[i].push_back(bp);
_breakpointRpnList[i].push_back(*expEval.GetRpnList(bp.GetCondition()));
_hasBreakpoint[i] = true;
}
} }
} }
_bpUpdateNeeded = false;
} }
_bpUpdateNeeded = false;
} }
bool Debugger::HasMatchingBreakpoint(BreakpointType type, OperationInfo &operationInfo) bool Debugger::HasMatchingBreakpoint(BreakpointType type, OperationInfo &operationInfo)
@ -244,7 +242,9 @@ bool Debugger::HasMatchingBreakpoint(BreakpointType type, OperationInfo &operati
return false; return false;
} }
UpdateBreakpoints(); if(_bpUpdateNeeded) {
UpdateBreakpoints();
}
uint32_t absoluteAddr = _mapper->ToAbsoluteAddress(operationInfo.Address); uint32_t absoluteAddr = _mapper->ToAbsoluteAddress(operationInfo.Address);
vector<Breakpoint> &breakpoints = _breakpoints[(int)type]; vector<Breakpoint> &breakpoints = _breakpoints[(int)type];
@ -488,7 +488,7 @@ bool Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &ad
GetState(&_debugState, false); GetState(&_debugState, false);
shared_ptr<DisassemblyInfo> disassemblyInfo; DisassemblyInfo disassemblyInfo;
if(_codeRunner && _codeRunner->IsRunning() && addr >= 0x3000 && addr < 0x4000) { if(_codeRunner && _codeRunner->IsRunning() && addr >= 0x3000 && addr < 0x4000) {
disassemblyInfo = _codeRunner->GetDisassemblyInfo(addr); disassemblyInfo = _codeRunner->GetDisassemblyInfo(addr);
} else { } else {
@ -560,19 +560,30 @@ bool Debugger::SleepUntilResume()
return false; return false;
} }
void Debugger::PrivateProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value) void Debugger::PrivateProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t value)
{ {
if(type != MemoryOperationType::Write) { int32_t absoluteAddr = _mapper->ToAbsoluteChrAddress(addr);
int32_t absoluteAddr = _mapper->ToAbsoluteChrAddress(addr); _codeDataLogger->SetFlag(absoluteAddr, type == MemoryOperationType::Read ? CdlChrFlags::Read : CdlChrFlags::Drawn);
_codeDataLogger->SetFlag(absoluteAddr, type == MemoryOperationType::Read ? CdlChrFlags::Read : CdlChrFlags::Drawn);
}
BreakpointType bpType = type == MemoryOperationType::Write ? BreakpointType::WriteVram : BreakpointType::ReadVram; if(_hasBreakpoint[BreakpointType::ReadVram]) {
OperationInfo operationInfo { addr, value, type }; OperationInfo operationInfo{ addr, value, type };
if(_hasBreakpoint[bpType] && HasMatchingBreakpoint(bpType, operationInfo)) { if(HasMatchingBreakpoint(BreakpointType::ReadVram, operationInfo)) {
//Found a matching breakpoint, stop execution //Found a matching breakpoint, stop execution
Step(1); Step(1);
SleepUntilResume(); SleepUntilResume();
}
}
}
void Debugger::PrivateProcessVramWriteOperation(uint16_t addr, uint8_t value)
{
if(_hasBreakpoint[BreakpointType::WriteVram]) {
OperationInfo operationInfo{ addr, value, MemoryOperationType::Write };
if(HasMatchingBreakpoint(BreakpointType::WriteVram, operationInfo)) {
//Found a matching breakpoint, stop execution
Step(1);
SleepUntilResume();
}
} }
} }
@ -753,10 +764,17 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin
return true; return true;
} }
void Debugger::ProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value) void Debugger::ProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t value)
{ {
if(Debugger::Instance) { if(Debugger::Instance) {
Debugger::Instance->PrivateProcessVramOperation(type, addr, value); Debugger::Instance->PrivateProcessVramReadOperation(type, addr, value);
}
}
void Debugger::ProcessVramWriteOperation(uint16_t addr, uint8_t value)
{
if(Debugger::Instance) {
Debugger::Instance->PrivateProcessVramWriteOperation(addr, value);
} }
} }

View File

@ -110,7 +110,8 @@ private:
void PrivateProcessPpuCycle(); void PrivateProcessPpuCycle();
bool PrivateProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t &value); bool PrivateProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t &value);
void PrivateProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value); void PrivateProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t value);
void PrivateProcessVramWriteOperation(uint16_t addr, uint8_t value);
bool HasMatchingBreakpoint(BreakpointType type, OperationInfo &operationInfo); bool HasMatchingBreakpoint(BreakpointType type, OperationInfo &operationInfo);
void UpdateCallstack(uint32_t addr); void UpdateCallstack(uint32_t addr);
@ -176,7 +177,8 @@ public:
int32_t EvaluateExpression(string expression, EvalResultType &resultType); int32_t EvaluateExpression(string expression, EvalResultType &resultType);
static bool ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t &value); static bool ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t &value);
static void ProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value); static void ProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t value);
static void ProcessVramWriteOperation(uint16_t addr, uint8_t value);
static void ProcessPpuCycle(); static void ProcessPpuCycle();
static void SetLastFramePpuScroll(uint16_t x, uint16_t y); static void SetLastFramePpuScroll(uint16_t x, uint16_t y);

View File

@ -78,23 +78,25 @@ void Disassembler::BuildOpCodeTables(bool useLowerCase)
false,false,true, true, true, false,false,true, false,false,true, true, true, false,false,true //F false,false,true, true, true, false,false,true, false,false,true, true, true, false,false,true //F
}; };
AddrMode opMode[256] = { typedef AddrMode M;
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Acc, Imm, Abs, Abs, Abs, Abs, AddrMode opMode[] = {
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, // 0 1 2 3 4 5 6 7 8 9 A B C D E F
Abs, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Acc, Imm, Abs, Abs, Abs, Abs, M::Imp, M::IndX, M::None, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Acc, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //0
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//1
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Acc, Imm, Abs, Abs, Abs, Abs, M::Abs, M::IndX, M::None, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Acc, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //2
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//3
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Acc, Imm, Ind, Abs, Abs, Abs, M::Imp, M::IndX, M::None, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Acc, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //4
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//5
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, M::Imp, M::IndX, M::None, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Acc, M::Imm, M::Ind, M::Abs, M::Abs, M::Abs, //6
Rel, IndYW, None, IndY, ZeroX, ZeroX, ZeroY, ZeroY, Imp, AbsYW, Imp, AbsY, AbsXW, AbsXW, AbsYW, AbsY, M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//7
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, M::Imm, M::IndX, M::Imm, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Imp, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //8
Rel, IndY, None, IndY, ZeroX, ZeroX, ZeroY, ZeroY, Imp, AbsY, Imp, AbsY, AbsX, AbsX, AbsY, AbsY, M::Rel, M::IndYW, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroY, M::ZeroY, M::Imp, M::AbsYW,M::Imp, M::AbsYW,M::AbsXW,M::AbsXW,M::AbsYW,M::AbsYW,//9
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, M::Imm, M::IndX, M::Imm, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Imp, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //A
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, M::Rel, M::IndY, M::None, M::IndY, M::ZeroX, M::ZeroX, M::ZeroY, M::ZeroY, M::Imp, M::AbsY, M::Imp, M::AbsY, M::AbsX, M::AbsX, M::AbsY, M::AbsY, //B
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, M::Imm, M::IndX, M::Imm, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Imp, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //C
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//D
M::Imm, M::IndX, M::Imm, M::IndX, M::Zero, M::Zero, M::Zero, M::Zero, M::Imp, M::Imm, M::Imp, M::Imm, M::Abs, M::Abs, M::Abs, M::Abs, //E
M::Rel, M::IndY, M::None, M::IndYW, M::ZeroX, M::ZeroX, M::ZeroX, M::ZeroX, M::Imp, M::AbsY, M::Imp, M::AbsYW,M::AbsX, M::AbsX, M::AbsXW,M::AbsXW,//F
}; };
for(int i = 0; i < 256; i++) { for(int i = 0; i < 256; i++) {
@ -201,14 +203,14 @@ uint32_t Disassembler::BuildCache(AddressTypeInfo &info, uint16_t cpuAddress, bo
int32_t absoluteAddr = info.Address; int32_t absoluteAddr = info.Address;
if(info.Address >= 0) { if(info.Address >= 0) {
shared_ptr<DisassemblyInfo> disInfo = (*cache)[info.Address]; DisassemblyInfo *disInfo = (*cache)[info.Address].get();
if(!disInfo) { if(!disInfo) {
while(absoluteAddr < (int32_t)size && !(*cache)[absoluteAddr]) { while(absoluteAddr < (int32_t)size && !(*cache)[absoluteAddr]) {
bool isJump = IsUnconditionalJump(source[absoluteAddr]); bool isJump = IsUnconditionalJump(source[absoluteAddr]);
disInfo = shared_ptr<DisassemblyInfo>(new DisassemblyInfo(source+absoluteAddr, isSubEntryPoint)); disInfo = new DisassemblyInfo(source+absoluteAddr, isSubEntryPoint);
isSubEntryPoint = false; isSubEntryPoint = false;
(*cache)[absoluteAddr] = disInfo; (*cache)[absoluteAddr] = shared_ptr<DisassemblyInfo>(disInfo);
absoluteAddr += disInfo->GetSize(); absoluteAddr += disInfo->GetSize();
if(isJump) { if(isJump) {
@ -604,14 +606,19 @@ string Disassembler::GetCode(AddressTypeInfo &addressInfo, uint32_t endAddr, uin
return output; return output;
} }
shared_ptr<DisassemblyInfo> Disassembler::GetDisassemblyInfo(AddressTypeInfo &info) DisassemblyInfo Disassembler::GetDisassemblyInfo(AddressTypeInfo &info)
{ {
DisassemblyInfo* disassemblyInfo = nullptr;
switch(info.Type) { switch(info.Type) {
case AddressType::InternalRam: return _disassembleMemoryCache[info.Address & 0x7FF]; case AddressType::InternalRam: disassemblyInfo = _disassembleMemoryCache[info.Address & 0x7FF].get(); break;
case AddressType::PrgRom: return _disassembleCache[info.Address]; case AddressType::PrgRom: disassemblyInfo = _disassembleCache[info.Address].get(); break;
case AddressType::WorkRam: return _disassembleWorkRamCache[info.Address]; case AddressType::WorkRam: disassemblyInfo = _disassembleWorkRamCache[info.Address].get(); break;
case AddressType::SaveRam: return _disassembleSaveRamCache[info.Address]; case AddressType::SaveRam: disassemblyInfo = _disassembleSaveRamCache[info.Address].get(); break;
} }
return nullptr; if(disassemblyInfo) {
return *disassemblyInfo;
} else {
return DisassemblyInfo();
}
} }

View File

@ -42,7 +42,7 @@ public:
string GetCode(AddressTypeInfo &addressInfo, uint32_t endAddr, uint16_t memoryAddr, bool showEffectiveAddresses, bool showOnlyDiassembledCode, State& cpuState, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager); string GetCode(AddressTypeInfo &addressInfo, uint32_t endAddr, uint16_t memoryAddr, bool showEffectiveAddresses, bool showOnlyDiassembledCode, State& cpuState, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
shared_ptr<DisassemblyInfo> GetDisassemblyInfo(AddressTypeInfo &info); DisassemblyInfo GetDisassemblyInfo(AddressTypeInfo &info);
void RebuildPrgRomCache(uint32_t absoluteAddr, int32_t length); void RebuildPrgRomCache(uint32_t absoluteAddr, int32_t length);
}; };

View File

@ -29,6 +29,10 @@ static const char* hexTable[256] = {
"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
}; };
DisassemblyInfo::DisassemblyInfo()
{
}
void DisassemblyInfo::ToString(string &out, uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager) void DisassemblyInfo::ToString(string &out, uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager)
{ {
char buffer[500]; char buffer[500];

View File

@ -21,6 +21,7 @@ private:
AddrMode _opMode; AddrMode _opMode;
public: public:
DisassemblyInfo();
DisassemblyInfo(uint8_t* opPointer, bool isSubEntryPoint); DisassemblyInfo(uint8_t* opPointer, bool isSubEntryPoint);
void SetSubEntryPoint(); void SetSubEntryPoint();

View File

@ -14,7 +14,7 @@ Language EmulationSettings::_displayLanguage = Language::English;
uint64_t EmulationSettings::_flags = 0; uint64_t EmulationSettings::_flags = 0;
bool EmulationSettings::_audioSettingsChanged = true; bool EmulationSettings::_audioSettingsChanged = true;
uint32_t EmulationSettings::_audioLatency = 20000; uint32_t EmulationSettings::_audioLatency = 50;
double EmulationSettings::_channelVolume[11] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; double EmulationSettings::_channelVolume[11] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
double EmulationSettings::_channelPanning[11] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; double EmulationSettings::_channelPanning[11] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
EqualizerFilterType EmulationSettings::_equalizerFilterType = EqualizerFilterType::None; EqualizerFilterType EmulationSettings::_equalizerFilterType = EqualizerFilterType::None;

View File

@ -20,7 +20,9 @@ TraceLogger::TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryMan
_labelManager = labelManager; _labelManager = labelManager;
_instance = this; _instance = this;
_currentPos = 0; _currentPos = 0;
_logCount = 0;
_logToFile = false; _logToFile = false;
_pendingLog = false;
} }
TraceLogger::~TraceLogger() TraceLogger::~TraceLogger()
@ -103,7 +105,7 @@ void TraceLogger::GetStatusFlag(string &output, uint8_t ps)
} }
} }
void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, shared_ptr<DisassemblyInfo> &disassemblyInfo, bool firstLine) void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, DisassemblyInfo &disassemblyInfo, bool firstLine)
{ {
if(!firstLine) { if(!firstLine) {
output += "\n"; output += "\n";
@ -113,7 +115,7 @@ void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &pp
if(_options.ShowByteCode) { if(_options.ShowByteCode) {
string byteCode; string byteCode;
disassemblyInfo->GetByteCode(byteCode); disassemblyInfo.GetByteCode(byteCode);
output += byteCode + std::string(13 - byteCode.size(), ' '); output += byteCode + std::string(13 - byteCode.size(), ' ');
} }
@ -125,8 +127,8 @@ void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &pp
string code; string code;
LabelManager* labelManager = _options.UseLabels ? _labelManager.get() : nullptr; LabelManager* labelManager = _options.UseLabels ? _labelManager.get() : nullptr;
disassemblyInfo->ToString(code, cpuState.DebugPC, _memoryManager.get(), labelManager); disassemblyInfo.ToString(code, cpuState.DebugPC, _memoryManager.get(), labelManager);
disassemblyInfo->GetEffectiveAddressString(code, cpuState, _memoryManager.get(), labelManager); disassemblyInfo.GetEffectiveAddressString(code, cpuState, _memoryManager.get(), labelManager);
code += std::string(std::max(0, (int)(32 - code.size())), ' '); code += std::string(std::max(0, (int)(32 - code.size())), ' ');
output += code; output += code;
@ -159,7 +161,7 @@ void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &pp
} }
} }
bool TraceLogger::ConditionMatches(DebugState &state, shared_ptr<DisassemblyInfo> &disassemblyInfo, OperationInfo &operationInfo) bool TraceLogger::ConditionMatches(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo)
{ {
if(!_conditionRpnList.empty()) { if(!_conditionRpnList.empty()) {
EvalResultType type; EvalResultType type;
@ -168,6 +170,7 @@ bool TraceLogger::ConditionMatches(DebugState &state, shared_ptr<DisassemblyInfo
//Condition did not match, keep state/disassembly info for instruction's subsequent cycles //Condition did not match, keep state/disassembly info for instruction's subsequent cycles
_lastState = state; _lastState = state;
_lastDisassemblyInfo = disassemblyInfo; _lastDisassemblyInfo = disassemblyInfo;
_pendingLog = true;
} }
return false; return false;
} }
@ -175,13 +178,17 @@ bool TraceLogger::ConditionMatches(DebugState &state, shared_ptr<DisassemblyInfo
return true; return true;
} }
void TraceLogger::AddRow(shared_ptr<DisassemblyInfo> &disassemblyInfo, DebugState &state) void TraceLogger::AddRow(DisassemblyInfo &disassemblyInfo, DebugState &state)
{ {
_disassemblyCache[_currentPos] = disassemblyInfo; _disassemblyCache[_currentPos] = disassemblyInfo;
_cpuStateCache[_currentPos] = state.CPU; _cpuStateCache[_currentPos] = state.CPU;
_ppuStateCache[_currentPos] = state.PPU; _ppuStateCache[_currentPos] = state.PPU;
_currentPos = (_currentPos + 1) % ExecutionLogSize; _currentPos = (_currentPos + 1) % ExecutionLogSize;
_lastDisassemblyInfo.reset(); _pendingLog = false;
if(_logCount < ExecutionLogSize) {
_logCount++;
}
if(_logToFile) { if(_logToFile) {
GetTraceRow(_outputBuffer, state.CPU, state.PPU, disassemblyInfo, _firstLine); GetTraceRow(_outputBuffer, state.CPU, state.PPU, disassemblyInfo, _firstLine);
@ -196,7 +203,7 @@ void TraceLogger::AddRow(shared_ptr<DisassemblyInfo> &disassemblyInfo, DebugStat
void TraceLogger::LogNonExec(OperationInfo& operationInfo) void TraceLogger::LogNonExec(OperationInfo& operationInfo)
{ {
if(_lastDisassemblyInfo) { if(_pendingLog) {
auto lock = _lock.AcquireSafe(); auto lock = _lock.AcquireSafe();
if(ConditionMatches(_lastState, _lastDisassemblyInfo, operationInfo)) { if(ConditionMatches(_lastState, _lastDisassemblyInfo, operationInfo)) {
AddRow(_lastDisassemblyInfo, _lastState); AddRow(_lastDisassemblyInfo, _lastState);
@ -204,13 +211,11 @@ void TraceLogger::LogNonExec(OperationInfo& operationInfo)
} }
} }
void TraceLogger::Log(DebugState &state, shared_ptr<DisassemblyInfo> disassemblyInfo, OperationInfo &operationInfo) void TraceLogger::Log(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo)
{ {
if(disassemblyInfo) { auto lock = _lock.AcquireSafe();
auto lock = _lock.AcquireSafe(); if(ConditionMatches(state, disassemblyInfo, operationInfo)) {
if(ConditionMatches(state, disassemblyInfo, operationInfo)) { AddRow(disassemblyInfo, state);
AddRow(disassemblyInfo, state);
}
} }
} }
@ -218,14 +223,13 @@ const char* TraceLogger::GetExecutionTrace(uint32_t lineCount)
{ {
_executionTrace.clear(); _executionTrace.clear();
auto lock = _lock.AcquireSafe(); auto lock = _lock.AcquireSafe();
lineCount = std::min(lineCount, _logCount);
int startPos = _currentPos + ExecutionLogSize - lineCount; int startPos = _currentPos + ExecutionLogSize - lineCount;
bool firstLine = true; bool firstLine = true;
for(int i = 0; i < (int)lineCount; i++) { for(int i = 0; i < (int)lineCount; i++) {
int index = (startPos + i) % ExecutionLogSize; int index = (startPos + i) % ExecutionLogSize;
if(_disassemblyCache[index]) { GetTraceRow(_executionTrace, _cpuStateCache[index], _ppuStateCache[index], _disassemblyCache[index], firstLine);
GetTraceRow(_executionTrace, _cpuStateCache[index], _ppuStateCache[index], _disassemblyCache[index], firstLine); firstLine = false;
firstLine = false;
}
} }
return _executionTrace.c_str(); return _executionTrace.c_str();
} }

View File

@ -2,8 +2,8 @@
#include "stdafx.h" #include "stdafx.h"
#include "DebuggerTypes.h" #include "DebuggerTypes.h"
#include "../Utilities/SimpleLock.h" #include "../Utilities/SimpleLock.h"
#include "DisassemblyInfo.h"
class DisassemblyInfo;
class MemoryManager; class MemoryManager;
class LabelManager; class LabelManager;
class ExpressionEvaluator; class ExpressionEvaluator;
@ -47,35 +47,39 @@ private:
shared_ptr<ExpressionEvaluator> _expEvaluator; shared_ptr<ExpressionEvaluator> _expEvaluator;
vector<int> _conditionRpnList; vector<int> _conditionRpnList;
bool _pendingLog;
DebugState _lastState; DebugState _lastState;
shared_ptr<DisassemblyInfo> _lastDisassemblyInfo; DisassemblyInfo _lastDisassemblyInfo;
constexpr static int ExecutionLogSize = 30000; constexpr static int ExecutionLogSize = 30000;
bool _logToFile; bool _logToFile;
uint16_t _currentPos; uint16_t _currentPos;
uint32_t _logCount;
State _cpuStateCache[ExecutionLogSize] = {}; State _cpuStateCache[ExecutionLogSize] = {};
PPUDebugState _ppuStateCache[ExecutionLogSize] = {}; PPUDebugState _ppuStateCache[ExecutionLogSize] = {};
shared_ptr<DisassemblyInfo> _disassemblyCache[ExecutionLogSize] = {}; DisassemblyInfo _disassemblyCache[ExecutionLogSize];
SimpleLock _lock; SimpleLock _lock;
string _executionTrace; string _executionTrace;
void GetStatusFlag(string &output, uint8_t ps); void GetStatusFlag(string &output, uint8_t ps);
void AddRow(shared_ptr<DisassemblyInfo> &disassemblyInfo, DebugState &state); void AddRow(DisassemblyInfo &disassemblyInfo, DebugState &state);
bool ConditionMatches(DebugState &state, shared_ptr<DisassemblyInfo> &disassemblyInfo, OperationInfo &operationInfo); bool ConditionMatches(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo);
void GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, DisassemblyInfo &disassemblyInfo, bool firstLine);
public: public:
TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager); TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
~TraceLogger(); ~TraceLogger();
void Log(DebugState &state, shared_ptr<DisassemblyInfo> disassemblyInfo, OperationInfo &operationInfo); void Log(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo);
void LogNonExec(OperationInfo& operationInfo); void LogNonExec(OperationInfo& operationInfo);
void SetOptions(TraceLoggerOptions options); void SetOptions(TraceLoggerOptions options);
void StartLogging(string filename); void StartLogging(string filename);
void StopLogging(); void StopLogging();
void GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, shared_ptr<DisassemblyInfo> &disassemblyInfo, bool firstLine);
const char* GetExecutionTrace(uint32_t lineCount); const char* GetExecutionTrace(uint32_t lineCount);
static void LogStatic(string log); static void LogStatic(string log);