Skip to content

Commit

Permalink
add emux, add to recompiler
Browse files Browse the repository at this point in the history
  • Loading branch information
HailToDodongo committed Dec 27, 2023
1 parent 432c4e3 commit 92b34c2
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 2 deletions.
9 changes: 9 additions & 0 deletions ares/ares/node/debugger/tracer/instruction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ struct Instruction : Tracer {
for(auto& history : _history) history = ~0ull;
}

auto setEnabled(bool enabled) -> void {
//Tracer::setEnabled(enabled); // @TODO
if(!enabled) {
_omitted = 0;
setMask(_mask);
setDepth(_depth);
}
}

auto address(u64 address) -> bool {
address &= ~0ull >> (64 - _addressBits); //mask upper bits of address
_address = address;
Expand Down
5 changes: 5 additions & 0 deletions ares/n64/rsp/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ auto RSP::Debugger::instruction() -> void {
rsp.disassembler.showColors = 1;
}
}

if(tracer.instructionCountdown) {
if (--tracer.instructionCountdown == 0)
tracer.instruction->setEnabled(false);
}
}

auto RSP::Debugger::ioSCC(bool mode, u32 address, u32 data) -> void {
Expand Down
133 changes: 133 additions & 0 deletions ares/n64/rsp/emux.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
auto RSP::TNE(cr32& rs, cr32& rt, u32 code) -> void {
if(&rs != &rt) return INVALID();
EMUX(rt, code);
}

auto RSP::EMUX(cr32& rt, u32 code) -> void {
switch (code) {
case 0x20: // trace(start)
debugger.tracer.instruction->setEnabled(true);
debugger.tracer.instructionCountdown = 0;
break;
case 0x21: // trace(count)
printf("[emux] trace(count): %08x\n", rt.u32);
debugger.tracer.instruction->setEnabled(true);
debugger.tracer.instructionCountdown = rt.u32;
break;
case 0x22: // trace(stop)
debugger.tracer.instruction->setEnabled(false);
break;
case 0x30: // log(byte)
fputc(rt.u32 & 0xFF, stdout);
break;
case 0x31: { // log(string)
u32 i = 0;
do {
char c = dmem.read<Byte>(rt.u32 + i);
if (c == '\0') break;
fputc(c, stdout);
} while (++i < 4096);
} break;
case 0x32: // log(buflen)
emux.buflen = rt.u32;
break;
case 0x33: // log(buf)
for (auto i : range(emux.buflen)) {
fputc(dmem.read<Byte>(rt.u32 + i), stdout);
}
break;
case 0x40: case 0x48: { // dump_regs(gpr)
static const char *mips_reg_names[32] = { "zr", "at", "v0", "v1", "a0",
"a1", "a2", "a3", "t0", "t1",
"t2", "t3", "t4", "t5", "t6",
"t7", "s0", "s1", "s2", "s3",
"s4", "s5", "s6", "s7", "t8",
"t9", "k0", "k1", "gp", "sp",
"fp", "ra" };
n32 mask = rt.u32;
const char *fmt = code & 0x8 ? "%s: %-12d" : "%s: %04x %04x";
bool partial = false;
for (u32 i : range(32)) {
if (mask && !mask.bit(i)) continue;
u32 val = ipu.r[i].u32;
fprintf(stdout, fmt, mips_reg_names[i], val >> 16, val & 0xFFFF);
if (i % 4 == 3) fputc('\n', stdout), partial = false;
else fputs(" ", stdout), partial = true;
}
if (partial) fputc('\n', stdout);
} break;
case 0x41: case 0x44: { // dump_regs(cop0)
static const char *cop0_reg_names[16] = {
"dma_spaddr", "dma_ramaddr", "dma_read", "dma_write",
"sp_status", "dma_full", "dma_busy", "semaphore",
"dp_start", "dp_end", "dp_current", "dp_status",
"dp_clock", "dp_busy", "dp_pipe_busy", "dp_tmem_busy"
};
n32 mask = rt.u32;
const char *fmt = code & 0x8 ? "%s: %-12d" : "%s: %04x %04x";
bool partial = false;
Thread dummyThread{};
for (u32 i : range(16)) {
if (mask && !mask.bit(i)) continue;
u32 val;
if (i == 7) val = status.semaphore; // avoid side effects
else val = (i & 8) ? Nintendo64::rdp.readWord(i & 7, *this) : Nintendo64::rsp.ioRead(i & 7, dummyThread);
fprintf(stdout, fmt, cop0_reg_names[i], val >> 16, val & 0xFFFF);
if (i % 4 == 3) fputc('\n', stdout), partial = false;
else fputs(" ", stdout), partial = true;
}
if (partial) fputc('\n', stdout);
} break;
case 0x42: case 0x46: case 0x4A: case 0x4C: { // dump_regs(cop2)
auto dump_vr = [&](r128& vr) {
for (auto i : range(8)) {
if (code & 0x8) fprintf(stdout, "%-6d", vr.s16(i));
else fprintf(stdout, "%04x", vr.u16(i));
if (i < 7) fputc(' ', stdout);
if (i == 3) fputc(' ', stdout);
}
};

n32 mask = rt.u32;
bool partial = false;
for (u32 i : range(32)) {
if (mask && !mask.bit(i)) continue;
fprintf(stdout, "v%02d: ", i);
dump_vr(vpu.r[i]);
if (i % 2 == 1) fputc('\n', stdout), partial = false;
else fputs(" ", stdout), partial = true;
}
if (partial) fputc('\n', stdout);
if (code & 0x4) {
r128* accs[3] = { &vpu.acch, &vpu.accm, &vpu.accl };
const char *accnames[] = { "acch", "accm", "accl" };

auto dump_vc8 = [&](r128& vc) {
for (auto i : range(8)) {
fprintf(stdout, "%c", vc.get(i) ? '1' : '-');
if (i == 3) fputc(' ', stdout);
}
};
auto dump_vc16 = [&](r128& vch, r128& vcl) {
dump_vc8(vch);
fputc(' ', stdout);
dump_vc8(vcl);
};

for (auto i : range(3)) {
fprintf(stdout, "%s: ", accnames[i]);
dump_vr(*accs[i]);
fputs(" ", stdout);
switch (i) {
case 0: fprintf(stdout, "vco: "); dump_vc16(vpu.vcoh, vpu.vcol); fprintf(stdout, "\n"); break;
case 1: fprintf(stdout, "vcc: "); dump_vc16(vpu.vcch, vpu.vccl); fprintf(stdout, "\n"); break;
case 2: fprintf(stdout, "vce: "); dump_vc8(vpu.vce); fprintf(stdout, "\n"); break;
}
}
}
} break;
default:
printf("[emux] unknown emux code: %08x\n", code);
break;
}
}
3 changes: 2 additions & 1 deletion ares/n64/rsp/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#define RDn (OP >> 11 & 31)
#define RTn (OP >> 16 & 31)
#define RSn (OP >> 21 & 31)
#define CODE (OP >> 6 & 1023)
#define VDn (OP >> 6 & 31)
#define VSn (OP >> 11 & 31)
#define VTn (OP >> 16 & 31)
Expand Down Expand Up @@ -166,7 +167,7 @@ auto RSP::interpreterSPECIAL() -> void {
op(0x33, INVALID); //TLTU
op(0x34, INVALID); //TEQ
op(0x35, INVALID);
op(0x36, INVALID); //TNE
op(0x36, TNE, RS, RT, CODE); //TNE
op(0x37, INVALID);
op(0x38, INVALID); //DSLL
op(0x39, INVALID);
Expand Down
18 changes: 17 additions & 1 deletion ares/n64/rsp/recompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ auto RSP::Recompiler::emit(u12 address) -> Block* {
#define Vdn (instruction >> 6 & 31)
#define Vsn (instruction >> 11 & 31)
#define Vtn (instruction >> 16 & 31)
#define Code (instruction >> 6 & 1023)
#define Rd sreg(1), offsetof(IPU, r) + Rdn * sizeof(r32)
#define Rt sreg(1), offsetof(IPU, r) + Rtn * sizeof(r32)
#define Rs sreg(1), offsetof(IPU, r) + Rsn * sizeof(r32)
Expand Down Expand Up @@ -547,7 +548,21 @@ auto RSP::Recompiler::emitSPECIAL(u32 instruction) -> bool {
}

//INVALID
case range20(0x2c, 0x3f): {
case range10(0x2c, 0x35): {
return 0;
}

//TNE Rs,Rt,Code
case 0x36: {
lea(reg(1), Rs);
lea(reg(2), Rt);
mov32(reg(3), imm(Code));
call(&RSP::TNE);
return 0;
}

//INVALID
case range9(0x37, 0x3f): {
return 0;
}

Expand Down Expand Up @@ -1486,6 +1501,7 @@ auto RSP::Recompiler::isTerminal(u32 instruction) -> bool {
#undef Vd
#undef Vs
#undef Vt
#undef Code
#undef i16
#undef n16
#undef n26
Expand Down
1 change: 1 addition & 0 deletions ares/n64/rsp/rsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ RSP rsp;
#include "debugger.cpp"
#include "serialization.cpp"
#include "disassembler.cpp"
#include "emux.cpp"

auto RSP::load(Node::Object parent) -> void {
node = parent->append<Node::Object>("RSP");
Expand Down
8 changes: 8 additions & 0 deletions ares/n64/rsp/rsp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct RSP : Thread, Memory::RCP<RSP> {
struct Tracer {
Node::Debugger::Tracer::Instruction instruction;
Node::Debugger::Tracer::Notification io;
i32 instructionCountdown = 0;
} tracer;
} debugger;

Expand Down Expand Up @@ -476,6 +477,13 @@ struct RSP : Thread, Memory::RCP<RSP> {
template<u8 e> auto VXOR(r128& rd, cr128& vs, cr128& vt) -> void;
template<u8 e> auto VZERO(r128& rd, cr128& vs, cr128& vt) -> void;

//emux.cpp
auto TNE(cr32& rt, cr32& rs, u32 code) -> void;
auto EMUX(cr32& rt, u32 code) -> void;
struct {
u32 buflen;
} emux;

//unserialized:
u16 reciprocals[512];
u16 inverseSquareRoots[512];
Expand Down

0 comments on commit 92b34c2

Please sign in to comment.