mirror of
https://github.com/libretro/Mesen.git
synced 2024-11-23 17:19:39 +00:00
Debugger: General speed optimizations
This commit is contained in:
parent
ce3e4d7c80
commit
4e14a83625
@ -800,7 +800,7 @@ void BaseMapper::InternalWriteVRAM(uint16_t addr, uint8_t value)
|
||||
void BaseMapper::WriteVRAM(uint16_t addr, uint8_t value)
|
||||
{
|
||||
ProcessVramAccess(addr);
|
||||
Debugger::ProcessVramOperation(MemoryOperationType::Write, addr, value);
|
||||
Debugger::ProcessVramWriteOperation(addr, value);
|
||||
NotifyVRAMAddressChange(addr);
|
||||
|
||||
if(_chrPageAccessType[addr >> 8] & MemoryAccessType::Write) {
|
||||
|
@ -179,7 +179,7 @@ public:
|
||||
NotifyVRAMAddressChange(addr);
|
||||
|
||||
uint8_t value = MapperReadVRAM(addr, type);
|
||||
Debugger::ProcessVramOperation(type, addr, value);
|
||||
Debugger::ProcessVramReadOperation(type, addr, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
35
Core/CPU.cpp
35
Core/CPU.cpp
@ -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
|
||||
};
|
||||
|
||||
typedef AddrMode M;
|
||||
AddrMode addrMode[] = {
|
||||
// 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
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //1
|
||||
Abs, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //2
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //3
|
||||
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //4
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //5
|
||||
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //6
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //7
|
||||
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //8
|
||||
Rel, IndYW, None, IndYW, ZeroX, ZeroX, ZeroY, ZeroY, Imp, AbsYW, Imp, AbsYW, AbsXW, AbsXW, AbsYW, AbsYW, //9
|
||||
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //A
|
||||
Rel, IndY, None, IndY, ZeroX, ZeroX, ZeroY, ZeroY, Imp, AbsY, Imp, AbsY, AbsX, AbsX, AbsY, AbsY, //B
|
||||
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //C
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //D
|
||||
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs, //E
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW, //F
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
};
|
||||
|
||||
memcpy(_opTable, opTable, sizeof(opTable));
|
||||
|
@ -22,7 +22,7 @@ namespace PSFlags
|
||||
};
|
||||
}
|
||||
|
||||
enum AddrMode
|
||||
enum class AddrMode
|
||||
{
|
||||
None, Acc, Imp, Imm, Rel,
|
||||
Zero, Abs, ZeroX, ZeroY,
|
||||
|
@ -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);
|
||||
}
|
@ -18,7 +18,7 @@ public:
|
||||
CodeRunner(vector<uint8_t> byteCode, Debugger *debugger);
|
||||
|
||||
bool IsRunning();
|
||||
shared_ptr<DisassemblyInfo> GetDisassemblyInfo(uint16_t cpuAddress);
|
||||
DisassemblyInfo GetDisassemblyInfo(uint16_t cpuAddress);
|
||||
|
||||
void GetMemoryRanges(MemoryRanges &ranges) override;
|
||||
uint8_t ReadRAM(uint16_t addr) override;
|
||||
|
@ -213,28 +213,26 @@ void Debugger::SetBreakpoints(Breakpoint breakpoints[], uint32_t length)
|
||||
|
||||
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++) {
|
||||
_breakpoints[i].clear();
|
||||
_breakpointRpnList[i].clear();
|
||||
_hasBreakpoint[i] = false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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)
|
||||
@ -244,7 +242,9 @@ bool Debugger::HasMatchingBreakpoint(BreakpointType type, OperationInfo &operati
|
||||
return false;
|
||||
}
|
||||
|
||||
UpdateBreakpoints();
|
||||
if(_bpUpdateNeeded) {
|
||||
UpdateBreakpoints();
|
||||
}
|
||||
|
||||
uint32_t absoluteAddr = _mapper->ToAbsoluteAddress(operationInfo.Address);
|
||||
vector<Breakpoint> &breakpoints = _breakpoints[(int)type];
|
||||
@ -488,7 +488,7 @@ bool Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &ad
|
||||
|
||||
GetState(&_debugState, false);
|
||||
|
||||
shared_ptr<DisassemblyInfo> disassemblyInfo;
|
||||
DisassemblyInfo disassemblyInfo;
|
||||
if(_codeRunner && _codeRunner->IsRunning() && addr >= 0x3000 && addr < 0x4000) {
|
||||
disassemblyInfo = _codeRunner->GetDisassemblyInfo(addr);
|
||||
} else {
|
||||
@ -560,19 +560,30 @@ bool Debugger::SleepUntilResume()
|
||||
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);
|
||||
_codeDataLogger->SetFlag(absoluteAddr, type == MemoryOperationType::Read ? CdlChrFlags::Read : CdlChrFlags::Drawn);
|
||||
}
|
||||
int32_t absoluteAddr = _mapper->ToAbsoluteChrAddress(addr);
|
||||
_codeDataLogger->SetFlag(absoluteAddr, type == MemoryOperationType::Read ? CdlChrFlags::Read : CdlChrFlags::Drawn);
|
||||
|
||||
BreakpointType bpType = type == MemoryOperationType::Write ? BreakpointType::WriteVram : BreakpointType::ReadVram;
|
||||
OperationInfo operationInfo { addr, value, type };
|
||||
if(_hasBreakpoint[bpType] && HasMatchingBreakpoint(bpType, operationInfo)) {
|
||||
//Found a matching breakpoint, stop execution
|
||||
Step(1);
|
||||
SleepUntilResume();
|
||||
if(_hasBreakpoint[BreakpointType::ReadVram]) {
|
||||
OperationInfo operationInfo{ addr, value, type };
|
||||
if(HasMatchingBreakpoint(BreakpointType::ReadVram, operationInfo)) {
|
||||
//Found a matching breakpoint, stop execution
|
||||
Step(1);
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,8 @@ private:
|
||||
|
||||
void PrivateProcessPpuCycle();
|
||||
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);
|
||||
|
||||
void UpdateCallstack(uint32_t addr);
|
||||
@ -176,7 +177,8 @@ public:
|
||||
int32_t EvaluateExpression(string expression, EvalResultType &resultType);
|
||||
|
||||
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 SetLastFramePpuScroll(uint16_t x, uint16_t y);
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
AddrMode opMode[256] = {
|
||||
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Acc, Imm, Abs, Abs, Abs, Abs,
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW,
|
||||
Abs, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Acc, Imm, Abs, Abs, Abs, Abs,
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW,
|
||||
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Acc, Imm, Abs, Abs, Abs, Abs,
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW,
|
||||
Imp, IndX, None, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Acc, Imm, Ind, Abs, Abs, Abs,
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW,
|
||||
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs,
|
||||
Rel, IndYW, None, IndY, ZeroX, ZeroX, ZeroY, ZeroY, Imp, AbsYW, Imp, AbsY, AbsXW, AbsXW, AbsYW, AbsY,
|
||||
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs,
|
||||
Rel, IndY, None, IndY, ZeroX, ZeroX, ZeroY, ZeroY, Imp, AbsY, Imp, AbsY, AbsX, AbsX, AbsY, AbsY,
|
||||
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs,
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW,
|
||||
Imm, IndX, Imm, IndX, Zero, Zero, Zero, Zero, Imp, Imm, Imp, Imm, Abs, Abs, Abs, Abs,
|
||||
Rel, IndY, None, IndYW, ZeroX, ZeroX, ZeroX, ZeroX, Imp, AbsY, Imp, AbsYW, AbsX, AbsX, AbsXW, AbsXW,
|
||||
typedef AddrMode M;
|
||||
AddrMode opMode[] = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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++) {
|
||||
@ -201,14 +203,14 @@ uint32_t Disassembler::BuildCache(AddressTypeInfo &info, uint16_t cpuAddress, bo
|
||||
int32_t absoluteAddr = info.Address;
|
||||
|
||||
if(info.Address >= 0) {
|
||||
shared_ptr<DisassemblyInfo> disInfo = (*cache)[info.Address];
|
||||
DisassemblyInfo *disInfo = (*cache)[info.Address].get();
|
||||
if(!disInfo) {
|
||||
while(absoluteAddr < (int32_t)size && !(*cache)[absoluteAddr]) {
|
||||
bool isJump = IsUnconditionalJump(source[absoluteAddr]);
|
||||
disInfo = shared_ptr<DisassemblyInfo>(new DisassemblyInfo(source+absoluteAddr, isSubEntryPoint));
|
||||
disInfo = new DisassemblyInfo(source+absoluteAddr, isSubEntryPoint);
|
||||
isSubEntryPoint = false;
|
||||
|
||||
(*cache)[absoluteAddr] = disInfo;
|
||||
(*cache)[absoluteAddr] = shared_ptr<DisassemblyInfo>(disInfo);
|
||||
|
||||
absoluteAddr += disInfo->GetSize();
|
||||
if(isJump) {
|
||||
@ -604,14 +606,19 @@ string Disassembler::GetCode(AddressTypeInfo &addressInfo, uint32_t endAddr, uin
|
||||
return output;
|
||||
}
|
||||
|
||||
shared_ptr<DisassemblyInfo> Disassembler::GetDisassemblyInfo(AddressTypeInfo &info)
|
||||
DisassemblyInfo Disassembler::GetDisassemblyInfo(AddressTypeInfo &info)
|
||||
{
|
||||
DisassemblyInfo* disassemblyInfo = nullptr;
|
||||
switch(info.Type) {
|
||||
case AddressType::InternalRam: return _disassembleMemoryCache[info.Address & 0x7FF];
|
||||
case AddressType::PrgRom: return _disassembleCache[info.Address];
|
||||
case AddressType::WorkRam: return _disassembleWorkRamCache[info.Address];
|
||||
case AddressType::SaveRam: return _disassembleSaveRamCache[info.Address];
|
||||
case AddressType::InternalRam: disassemblyInfo = _disassembleMemoryCache[info.Address & 0x7FF].get(); break;
|
||||
case AddressType::PrgRom: disassemblyInfo = _disassembleCache[info.Address].get(); break;
|
||||
case AddressType::WorkRam: disassemblyInfo = _disassembleWorkRamCache[info.Address].get(); break;
|
||||
case AddressType::SaveRam: disassemblyInfo = _disassembleSaveRamCache[info.Address].get(); break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
if(disassemblyInfo) {
|
||||
return *disassemblyInfo;
|
||||
} else {
|
||||
return DisassemblyInfo();
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
shared_ptr<DisassemblyInfo> GetDisassemblyInfo(AddressTypeInfo &info);
|
||||
DisassemblyInfo GetDisassemblyInfo(AddressTypeInfo &info);
|
||||
|
||||
void RebuildPrgRomCache(uint32_t absoluteAddr, int32_t length);
|
||||
};
|
||||
|
@ -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"
|
||||
};
|
||||
|
||||
DisassemblyInfo::DisassemblyInfo()
|
||||
{
|
||||
}
|
||||
|
||||
void DisassemblyInfo::ToString(string &out, uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager)
|
||||
{
|
||||
char buffer[500];
|
||||
|
@ -21,6 +21,7 @@ private:
|
||||
AddrMode _opMode;
|
||||
|
||||
public:
|
||||
DisassemblyInfo();
|
||||
DisassemblyInfo(uint8_t* opPointer, bool isSubEntryPoint);
|
||||
|
||||
void SetSubEntryPoint();
|
||||
|
@ -14,7 +14,7 @@ Language EmulationSettings::_displayLanguage = Language::English;
|
||||
uint64_t EmulationSettings::_flags = 0;
|
||||
|
||||
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::_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;
|
||||
|
@ -20,7 +20,9 @@ TraceLogger::TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryMan
|
||||
_labelManager = labelManager;
|
||||
_instance = this;
|
||||
_currentPos = 0;
|
||||
_logCount = 0;
|
||||
_logToFile = false;
|
||||
_pendingLog = false;
|
||||
}
|
||||
|
||||
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) {
|
||||
output += "\n";
|
||||
@ -113,7 +115,7 @@ void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &pp
|
||||
|
||||
if(_options.ShowByteCode) {
|
||||
string byteCode;
|
||||
disassemblyInfo->GetByteCode(byteCode);
|
||||
disassemblyInfo.GetByteCode(byteCode);
|
||||
output += byteCode + std::string(13 - byteCode.size(), ' ');
|
||||
}
|
||||
|
||||
@ -125,8 +127,8 @@ void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &pp
|
||||
|
||||
string code;
|
||||
LabelManager* labelManager = _options.UseLabels ? _labelManager.get() : nullptr;
|
||||
disassemblyInfo->ToString(code, cpuState.DebugPC, _memoryManager.get(), labelManager);
|
||||
disassemblyInfo->GetEffectiveAddressString(code, cpuState, _memoryManager.get(), labelManager);
|
||||
disassemblyInfo.ToString(code, cpuState.DebugPC, _memoryManager.get(), labelManager);
|
||||
disassemblyInfo.GetEffectiveAddressString(code, cpuState, _memoryManager.get(), labelManager);
|
||||
code += std::string(std::max(0, (int)(32 - code.size())), ' ');
|
||||
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()) {
|
||||
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
|
||||
_lastState = state;
|
||||
_lastDisassemblyInfo = disassemblyInfo;
|
||||
_pendingLog = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -175,13 +178,17 @@ bool TraceLogger::ConditionMatches(DebugState &state, shared_ptr<DisassemblyInfo
|
||||
return true;
|
||||
}
|
||||
|
||||
void TraceLogger::AddRow(shared_ptr<DisassemblyInfo> &disassemblyInfo, DebugState &state)
|
||||
void TraceLogger::AddRow(DisassemblyInfo &disassemblyInfo, DebugState &state)
|
||||
{
|
||||
_disassemblyCache[_currentPos] = disassemblyInfo;
|
||||
_cpuStateCache[_currentPos] = state.CPU;
|
||||
_ppuStateCache[_currentPos] = state.PPU;
|
||||
_currentPos = (_currentPos + 1) % ExecutionLogSize;
|
||||
_lastDisassemblyInfo.reset();
|
||||
_pendingLog = false;
|
||||
|
||||
if(_logCount < ExecutionLogSize) {
|
||||
_logCount++;
|
||||
}
|
||||
|
||||
if(_logToFile) {
|
||||
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)
|
||||
{
|
||||
if(_lastDisassemblyInfo) {
|
||||
if(_pendingLog) {
|
||||
auto lock = _lock.AcquireSafe();
|
||||
if(ConditionMatches(_lastState, _lastDisassemblyInfo, operationInfo)) {
|
||||
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();
|
||||
if(ConditionMatches(state, disassemblyInfo, operationInfo)) {
|
||||
AddRow(disassemblyInfo, state);
|
||||
}
|
||||
auto lock = _lock.AcquireSafe();
|
||||
if(ConditionMatches(state, disassemblyInfo, operationInfo)) {
|
||||
AddRow(disassemblyInfo, state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,14 +223,13 @@ const char* TraceLogger::GetExecutionTrace(uint32_t lineCount)
|
||||
{
|
||||
_executionTrace.clear();
|
||||
auto lock = _lock.AcquireSafe();
|
||||
lineCount = std::min(lineCount, _logCount);
|
||||
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;
|
||||
}
|
||||
GetTraceRow(_executionTrace, _cpuStateCache[index], _ppuStateCache[index], _disassemblyCache[index], firstLine);
|
||||
firstLine = false;
|
||||
}
|
||||
return _executionTrace.c_str();
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "DebuggerTypes.h"
|
||||
#include "../Utilities/SimpleLock.h"
|
||||
#include "DisassemblyInfo.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class MemoryManager;
|
||||
class LabelManager;
|
||||
class ExpressionEvaluator;
|
||||
@ -47,35 +47,39 @@ private:
|
||||
|
||||
shared_ptr<ExpressionEvaluator> _expEvaluator;
|
||||
vector<int> _conditionRpnList;
|
||||
|
||||
bool _pendingLog;
|
||||
DebugState _lastState;
|
||||
shared_ptr<DisassemblyInfo> _lastDisassemblyInfo;
|
||||
DisassemblyInfo _lastDisassemblyInfo;
|
||||
|
||||
constexpr static int ExecutionLogSize = 30000;
|
||||
bool _logToFile;
|
||||
uint16_t _currentPos;
|
||||
uint32_t _logCount;
|
||||
State _cpuStateCache[ExecutionLogSize] = {};
|
||||
PPUDebugState _ppuStateCache[ExecutionLogSize] = {};
|
||||
shared_ptr<DisassemblyInfo> _disassemblyCache[ExecutionLogSize] = {};
|
||||
DisassemblyInfo _disassemblyCache[ExecutionLogSize];
|
||||
|
||||
SimpleLock _lock;
|
||||
string _executionTrace;
|
||||
|
||||
void GetStatusFlag(string &output, uint8_t ps);
|
||||
void AddRow(shared_ptr<DisassemblyInfo> &disassemblyInfo, DebugState &state);
|
||||
bool ConditionMatches(DebugState &state, shared_ptr<DisassemblyInfo> &disassemblyInfo, OperationInfo &operationInfo);
|
||||
void AddRow(DisassemblyInfo &disassemblyInfo, DebugState &state);
|
||||
bool ConditionMatches(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo);
|
||||
|
||||
void GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, DisassemblyInfo &disassemblyInfo, bool firstLine);
|
||||
|
||||
public:
|
||||
TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
|
||||
~TraceLogger();
|
||||
|
||||
|
||||
void Log(DebugState &state, shared_ptr<DisassemblyInfo> disassemblyInfo, OperationInfo &operationInfo);
|
||||
void Log(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo);
|
||||
void LogNonExec(OperationInfo& operationInfo);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user