Massive register overhaul

This commit is contained in:
SimoneN64
2024-07-05 16:56:14 +02:00
parent d90e26ac0c
commit ac9ff89bf1
9 changed files with 521 additions and 587 deletions

View File

@@ -48,10 +48,6 @@ int Interpreter::Step() {
return 1;
}
if((u64)regs.pc == 0xFFFFFFFF8002070C) {
printf("\n");
}
regs.oldPC = regs.pc;
regs.pc = regs.nextPC;
regs.nextPC += 4;

View File

@@ -337,11 +337,6 @@ template<> void Mem::Write<u8>(Registers& regs, u32 paddr, u32 val) {
const auto pointer = writePages[page];
SI& si = mmio.si;
if(paddr == 0x0023e650) {
//DumpRDRAM();
//fmt::print("PC is 0x{:016X}: Writing 0x{:02X} -> 0x{:08X}\n", (u64)regs.oldPC, (u8)val, paddr);
}
if(pointer) {
((u8*)pointer)[BYTE_ADDRESS(offset)] = val;
} else {
@@ -387,11 +382,6 @@ template<> void Mem::Write<u16>(Registers& regs, u32 paddr, u32 val) {
const auto pointer = writePages[page];
SI& si = mmio.si;
if(paddr == 0x0023e650) {
//DumpRDRAM();
//fmt::print("PC is 0x{:016X}: Writing 0x{:04X} -> 0x{:08X}\n", (u64) regs.oldPC, (u16) val, paddr);
}
if(pointer) {
Util::WriteAccess<u16>((u8*)pointer, HALF_ADDRESS(offset), val);
} else {
@@ -437,11 +427,6 @@ template<> void Mem::Write<u32>(Registers& regs, u32 paddr, u32 val) {
const auto pointer = writePages[page];
SI& si = mmio.si;
if(paddr == 0x0023e650) {
//DumpRDRAM();
//fmt::print("PC is 0x{:016X}: Writing 0x{:08X} -> 0x{:08X}\n", (u64) regs.oldPC, val, paddr);
}
if(pointer) {
Util::WriteAccess<u32>((u8*)pointer, offset, val);
} else {
@@ -481,11 +466,6 @@ void Mem::Write(Registers& regs, u32 paddr, u64 val) {
const auto pointer = writePages[page];
SI& si = mmio.si;
if(paddr == 0x0023e650) {
//DumpRDRAM();
//fmt::print("PC is 0x{:016X}: Writing 0x{:016X} -> 0x{:08X}\n", (u64) regs.oldPC, val, paddr);
}
if(pointer) {
Util::WriteAccess<u64>((u8*)pointer, offset, val);
} else {

View File

@@ -51,12 +51,12 @@ void Interpreter::special(u32 instr) {
case DADDU: daddu(instr); break;
case DSUB: dsub(instr); break;
case DSUBU: dsubu(instr); break;
case TGE: trap(regs.gpr[RS(instr)] >= regs.gpr[RT(instr)]); break;
case TGEU: trap((u64)regs.gpr[RS(instr)] >= (u64)regs.gpr[RT(instr)]); break;
case TLT: trap(regs.gpr[RS(instr)] < regs.gpr[RT(instr)]); break;
case TLTU: trap((u64)regs.gpr[RS(instr)] < (u64)regs.gpr[RT(instr)]); break;
case TEQ: trap(regs.gpr[RS(instr)] == regs.gpr[RT(instr)]); break;
case TNE: trap(regs.gpr[RS(instr)] != regs.gpr[RT(instr)]); break;
case TGE: trap(regs.Read<s64>(RS(instr)) >= regs.Read<s64>(RT(instr))); break;
case TGEU: trap(regs.Read<u64>(RS(instr)) >= regs.Read<u64>(RT(instr))); break;
case TLT: trap(regs.Read<s64>(RS(instr)) < regs.Read<s64>(RT(instr))); break;
case TLTU: trap(regs.Read<u64>(RS(instr)) < regs.Read<u64>(RT(instr))); break;
case TEQ: trap(regs.Read<s64>(RS(instr)) == regs.Read<s64>(RT(instr))); break;
case TNE: trap(regs.Read<s64>(RS(instr)) != regs.Read<s64>(RT(instr))); break;
case DSLL: dsll(instr); break;
case DSRL: dsrl(instr); break;
case DSRA: dsra(instr); break;
@@ -72,20 +72,20 @@ void Interpreter::regimm(u32 instr) {
u8 mask = ((instr >> 16) & 0x1F);
// 000r_rccc
switch (mask) { // TODO: named constants for clearer code
case BLTZ: b(instr, regs.gpr[RS(instr)] < 0); break;
case BGEZ: b(instr, regs.gpr[RS(instr)] >= 0); break;
case BLTZL: bl(instr, regs.gpr[RS(instr)] < 0); break;
case BGEZL: bl(instr, regs.gpr[RS(instr)] >= 0); break;
case TGEI: trap(regs.gpr[RS(instr)] >= s64(s16(instr))); break;
case TGEIU: trap(u64(regs.gpr[RS(instr)]) >= u64(s64(s16(instr)))); break;
case TLTI: trap(regs.gpr[RS(instr)] < s64(s16(instr))); break;
case TLTIU: trap(u64(regs.gpr[RS(instr)]) < u64(s64(s16(instr)))); break;
case TEQI: trap(regs.gpr[RS(instr)] == s64(s16(instr))); break;
case TNEI: trap(regs.gpr[RS(instr)] != s64(s16(instr))); break;
case BLTZAL: blink(instr, regs.gpr[RS(instr)] < 0); break;
case BGEZAL: blink(instr, regs.gpr[RS(instr)] >= 0); break;
case BLTZALL: bllink(instr, regs.gpr[RS(instr)] < 0); break;
case BGEZALL: bllink(instr, regs.gpr[RS(instr)] >= 0); break;
case BLTZ: b(instr, regs.Read<s64>(RS(instr)) < 0); break;
case BGEZ: b(instr, regs.Read<s64>(RS(instr)) >= 0); break;
case BLTZL: bl(instr, regs.Read<s64>(RS(instr)) < 0); break;
case BGEZL: bl(instr, regs.Read<s64>(RS(instr)) >= 0); break;
case TGEI: trap(regs.Read<s64>(RS(instr)) >= s64(s16(instr))); break;
case TGEIU: trap(regs.Read<u64>(RS(instr)) >= u64(s64(s16(instr)))); break;
case TLTI: trap(regs.Read<s64>(RS(instr)) < s64(s16(instr))); break;
case TLTIU: trap(regs.Read<u64>(RS(instr)) < u64(s64(s16(instr)))); break;
case TEQI: trap(regs.Read<s64>(RS(instr)) == s64(s16(instr))); break;
case TNEI: trap(regs.Read<s64>(RS(instr)) != s64(s16(instr))); break;
case BLTZAL: blink(instr, regs.Read<s64>(RS(instr)) < 0); break;
case BGEZAL: blink(instr, regs.Read<s64>(RS(instr)) >= 0); break;
case BLTZALL: bllink(instr, regs.Read<s64>(RS(instr)) < 0); break;
case BGEZALL: bllink(instr, regs.Read<s64>(RS(instr)) >= 0); break;
default:
Util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})", (mask >> 3) & 3, mask & 7, instr, (u64)regs.oldPC);
}
@@ -116,13 +116,10 @@ void Interpreter::Exec(u32 instr) {
case REGIMM: regimm(instr); break;
case J: j(instr); break;
case JAL: jal(instr); break;
case BEQ: b(instr, regs.gpr[RS(instr)] == regs.gpr[RT(instr)]); break;
case BNE: {
//fmt::print("RS: {:016X}, RT: {:016X}", (u64)regs.gpr[RS(instr)], (u64)regs.gpr[RT(instr)]);
b(instr, regs.gpr[RS(instr)] != regs.gpr[RT(instr)]);
} break;
case BLEZ: b(instr, regs.gpr[RS(instr)] <= 0); break;
case BGTZ: b(instr, regs.gpr[RS(instr)] > 0); break;
case BEQ: b(instr, regs.Read<s64>(RS(instr)) == regs.Read<s64>(RT(instr))); break;
case BNE: b(instr, regs.Read<s64>(RS(instr)) != regs.Read<s64>(RT(instr))); break;
case BLEZ: b(instr, regs.Read<s64>(RS(instr)) <= 0); break;
case BGTZ: b(instr, regs.Read<s64>(RS(instr)) > 0); break;
case ADDI: addi(instr); break;
case ADDIU: addiu(instr); break;
case SLTI: slti(instr); break;
@@ -134,10 +131,10 @@ void Interpreter::Exec(u32 instr) {
case COP0: regs.cop0.decode(*this, instr); break;
case COP1: regs.cop1.decode(*this, instr); break;
case COP2: cop2Decode(instr); break;
case BEQL: bl(instr, regs.gpr[RS(instr)] == regs.gpr[RT(instr)]); break;
case BNEL: bl(instr, regs.gpr[RS(instr)] != regs.gpr[RT(instr)]); break;
case BLEZL: bl(instr, regs.gpr[RS(instr)] <= 0); break;
case BGTZL: bl(instr, regs.gpr[RS(instr)] > 0); break;
case BEQL: bl(instr, regs.Read<s64>(RS(instr)) == regs.Read<s64>(RT(instr))); break;
case BNEL: bl(instr, regs.Read<s64>(RS(instr)) != regs.Read<s64>(RT(instr))); break;
case BLEZL: bl(instr, regs.Read<s64>(RS(instr)) <= 0); break;
case BGTZL: bl(instr, regs.Read<s64>(RS(instr)) > 0); break;
case DADDI: daddi(instr); break;
case DADDIU: daddiu(instr); break;
case LDL: ldl(instr); break;

File diff suppressed because it is too large Load Diff

View File

@@ -342,202 +342,202 @@ void PIF::HLE(bool pal, CICType cicType) {
Util::warn("Unknown CIC type!");
break;
case CIC_NUS_6101:
regs.gpr[0] = 0x0000000000000000;
regs.gpr[1] = 0x0000000000000000;
regs.gpr[2] = 0xFFFFFFFFDF6445CCll;
regs.gpr[3] = 0xFFFFFFFFDF6445CCll;
regs.gpr[4] = 0x00000000000045CC;
regs.gpr[5] = 0x0000000073EE317A;
regs.gpr[6] = 0xFFFFFFFFA4001F0Cll;
regs.gpr[7] = 0xFFFFFFFFA4001F08ll;
regs.gpr[8] = 0x00000000000000C0;
regs.gpr[9] = 0x0000000000000000;
regs.gpr[10] = 0x0000000000000040;
regs.gpr[11] = 0xFFFFFFFFA4000040ll;
regs.gpr[12] = 0xFFFFFFFFC7601FACll;
regs.gpr[13] = 0xFFFFFFFFC7601FACll;
regs.gpr[14] = 0xFFFFFFFFB48E2ED6ll;
regs.gpr[15] = 0xFFFFFFFFBA1A7D4Bll;
regs.gpr[16] = 0x0000000000000000;
regs.gpr[17] = 0x0000000000000000;
regs.gpr[18] = 0x0000000000000000;
regs.gpr[19] = 0x0000000000000000;
regs.gpr[20] = 0x0000000000000001;
regs.gpr[21] = 0x0000000000000000;
regs.gpr[23] = 0x0000000000000001;
regs.gpr[24] = 0x0000000000000002;
regs.gpr[25] = 0xFFFFFFFF905F4718ll;
regs.gpr[26] = 0x0000000000000000;
regs.gpr[27] = 0x0000000000000000;
regs.gpr[28] = 0x0000000000000000;
regs.gpr[29] = 0xFFFFFFFFA4001FF0ll;
regs.gpr[30] = 0x0000000000000000;
regs.gpr[31] = 0xFFFFFFFFA4001550ll;
regs.Write(0, 0x0000000000000000);
regs.Write(1, 0x0000000000000000);
regs.Write(2, 0xFFFFFFFFDF6445CC);
regs.Write(3, 0xFFFFFFFFDF6445CC);
regs.Write(4, 0x00000000000045CC);
regs.Write(5, 0x0000000073EE317A);
regs.Write(6, 0xFFFFFFFFA4001F0C);
regs.Write(7, 0xFFFFFFFFA4001F08);
regs.Write(8, 0x00000000000000C0);
regs.Write(9, 0x0000000000000000);
regs.Write(10, 0x0000000000000040);
regs.Write(11, 0xFFFFFFFFA4000040);
regs.Write(12, 0xFFFFFFFFC7601FAC);
regs.Write(13, 0xFFFFFFFFC7601FAC);
regs.Write(14, 0xFFFFFFFFB48E2ED6);
regs.Write(15, 0xFFFFFFFFBA1A7D4B);
regs.Write(16, 0x0000000000000000);
regs.Write(17, 0x0000000000000000);
regs.Write(18, 0x0000000000000000);
regs.Write(19, 0x0000000000000000);
regs.Write(20, 0x0000000000000001);
regs.Write(21, 0x0000000000000000);
regs.Write(23, 0x0000000000000001);
regs.Write(24, 0x0000000000000002);
regs.Write(25, 0xFFFFFFFF905F4718);
regs.Write(26, 0x0000000000000000);
regs.Write(27, 0x0000000000000000);
regs.Write(28, 0x0000000000000000);
regs.Write(29, 0xFFFFFFFFA4001FF0);
regs.Write(30, 0x0000000000000000);
regs.Write(31, 0xFFFFFFFFA4001550);
regs.lo = 0xFFFFFFFFBA1A7D4Bll;
regs.hi = 0xFFFFFFFF997EC317ll;
break;
case CIC_NUS_7102:
regs.gpr[0] = 0x0000000000000000;
regs.gpr[1] = 0x0000000000000001;
regs.gpr[2] = 0x000000001E324416;
regs.gpr[3] = 0x000000001E324416;
regs.gpr[4] = 0x0000000000004416;
regs.gpr[5] = 0x000000000EC5D9AF;
regs.gpr[6] = 0xFFFFFFFFA4001F0Cll;
regs.gpr[7] = 0xFFFFFFFFA4001F08ll;
regs.gpr[8] = 0x00000000000000C0;
regs.gpr[9] = 0x0000000000000000;
regs.gpr[10] = 0x0000000000000040;
regs.gpr[11] = 0xFFFFFFFFA4000040ll;
regs.gpr[12] = 0x00000000495D3D7B;
regs.gpr[13] = 0xFFFFFFFF8B3DFA1Ell;
regs.gpr[14] = 0x000000004798E4D4;
regs.gpr[15] = 0xFFFFFFFFF1D30682ll;
regs.gpr[16] = 0x0000000000000000;
regs.gpr[17] = 0x0000000000000000;
regs.gpr[18] = 0x0000000000000000;
regs.gpr[19] = 0x0000000000000000;
regs.gpr[20] = 0x0000000000000000;
regs.gpr[21] = 0x0000000000000000;
regs.gpr[22] = 0x000000000000003F;
regs.gpr[23] = 0x0000000000000007;
regs.gpr[24] = 0x0000000000000000;
regs.gpr[25] = 0x0000000013D05CAB;
regs.gpr[26] = 0x0000000000000000;
regs.gpr[27] = 0x0000000000000000;
regs.gpr[28] = 0x0000000000000000;
regs.gpr[29] = 0xFFFFFFFFA4001FF0ll;
regs.gpr[30] = 0x0000000000000000;
regs.gpr[31] = 0xFFFFFFFFA4001554ll;
regs.Write(0, 0x0000000000000000);
regs.Write(1, 0x0000000000000001);
regs.Write(2, 0x000000001E324416);
regs.Write(3, 0x000000001E324416);
regs.Write(4, 0x0000000000004416);
regs.Write(5, 0x000000000EC5D9AF);
regs.Write(6, 0xFFFFFFFFA4001F0C);
regs.Write(7, 0xFFFFFFFFA4001F08);
regs.Write(8, 0x00000000000000C0);
regs.Write(9, 0x0000000000000000);
regs.Write(10, 0x0000000000000040);
regs.Write(11, 0xFFFFFFFFA4000040);
regs.Write(12, 0x00000000495D3D7B);
regs.Write(13, 0xFFFFFFFF8B3DFA1E);
regs.Write(14, 0x000000004798E4D4);
regs.Write(15, 0xFFFFFFFFF1D30682);
regs.Write(16, 0x0000000000000000);
regs.Write(17, 0x0000000000000000);
regs.Write(18, 0x0000000000000000);
regs.Write(19, 0x0000000000000000);
regs.Write(20, 0x0000000000000000);
regs.Write(21, 0x0000000000000000);
regs.Write(22, 0x000000000000003F);
regs.Write(23, 0x0000000000000007);
regs.Write(24, 0x0000000000000000);
regs.Write(25, 0x0000000013D05CAB);
regs.Write(26, 0x0000000000000000);
regs.Write(27, 0x0000000000000000);
regs.Write(28, 0x0000000000000000);
regs.Write(29, 0xFFFFFFFFA4001FF0);
regs.Write(30, 0x0000000000000000);
regs.Write(31, 0xFFFFFFFFA4001554);
regs.lo = 0xFFFFFFFFF1D30682ll;
regs.hi = 0x0000000010054A98;
break;
case CIC_NUS_6102_7101:
regs.gpr[0] = 0x0000000000000000;
regs.gpr[1] = 0x0000000000000001;
regs.gpr[2] = 0x000000000EBDA536;
regs.gpr[3] = 0x000000000EBDA536;
regs.gpr[4] = 0x000000000000A536;
regs.gpr[5] = 0xFFFFFFFFC0F1D859ll;
regs.gpr[6] = 0xFFFFFFFFA4001F0Cll;
regs.gpr[7] = 0xFFFFFFFFA4001F08ll;
regs.gpr[8] = 0x00000000000000C0;
regs.gpr[9] = 0x0000000000000000;
regs.gpr[10] = 0x0000000000000040;
regs.gpr[11] = 0xFFFFFFFFA4000040ll;
regs.gpr[12] = 0xFFFFFFFFED10D0B3ll;
regs.gpr[13] = 0x000000001402A4CC;
regs.gpr[14] = 0x000000002DE108EA;
regs.gpr[15] = 0x000000003103E121;
regs.gpr[16] = 0x0000000000000000;
regs.gpr[17] = 0x0000000000000000;
regs.gpr[18] = 0x0000000000000000;
regs.gpr[19] = 0x0000000000000000;
regs.gpr[20] = 0x0000000000000001;
regs.gpr[21] = 0x0000000000000000;
regs.gpr[23] = 0x0000000000000000;
regs.gpr[24] = 0x0000000000000000;
regs.gpr[25] = 0xFFFFFFFF9DEBB54Fll;
regs.gpr[26] = 0x0000000000000000;
regs.gpr[27] = 0x0000000000000000;
regs.gpr[28] = 0x0000000000000000;
regs.gpr[29] = 0xFFFFFFFFA4001FF0ll;
regs.gpr[30] = 0x0000000000000000;
regs.gpr[31] = 0xFFFFFFFFA4001550ll;
regs.Write(0, 0x0000000000000000);
regs.Write(1, 0x0000000000000001);
regs.Write(2, 0x000000000EBDA536);
regs.Write(3, 0x000000000EBDA536);
regs.Write(4, 0x000000000000A536);
regs.Write(5, 0xFFFFFFFFC0F1D859);
regs.Write(6, 0xFFFFFFFFA4001F0C);
regs.Write(7, 0xFFFFFFFFA4001F08);
regs.Write(8, 0x00000000000000C0);
regs.Write(9, 0x0000000000000000);
regs.Write(10, 0x0000000000000040);
regs.Write(11, 0xFFFFFFFFA4000040);
regs.Write(12, 0xFFFFFFFFED10D0B3);
regs.Write(13, 0x000000001402A4CC);
regs.Write(14, 0x000000002DE108EA);
regs.Write(15, 0x000000003103E121);
regs.Write(16, 0x0000000000000000);
regs.Write(17, 0x0000000000000000);
regs.Write(18, 0x0000000000000000);
regs.Write(19, 0x0000000000000000);
regs.Write(20, 0x0000000000000001);
regs.Write(21, 0x0000000000000000);
regs.Write(23, 0x0000000000000000);
regs.Write(24, 0x0000000000000000);
regs.Write(25, 0xFFFFFFFF9DEBB54F);
regs.Write(26, 0x0000000000000000);
regs.Write(27, 0x0000000000000000);
regs.Write(28, 0x0000000000000000);
regs.Write(29, 0xFFFFFFFFA4001FF0);
regs.Write(30, 0x0000000000000000);
regs.Write(31, 0xFFFFFFFFA4001550);
regs.hi = 0x000000003FC18657;
regs.lo = 0x000000003103E121;
if (pal) {
regs.gpr[20] = 0x0000000000000000;
regs.gpr[23] = 0x0000000000000006;
regs.gpr[31] = 0xFFFFFFFFA4001554ll;
regs.Write(20, 0x0000000000000000);
regs.Write(23, 0x0000000000000006);
regs.Write(31, 0xFFFFFFFFA4001554);
}
break;
case CIC_NUS_6103_7103:
regs.gpr[0] = 0x0000000000000000;
regs.gpr[1] = 0x0000000000000001;
regs.gpr[2] = 0x0000000049A5EE96;
regs.gpr[3] = 0x0000000049A5EE96;
regs.gpr[4] = 0x000000000000EE96;
regs.gpr[5] = 0xFFFFFFFFD4646273ll;
regs.gpr[6] = 0xFFFFFFFFA4001F0Cll;
regs.gpr[7] = 0xFFFFFFFFA4001F08ll;
regs.gpr[8] = 0x00000000000000C0;
regs.gpr[9] = 0x0000000000000000;
regs.gpr[10] = 0x0000000000000040;
regs.gpr[11] = 0xFFFFFFFFA4000040ll;
regs.gpr[12] = 0xFFFFFFFFCE9DFBF7ll;
regs.gpr[13] = 0xFFFFFFFFCE9DFBF7ll;
regs.gpr[14] = 0x000000001AF99984;
regs.gpr[15] = 0x0000000018B63D28;
regs.gpr[16] = 0x0000000000000000;
regs.gpr[17] = 0x0000000000000000;
regs.gpr[18] = 0x0000000000000000;
regs.gpr[19] = 0x0000000000000000;
regs.gpr[20] = 0x0000000000000001;
regs.gpr[21] = 0x0000000000000000;
regs.gpr[23] = 0x0000000000000000;
regs.gpr[24] = 0x0000000000000000;
regs.gpr[25] = 0xFFFFFFFF825B21C9ll;
regs.gpr[26] = 0x0000000000000000;
regs.gpr[27] = 0x0000000000000000;
regs.gpr[28] = 0x0000000000000000;
regs.gpr[29] = 0xFFFFFFFFA4001FF0ll;
regs.gpr[30] = 0x0000000000000000;
regs.gpr[31] = 0xFFFFFFFFA4001550ll;
regs.Write(0, 0x0000000000000000);
regs.Write(1, 0x0000000000000001);
regs.Write(2, 0x0000000049A5EE96);
regs.Write(3, 0x0000000049A5EE96);
regs.Write(4, 0x000000000000EE96);
regs.Write(5, 0xFFFFFFFFD4646273);
regs.Write(6, 0xFFFFFFFFA4001F0C);
regs.Write(7, 0xFFFFFFFFA4001F08);
regs.Write(8, 0x00000000000000C0);
regs.Write(9, 0x0000000000000000);
regs.Write(10, 0x0000000000000040);
regs.Write(11, 0xFFFFFFFFA4000040);
regs.Write(12, 0xFFFFFFFFCE9DFBF7);
regs.Write(13, 0xFFFFFFFFCE9DFBF7);
regs.Write(14, 0x000000001AF99984);
regs.Write(15, 0x0000000018B63D28);
regs.Write(16, 0x0000000000000000);
regs.Write(17, 0x0000000000000000);
regs.Write(18, 0x0000000000000000);
regs.Write(19, 0x0000000000000000);
regs.Write(20, 0x0000000000000001);
regs.Write(21, 0x0000000000000000);
regs.Write(23, 0x0000000000000000);
regs.Write(24, 0x0000000000000000);
regs.Write(25, 0xFFFFFFFF825B21C9);
regs.Write(26, 0x0000000000000000);
regs.Write(27, 0x0000000000000000);
regs.Write(28, 0x0000000000000000);
regs.Write(29, 0xFFFFFFFFA4001FF0);
regs.Write(30, 0x0000000000000000);
regs.Write(31, 0xFFFFFFFFA4001550);
regs.lo = 0x0000000018B63D28;
regs.hi = 0x00000000625C2BBE;
if (pal) {
regs.gpr[20] = 0x0000000000000000;
regs.gpr[23] = 0x0000000000000006;
regs.gpr[31] = 0xFFFFFFFFA4001554ll;
regs.Write(20, 0x0000000000000000);
regs.Write(23, 0x0000000000000006);
regs.Write(31, 0xFFFFFFFFA4001554);
}
break;
case CIC_NUS_6105_7105:
regs.gpr[0] = 0x0000000000000000;
regs.gpr[1] = 0x0000000000000000;
regs.gpr[2] = 0xFFFFFFFFF58B0FBFll;
regs.gpr[3] = 0xFFFFFFFFF58B0FBFll;
regs.gpr[4] = 0x0000000000000FBF;
regs.gpr[5] = 0xFFFFFFFFDECAAAD1ll;
regs.gpr[6] = 0xFFFFFFFFA4001F0Cll;
regs.gpr[7] = 0xFFFFFFFFA4001F08ll;
regs.gpr[8] = 0x00000000000000C0;
regs.gpr[9] = 0x0000000000000000;
regs.gpr[10] = 0x0000000000000040;
regs.gpr[11] = 0xFFFFFFFFA4000040ll;
regs.gpr[12] = 0xFFFFFFFF9651F81Ell;
regs.gpr[13] = 0x000000002D42AAC5;
regs.gpr[14] = 0x00000000489B52CF;
regs.gpr[15] = 0x0000000056584D60;
regs.gpr[16] = 0x0000000000000000;
regs.gpr[17] = 0x0000000000000000;
regs.gpr[18] = 0x0000000000000000;
regs.gpr[19] = 0x0000000000000000;
regs.gpr[20] = 0x0000000000000001;
regs.gpr[21] = 0x0000000000000000;
regs.gpr[23] = 0x0000000000000000;
regs.gpr[24] = 0x0000000000000002;
regs.gpr[25] = 0xFFFFFFFFCDCE565Fll;
regs.gpr[26] = 0x0000000000000000;
regs.gpr[27] = 0x0000000000000000;
regs.gpr[28] = 0x0000000000000000;
regs.gpr[29] = 0xFFFFFFFFA4001FF0ll;
regs.gpr[30] = 0x0000000000000000;
regs.gpr[31] = 0xFFFFFFFFA4001550ll;
regs.Write(0, 0x0000000000000000);
regs.Write(1, 0x0000000000000000);
regs.Write(2, 0xFFFFFFFFF58B0FBF);
regs.Write(3, 0xFFFFFFFFF58B0FBF);
regs.Write(4, 0x0000000000000FBF);
regs.Write(5, 0xFFFFFFFFDECAAAD1);
regs.Write(6, 0xFFFFFFFFA4001F0C);
regs.Write(7, 0xFFFFFFFFA4001F08);
regs.Write(8, 0x00000000000000C0);
regs.Write(9, 0x0000000000000000);
regs.Write(10, 0x0000000000000040);
regs.Write(11, 0xFFFFFFFFA4000040);
regs.Write(12, 0xFFFFFFFF9651F81E);
regs.Write(13, 0x000000002D42AAC5);
regs.Write(14, 0x00000000489B52CF);
regs.Write(15, 0x0000000056584D60);
regs.Write(16, 0x0000000000000000);
regs.Write(17, 0x0000000000000000);
regs.Write(18, 0x0000000000000000);
regs.Write(19, 0x0000000000000000);
regs.Write(20, 0x0000000000000001);
regs.Write(21, 0x0000000000000000);
regs.Write(23, 0x0000000000000000);
regs.Write(24, 0x0000000000000002);
regs.Write(25, 0xFFFFFFFFCDCE565F);
regs.Write(26, 0x0000000000000000);
regs.Write(27, 0x0000000000000000);
regs.Write(28, 0x0000000000000000);
regs.Write(29, 0xFFFFFFFFA4001FF0);
regs.Write(30, 0x0000000000000000);
regs.Write(31, 0xFFFFFFFFA4001550);
regs.lo = 0x0000000056584D60;
regs.hi = 0x000000004BE35D1F;
if (pal) {
regs.gpr[20] = 0x0000000000000000;
regs.gpr[23] = 0x0000000000000006;
regs.gpr[31] = 0xFFFFFFFFA4001554ll;
regs.Write(20, 0x0000000000000000);
regs.Write(23, 0x0000000000000006);
regs.Write(31, 0xFFFFFFFFA4001554);
}
mem.Write<u32>(regs, IMEM_REGION_START + 0x00, 0x3C0DBFC0);
@@ -550,49 +550,49 @@ void PIF::HLE(bool pal, CICType cicType) {
mem.Write<u32>(regs, IMEM_REGION_START + 0x1C, 0x3C0BB000);
break;
case CIC_NUS_6106_7106:
regs.gpr[0] = 0x0000000000000000;
regs.gpr[1] = 0x0000000000000000;
regs.gpr[2] = 0xFFFFFFFFA95930A4ll;
regs.gpr[3] = 0xFFFFFFFFA95930A4ll;
regs.gpr[4] = 0x00000000000030A4;
regs.gpr[5] = 0xFFFFFFFFB04DC903ll;
regs.gpr[6] = 0xFFFFFFFFA4001F0Cll;
regs.gpr[7] = 0xFFFFFFFFA4001F08ll;
regs.gpr[8] = 0x00000000000000C0;
regs.gpr[9] = 0x0000000000000000;
regs.gpr[10] = 0x0000000000000040;
regs.gpr[11] = 0xFFFFFFFFA4000040ll;
regs.gpr[12] = 0xFFFFFFFFBCB59510ll;
regs.gpr[13] = 0xFFFFFFFFBCB59510ll;
regs.gpr[14] = 0x000000000CF85C13;
regs.gpr[15] = 0x000000007A3C07F4;
regs.gpr[16] = 0x0000000000000000;
regs.gpr[17] = 0x0000000000000000;
regs.gpr[18] = 0x0000000000000000;
regs.gpr[19] = 0x0000000000000000;
regs.gpr[20] = 0x0000000000000001;
regs.gpr[21] = 0x0000000000000000;
regs.gpr[23] = 0x0000000000000000;
regs.gpr[24] = 0x0000000000000002;
regs.gpr[25] = 0x00000000465E3F72;
regs.gpr[26] = 0x0000000000000000;
regs.gpr[27] = 0x0000000000000000;
regs.gpr[28] = 0x0000000000000000;
regs.gpr[29] = 0xFFFFFFFFA4001FF0ll;
regs.gpr[30] = 0x0000000000000000;
regs.gpr[31] = 0xFFFFFFFFA4001550ll;
regs.Write(0, 0x0000000000000000);
regs.Write(1, 0x0000000000000000);
regs.Write(2, 0xFFFFFFFFA95930A4);
regs.Write(3, 0xFFFFFFFFA95930A4);
regs.Write(4, 0x00000000000030A4);
regs.Write(5, 0xFFFFFFFFB04DC903);
regs.Write(6, 0xFFFFFFFFA4001F0C);
regs.Write(7, 0xFFFFFFFFA4001F08);
regs.Write(8, 0x00000000000000C0);
regs.Write(9, 0x0000000000000000);
regs.Write(10, 0x0000000000000040);
regs.Write(11, 0xFFFFFFFFA4000040);
regs.Write(12, 0xFFFFFFFFBCB59510);
regs.Write(13, 0xFFFFFFFFBCB59510);
regs.Write(14, 0x000000000CF85C13);
regs.Write(15, 0x000000007A3C07F4);
regs.Write(16, 0x0000000000000000);
regs.Write(17, 0x0000000000000000);
regs.Write(18, 0x0000000000000000);
regs.Write(19, 0x0000000000000000);
regs.Write(20, 0x0000000000000001);
regs.Write(21, 0x0000000000000000);
regs.Write(23, 0x0000000000000000);
regs.Write(24, 0x0000000000000002);
regs.Write(25, 0x00000000465E3F72);
regs.Write(26, 0x0000000000000000);
regs.Write(27, 0x0000000000000000);
regs.Write(28, 0x0000000000000000);
regs.Write(29, 0xFFFFFFFFA4001FF0);
regs.Write(30, 0x0000000000000000);
regs.Write(31, 0xFFFFFFFFA4001550);
regs.lo = 0x000000007A3C07F4;
regs.hi = 0x0000000023953898;
if (pal) {
regs.gpr[20] = 0x0000000000000000;
regs.gpr[23] = 0x0000000000000006;
regs.gpr[31] = 0xFFFFFFFFA4001554ll;
regs.Write(20, 0x0000000000000000);
regs.Write(23, 0x0000000000000006);
regs.Write(31, 0xFFFFFFFFA4001554);
}
break;
}
regs.gpr[22] = (cicSeeds[cicType] >> 8) & 0xFF;
regs.Write(22, (cicSeeds[cicType] >> 8) & 0xFF);
regs.cop0.Reset();
mem.Write<u32>(regs, 0x04300004, 0x01010101);
std::copy(mem.rom.cart.begin(), mem.rom.cart.begin() + 0x1000, mem.mmio.rsp.dmem.begin());

View File

@@ -30,4 +30,80 @@ void Registers::SetPC32(s32 val) {
pc = s64(val);
nextPC = pc + 4;
}
template <> u64 Registers::Read<u64>(size_t idx) {
return idx == 0 ? 0 : gpr[idx];
}
template <> s64 Registers::Read<s64>(size_t idx) {
return s64(Read<u64>(idx));
}
template <> u32 Registers::Read<u32>(size_t idx) {
return idx == 0 ? 0 : gpr[idx];
}
template <> s32 Registers::Read<s32>(size_t idx) {
return s32(Read<u32>(idx));
}
template <> u16 Registers::Read<u16>(size_t idx) {
return idx == 0 ? 0 : gpr[idx];
}
template <> s16 Registers::Read<s16>(size_t idx) {
return s16(Read<u16>(idx));
}
template <> u8 Registers::Read<u8>(size_t idx) {
return idx == 0 ? 0 : gpr[idx];
}
template <> s8 Registers::Read<s8>(size_t idx) {
return s8(Read<u8>(idx));
}
template <> void Registers::Write<bool>(size_t idx, bool v) {
if(idx == 0) return;
gpr[idx] = v;
}
template <> void Registers::Write<u64>(size_t idx, u64 v) {
if(idx == 0) return;
gpr[idx] = v;
}
template <> void Registers::Write<s64>(size_t idx, s64 v) {
Write<u64>(idx, v);
}
template <> void Registers::Write<u32>(size_t idx, u32 v) {
if(idx == 0) return;
gpr[idx] = (u32)v;
}
template <> void Registers::Write<s32>(size_t idx, s32 v) {
if(idx == 0) return;
gpr[idx] = v;
}
template <> void Registers::Write<u16>(size_t idx, u16 v) {
if(idx == 0) return;
gpr[idx] = (u16)v;
}
template <> void Registers::Write<s16>(size_t idx, s16 v) {
if(idx == 0) return;
gpr[idx] = v;
}
template <> void Registers::Write<u8>(size_t idx, u8 v) {
if(idx == 0) return;
gpr[idx] = (u8)v;
}
template <> void Registers::Write<s8>(size_t idx, s8 v) {
if(idx == 0) return;
gpr[idx] = v;
}
}

View File

@@ -7,7 +7,6 @@ struct Registers {
void Reset();
void SetPC64(s64);
void SetPC32(s32);
s64 gpr[32]{};
Cop0 cop0;
Cop1 cop1;
s64 oldPC{}, pc{}, nextPC{};
@@ -25,5 +24,12 @@ struct Registers {
extraCycles = 0;
return ret;
}
template <typename T>
T Read(size_t);
template <typename T>
void Write(size_t, T);
private:
s64 gpr[32]{};
};
}

View File

@@ -4,19 +4,19 @@
namespace n64 {
void Cop0::mtc0(u32 instr) {
SetReg32(RD(instr), regs.gpr[RT(instr)]);
SetReg32(RD(instr), regs.Read<u32>(RT(instr)));
}
void Cop0::dmtc0(u32 instr) {
SetReg64(RD(instr), regs.gpr[RT(instr)]);
SetReg64(RD(instr), regs.Read<u64>(RT(instr)));
}
void Cop0::mfc0(u32 instr) {
regs.gpr[RT(instr)] = s32(GetReg32(RD(instr)));
regs.Write(RT(instr), s32(GetReg32(RD(instr))));
}
void Cop0::dmfc0(u32 instr) const {
regs.gpr[RT(instr)] = s64(GetReg64(RD(instr)));
regs.Write(RT(instr), s64(GetReg64(RD(instr))));
}
void Cop0::eret() {

View File

@@ -471,13 +471,13 @@ void Cop1::cfc1(u32 instr) {
break;
default: Util::panic("Undefined CFC1 with rd != 0 or 31");
}
regs.gpr[RT(instr)] = val;
regs.Write(RT(instr), val);
}
void Cop1::ctc1(u32 instr) {
if(!CheckFPUUsable<true>()) return;
u8 fs = RD(instr);
u32 val = regs.gpr[RT(instr)];
u32 val = regs.Read<s64>(RT(instr));
switch(fs) {
case 0: break;
case 31: {
@@ -1087,7 +1087,7 @@ template void Cop1::sdc1<Interpreter>(Interpreter&, Mem&, u32);
template void Cop1::sdc1<JIT>(JIT&, Mem&, u32);
void Cop1::lwc1Interp(Mem& mem, u32 instr) {
u64 addr = (s64)(s16)instr + regs.gpr[BASE(instr)];
u64 addr = (s64)(s16)instr + regs.Read<s64>(BASE(instr));
u32 physical;
if(!regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) {
@@ -1100,7 +1100,7 @@ void Cop1::lwc1Interp(Mem& mem, u32 instr) {
}
void Cop1::swc1Interp(Mem& mem, u32 instr) {
u64 addr = (s64)(s16)instr + regs.gpr[BASE(instr)];
u64 addr = (s64)(s16)instr + regs.Read<s64>(BASE(instr));
u32 physical;
if(!regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) {
@@ -1118,7 +1118,7 @@ void Cop1::unimplemented() {
}
void Cop1::ldc1Interp(Mem& mem, u32 instr) {
u64 addr = (s64)(s16)instr + regs.gpr[BASE(instr)];
u64 addr = (s64)(s16)instr + regs.Read<s64>(BASE(instr));
u32 physical;
if(!regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) {
@@ -1131,7 +1131,7 @@ void Cop1::ldc1Interp(Mem& mem, u32 instr) {
}
void Cop1::sdc1Interp(Mem& mem, u32 instr) {
u64 addr = (s64)(s16)instr + regs.gpr[BASE(instr)];
u64 addr = (s64)(s16)instr + regs.Read<s64>(BASE(instr));
u32 physical;
if(!regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) {
@@ -1144,21 +1144,21 @@ void Cop1::sdc1Interp(Mem& mem, u32 instr) {
void Cop1::mfc1(u32 instr) {
if(!CheckFPUUsable<true>()) return;
regs.gpr[RT(instr)] = FGR_T<s32>(regs.cop0.status, FS(instr));
regs.Write(RT(instr), FGR_T<s32>(regs.cop0.status, FS(instr)));
}
void Cop1::dmfc1(u32 instr) {
if(!CheckFPUUsable<true>()) return;
regs.gpr[RT(instr)] = FGR_S<s64>(regs.cop0.status, FS(instr));
regs.Write(RT(instr), FGR_S<s64>(regs.cop0.status, FS(instr)));
}
void Cop1::mtc1(u32 instr) {
if(!CheckFPUUsable<true>()) return;
FGR_T<s32>(regs.cop0.status, FS(instr)) = regs.gpr[RT(instr)];
FGR_T<s32>(regs.cop0.status, FS(instr)) = regs.Read<s64>(RT(instr));
}
void Cop1::dmtc1(u32 instr) {
if(!CheckFPUUsable<true>()) return;
FGR_S<u64>(regs.cop0.status, FS(instr)) = regs.gpr[RT(instr)];
FGR_S<u64>(regs.cop0.status, FS(instr)) = regs.Read<s64>(RT(instr));
}
}