mirror of
https://github.com/devinacker/bsnes-plus.git
synced 2024-06-11 00:37:46 -04:00
disasm: treat calls and branches differently for state tracking purposes
This commit is contained in:
parent
a632b50acc
commit
c593fd0b96
|
@ -77,11 +77,13 @@ void SGBDebugger::disassemble_opcode_ex(SGBDebugger::Opcode &opcode, uint24 addr
|
|||
case 0x18: case 0xc3: case 0xe9:
|
||||
opcode.flags |= Opcode::FLAG_BRA; break;
|
||||
case 0x20: case 0x28: case 0x30: case 0x38:
|
||||
case 0xc2: 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:
|
||||
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:
|
||||
|
|
|
@ -5,7 +5,8 @@ struct Opcode {
|
|||
FLAG_INDIRECT = 0x04, // indirect memory accesses
|
||||
FLAG_PUSH_F = 0x10, // pushes flags
|
||||
FLAG_POP_F = 0x20, // pops flags
|
||||
FLAG_RETURN = 0x40, // returns from call (unconditionally)
|
||||
FLAG_CALL = 0x40, // performs call
|
||||
FLAG_RETURN = 0x80, // returns from call (unconditionally)
|
||||
};
|
||||
|
||||
void set(uint16 flags, uint8 optype1, uint8 optype2, const char *opcode, uint8 (¶m)[3], uint8 paramsize=0) {
|
||||
|
@ -29,6 +30,7 @@ struct Opcode {
|
|||
inline bool isIndirect() const { return flags & FLAG_INDIRECT; }
|
||||
inline bool pushesF() const { return flags & FLAG_PUSH_F; }
|
||||
inline bool popsF() const { return flags & FLAG_POP_F; }
|
||||
inline bool isCall() const { return flags & FLAG_CALL; }
|
||||
inline bool returns() const { return flags & FLAG_RETURN; }
|
||||
|
||||
uint8 op() {
|
||||
|
|
|
@ -124,10 +124,12 @@ void CPUcore::disassemble_opcode_ex(CPUcore::Opcode &opcode, uint32 addr, bool e
|
|||
opcode.flags |= Opcode::FLAG_BRK; break;
|
||||
case 0x08:
|
||||
opcode.flags |= Opcode::FLAG_PUSH_P; break;
|
||||
case 0x10: case 0x20: case 0x22: case 0x30:
|
||||
case 0x50: case 0x70: case 0x90: case 0xb0:
|
||||
case 0xd0: case 0xf0: case 0xfc:
|
||||
case 0x10: case 0x30: case 0x50: case 0x70:
|
||||
case 0x90: case 0xb0: case 0xd0: case 0xf0:
|
||||
case 0xfc:
|
||||
opcode.flags |= Opcode::FLAG_BRA_CONTINUE; break;
|
||||
case 0x20: case 0x22:
|
||||
opcode.flags |= Opcode::FLAG_CALL; break;
|
||||
case 0x28:
|
||||
opcode.flags |= Opcode::FLAG_POP_P; break;
|
||||
case 0x40: case 0x60: case 0x6b:
|
||||
|
|
|
@ -9,7 +9,8 @@ struct Opcode {
|
|||
FLAG_SET_X = 0x80, // sets X flag
|
||||
FLAG_PUSH_P = 0x100, // pushes flags
|
||||
FLAG_POP_P = 0x200, // pops flags
|
||||
FLAG_RETURN = 0x400, // returns from call
|
||||
FLAG_CALL = 0x400, // performs call
|
||||
FLAG_RETURN = 0x800, // returns from call
|
||||
FLAG_BRK = 0x1000, // software interrupt
|
||||
FLAG_HALT = 0x2000, // STP
|
||||
FLAG_RESET_E = 0x8000 // modifies E flag
|
||||
|
@ -40,6 +41,7 @@ struct Opcode {
|
|||
inline bool popsP() const { return flags & FLAG_POP_P; }
|
||||
inline bool breaks() const { return flags & FLAG_BRK; }
|
||||
inline bool halts() const { return flags & FLAG_HALT; }
|
||||
inline bool isCall() const { return flags & FLAG_CALL; }
|
||||
inline bool returns() const { return flags & FLAG_RETURN; }
|
||||
|
||||
uint8 op8(unsigned index = 0) {
|
||||
|
|
|
@ -65,8 +65,13 @@ uint32_t CPUAnalyst::performAnalysis(uint32_t address, CPUAnalystState &state, b
|
|||
break;
|
||||
}
|
||||
|
||||
if (op.isBraWithContinue() && !op.isIndirect()) {
|
||||
if (op.isCall()) {
|
||||
// analyze the call target, preserving any state changes inside the subroutine
|
||||
numRoutines += performAnalysis(core.decode(op.optype, op.opall(), address), state);
|
||||
} else if (op.isBraWithContinue() && !op.isIndirect()) {
|
||||
// analyze the branch target, not preserving any state changes from when the branch is taken
|
||||
CPUAnalystState tempState(state);
|
||||
numRoutines += performAnalysis(core.decode(op.optype, op.opall(), address), tempState);
|
||||
}
|
||||
|
||||
if (op.isBra() && !op.isIndirect()) {
|
||||
|
|
|
@ -92,23 +92,20 @@ void SMPcore::disassemble_opcode_ex(SMPcore::Opcode &opcode, uint16 addr) {
|
|||
opcode.set(0, op.mode, op.name, param, SNESSMP::getOpcodeLength(param[0]) - 1);
|
||||
|
||||
switch (param[0]) {
|
||||
case 0x01: case 0x04:
|
||||
case 0x10: case 0x11: case 0x13:
|
||||
case 0x21: case 0x23: case 0x2e:
|
||||
case 0x30: case 0x31: case 0x33: case 0x3f:
|
||||
case 0x41: case 0x43: case 0x4f:
|
||||
case 0x50: case 0x51: case 0x53:
|
||||
case 0x61: case 0x63: case 0x6e:
|
||||
case 0x70: case 0x71: case 0x73:
|
||||
case 0x81: case 0x83:
|
||||
case 0x90: case 0x91: case 0x93:
|
||||
case 0xa1: case 0xa3:
|
||||
case 0xb0: case 0xb1: case 0xb3:
|
||||
case 0xc1: case 0xc3:
|
||||
case 0xd0: case 0xd1: case 0xd3: case 0xde:
|
||||
case 0xe1: case 0xe3:
|
||||
case 0xf0: case 0xf1: case 0xf3: case 0xfe:
|
||||
case 0x04: case 0x10: case 0x13: case 0x23:
|
||||
case 0x2e: case 0x30: case 0x33: case 0x43:
|
||||
case 0x50: case 0x53: case 0x63: case 0x6e:
|
||||
case 0x70: case 0x73: case 0x83: case 0x90:
|
||||
case 0x93: case 0xa3: case 0xb0: case 0xb3:
|
||||
case 0xc3: case 0xd0: case 0xd3: case 0xde:
|
||||
case 0xe3: case 0xf0: case 0xf3: case 0xfe:
|
||||
opcode.flags |= Opcode::FLAG_BRA_CONTINUE; break;
|
||||
case 0x01: case 0x11: case 0x21: case 0x31:
|
||||
case 0x3f: case 0x41: case 0x4f: case 0x51:
|
||||
case 0x61: case 0x71: case 0x81: case 0x91:
|
||||
case 0xa1: case 0xb1: case 0xc1: case 0xd1:
|
||||
case 0xe1: case 0xf1:
|
||||
opcode.flags |= Opcode::FLAG_CALL; break;
|
||||
case 0x0d:
|
||||
opcode.flags |= Opcode::FLAG_PUSH_P; break;
|
||||
case 0x0f:
|
||||
|
|
|
@ -7,7 +7,8 @@ struct Opcode {
|
|||
FLAG_SET_P = 0x20, // sets P flag
|
||||
FLAG_PUSH_P = 0x100, // pushes flags
|
||||
FLAG_POP_P = 0x200, // pops flags
|
||||
FLAG_RETURN = 0x400, // returns from call
|
||||
FLAG_CALL = 0x400, // performs call
|
||||
FLAG_RETURN = 0x800, // returns from call
|
||||
FLAG_BRK = 0x1000, // software interrupt
|
||||
FLAG_HALT = 0x2000, // sleep/stop
|
||||
};
|
||||
|
@ -36,6 +37,7 @@ struct Opcode {
|
|||
inline bool popsP() const { return flags & FLAG_POP_P; }
|
||||
inline bool breaks() const { return flags & FLAG_BRK; }
|
||||
inline bool halts() const { return flags & FLAG_HALT; }
|
||||
inline bool isCall() const { return flags & FLAG_CALL; }
|
||||
inline bool returns() const { return flags & FLAG_RETURN; }
|
||||
|
||||
uint8 op() {
|
||||
|
|
|
@ -276,7 +276,7 @@ void SgbDisasmProcessor::analyze(uint32_t address) {
|
|||
SNES::supergameboy.usage(address) |= SNES::SGBDebugger::UsageOpcode;
|
||||
SNES::supergameboy.disassemble_opcode_ex(op, address);
|
||||
|
||||
if (op.isBraWithContinue() && !op.isIndirect()) {
|
||||
if (op.isCall() || (op.isBraWithContinue() && !op.isIndirect())) {
|
||||
uint32_t target = decode(op, address);
|
||||
if (usage(target) == 0) {
|
||||
// hack: if jumping from fixed to swappable ROM bank, don't continue
|
||||
|
|
Loading…
Reference in a new issue