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)
{
ProcessVramAccess(addr);
Debugger::ProcessVramOperation(MemoryOperationType::Write, addr, value);
Debugger::ProcessVramWriteOperation(addr, value);
NotifyVRAMAddressChange(addr);
if(_chrPageAccessType[addr >> 8] & MemoryAccessType::Write) {

View File

@ -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;
}

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
};
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));

View File

@ -22,7 +22,7 @@ namespace PSFlags
};
}
enum AddrMode
enum class AddrMode
{
None, Acc, Imp, Imm, Rel,
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);
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;

View File

@ -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);
}
}

View File

@ -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);

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
};
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();
}
}

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);
shared_ptr<DisassemblyInfo> GetDisassemblyInfo(AddressTypeInfo &info);
DisassemblyInfo GetDisassemblyInfo(AddressTypeInfo &info);
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"
};
DisassemblyInfo::DisassemblyInfo()
{
}
void DisassemblyInfo::ToString(string &out, uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager)
{
char buffer[500];

View File

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

View File

@ -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;

View File

@ -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();
}

View File

@ -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);