bsnes-plus/bsnes/ui-qt/debugger/tracer.cpp
2020-02-27 18:43:15 -05:00

148 lines
4.1 KiB
C++

#include "tracer.moc"
Tracer *tracer;
void Tracer::stepCpu() {
if(traceCpu) {
unsigned addr = SNES::cpu.regs.pc;
if(!traceMask || !(traceMaskCPU[addr >> 3] & (0x80 >> (addr & 7)))) {
char text[256];
SNES::cpu.disassemble_opcode(text, addr, config().debugger.showHClocks);
tracefile.print(string() << text << "\n");
}
traceMaskCPU[addr >> 3] |= 0x80 >> (addr & 7);
}
}
void Tracer::stepSmp() {
if(traceSmp) {
unsigned addr = SNES::smp.regs.pc;
if(!traceMask || !(traceMaskSMP[addr >> 3] & (0x80 >> (addr & 7)))) {
char text[256];
SNES::smp.disassemble_opcode(text, addr);
tracefile.print(string() << text << "\n");
}
traceMaskSMP[addr >> 3] |= 0x80 >> (addr & 7);
}
}
void Tracer::stepSa1() {
if(traceSa1) {
unsigned addr = SNES::sa1.regs.pc;
if(!traceMask || !(traceMaskSA1[addr >> 3] & (0x80 >> (addr & 7)))) {
char text[256];
SNES::sa1.disassemble_opcode(text, addr, config().debugger.showHClocks);
tracefile.print(string() << text << "\n");
}
traceMaskSA1[addr >> 3] |= 0x80 >> (addr & 7);
}
}
void Tracer::stepSfx() {
if(traceSfx) {
unsigned addr = SNES::superfx.opcode_pc;
if(!traceMask || !(traceMaskSFX[addr >> 3] & (0x80 >> (addr & 7)))) {
char text[256];
SNES::superfx.disassemble_opcode(text, addr);
tracefile.print(string() << text << "\n");
}
traceMaskSFX[addr >> 3] |= 0x80 >> (addr & 7);
}
}
void Tracer::stepSgb() {
if(traceSgb) {
unsigned addr = SNES::supergameboy.opcode_pc;
if(!traceMask || !(traceMaskSGB[addr >> 3] & (0x80 >> (addr & 7)))) {
char text[256];
SNES::supergameboy.disassemble_opcode(text, addr);
tracefile.print(string() << text << "\n");
}
traceMaskSGB[addr >> 3] |= 0x80 >> (addr & 7);
}
}
void Tracer::resetTraceState() {
tracefile.close();
setTraceState(traceCpu || traceSmp || traceSa1 || traceSfx || traceSgb);
// reset trace masks
if (traceMask)
setTraceMaskState(true);
}
void Tracer::setTraceState(bool state) {
if(state && !tracefile.open() && SNES::cartridge.loaded()) {
string name = filepath(nall::basename(cartridge.fileName), config().path.data);
name << "-trace.log";
tracefile.open(name, file::mode::write);
} else if(!traceCpu && !traceSmp && !traceSa1 && !traceSfx && !traceSgb && tracefile.open()) {
tracefile.close();
}
}
void Tracer::setCpuTraceState(int state) {
traceCpu = (state == Qt::Checked);
setTraceState(traceCpu);
}
void Tracer::setSmpTraceState(int state) {
traceSmp = (state == Qt::Checked);
setTraceState(traceSmp);
}
void Tracer::setSa1TraceState(int state) {
traceSa1 = (state == Qt::Checked);
setTraceState(traceSa1);
}
void Tracer::setSfxTraceState(int state) {
traceSfx = (state == Qt::Checked);
setTraceState(traceSfx);
}
void Tracer::setSgbTraceState(int state) {
traceSgb = (state == Qt::Checked);
setTraceState(traceSgb);
}
void Tracer::setTraceMaskState(bool state) {
traceMask = state;
if(traceMask) {
//flush all bitmasks once enabled
memset(traceMaskCPU, 0x00, (1 << 24) >> 3);
memset(traceMaskSMP, 0x00, (1 << 16) >> 3);
memset(traceMaskSA1, 0x00, (1 << 24) >> 3);
memset(traceMaskSFX, 0x00, (1 << 23) >> 3);
memset(traceMaskSGB, 0x00, (1 << 24) >> 3);
}
}
Tracer::Tracer() {
traceCpu = false;
traceSmp = false;
traceSa1 = false;
traceSfx = false;
traceSgb = false;
traceMask = false;
traceMaskCPU = new uint8_t[(1 << 24) >> 3]();
traceMaskSMP = new uint8_t[(1 << 16) >> 3]();
traceMaskSA1 = new uint8_t[(1 << 24) >> 3]();
traceMaskSFX = new uint8_t[(1 << 23) >> 3]();
traceMaskSGB = new uint8_t[(1 << 24) >> 3]();
SNES::cpu.step_event = { &Tracer::stepCpu, this };
SNES::smp.step_event = { &Tracer::stepSmp, this };
SNES::sa1.step_event = { &Tracer::stepSa1, this };
SNES::superfx.step_event = { &Tracer::stepSfx, this };
SNES::supergameboy.step_event = { &Tracer::stepSgb, this };
}
Tracer::~Tracer() {
delete[] traceMaskCPU;
delete[] traceMaskSMP;
delete[] traceMaskSA1;
delete[] traceMaskSFX;
delete[] traceMaskSGB;
if(tracefile.open()) tracefile.close();
}