mirror of
https://github.com/devinacker/bsnes-plus.git
synced 2025-04-02 10:52:46 -04:00
167 lines
4.3 KiB
C++
167 lines
4.3 KiB
C++
#ifdef SMPCORE_CPP
|
|
|
|
uint16 SMPcore::relb(int8 offset, int op_len, uint16 pc) {
|
|
return pc + op_len + offset;
|
|
}
|
|
|
|
uint8 SMPcore::dreadb(uint16 addr) {
|
|
SNES::debugger.bus_access = true;
|
|
return smp.op_debugread(addr);
|
|
SNES::debugger.bus_access = false;
|
|
}
|
|
|
|
uint16 SMPcore::dreadw(uint16 addr) {
|
|
uint16 r;
|
|
r = dreadb(addr + 0) << 0;
|
|
r |= dreadb(addr + 1) << 8;
|
|
return r;
|
|
}
|
|
|
|
uint16 SMPcore::decode(uint8 offset_type, uint16 addr, uint16 pc) {
|
|
uint16 r = 0;
|
|
uint16 dp = regs.p.p << 8;
|
|
|
|
switch(offset_type) {
|
|
case SNESSMP::Direct:
|
|
r = dp | (addr & 0xff);
|
|
break;
|
|
case SNESSMP::DirectIndX:
|
|
case SNESSMP::DirectIndXA:
|
|
case SNESSMP::DirectIndXY:
|
|
case SNESSMP::ADirectIndX:
|
|
case SNESSMP::YDirectIndX:
|
|
r = dp | ((addr + regs.x) & 0xff);
|
|
break;
|
|
case SNESSMP::DirectIndYX:
|
|
case SNESSMP::XDirectIndY:
|
|
r = dp | ((addr + regs.y) & 0xff);
|
|
break;
|
|
case SNESSMP::Absolute:
|
|
r = addr;
|
|
break;
|
|
case SNESSMP::AbsoluteXA:
|
|
case SNESSMP::AAbsoluteX:
|
|
r = addr + regs.x;
|
|
break;
|
|
case SNESSMP::AbsoluteYA:
|
|
case SNESSMP::AAbsoluteY:
|
|
r = addr + regs.y;
|
|
break;
|
|
case SNESSMP::AIDirectIndX:
|
|
case SNESSMP::IDirectIndXA:
|
|
r = dreadw(dp | ((addr + regs.x) & 0xff));
|
|
break;
|
|
case SNESSMP::AIDirectIndY:
|
|
case SNESSMP::IDirectIndYA:
|
|
r = dreadw(dp | (addr & 0xff)) + regs.y;
|
|
break;
|
|
case SNESSMP::IAbsoluteX:
|
|
r = dreadw(addr + regs.x);
|
|
break;
|
|
case SNESSMP::Relative:
|
|
case SNESSMP::YRelative:
|
|
r = relb((int8)addr, 2, pc);
|
|
break;
|
|
case SNESSMP::DirectRelative:
|
|
case SNESSMP::DirectIndXRelative:
|
|
r = relb((int8)addr, 3, pc);
|
|
break;
|
|
case SNESSMP::PVector:
|
|
r = 0xff00 | (addr & 0xff);
|
|
break;
|
|
case SNESSMP::TVector:
|
|
addr = dreadb(pc) >> 4;
|
|
addr = 0xffde - (addr << 1);
|
|
r = dreadw(addr);
|
|
break;
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
void SMPcore::disassemble_opcode_ex(SMPcore::Opcode &opcode, uint16 addr) {
|
|
uint8 param[3];
|
|
|
|
SNES::debugger.bus_access = true;
|
|
param[0] = smp.op_debugread(addr + 0);
|
|
param[1] = smp.op_debugread(addr + 1);
|
|
param[2] = smp.op_debugread(addr + 2);
|
|
SNES::debugger.bus_access = false;
|
|
|
|
const SNESSMP::OpcodeInfo& op = smpOpcodeInfo[param[0]];
|
|
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:
|
|
opcode.flags |= Opcode::FLAG_BRA_CONTINUE; break;
|
|
case 0x0d:
|
|
opcode.flags |= Opcode::FLAG_PUSH_P; break;
|
|
case 0x0f:
|
|
opcode.flags |= Opcode::FLAG_BRK; break;
|
|
case 0x1f: case 0x2f: case 0x5f:
|
|
opcode.flags |= Opcode::FLAG_BRA; break;
|
|
case 0x20:
|
|
opcode.flags |= Opcode::FLAG_RESET_P; break;
|
|
case 0x40:
|
|
opcode.flags |= Opcode::FLAG_SET_P; break;
|
|
case 0x6f: case 0x7f:
|
|
opcode.flags |= Opcode::FLAG_RETURN; break;
|
|
case 0x8e:
|
|
opcode.flags |= Opcode::FLAG_POP_P; break;
|
|
case 0xef: case 0xff:
|
|
opcode.flags |= Opcode::FLAG_HALT; break;
|
|
}
|
|
|
|
if (SNESSMP::getOpcodeIndirect(param[0])) {
|
|
opcode.flags |= Opcode::FLAG_INDIRECT;
|
|
}
|
|
}
|
|
|
|
void SMPcore::disassemble_opcode(char *output, uint16 addr) {
|
|
char *s, t[512];
|
|
uint8 op, op0, op1;
|
|
s = output;
|
|
|
|
sprintf(s, "..%.4x ", addr);
|
|
|
|
SNES::debugger.bus_access = true;
|
|
op = smp.op_debugread(addr + 0);
|
|
op0 = smp.op_debugread(addr + 1);
|
|
op1 = smp.op_debugread(addr + 2);
|
|
SNES::debugger.bus_access = false;
|
|
|
|
sprintf(t, "%-23s ", SNESSMP::disassemble(addr, op, op0, op1, regs.p.p)());
|
|
strcat(s, t);
|
|
|
|
sprintf(t, "A:%.2x X:%.2x Y:%.2x SP:01%.2x YA:%.4x ",
|
|
regs.a, regs.x, regs.y, regs.sp, (uint16)regs.ya);
|
|
strcat(s, t);
|
|
|
|
sprintf(t, "%c%c%c%c%c%c%c%c",
|
|
regs.p.n ? 'N' : '.',
|
|
regs.p.v ? 'V' : '.',
|
|
regs.p.p ? 'P' : '.',
|
|
regs.p.b ? 'B' : '.',
|
|
regs.p.h ? 'H' : '.',
|
|
regs.p.i ? 'I' : '.',
|
|
regs.p.z ? 'Z' : '.',
|
|
regs.p.c ? 'C' : '.');
|
|
strcat(s, t);
|
|
}
|
|
|
|
#endif
|