reduce branching in emulation of CPU/RSP parallelization

This commit is contained in:
CocoSimone
2022-12-12 02:47:16 +01:00
parent 30a0a43d08
commit 23bdd74f8a
5 changed files with 37 additions and 35 deletions

View File

@@ -33,7 +33,7 @@ CartInfo Core::LoadROM(const std::string& rom_) {
void Core::Run(Window& window, float volumeL, float volumeR) {
MMIO& mmio = mem.mmio;
Controller& controller = mmio.si.controller;
int cpuSteps = 0;
for(int field = 0; field < mmio.vi.numFields; field++) {
int frameCycles = 0;
if(!pause && romLoaded) {
@@ -46,14 +46,11 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
for(;cycles <= mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) {
cpu.Step(mem);
cpuSteps++;
if(mmio.rsp.spStatus.halt) {
mmio.rsp.steps = 0;
cpuSteps = 0;
} else {
if(cpuSteps > 2) {
if(!mmio.rsp.spStatus.halt) {
cpu.regs.steps++;
if(cpu.regs.steps > 2) {
mmio.rsp.steps += 2;
cpuSteps -= 3;
cpu.regs.steps -= 3;
}
while(mmio.rsp.steps > 0) {

View File

@@ -53,13 +53,13 @@ void Cpu::Step(Mem& mem) {
regs.prevDelaySlot = regs.delaySlot;
regs.delaySlot = false;
u32 instruction = mem.Read32(regs, regs.pc, regs.pc);
if(ShouldServiceInterrupt(regs)) {
FireException(regs, ExceptionCode::Interrupt, 0, regs.pc);
return;
}
u32 instruction = mem.Read32(regs, regs.pc, regs.pc);
regs.oldPC = regs.pc;
regs.pc = regs.nextPC;
regs.nextPC += 4;

View File

@@ -1,6 +1,7 @@
#include <n64/core/RSP.hpp>
#include <util.hpp>
#include <n64/core/Mem.hpp>
#include <n64/core/cpu/Registers.hpp>
namespace n64 {
RSP::RSP() {
@@ -90,6 +91,32 @@ auto RSP::Read(u32 addr) -> u32{
}
}
void RSP::WriteStatus(MI& mi, Registers& regs, u32 value) {
auto write = SPStatusWrite{.raw = value};
if(write.clearHalt && !write.setHalt) {
spStatus.halt = false;
}
if(write.setHalt && !write.clearHalt) {
regs.steps = 0;
spStatus.halt = true;
}
if(write.clearBroke) spStatus.broke = false;
if(write.clearIntr && !write.setIntr)
InterruptLower(mi, regs, Interrupt::SP);
if(write.setIntr && !write.clearIntr)
InterruptRaise(mi, regs, Interrupt::SP);
CLEAR_SET(spStatus.singleStep, write.clearSstep, write.setSstep);
CLEAR_SET(spStatus.interruptOnBreak, write.clearIntrOnBreak, write.setIntrOnBreak);
CLEAR_SET(spStatus.signal0, write.clearSignal0, write.setSignal0);
CLEAR_SET(spStatus.signal1, write.clearSignal1, write.setSignal1);
CLEAR_SET(spStatus.signal2, write.clearSignal2, write.setSignal2);
CLEAR_SET(spStatus.signal3, write.clearSignal3, write.setSignal3);
CLEAR_SET(spStatus.signal4, write.clearSignal4, write.setSignal4);
CLEAR_SET(spStatus.signal5, write.clearSignal5, write.setSignal5);
CLEAR_SET(spStatus.signal6, write.clearSignal6, write.setSignal6);
CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7);
}
void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) {
MI& mi = mem.mmio.mi;
switch (addr) {

View File

@@ -194,31 +194,6 @@ struct RSP {
return value;
}
inline void WriteStatus(MI& mi, Registers& regs, u32 value) {
auto write = SPStatusWrite{.raw = value};
if(write.clearHalt && !write.setHalt) {
spStatus.halt = false;
}
if(write.setHalt && !write.clearHalt) {
spStatus.halt = true;
}
if(write.clearBroke) spStatus.broke = false;
if(write.clearIntr && !write.setIntr)
InterruptLower(mi, regs, Interrupt::SP);
if(write.setIntr && !write.clearIntr)
InterruptRaise(mi, regs, Interrupt::SP);
CLEAR_SET(spStatus.singleStep, write.clearSstep, write.setSstep);
CLEAR_SET(spStatus.interruptOnBreak, write.clearIntrOnBreak, write.setIntrOnBreak);
CLEAR_SET(spStatus.signal0, write.clearSignal0, write.setSignal0);
CLEAR_SET(spStatus.signal1, write.clearSignal1, write.setSignal1);
CLEAR_SET(spStatus.signal2, write.clearSignal2, write.setSignal2);
CLEAR_SET(spStatus.signal3, write.clearSignal3, write.setSignal3);
CLEAR_SET(spStatus.signal4, write.clearSignal4, write.setSignal4);
CLEAR_SET(spStatus.signal5, write.clearSignal5, write.setSignal5);
CLEAR_SET(spStatus.signal6, write.clearSignal6, write.setSignal6);
CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7);
}
inline u32 ReadWord(u32 addr) {
addr &= 0xfff;
return GET_RSP_WORD(addr);
@@ -400,6 +375,8 @@ struct RSP {
rsp.lastSuccessfulDRAMAddr.address = dram_address;
rsp.spDMALen.raw = 0xFF8 | (rsp.spDMALen.skip << 20);
}
void WriteStatus(MI& mi, Registers& regs, u32 value);
private:
inline void branch(u16 address, bool cond) {
if(cond) {

View File

@@ -13,5 +13,6 @@ struct Registers {
s64 oldPC, pc, nextPC;
s64 hi, lo;
bool prevDelaySlot, delaySlot;
int steps = 0;
};
}