mirror of
https://github.com/devinacker/bsnes-plus.git
synced 2025-04-02 10:52:46 -04:00
81 lines
2.6 KiB
C++
81 lines
2.6 KiB
C++
struct Opcode {
|
|
enum Flag {
|
|
FLAG_BRA = 0x01, // jumps and unconditional branches
|
|
FLAG_BRA_CONTINUE = 0x02, // calls and conditional branches
|
|
FLAG_INDIRECT = 0x04, // indirect memory accesses
|
|
FLAG_RESET_M = 0x10, // clears M flag
|
|
FLAG_RESET_X = 0x20, // clears X flag
|
|
FLAG_SET_M = 0x40, // sets M flag
|
|
FLAG_SET_X = 0x80, // sets X flag
|
|
FLAG_PUSH_P = 0x100, // pushes flags
|
|
FLAG_POP_P = 0x200, // pops flags
|
|
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
|
|
};
|
|
|
|
void set(uint16 flags, uint8 optype, const char *opcode, uint8 (¶m)[4], uint8 paramsize=0) {
|
|
this->flags = flags;
|
|
this->optype = optype;
|
|
this->opcode = opcode;
|
|
|
|
*((uint32*)&this->param) = *((uint32*)¶m);
|
|
this->paramsize = paramsize;
|
|
}
|
|
|
|
uint8 size() const {
|
|
return 1 + paramsize;
|
|
}
|
|
|
|
inline bool isBra() const { return flags & FLAG_BRA; }
|
|
inline bool isBraWithContinue() const { return flags & FLAG_BRA_CONTINUE; }
|
|
inline bool isIndirect() const { return flags & FLAG_INDIRECT; }
|
|
inline bool resetsX() const { return flags & FLAG_RESET_X; }
|
|
inline bool resetsM() const { return flags & FLAG_RESET_M; }
|
|
inline bool resetsE() const { return flags & FLAG_RESET_E; }
|
|
inline bool setsX() const { return flags & FLAG_SET_X; }
|
|
inline bool setsM() const { return flags & FLAG_SET_M; }
|
|
inline bool pushesP() const { return flags & FLAG_PUSH_P; }
|
|
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) {
|
|
return param[1 + index];
|
|
}
|
|
|
|
uint16 op16() {
|
|
return param[1] | param[2] << 8;
|
|
}
|
|
|
|
uint32 op24() {
|
|
return param[1] | param[2] << 8 | param[3] << 16;
|
|
}
|
|
|
|
uint32 opall() {
|
|
switch (size()) {
|
|
default:
|
|
case 1: return 0;
|
|
case 2: return op8();
|
|
case 3: return op16();
|
|
case 4: return op24();
|
|
}
|
|
}
|
|
|
|
uint16 flags;
|
|
uint8 optype;
|
|
uint8 param[4];
|
|
uint8 paramsize;
|
|
const char *opcode;
|
|
};
|
|
|
|
void disassemble_opcode(char *output, uint32 addr, bool hclocks = false);
|
|
void disassemble_opcode_ex(Opcode &opcode, uint32 addr, bool e, bool m, bool x);
|
|
uint8 dreadb(uint32 addr);
|
|
uint16 dreadw(uint32 addr);
|
|
uint32 dreadl(uint32 addr);
|
|
uint32 decode(uint8 offset_type, uint32 addr, uint32 pc);
|