This commit is contained in:
2026-03-23 12:11:07 +01:00
commit e64eb40b38
4573 changed files with 3117439 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
add_library(rsp decode.cpp instructions.cpp)
+456
View File
@@ -0,0 +1,456 @@
#include <Core.hpp>
#include <log.hpp>
namespace n64 {
void RSP::special(const Instruction instr) {
MI& mi = Core::GetMem().mmio.mi;
switch (instr.cop_funct()) {
case 0x00:
if (instr != 0) {
sll(instr);
}
break;
case 0x02:
srl(instr);
break;
case 0x03:
sra(instr);
break;
case 0x04:
sllv(instr);
break;
case 0x06:
srlv(instr);
break;
case 0x07:
srav(instr);
break;
case 0x08:
jr(instr);
break;
case 0x09:
jalr(instr);
break;
case 0x0D:
spStatus.halt = true;
steps = 0;
spStatus.broke = true;
if (spStatus.interruptOnBreak) {
mi.InterruptRaise(MI::Interrupt::SP);
}
break;
case 0x20:
case 0x21:
add(instr);
break;
case 0x22:
case 0x23:
sub(instr);
break;
case 0x24:
and_(instr);
break;
case 0x25:
or_(instr);
break;
case 0x26:
xor_(instr);
break;
case 0x27:
nor(instr);
break;
case 0x2A:
slt(instr);
break;
case 0x2B:
sltu(instr);
break;
default:
panic("Unhandled RSP special instruction ({:06b})", instr.cop_funct());
}
}
void RSP::regimm(const Instruction instr) {
switch (instr.cop_rt()) {
case 0x00:
b(instr, gpr[instr.rs()] < 0);
break;
case 0x01:
b(instr, gpr[instr.rs()] >= 0);
break;
case 0x10:
blink(instr, gpr[instr.rs()] < 0);
break;
case 0x11:
blink(instr, gpr[instr.rs()] >= 0);
break;
default:
panic("Unhandled RSP regimm instruction ({:05b})", instr.cop_rt());
}
}
void RSP::lwc2(const Instruction instr) {
switch (instr.rd()) {
case 0x00:
lbv(instr);
break;
case 0x01:
lsv(instr);
break;
case 0x02:
llv(instr);
break;
case 0x03:
ldv(instr);
break;
case 0x04:
lqv(instr);
break;
case 0x05:
lrv(instr);
break;
case 0x06:
lpv(instr);
break;
case 0x07:
luv(instr);
break;
case 0x08:
lhv(instr);
break;
case 0x09:
lfv(instr);
break;
case 0x0A:
break;
case 0x0B:
ltv(instr);
break;
default:
panic("Unhandled RSP LWC2 {:05b}", instr.rd());
}
}
void RSP::swc2(const Instruction instr) {
switch (instr.rd()) {
case 0x00:
sbv(instr);
break;
case 0x01:
ssv(instr);
break;
case 0x02:
slv(instr);
break;
case 0x03:
sdv(instr);
break;
case 0x04:
sqv(instr);
break;
case 0x05:
srv(instr);
break;
case 0x06:
spv(instr);
break;
case 0x07:
suv(instr);
break;
case 0x08:
shv(instr);
break;
case 0x09:
sfv(instr);
break;
case 0x0A:
swv(instr);
break;
case 0x0B:
stv(instr);
break;
default:
panic("Unhandled RSP SWC2 {:05b}", instr.rd());
}
}
void RSP::cop2(const Instruction instr) {
switch (instr.cop_funct()) {
case 0x00:
if (instr >> 25 & 1) {
vmulf(instr);
} else {
switch (instr.cop_rs()) {
case 0x00:
mfc2(instr);
break;
case 0x02:
cfc2(instr);
break;
case 0x04:
mtc2(instr);
break;
case 0x06:
ctc2(instr);
break;
default:
panic("Unhandled RSP COP2 sub ({:05b})", instr.cop_rs());
}
}
break;
case 0x01:
vmulu(instr);
break;
case 0x02:
vrndp(instr);
break;
case 0x03:
vmulq(instr);
break;
case 0x04:
vmudl(instr);
break;
case 0x05:
vmudm(instr);
break;
case 0x06:
vmudn(instr);
break;
case 0x07:
vmudh(instr);
break;
case 0x08:
vmacf(instr);
break;
case 0x09:
vmacu(instr);
break;
case 0x0A:
vrndn(instr);
break;
case 0x0B:
vmacq(instr);
break;
case 0x0C:
vmadl(instr);
break;
case 0x0D:
vmadm(instr);
break;
case 0x0E:
vmadn(instr);
break;
case 0x0F:
vmadh(instr);
break;
case 0x10:
vadd(instr);
break;
case 0x11:
vsub(instr);
break;
case 0x12:
vzero(instr);
break;
case 0x13:
vabs(instr);
break;
case 0x14:
vaddc(instr);
break;
case 0x15:
vsubc(instr);
break;
case 0x16 ... 0x1C:
case 0x1E:
case 0x1F:
case 0x2E:
case 0x2F:
vzero(instr);
break;
case 0x1D:
vsar(instr);
break;
case 0x20:
vlt(instr);
break;
case 0x21:
veq(instr);
break;
case 0x22:
vne(instr);
break;
case 0x23:
vge(instr);
break;
case 0x24:
vcl(instr);
break;
case 0x25:
vch(instr);
break;
case 0x26:
vcr(instr);
break;
case 0x27:
vmrg(instr);
break;
case 0x28:
vand(instr);
break;
case 0x29:
vnand(instr);
break;
case 0x2A:
vor(instr);
break;
case 0x2B:
vnor(instr);
break;
case 0x2C:
vxor(instr);
break;
case 0x2D:
vnxor(instr);
break;
case 0x31:
vrcpl(instr);
break;
case 0x35:
vrsql(instr);
break;
case 0x32:
case 0x36:
vrcph(instr);
break;
case 0x30:
vrcp(instr);
break;
case 0x33:
vmov(instr);
break;
case 0x34:
vrsq(instr);
break;
case 0x38 ... 0x3E:
vzero(instr);
break;
case 0x37:
case 0x3F:
break;
default:
panic("Unhandled RSP COP2 ({:06b})", instr.cop_funct());
}
}
void RSP::cop0(const Instruction instr) {
if ((instr & 0x7FF) == 0) {
switch (instr.cop_rs()) {
case 0x00:
mfc0(Core::GetMem().mmio.rdp, instr);
break;
case 0x04:
mtc0(instr);
break;
default:
panic("Unhandled RSP COP0 ({:05b})", instr.cop_rs());
}
} else {
panic("RSP COP0 unknown {:08X}", u32(instr));
}
}
void RSP::Exec(const Instruction instr) {
Mem& mem = Core::GetMem();
MMIO &mmio = mem.mmio;
MI &mi = mmio.mi;
switch (instr.opcode()) {
case 0x00:
special(instr);
break;
case 0x01:
regimm(instr);
break;
case 0x02:
j(instr);
break;
case 0x03:
jal(instr);
break;
case 0x04:
b(instr, gpr[instr.rt()] == gpr[instr.rs()]);
break;
case 0x05:
b(instr, gpr[instr.rt()] != gpr[instr.rs()]);
break;
case 0x06:
b(instr, gpr[instr.rs()] <= 0);
break;
case 0x07:
b(instr, gpr[instr.rs()] > 0);
break;
case 0x08:
case 0x09:
addi(instr);
break;
case 0x0A:
slti(instr);
break;
case 0x0B:
sltiu(instr);
break;
case 0x0C:
andi(instr);
break;
case 0x0D:
ori(instr);
break;
case 0x0E:
xori(instr);
break;
case 0x0F:
lui(instr);
break;
case 0x10:
cop0(instr);
break;
case 0x12:
cop2(instr);
break;
case 0x20:
lb(instr);
break;
case 0x21:
lh(instr);
break;
case 0x23:
case 0x27:
lw(instr);
break;
case 0x24:
lbu(instr);
break;
case 0x25:
lhu(instr);
break;
case 0x28:
sb(instr);
break;
case 0x29:
sh(instr);
break;
case 0x2B:
sw(instr);
break;
case 0x32:
lwc2(instr);
break;
case 0x3A:
swc2(instr);
break;
default:
mem.DumpIMEM();
panic("Unhandled RSP instruction ({:06b}, {:04X})", instr.opcode(), oldPC);
}
}
} // namespace n64
File diff suppressed because it is too large Load Diff