bsnes-plus/bsnes/snes/chip/supergameboy/debugger/disassembler.cpp

127 lines
3.3 KiB
C++

#ifdef SUPERGAMEBOY_CPP
uint16 SGBDebugger::relb(int8 offset, int op_len, uint16 pc) {
return pc + op_len + offset;
}
uint8 SGBDebugger::dreadb(uint16 addr) {
SNES::debugger.bus_access = true;
return supergameboy.read_gb(addr);
SNES::debugger.bus_access = false;
}
uint16 SGBDebugger::dreadw(uint16 addr) {
uint16 r;
r = dreadb(addr + 0) << 0;
r |= dreadb(addr + 1) << 8;
return r;
}
uint24 SGBDebugger::decode(uint8 offset_type, uint16 addr, uint16 pc) {
uint24 r = 0;
uint16 dp = 0xff00;
switch(offset_type) {
case GBCPU::Addr8Ptr:
r = dp | (uint8)addr;
break;
case GBCPU::Addr16:
case GBCPU::Addr16Ptr:
r = addr;
break;
case GBCPU::RegBCPtr:
r = getRegister(RegisterBC);
break;
case GBCPU::RegCPtr:
r = dp | (uint8)getRegister(RegisterBC);
break;
case GBCPU::RegDEPtr:
r = getRegister(RegisterDE);
break;
case GBCPU::RegHLPtr:
case GBCPU::RegHLPtrInc:
case GBCPU::RegHLPtrDec:
case GBCPU::PrefixCB:
r = getRegister(RegisterHL);
break;
case GBCPU::PCRelative:
r = relb((int8)addr, 2, pc);
break;
case GBCPU::SPRelative:
r = relb((int8)addr, 2, getRegister(RegisterSP));
break;
case GBCPU::RST:
r = dreadb(pc) & 0x38;
break;
}
if (r > 0x4000 && sgb_addr_with_bank) {
r = sgb_addr_with_bank(r);
}
return r;
}
void SGBDebugger::disassemble_opcode_ex(SGBDebugger::Opcode &opcode, uint24 addr) {
uint8 param[3];
SNES::debugger.bus_access = true;
param[0] = read_gb(addr + 0);
param[1] = read_gb(addr + 1);
param[2] = read_gb(addr + 2);
SNES::debugger.bus_access = false;
const GBCPU::OpcodeInfo& op = gbOpcodeInfo[param[0]];
opcode.set(0, op.mode0, op.mode1, op.name, param, GBCPU::getOpcodeLength(param[0]) - 1);
switch (param[0]) {
case 0x18: case 0xc3: case 0xe9:
opcode.flags |= Opcode::FLAG_BRA; break;
case 0x20: case 0x28: case 0x30: case 0x38:
case 0xc2: case 0xca: case 0xd2: case 0xda:
opcode.flags |= Opcode::FLAG_BRA_CONTINUE; break;
case 0xc4: case 0xc7: case 0xcc: case 0xcd:
case 0xcf: case 0xd4: case 0xd7: case 0xdc:
case 0xdf: case 0xe7: case 0xef: case 0xf7:
case 0xff:
opcode.flags |= Opcode::FLAG_CALL; break;
case 0xc9: case 0xd9:
opcode.flags |= Opcode::FLAG_RETURN; break;
case 0xf1:
opcode.flags |= Opcode::FLAG_POP_F; break;
case 0xf5:
opcode.flags |= Opcode::FLAG_PUSH_F; break;
}
if (GBCPU::getOpcodeIndirect(param[0], param[1])) {
opcode.flags |= Opcode::FLAG_INDIRECT;
}
}
void SGBDebugger::disassemble_opcode(char *output, uint24 addr) {
char t[256];
char *s = output;
sprintf(s, "%.6x ", addr);
uint8 op = read_gb(addr);
uint8 op0 = read_gb(addr + 1);
uint8 op1 = read_gb(addr + 2);
sprintf(t, "%-23s ", nall::GBCPU::disassemble((uint16)addr, op, op0, op1)());
strcat(s, t);
uint16_t af = getRegister(RegisterAF);
uint16_t bc = getRegister(RegisterBC);
uint16_t de = getRegister(RegisterDE);
uint16_t hl = getRegister(RegisterHL);
uint16_t sp = getRegister(RegisterSP);
sprintf(t, "AF:%.4x BC:%.4x DE:%.4x HL:%.4x SP:%.4x ", af, bc, de, hl, sp);
strcat(s, t);
sprintf(t, "%c%c%c%c ",
(af & 0x80) ? 'Z' : '.', (af & 0x40) ? 'N' : '.',
(af & 0x20) ? 'H' : '.', (af & 0x10) ? 'C' : '.');
strcat(s, t);
}
#endif