have two different functions to set PC in r4300i, for word and dword + set the initial PC after PIF HLE instead of Registers constructor

This commit is contained in:
CocoSimone
2023-02-19 12:16:20 +01:00
parent abc14302cc
commit f56e1bafa2
8 changed files with 20 additions and 15 deletions

View File

@@ -21,10 +21,10 @@ void dmfc0(n64::Registers& regs, u32 instr) {
void eret(n64::Registers& regs) { void eret(n64::Registers& regs) {
if(regs.cop0.status.erl) { if(regs.cop0.status.erl) {
regs.SetPC(regs.cop0.ErrorEPC); regs.SetPC64(regs.cop0.ErrorEPC);
regs.cop0.status.erl = false; regs.cop0.status.erl = false;
} else { } else {
regs.SetPC(regs.cop0.EPC); regs.SetPC64(regs.cop0.EPC);
regs.cop0.status.exl = false; regs.cop0.status.exl = false;
} }
regs.cop0.llbit = false; regs.cop0.llbit = false;

View File

@@ -164,7 +164,7 @@ void branch_likely(Registers& regs, bool cond, s64 address) {
if (cond) { if (cond) {
regs.nextPC = address; regs.nextPC = address;
} else { } else {
regs.SetPC(regs.nextPC); regs.SetPC64(regs.nextPC);
} }
} }

View File

@@ -21,10 +21,10 @@ void Cop0::dmfc0(Registers& regs, u32 instr) {
void Cop0::eret(Registers& regs) { void Cop0::eret(Registers& regs) {
if(status.erl) { if(status.erl) {
regs.SetPC(ErrorEPC); regs.SetPC64(ErrorEPC);
status.erl = false; status.erl = false;
} else { } else {
regs.SetPC(EPC); regs.SetPC64(EPC);
status.exl = false; status.exl = false;
} }
llbit = false; llbit = false;

View File

@@ -163,7 +163,7 @@ void Interpreter::branch_likely(bool cond, s64 address) {
if (cond) { if (cond) {
regs.nextPC = address; regs.nextPC = address;
} else { } else {
regs.SetPC(regs.nextPC); regs.SetPC64(regs.nextPC);
} }
} }

View File

@@ -333,6 +333,7 @@ void DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo) {
regs.gpr[22] = (cicSeeds[cicType] >> 8) & 0xFF; regs.gpr[22] = (cicSeeds[cicType] >> 8) & 0xFF;
regs.cop0.Reset(); regs.cop0.Reset();
mem.Write32(regs, 0x04300004, 0x01010101); mem.Write32(regs, 0x04300004, 0x01010101);
regs.SetPC32(0xA4000040);
} }
void ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo) { void ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo) {

View File

@@ -274,15 +274,15 @@ void FireException(Registers& regs, ExceptionCode code, int cop, bool useOldPC)
case ExceptionCode::ReservedInstruction: case ExceptionCode::CoprocessorUnusable: case ExceptionCode::ReservedInstruction: case ExceptionCode::CoprocessorUnusable:
case ExceptionCode::Overflow: case ExceptionCode::Trap: case ExceptionCode::Overflow: case ExceptionCode::Trap:
case ExceptionCode::FloatingPointError: case ExceptionCode::Watch: case ExceptionCode::FloatingPointError: case ExceptionCode::Watch:
regs.SetPC(s64(s32(0x80000180))); regs.SetPC32(0x80000180);
break; break;
case ExceptionCode::TLBLoad: case ExceptionCode::TLBStore: case ExceptionCode::TLBLoad: case ExceptionCode::TLBStore:
if(old_exl || regs.cop0.tlbError == INVALID) { if(old_exl || regs.cop0.tlbError == INVALID) {
regs.SetPC(s64(s32(0x80000180))); regs.SetPC32(0x80000180);
} else if(Is64BitAddressing(regs.cop0, regs.cop0.badVaddr)) { } else if(Is64BitAddressing(regs.cop0, regs.cop0.badVaddr)) {
regs.SetPC(s64(s32(0x80000080))); regs.SetPC32(0x80000080);
} else { } else {
regs.SetPC(s64(s32(0x80000000))); regs.SetPC32(0x80000000);
} }
break; break;
default: Util::panic("Unhandled exception! {}\n", static_cast<u8>(code)); default: Util::panic("Unhandled exception! {}\n", static_cast<u8>(code));

View File

@@ -9,14 +9,17 @@ void Registers::Reset() {
delaySlot = false; delaySlot = false;
prevDelaySlot = false; prevDelaySlot = false;
memset(gpr, 0, 32*sizeof(s64)); memset(gpr, 0, 32*sizeof(s64));
oldPC = (s64)0xFFFFFFFFA4000040;
pc = oldPC;
nextPC = pc + 4;
} }
void Registers::SetPC(s64 val) { void Registers::SetPC64(s64 val) {
oldPC = pc; oldPC = pc;
pc = val; pc = val;
nextPC = pc + 4; nextPC = pc + 4;
} }
void Registers::SetPC32(s32 val) {
oldPC = pc;
pc = s64(val);
nextPC = pc + 4;
}
} }

View File

@@ -6,7 +6,8 @@ namespace n64 {
struct Registers { struct Registers {
Registers(); Registers();
void Reset(); void Reset();
void SetPC(s64); void SetPC64(s64);
void SetPC32(s32);
s64 gpr[32]; s64 gpr[32];
Cop0 cop0; Cop0 cop0;
Cop1 cop1; Cop1 cop1;