Refactor many other things

This commit is contained in:
SimoneN64
2024-05-13 20:54:53 +02:00
committed by Simone
parent 5148a836a1
commit 059f884ca7
23 changed files with 150 additions and 141 deletions

View File

@@ -3,18 +3,6 @@
#include <ParallelRDPWrapper.hpp>
namespace n64 {
u32 extraCycles = 0;
void CpuStall(u32 cycles) {
extraCycles += cycles;
}
u32 PopStalledCycles() {
u32 ret = extraCycles;
extraCycles = 0;
return ret;
}
Core::Core() : cpu(std::make_unique<Interpreter>()) {}
void Core::Stop() {
@@ -71,7 +59,7 @@ void Core::Run(float volumeL, float volumeR) {
for(; cycles < mem.mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) {
u32 taken = cpu->Step();
taken += PopStalledCycles();
taken += regs.PopStalledCycles();
static u32 cpuSteps = 0;
cpuSteps += taken;
if(mmio.rsp.spStatus.halt) {
@@ -91,7 +79,7 @@ void Core::Run(float volumeL, float volumeR) {
cycles += taken;
frameCycles += taken;
scheduler.Tick(taken, mem, regs);
scheduler.Tick(taken, mem);
}
cycles -= mmio.vi.cyclesPerHalfline;
@@ -101,8 +89,8 @@ void Core::Run(float volumeL, float volumeR) {
mmio.mi.InterruptRaise(MI::Interrupt::VI);
}
mmio.ai.Step(cpu->mem, regs, frameCycles, volumeL, volumeR);
scheduler.Tick(frameCycles, mem, regs);
mmio.ai.Step(frameCycles, volumeL, volumeR);
scheduler.Tick(frameCycles, mem);
}
}

View File

@@ -30,8 +30,4 @@ struct Core {
size_t memSize{}, cpuSize{}, verSize{};
int slot = 0;
};
extern u32 extraCycles;
void CpuStall(u32 cycles);
u32 PopStalledCycles();
}

View File

@@ -25,7 +25,7 @@ u64 Scheduler::Remove(EventType type) {
return 0;
}
void Scheduler::Tick(u64 t, n64::Mem& mem, n64::Registers& regs) {
void Scheduler::Tick(u64 t, n64::Mem& mem) {
ticks += t;
n64::MI& mi = mem.mmio.mi;
n64::SI& si = mem.mmio.si;
@@ -34,7 +34,7 @@ void Scheduler::Tick(u64 t, n64::Mem& mem, n64::Registers& regs) {
while(ticks >= events.top().time) {
switch(auto type = events.top().type) {
case SI_DMA:
si.DMA(mem, regs);
si.DMA();
break;
case PI_DMA_COMPLETE:
mi.InterruptRaise(n64::MI::Interrupt::PI);

View File

@@ -53,7 +53,7 @@ struct Scheduler {
void EnqueueRelative(u64, EventType);
void EnqueueAbsolute(u64, EventType);
u64 Remove(EventType);
void Tick(u64 t, n64::Mem&, n64::Registers&);
void Tick(u64 t, n64::Mem&);
IterableEvents events;
u64 ticks = 0;

View File

@@ -1,7 +1,5 @@
#include <core/MMIO.hpp>
#include <log.hpp>
#include <core/Mem.hpp>
#include <core/registers/Registers.hpp>
namespace n64 {
void MMIO::Reset() {
@@ -22,24 +20,24 @@ u32 MMIO::Read(u32 addr) {
case MI_REGION: return mi.Read(addr);
case VI_REGION: return vi.Read(addr);
case AI_REGION: return ai.Read(addr);
case PI_REGION: return pi.Read(mi, addr);
case PI_REGION: return pi.Read(addr);
case RI_REGION: return ri.Read(addr);
case SI_REGION: return si.Read(mi, addr);
case SI_REGION: return si.Read(addr);
default:
Util::panic("Unhandled mmio read at addr {:08X}", addr);
}
}
void MMIO::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
void MMIO::Write(u32 addr, u32 val) {
switch (addr) {
case RSP_REGION: rsp.Write(addr, val); break;
case RDP_REGION: rdp.Write(mi, regs, rsp, addr, val); break;
case MI_REGION: mi.Write(regs, addr, val); break;
case VI_REGION: vi.Write(mi, regs, addr, val); break;
case AI_REGION: ai.Write(mem, regs, addr, val); break;
case PI_REGION: pi.Write(mem, regs, addr, val); break;
case RDP_REGION: rdp.Write(addr, val); break;
case MI_REGION: mi.Write(addr, val); break;
case VI_REGION: vi.Write(addr, val); break;
case AI_REGION: ai.Write(addr, val); break;
case PI_REGION: pi.Write(addr, val); break;
case RI_REGION: ri.Write(addr, val); break;
case SI_REGION: si.Write(mem, regs, addr, val); break;
case SI_REGION: si.Write(addr, val); break;
default:
Util::panic("Unhandled mmio write at addr {:08X} with val {:08X}", addr, val);
}

View File

@@ -13,7 +13,7 @@ struct Mem;
struct Registers;
struct MMIO {
MMIO(Mem& mem, Registers& regs) : mi(regs), si(mem, regs), rsp(mem, regs) {}
MMIO(Mem& mem, Registers& regs) : vi(mem, regs), mi(regs), ai(mem, regs), pi(mem, regs), si(mem, regs), rsp(mem, regs), rdp(mem, regs) {}
void Reset();
VI vi;
@@ -26,7 +26,7 @@ struct MMIO {
RDP rdp;
u32 Read(u32);
void Write(Mem&, Registers&, u32, u32);
void Write(u32, u32);
std::vector<u8> Serialize();
void Deserialize(const std::vector<u8>&);
};

View File

@@ -193,7 +193,7 @@ template<> u8 Mem::Read(n64::Registers &regs, u32 paddr) {
return src[BYTE_ADDRESS(paddr & 0xfff)];
}
case REGION_CART:
return mmio.pi.BusRead<u8, false>(*this, paddr);
return mmio.pi.BusRead<u8, false>(paddr);
case 0x04040000 ... 0x040FFFFF:
case 0x04100000 ... 0x041FFFFF:
case 0x04600000 ... 0x048FFFFF:
@@ -238,7 +238,7 @@ template<> u16 Mem::Read(n64::Registers &regs, u32 paddr) {
case MMIO_REGION:
return mmio.Read(paddr);
case REGION_CART:
return mmio.pi.BusRead<u16, false>(*this, paddr);
return mmio.pi.BusRead<u16, false>(paddr);
case PIF_ROM_REGION:
return Util::ReadAccess<u16>(si.pif.bootrom, HALF_ADDRESS(paddr) - PIF_ROM_REGION_START);
case PIF_RAM_REGION:
@@ -273,7 +273,7 @@ template<> u32 Mem::Read(n64::Registers &regs, u32 paddr) {
case MMIO_REGION:
return mmio.Read(paddr);
case REGION_CART:
return mmio.pi.BusRead<u32, false>(*this, paddr);
return mmio.pi.BusRead<u32, false>(paddr);
case PIF_ROM_REGION:
return Util::ReadAccess<u32>(si.pif.bootrom, paddr - PIF_ROM_REGION_START);
case PIF_RAM_REGION:
@@ -305,7 +305,7 @@ template<> u64 Mem::Read(n64::Registers &regs, u32 paddr) {
case MMIO_REGION:
return mmio.Read(paddr);
case REGION_CART:
return mmio.pi.BusRead<u64, false>(*this, paddr);
return mmio.pi.BusRead<u64, false>(paddr);
case PIF_ROM_REGION:
return Util::ReadAccess<u64>(si.pif.bootrom, paddr - PIF_ROM_REGION_START);
case PIF_RAM_REGION:
@@ -342,7 +342,7 @@ template<> void Mem::Write<u8>(Registers& regs, u32 paddr, u32 val) {
} break;
case REGION_CART:
Util::trace("BusWrite<u8> @ {:08X} = {:02X}", paddr, val);
mmio.pi.BusWrite<u8, false>(*this, paddr, val);
mmio.pi.BusWrite<u8, false>(paddr, val);
break;
case MMIO_REGION:
Util::panic("MMIO Write<u8>!");
@@ -387,7 +387,7 @@ template<> void Mem::Write<u16>(Registers& regs, u32 paddr, u32 val) {
} break;
case REGION_CART:
Util::trace("BusWrite<u8> @ {:08X} = {:04X}", paddr, val);
mmio.pi.BusWrite<u16, false>(*this, paddr, val);
mmio.pi.BusWrite<u16, false>(paddr, val);
break;
case MMIO_REGION:
Util::panic("MMIO Write<u16>!");
@@ -430,10 +430,10 @@ template<> void Mem::Write<u32>(Registers& regs, u32 paddr, u32 val) {
} break;
case REGION_CART:
Util::trace("BusWrite<u8> @ {:08X} = {:08X}", paddr, val);
mmio.pi.BusWrite<u32, false>(*this, paddr, val);
mmio.pi.BusWrite<u32, false>(paddr, val);
break;
case MMIO_REGION:
mmio.Write(*this, regs, paddr, val);
mmio.Write(paddr, val);
break;
case PIF_RAM_REGION:
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(val));
@@ -470,7 +470,7 @@ void Mem::Write(Registers& regs, u32 paddr, u64 val) {
} break;
case REGION_CART:
Util::trace("BusWrite<u8> @ {:08X} = {:016X}", paddr, val);
mmio.pi.BusWrite<false>(*this, paddr, val);
mmio.pi.BusWrite<false>(paddr, val);
break;
case MMIO_REGION:
Util::panic("MMIO Write!");

View File

@@ -5,7 +5,7 @@
#include <core/mmio/Interrupt.hpp>
namespace n64 {
RDP::RDP() {
RDP::RDP(Mem& mem, Registers& regs) : mem(mem), regs(regs) {
rdram.resize(RDRAM_SIZE);
memset(cmd_buf, 0, 0x100000);
dpc.status.raw = 0x80;
@@ -40,17 +40,17 @@ auto RDP::Read(u32 addr) const -> u32 {
}
}
void RDP::Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val) {
void RDP::Write(u32 addr, u32 val) {
switch(addr) {
case 0x04100000: WriteStart(val); break;
case 0x04100004: WriteEnd(mi, regs, rsp, val); break;
case 0x0410000C: WriteStatus(mi, regs, rsp, val); break;
case 0x04100004: WriteEnd(val); break;
case 0x0410000C: WriteStatus(val); break;
default:
Util::panic("Unhandled DP Command Registers write (addr: {:08X}, val: {:08X})", addr, val);
}
}
void RDP::WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val) {
void RDP::WriteStatus(u32 val) {
DPCStatusWrite temp{};
temp.raw = val;
@@ -69,7 +69,7 @@ void RDP::WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val) {
CLEAR_SET(dpc.status.tmemBusy, temp.clearTmem, false);
if(!dpc.status.freeze) {
RunCommand(mi, regs, rsp);
RunCommand();
}
}
/*
@@ -114,7 +114,7 @@ FORCE_INLINE void logCommand(u8 cmd) {
}
*/
void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
void RDP::RunCommand() {
if (dpc.status.freeze) {
return;
}
@@ -138,7 +138,7 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
if (dpc.status.xbusDmemDma) {
for (int i = 0; i < len; i += 4) {
u32 cmd = Util::ReadAccess<u32>(rsp.dmem, (current + i) & 0xFFF);
u32 cmd = Util::ReadAccess<u32>(mem.mmio.rsp.dmem, (current + i) & 0xFFF);
cmd_buf[remaining_cmds + (i >> 2)] = cmd;
}
} else {
@@ -181,7 +181,7 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
}
if (cmd == 0x29) {
OnFullSync(mi, regs);
OnFullSync();
}
buf_index += cmd_len;
@@ -198,12 +198,12 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
dpc.status.cbufReady = true;
}
void RDP::OnFullSync(MI& mi, Registers& regs) {
void RDP::OnFullSync() {
ParallelRdpOnFullSync();
dpc.status.pipeBusy = false;
dpc.status.startGclk = false;
dpc.status.cbufReady = false;
mi.InterruptRaise(MI::Interrupt::DP);
mem.mmio.mi.InterruptRaise(MI::Interrupt::DP);
}
}

View File

@@ -5,7 +5,7 @@
namespace n64 {
struct RSP;
struct MI;
struct Mem;
struct Registers;
union DPCStatusWrite {
@@ -54,15 +54,15 @@ struct RDP {
DPC dpc{};
u32 cmd_buf[0xFFFFF]{};
RDP();
RDP(Mem&, Registers&);
void Reset();
std::vector<u8> rdram{};
[[nodiscard]] auto Read(u32 addr) const -> u32;
void Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val);
void WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val);
void RunCommand(MI& mi, Registers& regs, RSP& rsp);
void OnFullSync(MI& mi, Registers& regs);
void Write(u32 addr, u32 val);
void WriteStatus(u32 val);
void RunCommand();
void OnFullSync();
FORCE_INLINE void WriteStart(u32 val) {
if(!dpc.status.startValid) {
@@ -71,13 +71,16 @@ struct RDP {
dpc.status.startValid = true;
}
FORCE_INLINE void WriteEnd(MI& mi, Registers& regs, RSP& rsp, u32 val) {
FORCE_INLINE void WriteEnd(u32 val) {
dpc.end = val & 0xFFFFF8;
if(dpc.status.startValid) {
dpc.current = dpc.start;
dpc.status.startValid = false;
}
RunCommand(mi, regs, rsp);
RunCommand();
}
private:
Mem& mem;
Registers& regs;
};
} // backend

View File

@@ -110,26 +110,26 @@ void RSP::WriteStatus(u32 value) {
CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7);
}
void RSP::Write(u32 addr, u32 value) {
void RSP::Write(u32 addr, u32 val) {
switch (addr) {
case 0x04040000: spDMASPAddr.raw = value & 0x1FF8; break;
case 0x04040004: spDMADRAMAddr.raw = value & 0xFFFFF8; break;
case 0x04040000: spDMASPAddr.raw = val & 0x1FF8; break;
case 0x04040004: spDMADRAMAddr.raw = val & 0xFFFFF8; break;
case 0x04040008: {
spDMALen.raw = value;
spDMALen.raw = val;
DMAtoRSP(mem.GetRDRAM());
} break;
case 0x0404000C: {
spDMALen.raw = value;
spDMALen.raw = val;
DMAtoRDRAM(mem.GetRDRAM());
} break;
case 0x04040010: WriteStatus(value); break;
case 0x04040010: WriteStatus(val); break;
case 0x0404001C: ReleaseSemaphore(); break;
case 0x04080000:
if(spStatus.halt) {
SetPC(value);
SetPC(val);
} break;
default:
Util::panic("Unimplemented SP register write {:08X}, val: {:08X}", addr, value);
Util::panic("Unimplemented SP register write {:08X}, val: {:08X}", addr, val);
}
}

View File

@@ -126,7 +126,7 @@ struct RSP {
Exec(instr);
}
auto Read(u32 addr) -> u32;
void Write(u32 addr, u32 value);
void Write(u32 addr, u32 val);
void Exec(u32 instr);
SPStatus spStatus{};
u16 oldPC{}, pc{}, nextPC{};

View File

@@ -4,6 +4,8 @@
#include <core/registers/Registers.hpp>
namespace n64 {
AI::AI(Mem &mem, Registers &regs) : mem(mem), regs(regs) { }
void AI::Reset() {
dmaEnable = false;
dacRate = 0;
@@ -33,7 +35,7 @@ auto AI::Read(u32 addr) const -> u32 {
return dmaLen[0];
}
void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
void AI::Write(u32 addr, u32 val) {
switch(addr) {
case 0x04500000:
if(dmaCount < 2) {
@@ -72,7 +74,7 @@ void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
}
}
void AI::Step(Mem& mem, Registers& regs, u32 cpuCycles, float volumeL, float volumeR) {
void AI::Step(u32 cpuCycles, float volumeL, float volumeR) {
cycles += cpuCycles;
while(cycles > dac.period) {
if (dmaCount == 0) {

View File

@@ -8,11 +8,11 @@ struct Mem;
struct Registers;
struct AI {
AI() = default;
AI(Mem&, Registers& regs);
void Reset();
auto Read(u32) const -> u32;
void Write(Mem&, Registers&, u32, u32);
void Step(Mem&, Registers&, u32, float, float);
void Write(u32, u32);
void Step(u32, float, float);
bool dmaEnable{};
u16 dacRate{};
u8 bitrate{};
@@ -28,5 +28,8 @@ struct AI {
u32 period{N64_CPU_FREQ / freq};
u32 precision{16};
} dac;
private:
Mem& mem;
Registers& regs;
};
}

View File

@@ -27,7 +27,7 @@ auto MI::Read(u32 paddr) const -> u32 {
}
}
void MI::Write(Registers& regs, u32 paddr, u32 val) {
void MI::Write(u32 paddr, u32 val) {
switch(paddr & 0xF) {
case 0x0:
miMode &= 0xFFFFFF80;

View File

@@ -26,7 +26,7 @@ struct MI {
MI(Registers&);
void Reset();
[[nodiscard]] auto Read(u32) const -> u32;
void Write(Registers& regs, u32, u32);
void Write(u32, u32);
void InterruptRaise(Interrupt intr);
void InterruptLower(Interrupt intr);
void UpdateInterrupt();

View File

@@ -4,7 +4,7 @@
#include <Scheduler.hpp>
namespace n64 {
PI::PI() {
PI::PI(Mem& mem, Registers& regs) : mem(mem), regs(regs) {
Reset();
}
@@ -42,13 +42,13 @@ bool PI::WriteLatch(u32 value) {
bool PI::ReadLatch() {
if (ioBusy) [[unlikely]] {
ioBusy = false;
CpuStall(scheduler.Remove(PI_BUS_WRITE_COMPLETE));
regs.CpuStall(scheduler.Remove(PI_BUS_WRITE_COMPLETE));
return false;
}
return true;
}
template<> auto PI::BusRead<u8, true>(Mem& mem, u32 addr) -> u8 {
template<> auto PI::BusRead<u8, true>(u32 addr) -> u8 {
switch (addr) {
case REGION_PI_UNKNOWN:
Util::panic("Reading byte from address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN - This is the N64DD, returning FF because it is not emulated", addr);
@@ -73,7 +73,7 @@ template<> auto PI::BusRead<u8, true>(Mem& mem, u32 addr) -> u8 {
}
}
template<> auto PI::BusRead<u8, false>(Mem& mem, u32 addr) -> u8 {
template<> auto PI::BusRead<u8, false>(u32 addr) -> u8 {
if (!ReadLatch()) [[unlikely]] {
return latch >> 24;
}
@@ -103,7 +103,7 @@ template<> auto PI::BusRead<u8, false>(Mem& mem, u32 addr) -> u8 {
}
}
template<> void PI::BusWrite<u8, true>(Mem& mem, u32 addr, u32 val) {
template<> void PI::BusWrite<u8, true>(u32 addr, u32 val) {
switch (addr) {
case REGION_PI_UNKNOWN:
Util::panic("Writing byte 0x{:02X} to address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN", val, addr);
@@ -127,17 +127,17 @@ template<> void PI::BusWrite<u8, true>(Mem& mem, u32 addr, u32 val) {
}
}
template<> void PI::BusWrite<u8, false>(Mem& mem, u32 addr, u32 val) {
template<> void PI::BusWrite<u8, false>(u32 addr, u32 val) {
u8 latch_shift = 24 - (addr & 1) * 8;
if (!WriteLatch(val << latch_shift) && addr != 0x05000020) [[unlikely]] {
return;
}
BusWrite<u8, true>(mem, addr, val);
BusWrite<u8, true>(addr, val);
}
template <> auto PI::BusRead<u16, false>(Mem& mem, u32 addr) -> u16 {
template <> auto PI::BusRead<u16, false>(u32 addr) -> u16 {
if (!ReadLatch()) [[unlikely]] {
return latch >> 16;
}
@@ -164,11 +164,11 @@ template <> auto PI::BusRead<u16, false>(Mem& mem, u32 addr) -> u16 {
}
}
template <> auto PI::BusRead<u16, true>(Mem& mem, u32 addr) -> u16 {
return BusRead<u16, false>(mem, addr);
template <> auto PI::BusRead<u16, true>(u32 addr) -> u16 {
return BusRead<u16, false>(addr);
}
template <> void PI::BusWrite<u16, false>(Mem&, u32 addr, u32 val) {
template <> void PI::BusWrite<u16, false>(u32 addr, u32 val) {
if (!WriteLatch(val << 16)) [[unlikely]] {
return;
}
@@ -190,11 +190,11 @@ template <> void PI::BusWrite<u16, false>(Mem&, u32 addr, u32 val) {
}
}
template <> void PI::BusWrite<u16, true>(Mem& mem, u32 addr, u32 val) {
BusWrite<u16, false>(mem, addr, val);
template <> void PI::BusWrite<u16, true>(u32 addr, u32 val) {
BusWrite<u16, false>(addr, val);
}
template <> auto PI::BusRead<u32, false>(Mem& mem, u32 addr) -> u32 {
template <> auto PI::BusRead<u32, false>(u32 addr) -> u32 {
if (!ReadLatch()) [[unlikely]] {
return latch;
}
@@ -232,11 +232,11 @@ template <> auto PI::BusRead<u32, false>(Mem& mem, u32 addr) -> u32 {
}
}
template <> auto PI::BusRead<u32, true>(Mem& mem, u32 addr) -> u32 {
return BusRead<u32, false>(mem, addr);
template <> auto PI::BusRead<u32, true>(u32 addr) -> u32 {
return BusRead<u32, false>(addr);
}
template <> void PI::BusWrite<u32, false>(Mem& mem, u32 addr, u32 val) {
template <> void PI::BusWrite<u32, false>(u32 addr, u32 val) {
switch (addr) {
case REGION_PI_UNKNOWN:
if (!WriteLatch(val)) [[unlikely]] {
@@ -293,11 +293,11 @@ template <> void PI::BusWrite<u32, false>(Mem& mem, u32 addr, u32 val) {
}
template <>
void PI::BusWrite<u32, true>(Mem& mem, u32 addr, u32 val) {
BusWrite<u32, false>(mem, addr, val);
void PI::BusWrite<u32, true>(u32 addr, u32 val) {
BusWrite<u32, false>(addr, val);
}
template <> auto PI::BusRead<u64, false>(Mem& mem, u32 addr) -> u64 {
template <> auto PI::BusRead<u64, false>(u32 addr) -> u64 {
if (!ReadLatch()) [[unlikely]] {
return (u64)latch << 32;
}
@@ -323,11 +323,11 @@ template <> auto PI::BusRead<u64, false>(Mem& mem, u32 addr) -> u64 {
}
}
template <> auto PI::BusRead<u64, true>(Mem& mem, u32 addr) -> u64 {
return BusRead<u64, false>(mem, addr);
template <> auto PI::BusRead<u64, true>(u32 addr) -> u64 {
return BusRead<u64, false>(addr);
}
template <> void PI::BusWrite<false>(Mem&, u32 addr, u64 val) {
template <> void PI::BusWrite<false>(u32 addr, u64 val) {
if (!WriteLatch(val >> 32)) [[unlikely]] {
return;
}
@@ -349,11 +349,11 @@ template <> void PI::BusWrite<false>(Mem&, u32 addr, u64 val) {
}
}
template <> void PI::BusWrite<true>(Mem& mem, u32 addr, u64 val) {
BusWrite<false>(mem, addr, val);
template <> void PI::BusWrite<true>(u32 addr, u64 val) {
BusWrite<false>(addr, val);
}
auto PI::Read(MI& mi, u32 addr) const -> u32 {
auto PI::Read(u32 addr) const -> u32 {
switch(addr) {
case 0x04600000: return dramAddr;
case 0x04600004: return cartAddr;
@@ -364,7 +364,7 @@ auto PI::Read(MI& mi, u32 addr) const -> u32 {
value |= (dmaBusy << 0); // Is PI DMA active? No, because it's instant
value |= (ioBusy << 1); // Is PI IO busy? No, because it's instant
value |= (0 << 2); // PI IO error?
value |= (mi.miIntr.pi << 3); // PI interrupt?
value |= (mem.mmio.mi.miIntr.pi << 3); // PI interrupt?
return value;
}
case 0x04600014: return piBsdDom1Lat;
@@ -427,7 +427,7 @@ u32 PI::AccessTiming(u8 domain, u32 length) const {
return cycles * 1.5; // Converting RCP clock speed to CPU clock speed
}
void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
void PI::Write(u32 addr, u32 val) {
MI& mi = mem.mmio.mi;
switch(addr) {
case 0x04600000: dramAddr = val & 0xFFFFFF; break;
@@ -444,7 +444,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
Util::panic("PI DMA RDRAM->CART ADDRESS TOO HIGH");
}
for (int i = 0; i < len; i++) {
BusWrite<u8, true>(mem, cartAddrInternal + i, mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE]);
BusWrite<u8, true>(cartAddrInternal + i, mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE]);
}
Util::trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr);
dmaBusy = true;
@@ -465,7 +465,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
}
for(u32 i = 0; i < len; i++) {
mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE] = BusRead<u8, true>(mem, cartAddrInternal + i);
mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE] = BusRead<u8, true>(cartAddrInternal + i);
}
dmaBusy = true;
Util::trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr);

View File

@@ -8,18 +8,18 @@ struct Mem;
struct Registers;
struct PI {
PI();
PI(Mem&, Registers&);
void Reset();
auto Read(MI&, u32) const -> u32;
void Write(Mem&, Registers&, u32, u32);
auto Read(u32) const -> u32;
void Write(u32, u32);
template<typename T, bool isDma>
void BusWrite(Mem&, u32, u32);
void BusWrite(u32, u32);
template<bool isDma>
void BusWrite(Mem&, u32, u64);
void BusWrite(u32, u64);
template<typename T, bool isDma>
auto BusRead(Mem&, u32) -> T;
auto BusRead(u32) -> T;
bool ReadLatch();
bool WriteLatch(u32 val);
@@ -34,5 +34,8 @@ struct PI {
u32 piBsdDom1Pwd{}, piBsdDom2Pwd{};
u32 piBsdDom1Pgs{}, piBsdDom2Pgs{};
u32 piBsdDom1Rls{}, piBsdDom2Rls{};
private:
Mem& mem;
Registers& regs;
};
}

View File

@@ -3,7 +3,7 @@
#include <Scheduler.hpp>
namespace n64 {
SI::SI(Mem& mem, Registers& regs) : pif(mem, regs) {
SI::SI(Mem& mem, Registers& regs) : mem(mem), regs(regs), pif(mem, regs) {
Reset();
}
@@ -14,7 +14,7 @@ void SI::Reset() {
pif.Reset();
}
auto SI::Read(MI& mi, u32 addr) const -> u32 {
auto SI::Read(u32 addr) const -> u32 {
switch(addr) {
case 0x04800000: return dramAddr;
case 0x04800004: case 0x04800010: return pifAddr;
@@ -24,7 +24,7 @@ auto SI::Read(MI& mi, u32 addr) const -> u32 {
val |= status.dmaBusy;
val |= (0 << 1);
val |= (0 << 3);
val |= (mi.miIntr.si << 12);
val |= (mem.mmio.mi.miIntr.si << 12);
return val;
}
default:
@@ -32,26 +32,25 @@ auto SI::Read(MI& mi, u32 addr) const -> u32 {
}
}
void SI::DMA(Mem& mem, Registers& regs) const {
SI& si = mem.mmio.si;
si.status.dmaBusy = false;
void SI::DMA() {
status.dmaBusy = false;
if (toDram) {
si.pif.ProcessCommands(mem);
pif.ProcessCommands(mem);
for(int i = 0; i < 64; i++) {
mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)] = si.pif.Read(si.pifAddr + i);
mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddr + i)] = pif.Read(pifAddr + i);
}
Util::trace("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})", si.pifAddr, si.dramAddr);
Util::trace("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})", pifAddr, dramAddr);
} else {
for(int i = 0; i < 64; i++) {
si.pif.Write(si.pifAddr + i, mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)]);
pif.Write(pifAddr + i, mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddr + i)]);
}
Util::trace("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})", si.dramAddr, si.pifAddr);
si.pif.ProcessCommands(mem);
Util::trace("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})", dramAddr, pifAddr);
pif.ProcessCommands(mem);
}
mem.mmio.mi.InterruptRaise(MI::Interrupt::SI);
}
void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
void SI::Write(u32 addr, u32 val) {
switch(addr) {
case 0x04800000:
dramAddr = val & RDRAM_DSIZE;

View File

@@ -28,10 +28,13 @@ struct SI {
u32 pifAddr{};
bool toDram = false;
auto Read(MI&, u32) const -> u32;
void Write(Mem&, Registers&, u32, u32);
void DMA(Mem&, Registers&) const;
auto Read(u32) const -> u32;
void Write(u32, u32);
void DMA();
PIF pif;
private:
Mem& mem;
Registers& regs;
};
#define SI_DMA_DELAY (65536 * 2)

View File

@@ -1,11 +1,11 @@
#include <core/mmio/VI.hpp>
#include <log.hpp>
#include <core/registers/Registers.hpp>
#include <core/mmio/MI.hpp>
#include <core/Mem.hpp>
#include <core/mmio/Interrupt.hpp>
namespace n64 {
VI::VI () {
VI::VI (Mem& mem, Registers& regs) : mem(mem), regs(regs) {
Reset();
}
@@ -43,7 +43,7 @@ u32 VI::Read(u32 paddr) const {
}
}
void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) {
void VI::Write(u32 paddr, u32 val) {
switch(paddr) {
case 0x04400000:
status.raw = val;
@@ -63,7 +63,7 @@ void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) {
intr = val & 0x3FF;
} break;
case 0x04400010:
mi.InterruptLower(MI::Interrupt::VI);
mem.mmio.mi.InterruptLower(MI::Interrupt::VI);
break;
case 0x04400014: burst.raw = val; break;
case 0x04400018: {

View File

@@ -72,14 +72,14 @@ union AxisStart {
};
};
struct MI;
struct Mem;
struct Registers;
struct VI {
VI();
VI(Mem&, Registers&);
void Reset();
[[nodiscard]] u32 Read(u32) const;
void Write(MI&, Registers&, u32, u32);
void Write(u32, u32);
AxisScale xscale{}, yscale{};
VIHsyncLeap hsyncLeap{};
VIStatus status{};
@@ -93,5 +93,8 @@ struct VI {
int numHalflines{};
int numFields{};
int cyclesPerHalfline{};
private:
Mem& mem;
Registers& regs;
};
} // backend

View File

@@ -14,5 +14,16 @@ struct Registers {
s64 hi{}, lo{};
bool prevDelaySlot{}, delaySlot{};
int steps = 0;
u32 extraCycles = 0;
void CpuStall(u32 cycles) {
extraCycles += cycles;
}
u32 PopStalledCycles() {
u32 ret = extraCycles;
extraCycles = 0;
return ret;
}
};
}

View File

@@ -75,8 +75,8 @@ FORCE_INLINE void SetCop0Reg(Registers& regs, Mem& mem, u8 index, u32 val) {
}
break;
case 8: rdp.WriteStart(val); break;
case 9: rdp.WriteEnd(mi, regs, rsp, val); break;
case 11: rdp.WriteStatus(mi, regs, rsp, val); break;
case 9: rdp.WriteEnd(val); break;
case 11: rdp.WriteStatus(val); break;
default: Util::panic("Unhandled RSP COP0 register write at index {}", index);
}
}