Cached interpreter plays Mario 64. Start looking into RSP as well
This commit is contained in:
@@ -1310,6 +1310,7 @@ void Cop1::swc1(const Instruction instr) {
|
||||
regs.cop0.HandleTLBException(addr);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
Core::GetInstance().interpreter.EvictCachedBlock(addr);
|
||||
mem.Write<u32>(physical, FGR_T<u32>(regs.cop0.status, instr.ft()));
|
||||
}
|
||||
}
|
||||
@@ -1337,6 +1338,7 @@ void Cop1::sdc1(const Instruction instr) {
|
||||
regs.cop0.HandleTLBException(addr);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
Core::GetInstance().interpreter.EvictCachedBlock(addr);
|
||||
mem.Write(physical, FGR_T<u64>(regs.cop0.status, instr.ft()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ void Interpreter::cop2Decode(const Instruction instr) {
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::Exec(const Instruction instr) {
|
||||
void Interpreter::DecodeExecute(const Instruction instr) {
|
||||
// 00rr_rccc
|
||||
switch (instr.opcode()) {
|
||||
case Instruction::SPECIAL:
|
||||
|
||||
@@ -140,7 +140,6 @@ void Interpreter::branch(const bool cond, const s64 address) {
|
||||
regs.delaySlot = true;
|
||||
if (cond) {
|
||||
regs.nextPC = address;
|
||||
Core::MaybeIdleSkip();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +147,6 @@ void Interpreter::branch_likely(const bool cond, const s64 address) {
|
||||
if (cond) {
|
||||
regs.delaySlot = true;
|
||||
regs.nextPC = address;
|
||||
Core::MaybeIdleSkip();
|
||||
} else {
|
||||
regs.SetPC64(regs.nextPC);
|
||||
}
|
||||
@@ -202,7 +200,7 @@ void Interpreter::lb(const Instruction instr) {
|
||||
|
||||
void Interpreter::lh(const Instruction instr) {
|
||||
const u64 address = regs.Read<s64>(instr.rs()) + (s16)instr;
|
||||
if (check_address_error(0b1, address)) {
|
||||
if (Core::IsAddressError(0b1, address)) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorLoad, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -220,7 +218,7 @@ void Interpreter::lh(const Instruction instr) {
|
||||
void Interpreter::lw(const Instruction instr) {
|
||||
const s16 offset = instr;
|
||||
const u64 address = regs.Read<s64>(instr.rs()) + offset;
|
||||
if (check_address_error(0b11, address)) {
|
||||
if (Core::IsAddressError(0b11, address)) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorLoad, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -243,7 +241,7 @@ void Interpreter::ll(const Instruction instr) {
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC);
|
||||
} else {
|
||||
const s32 result = mem.Read<u32>(physical);
|
||||
if (check_address_error(0b11, address)) {
|
||||
if (Core::IsAddressError(0b11, address)) {
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorLoad, 0, regs.oldPC);
|
||||
return;
|
||||
}
|
||||
@@ -287,7 +285,7 @@ void Interpreter::lwr(const Instruction instr) {
|
||||
|
||||
void Interpreter::ld(const Instruction instr) {
|
||||
const s64 address = regs.Read<s64>(instr.rs()) + (s16)instr;
|
||||
if (check_address_error(0b111, address)) {
|
||||
if (Core::IsAddressError(0b111, address)) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorLoad, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -315,7 +313,7 @@ void Interpreter::lld(const Instruction instr) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC);
|
||||
} else {
|
||||
if (check_address_error(0b111, address)) {
|
||||
if (Core::IsAddressError(0b111, address)) {
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorLoad, 0, regs.oldPC);
|
||||
} else {
|
||||
regs.Write(instr.rt(), mem.Read<u64>(paddr));
|
||||
@@ -369,7 +367,7 @@ void Interpreter::lbu(const Instruction instr) {
|
||||
|
||||
void Interpreter::lhu(const Instruction instr) {
|
||||
const s64 address = regs.Read<s64>(instr.rs()) + (s16)instr;
|
||||
if (check_address_error(0b1, address)) {
|
||||
if (Core::IsAddressError(0b1, address)) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorLoad, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -386,7 +384,7 @@ void Interpreter::lhu(const Instruction instr) {
|
||||
|
||||
void Interpreter::lwu(const Instruction instr) {
|
||||
const s64 address = regs.Read<s64>(instr.rs()) + (s16)instr;
|
||||
if (check_address_error(0b11, address)) {
|
||||
if (Core::IsAddressError(0b11, address)) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorLoad, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -409,6 +407,7 @@ void Interpreter::sb(const Instruction instr) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
EvictCachedBlock(address);
|
||||
mem.Write<u8>(paddr, regs.Read<s64>(instr.rt()));
|
||||
}
|
||||
}
|
||||
@@ -419,7 +418,7 @@ void Interpreter::sc(const Instruction instr) {
|
||||
if (regs.cop0.llbit) {
|
||||
regs.cop0.llbit = false;
|
||||
|
||||
if (check_address_error(0b11, address)) {
|
||||
if (Core::IsAddressError(0b11, address)) {
|
||||
regs.Write(instr.rt(), 0);
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorStore, 0, regs.oldPC);
|
||||
@@ -432,6 +431,7 @@ void Interpreter::sc(const Instruction instr) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
EvictCachedBlock(address);
|
||||
mem.Write<u32>(paddr, regs.Read<s64>(instr.rt()));
|
||||
regs.Write(instr.rt(), 1);
|
||||
}
|
||||
@@ -451,7 +451,7 @@ void Interpreter::scd(const Instruction instr) {
|
||||
if (regs.cop0.llbit) {
|
||||
regs.cop0.llbit = false;
|
||||
|
||||
if (check_address_error(0b111, address)) {
|
||||
if (Core::IsAddressError(0b111, address)) {
|
||||
regs.Write(instr.rt(), 0);
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorStore, 0, regs.oldPC);
|
||||
@@ -464,6 +464,7 @@ void Interpreter::scd(const Instruction instr) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
EvictCachedBlock(address);
|
||||
mem.Write<u32>(paddr, regs.Read<s64>(instr.rt()));
|
||||
regs.Write(instr.rt(), 1);
|
||||
}
|
||||
@@ -480,6 +481,7 @@ void Interpreter::sh(const Instruction instr) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
EvictCachedBlock(address);
|
||||
mem.Write<u16>(physical, regs.Read<s64>(instr.rt()));
|
||||
}
|
||||
}
|
||||
@@ -487,7 +489,7 @@ void Interpreter::sh(const Instruction instr) {
|
||||
void Interpreter::sw(const Instruction instr) {
|
||||
const s16 offset = instr;
|
||||
const u64 address = regs.Read<s64>(instr.rs()) + offset;
|
||||
if (check_address_error(0b11, address)) {
|
||||
if (Core::IsAddressError(0b11, address)) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorStore, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -498,13 +500,14 @@ void Interpreter::sw(const Instruction instr) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
EvictCachedBlock(address);
|
||||
mem.Write<u32>(physical, regs.Read<s64>(instr.rt()));
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::sd(const Instruction instr) {
|
||||
const s64 address = regs.Read<s64>(instr.rs()) + (s16)instr;
|
||||
if (check_address_error(0b111, address)) {
|
||||
if (Core::IsAddressError(0b111, address)) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::ExceptionCode::AddressErrorStore, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -515,6 +518,7 @@ void Interpreter::sd(const Instruction instr) {
|
||||
regs.cop0.HandleTLBException(address);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
EvictCachedBlock(address);
|
||||
mem.Write(physical, regs.Read<s64>(instr.rt()));
|
||||
}
|
||||
}
|
||||
@@ -530,6 +534,7 @@ void Interpreter::sdl(const Instruction instr) {
|
||||
const u64 mask = 0xFFFFFFFFFFFFFFFF >> shift;
|
||||
const u64 data = mem.Read<u64>(paddr & ~7);
|
||||
const u64 rt = regs.Read<s64>(instr.rt());
|
||||
EvictCachedBlock(address);
|
||||
mem.Write(paddr & ~7, (data & ~mask) | (rt >> shift));
|
||||
}
|
||||
}
|
||||
@@ -545,6 +550,7 @@ void Interpreter::sdr(const Instruction instr) {
|
||||
const u64 mask = 0xFFFFFFFFFFFFFFFF << shift;
|
||||
const u64 data = mem.Read<u64>(paddr & ~7);
|
||||
const u64 rt = regs.Read<s64>(instr.rt());
|
||||
EvictCachedBlock(address);
|
||||
mem.Write(paddr & ~7, (data & ~mask) | (rt << shift));
|
||||
}
|
||||
}
|
||||
@@ -560,6 +566,7 @@ void Interpreter::swl(const Instruction instr) {
|
||||
const u32 mask = 0xFFFFFFFF >> shift;
|
||||
const u32 data = mem.Read<u32>(paddr & ~3);
|
||||
const u32 rt = regs.Read<s64>(instr.rt());
|
||||
EvictCachedBlock(address);
|
||||
mem.Write<u32>(paddr & ~3, (data & ~mask) | (rt >> shift));
|
||||
}
|
||||
}
|
||||
@@ -575,6 +582,7 @@ void Interpreter::swr(const Instruction instr) {
|
||||
const u32 mask = 0xFFFFFFFF << shift;
|
||||
const u32 data = mem.Read<u32>(paddr & ~3);
|
||||
const u32 rt = regs.Read<s64>(instr.rt());
|
||||
EvictCachedBlock(address);
|
||||
mem.Write<u32>(paddr & ~3, (data & ~mask) | (rt << shift));
|
||||
}
|
||||
}
|
||||
@@ -869,12 +877,12 @@ void Interpreter::cache(const Instruction instr) {
|
||||
panic("Unknown cache type {}", type);
|
||||
|
||||
if (type == 0)
|
||||
return cache_type_instruction(op, vaddr, paddr, ptag);
|
||||
return CacheTypeInstruction(op, vaddr, paddr, ptag);
|
||||
|
||||
return cache_type_data(op, vaddr, paddr, ptag);
|
||||
return CacheTypeData(op, vaddr, paddr, ptag);
|
||||
}
|
||||
|
||||
void Interpreter::cache_type_instruction(const u8 op, const u64 vaddr, const u32 paddr, const u32 ptag) {
|
||||
void Interpreter::CacheTypeInstruction(const u8 op, const u64 vaddr, const u32 paddr, const u32 ptag) {
|
||||
switch (op) {
|
||||
case 0:
|
||||
icache.InvalidateIndex(vaddr);
|
||||
@@ -899,7 +907,7 @@ void Interpreter::cache_type_instruction(const u8 op, const u64 vaddr, const u32
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::cache_type_data(const u8 op, const u64 vaddr, const u32 paddr, const u32 ptag) {
|
||||
void Interpreter::CacheTypeData(const u8 op, const u64 vaddr, const u32 paddr, const u32 ptag) {
|
||||
switch (op) {
|
||||
case 0:
|
||||
dcache.WriteBack<true>(vaddr, paddr);
|
||||
|
||||
Reference in New Issue
Block a user