Fuck git
This commit is contained in:
@@ -0,0 +1 @@
|
||||
add_library(rsp decode.cpp instructions.cpp)
|
||||
@@ -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
Reference in New Issue
Block a user