#include namespace n64 { void InstructionCache::FillLine(u64 vaddr, u32 paddr) { int index = GetICacheLineIndex(vaddr); auto &line = lines[index]; line.valid = true; line.ptag = paddr & ~0x00000fff; auto &mmio = Core::GetMem().mmio; for (int i = 0; i < 8; i++) { line.data[i] = mmio.rdp.ReadRDRAM(line.ptag | index); } } void InstructionCache::StoreTag(u64 vaddr, u32 ptag, Cop0 &cop0) { auto &line = lines[GetICacheLineIndex(vaddr)]; line.valid = (cop0.tagLo.pstate >> 1) & 1; line.ptag = ptag; } void DataCache::StoreTag(u64 vaddr, u32 ptag, Cop0 &cop0) { auto &line = lines[GetDCacheLineIndex(vaddr)]; line.valid = (cop0.tagLo.pstate >> 1) & 1; line.dirty = (cop0.tagLo.pstate >> 0) & 1; line.ptag = ptag; } void InstructionCache::LoadTag(u64 vaddr) { auto &cop0 = Core::GetRegs().cop0; auto &line = lines[GetICacheLineIndex(vaddr)]; cop0.tagLo.pstate = line.valid << 1; cop0.tagLo.ptaglo = line.ptag; } void DataCache::LoadTag(u64 vaddr) { auto &cop0 = Core::GetRegs().cop0; auto &line = lines[GetDCacheLineIndex(vaddr)]; cop0.tagLo.pstate = (line.valid << 1) | line.dirty; cop0.tagLo.ptaglo = line.ptag; } template <> void DataCache::WriteBack(u64 vaddr, u32 paddr) { auto &mmio = Core::GetMem().mmio; DCacheLine &line = lines[GetDCacheLineIndex(vaddr)]; if (!line.valid) return; u32 origPhysAddr = (line.ptag << 12) | (paddr & 0xfff); u32 lineStart = GetDCacheLineStart(origPhysAddr); Core::GetInstance().interpreter.EvictCachedBlock(vaddr); for (int i = 0; i < 16; i++) { mmio.rdp.WriteRDRAM(lineStart + i, line.data[i]); } line.dirty = false; } template <> void DataCache::WriteBack(u64 vaddr, u32 paddr) { WriteBack(vaddr, paddr); lines[GetDCacheLineIndex(vaddr)].valid = false; } template <> void DataCache::WriteBack(u64 vaddr, u32 paddr, u32 ptag) { DCacheLine &line = lines[GetDCacheLineIndex(vaddr)]; if (line.ptag == ptag) WriteBack(vaddr, paddr); } template <> void DataCache::WriteBack(u64 vaddr, u32 paddr, u32 ptag) { DCacheLine &line = lines[GetDCacheLineIndex(vaddr)]; if (line.ptag == ptag) WriteBack(vaddr, paddr); } void InstructionCache::WriteBack(u64 vaddr, u32 paddr, u32 ptag) { auto &mmio = Core::GetMem().mmio; ICacheLine &line = lines[GetICacheLineIndex(vaddr)]; if (line.ptag == ptag && line.valid) { u32 origPhysAddr = (line.ptag << 12) | (paddr & 0xfff); u32 lineStart = GetICacheLineStart(origPhysAddr); Core::GetInstance().interpreter.EvictCachedBlock(vaddr); for (int i = 0; i < 16; i++) { mmio.rdp.WriteRDRAM(lineStart + i, line.data[i]); } } } } // namespace n64