mirror of https://github.com/PCSX2/pcsx2.git
Cache code cleanups.
This commit is contained in:
parent
dbfe21c444
commit
2f8932e370
459
pcsx2/Cache.cpp
459
pcsx2/Cache.cpp
|
@ -18,49 +18,56 @@
|
|||
#include "Common.h"
|
||||
#include "Cache.h"
|
||||
#include "vtlb.h"
|
||||
_cacheS pCache[64];
|
||||
|
||||
#define DIRTY_FLAG 0x40
|
||||
#define VALID_FLAG 0x20
|
||||
#define LRF_FLAG 0x10
|
||||
#define LOCK_FLAG 0x8
|
||||
|
||||
using namespace R5900;
|
||||
using namespace vtlb_private;
|
||||
|
||||
_cacheS pCache[64];
|
||||
|
||||
// The lower parts of a cache tags structure is as follows:
|
||||
// 31 - 12: The physical address cache tag.
|
||||
// 11 - 7: Unused.
|
||||
// 6: Dirty flag.
|
||||
// 5: Valid flag.
|
||||
// 4: LRF flag - least recently filled flag.
|
||||
// 3: Lock flag.
|
||||
// 2-0: Unused.
|
||||
|
||||
int getFreeCache(u32 mem, int mode, int * way ) {
|
||||
int number;
|
||||
int i = (mem >> 6) & 0x3F;
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
s32 ppf=mem+vmv;
|
||||
// 0xFFF - 12 bits, so x & ~0xFFF = the physical address cache tag.
|
||||
|
||||
u32 hand=(u8)vmv;
|
||||
u32 paddr=ppf-hand+0x80000000;
|
||||
const u32 DIRTY_FLAG = 0x40;
|
||||
const u32 VALID_FLAG = 0x20;
|
||||
const u32 LRF_FLAG = 0x10;
|
||||
const u32 LOCK_FLAG = 0x8;
|
||||
|
||||
int getFreeCache(u32 mem, int mode, int * way)
|
||||
{
|
||||
int number = 0;
|
||||
const int i = (mem >> 6) & 0x3F;
|
||||
const u32 vmv = vtlbdata.vmap[mem >> VTLB_PAGE_BITS];
|
||||
s32 ppf = mem + vmv;
|
||||
const u32 hand = (u8)vmv;
|
||||
const u32 paddr = ppf - hand + 0x80000000;
|
||||
|
||||
if((cpuRegs.CP0.n.Config & 0x10000) == 0) CACHE_LOG("Cache off!");
|
||||
|
||||
if ((pCache[i].tag[0] & ~0xFFF) == (paddr & ~0xFFF) && (pCache[i].tag[0] & VALID_FLAG))
|
||||
{
|
||||
*way = 0;
|
||||
if(pCache[i].tag[0] & LOCK_FLAG) CACHE_LOG("Index %x Way %x Locked!!", i, 0);
|
||||
if (pCache[i].tag[0] & LOCK_FLAG) CACHE_LOG("Index %x Way %x Locked!!", i, 0);
|
||||
return i;
|
||||
}
|
||||
else if((pCache[i].tag[1] & ~0xFFF) == (paddr & ~0xFFF) && (pCache[i].tag[1] & VALID_FLAG))
|
||||
{
|
||||
*way = 1;
|
||||
if(pCache[i].tag[1] & LOCK_FLAG) CACHE_LOG("Index %x Way %x Locked!!", i, 1);
|
||||
if (pCache[i].tag[1] & LOCK_FLAG) CACHE_LOG("Index %x Way %x Locked!!", i, 1);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
number = (((pCache[i].tag[0]) & LRF_FLAG) ^ ((pCache[i].tag[1]) & LRF_FLAG)) >> 4;
|
||||
|
||||
ppf = (ppf & ~0x3F);
|
||||
|
||||
ppf = (ppf & ~0x3F) ;
|
||||
if((pCache[i].tag[number] & (DIRTY_FLAG|VALID_FLAG)) == (DIRTY_FLAG|VALID_FLAG)) // Dirty Write
|
||||
if ((pCache[i].tag[number] & (DIRTY_FLAG | VALID_FLAG)) == (DIRTY_FLAG | VALID_FLAG)) // Dirty Write
|
||||
{
|
||||
s32 oldppf = (pCache[i].tag[number] & ~0x80000fff) + (mem & 0xFC0);
|
||||
|
||||
|
@ -76,15 +83,14 @@ int getFreeCache(u32 mem, int mode, int * way ) {
|
|||
pCache[i].tag[number] &= ~DIRTY_FLAG;
|
||||
}
|
||||
|
||||
|
||||
pCache[i].data[number][0].b8._u64[0] = *(mem64_t*)(ppf);
|
||||
pCache[i].data[number][0].b8._u64[1] = *(mem64_t*)(ppf+8);
|
||||
pCache[i].data[number][1].b8._u64[0] = *(mem64_t*)(ppf+16);
|
||||
pCache[i].data[number][1].b8._u64[1] = *(mem64_t*)(ppf+24);
|
||||
pCache[i].data[number][2].b8._u64[0] = *(mem64_t*)(ppf+32);
|
||||
pCache[i].data[number][2].b8._u64[1] = *(mem64_t*)(ppf+40);
|
||||
pCache[i].data[number][3].b8._u64[0] = *(mem64_t*)(ppf+48);
|
||||
pCache[i].data[number][3].b8._u64[1] = *(mem64_t*)(ppf+56);
|
||||
pCache[i].data[number][0].b8._u64[0] = *reinterpret_cast<mem64_t*>(ppf);
|
||||
pCache[i].data[number][0].b8._u64[1] = *reinterpret_cast<mem64_t*>(ppf+8);
|
||||
pCache[i].data[number][1].b8._u64[0] = *reinterpret_cast<mem64_t*>(ppf+16);
|
||||
pCache[i].data[number][1].b8._u64[1] = *reinterpret_cast<mem64_t*>(ppf+24);
|
||||
pCache[i].data[number][2].b8._u64[0] = *reinterpret_cast<mem64_t*>(ppf+32);
|
||||
pCache[i].data[number][2].b8._u64[1] = *reinterpret_cast<mem64_t*>(ppf+40);
|
||||
pCache[i].data[number][3].b8._u64[0] = *reinterpret_cast<mem64_t*>(ppf+48);
|
||||
pCache[i].data[number][3].b8._u64[1] = *reinterpret_cast<mem64_t*>(ppf+56);
|
||||
|
||||
*way = number;
|
||||
pCache[i].tag[number] |= VALID_FLAG;
|
||||
|
@ -97,155 +103,179 @@ int getFreeCache(u32 mem, int mode, int * way ) {
|
|||
pCache[i].tag[number] |= LRF_FLAG;
|
||||
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
void writeCache8(u32 mem, u8 value) {
|
||||
int i, number;
|
||||
//u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
//s32 ppf=(mem+vmv) & ~0x3f;
|
||||
i = getFreeCache(mem,1,&number);
|
||||
void writeCache8(u32 mem, u8 value)
|
||||
{
|
||||
int number = 0;
|
||||
const int i = getFreeCache(mem, 1, &number);
|
||||
|
||||
if(i == -1)
|
||||
if (i == -1)
|
||||
{
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
s32 ppf=mem+vmv;
|
||||
const u32 vmv = vtlbdata.vmap[mem >> VTLB_PAGE_BITS];
|
||||
s32 ppf = mem + vmv;
|
||||
*reinterpret_cast<mem8_t*>(ppf) = value;
|
||||
return;
|
||||
}
|
||||
CACHE_LOG("writeCache8 %8.8x adding to %d, way %d, value %x", mem, i,number,value);
|
||||
|
||||
CACHE_LOG("writeCache8 %8.8x adding to %d, way %d, value %x", mem, i, number, value);
|
||||
pCache[i].tag[number] |= DIRTY_FLAG; // Set Dirty Bit if mode == write
|
||||
pCache[i].data[number][(mem>>4) & 0x3].b8._u8[(mem&0xf)] = value;
|
||||
pCache[i].data[number][(mem >> 4) & 0x3].b8._u8[(mem & 0xf)] = value;
|
||||
}
|
||||
|
||||
void writeCache16(u32 mem, u16 value) {
|
||||
int i, number;
|
||||
//u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
//s32 ppf=(mem+vmv) & ~0x3f;
|
||||
i = getFreeCache(mem,1,&number);
|
||||
if(i == -1)
|
||||
void writeCache16(u32 mem, u16 value)
|
||||
{
|
||||
int number = 0;
|
||||
const int i = getFreeCache(mem, 1, &number);
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
s32 ppf=mem+vmv;
|
||||
const u32 vmv = vtlbdata.vmap[mem >> VTLB_PAGE_BITS];
|
||||
s32 ppf = mem + vmv;
|
||||
*reinterpret_cast<mem16_t*>(ppf) = value;
|
||||
return;
|
||||
}
|
||||
CACHE_LOG("writeCache16 %8.8x adding to %d, way %d, value %x", mem, i,number,value);
|
||||
|
||||
CACHE_LOG("writeCache16 %8.8x adding to %d, way %d, value %x", mem, i, number, value);
|
||||
pCache[i].tag[number] |= DIRTY_FLAG; // Set Dirty Bit if mode == write
|
||||
pCache[i].data[number][(mem>>4) & 0x3].b8._u16[(mem&0xf)>>1] = value;
|
||||
pCache[i].data[number][(mem >> 4) & 0x3].b8._u16[(mem & 0xf) >> 1] = value;
|
||||
}
|
||||
|
||||
void writeCache32(u32 mem, u32 value) {
|
||||
int i, number;
|
||||
//u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
//s32 ppf=(mem+vmv) & ~0x3f;
|
||||
i = getFreeCache(mem,1,&number);
|
||||
if(i == -1)
|
||||
void writeCache32(u32 mem, u32 value)
|
||||
{
|
||||
int number = 0;
|
||||
const int i = getFreeCache(mem, 1, &number);
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
s32 ppf=mem+vmv;
|
||||
const u32 vmv = vtlbdata.vmap[mem >> VTLB_PAGE_BITS];
|
||||
s32 ppf = mem + vmv;
|
||||
*reinterpret_cast<mem32_t*>(ppf) = value;
|
||||
return;
|
||||
}
|
||||
CACHE_LOG("writeCache32 %8.8x adding to %d, way %d, value %x", mem, i,number,value);
|
||||
|
||||
CACHE_LOG("writeCache32 %8.8x adding to %d, way %d, value %x", mem, i, number, value);
|
||||
pCache[i].tag[number] |= DIRTY_FLAG; // Set Dirty Bit if mode == write
|
||||
pCache[i].data[number][(mem>>4) & 0x3].b8._u32[(mem&0xf)>>2] = value;
|
||||
pCache[i].data[number][(mem >> 4) & 0x3].b8._u32[(mem & 0xf) >> 2] = value;
|
||||
}
|
||||
|
||||
void writeCache64(u32 mem, const u64 value) {
|
||||
int i, number;
|
||||
//u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
//s32 ppf=(mem+vmv) & ~0x3f;
|
||||
i = getFreeCache(mem,1,&number);
|
||||
if(i == -1)
|
||||
void writeCache64(u32 mem, const u64 value)
|
||||
{
|
||||
int number = 0;
|
||||
const int i = getFreeCache(mem, 1, &number);
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
s32 ppf=mem+vmv;
|
||||
const u32 vmv = vtlbdata.vmap[mem >> VTLB_PAGE_BITS];
|
||||
s32 ppf = mem + vmv;
|
||||
*reinterpret_cast<mem64_t*>(ppf) = value;
|
||||
return;
|
||||
}
|
||||
|
||||
CACHE_LOG("writeCache64 %8.8x adding to %d, way %d, value %x", mem, i,number,value);
|
||||
pCache[i].tag[number] |= DIRTY_FLAG; // Set Dirty Bit if mode == write
|
||||
pCache[i].data[number][(mem>>4) & 0x3].b8._u64[(mem&0xf)>>3] = value;
|
||||
pCache[i].data[number][(mem >> 4) & 0x3].b8._u64[(mem & 0xf) >> 3] = value;
|
||||
}
|
||||
|
||||
void writeCache128(u32 mem, const mem128_t* value){
|
||||
int i, number;
|
||||
//u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
//s32 ppf=(mem+vmv) & ~0x3f;
|
||||
i = getFreeCache(mem,1,&number);
|
||||
if(i == -1)
|
||||
void writeCache128(u32 mem, const mem128_t* value)
|
||||
{
|
||||
int number = 0;
|
||||
const int i = getFreeCache(mem, 1, &number);
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
s32 ppf=mem+vmv;
|
||||
const u32 vmv = vtlbdata.vmap[mem >> VTLB_PAGE_BITS];
|
||||
s32 ppf = mem + vmv;
|
||||
*reinterpret_cast<mem64_t*>(ppf) = value->lo;
|
||||
*reinterpret_cast<mem64_t*>(ppf+8) = value->hi;
|
||||
return;
|
||||
}
|
||||
|
||||
CACHE_LOG("writeCache128 %8.8x adding to %d way %x tag %x vallo = %x_%x valhi = %x_%x", mem, i, number, pCache[i].tag[number], value->lo, value->hi);
|
||||
pCache[i].tag[number] |= DIRTY_FLAG; // Set Dirty Bit if mode == write
|
||||
pCache[i].data[number][(mem>>4) & 0x3].b8._u64[0] = value->lo;
|
||||
pCache[i].data[number][(mem>>4) & 0x3].b8._u64[1] = value->hi;
|
||||
}
|
||||
|
||||
u8 readCache8(u32 mem) {
|
||||
int number;
|
||||
|
||||
int i = getFreeCache(mem,0,&number);
|
||||
if(i == -1)
|
||||
u8 readCache8(u32 mem)
|
||||
{
|
||||
int number = 0;
|
||||
const int i = getFreeCache(mem, 0, &number);
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
s32 ppf=mem+vmv;
|
||||
return *(u8*)ppf;
|
||||
const u32 vmv = vtlbdata.vmap[mem >> VTLB_PAGE_BITS];
|
||||
s32 ppf = mem + vmv;
|
||||
return *reinterpret_cast<u8*>(ppf);
|
||||
}
|
||||
|
||||
CACHE_LOG("readCache %8.8x from %d, way %d QW %x u8 part %x Really Reading %x", mem, i, number, (mem >> 4) & 0x3, (mem & 0xf) >> 2, (u32)pCache[i].data[number][(mem >> 4) & 0x3].b8._u8[(mem & 0xf)]);
|
||||
return pCache[i].data[number][(mem >> 4) & 0x3].b8._u8[(mem&0xf)];
|
||||
return pCache[i].data[number][(mem >> 4) & 0x3].b8._u8[(mem & 0xf)];
|
||||
}
|
||||
|
||||
u16 readCache16(u32 mem) {
|
||||
int number;
|
||||
|
||||
int i = getFreeCache(mem,0,&number);
|
||||
if(i == -1)
|
||||
u16 readCache16(u32 mem)
|
||||
{
|
||||
int number = 0;
|
||||
const int i = getFreeCache(mem, 0, &number);
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
s32 ppf=mem+vmv;
|
||||
return *(u16*)ppf;
|
||||
const u32 vmv = vtlbdata.vmap[mem >> VTLB_PAGE_BITS];
|
||||
s32 ppf = mem + vmv;
|
||||
return *reinterpret_cast<u16*>(ppf);
|
||||
}
|
||||
|
||||
CACHE_LOG("readCache %8.8x from %d, way %d QW %x u16 part %x Really Reading %x", mem, i, number, (mem >> 4) & 0x3, (mem & 0xf) >> 2, (u32)pCache[i].data[number][(mem >> 4) & 0x3].b8._u16[(mem & 0xf) >> 1]);
|
||||
return pCache[i].data[number][(mem >> 4) & 0x3].b8._u16[(mem&0xf)>>1];
|
||||
return pCache[i].data[number][(mem >> 4) & 0x3].b8._u16[(mem & 0xf) >> 1];
|
||||
}
|
||||
|
||||
u32 readCache32(u32 mem) {
|
||||
int number;
|
||||
|
||||
int i = getFreeCache(mem,0,&number);
|
||||
if(i == -1)
|
||||
u32 readCache32(u32 mem)
|
||||
{
|
||||
int number = 0;
|
||||
const int i = getFreeCache(mem, 0, &number);
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
s32 ppf=mem+vmv;
|
||||
return *(u32*)ppf;
|
||||
const u32 vmv = vtlbdata.vmap[mem >> VTLB_PAGE_BITS];
|
||||
s32 ppf = mem + vmv;
|
||||
return *reinterpret_cast<u32*>(ppf);
|
||||
}
|
||||
|
||||
CACHE_LOG("readCache %8.8x from %d, way %d QW %x u32 part %x Really Reading %x", mem, i, number, (mem >> 4) & 0x3, (mem & 0xf) >> 2, (u32)pCache[i].data[number][(mem >> 4) & 0x3].b8._u32[(mem & 0xf) >> 2]);
|
||||
return pCache[i].data[number][(mem >> 4) & 0x3].b8._u32[(mem&0xf)>>2];
|
||||
return pCache[i].data[number][(mem >> 4) & 0x3].b8._u32[(mem & 0xf) >> 2];
|
||||
}
|
||||
|
||||
u64 readCache64(u32 mem) {
|
||||
int number;
|
||||
|
||||
int i = getFreeCache(mem,0,&number);
|
||||
if(i == -1)
|
||||
u64 readCache64(u32 mem)
|
||||
{
|
||||
int number = 0;
|
||||
int i = getFreeCache(mem, 0, &number);
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
u32 vmv=vtlbdata.vmap[mem>>VTLB_PAGE_BITS];
|
||||
s32 ppf=mem+vmv;
|
||||
return *(u64*)ppf;
|
||||
u32 vmv = vtlbdata.vmap[mem >> VTLB_PAGE_BITS];
|
||||
s32 ppf=mem + vmv;
|
||||
return *reinterpret_cast<u64*>(ppf);
|
||||
}
|
||||
|
||||
CACHE_LOG("readCache %8.8x from %d, way %d QW %x u64 part %x Really Reading %x_%x", mem, i, number, (mem >> 4) & 0x3, (mem & 0xf) >> 2, pCache[i].data[number][(mem >> 4) & 0x3].b8._u64[(mem & 0xf) >> 3]);
|
||||
return pCache[i].data[number][(mem >> 4) & 0x3].b8._u64[(mem&0xf)>>3];
|
||||
return pCache[i].data[number][(mem >> 4) & 0x3].b8._u64[(mem & 0xf) >> 3];
|
||||
}
|
||||
|
||||
__forceinline void clear_cache(int index, int way)
|
||||
{
|
||||
pCache[index].tag[way] &= LRF_FLAG;
|
||||
|
||||
pCache[index].data[way][0].b8._u64[0] = 0;
|
||||
pCache[index].data[way][0].b8._u64[1] = 0;
|
||||
|
||||
pCache[index].data[way][1].b8._u64[0] = 0;
|
||||
pCache[index].data[way][1].b8._u64[1] = 0;
|
||||
|
||||
pCache[index].data[way][2].b8._u64[0] = 0;
|
||||
pCache[index].data[way][2].b8._u64[1] = 0;
|
||||
|
||||
pCache[index].data[way][3].b8._u64[0] = 0;
|
||||
pCache[index].data[way][3].b8._u64[1] = 0;
|
||||
}
|
||||
|
||||
namespace R5900 {
|
||||
|
@ -255,79 +285,70 @@ namespace OpcodeImpl
|
|||
{
|
||||
|
||||
extern int Dcache;
|
||||
void CACHE() {
|
||||
u32 addr;
|
||||
void CACHE()
|
||||
{
|
||||
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
|
||||
// CACHE_LOG("cpuRegs.GPR.r[_Rs_].UL[0] = %x, IMM = %x RT = %x", cpuRegs.GPR.r[_Rs_].UL[0], _Imm_, _Rt_);
|
||||
|
||||
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
|
||||
// CACHE_LOG("cpuRegs.GPR.r[_Rs_].UL[0] = %x, IMM = %x RT = %x", cpuRegs.GPR.r[_Rs_].UL[0], _Imm_, _Rt_);
|
||||
switch (_Rt_)
|
||||
{
|
||||
case 0x1a: //DHIN (Data Cache Hit Invalidate)
|
||||
{
|
||||
int index = (addr >> 6) & 0x3F;
|
||||
const int index = (addr >> 6) & 0x3F;
|
||||
int way = 0;
|
||||
u32 pfnaddr = addr;
|
||||
u32 vmv=vtlbdata.vmap[pfnaddr>>VTLB_PAGE_BITS];
|
||||
s32 ppf=pfnaddr+vmv;
|
||||
u32 hand=(u8)vmv;
|
||||
u32 paddr=ppf-hand+0x80000000;
|
||||
const u32 pfnaddr = addr;
|
||||
const u32 vmv = vtlbdata.vmap[pfnaddr >> VTLB_PAGE_BITS];
|
||||
const s32 ppf = pfnaddr + vmv;
|
||||
const u32 hand = (u8)vmv;
|
||||
const u32 paddr = ppf - hand + 0x80000000;
|
||||
|
||||
if((paddr & ~0xFFF) == (pCache[index].tag[0] & ~0xfff) && (pCache[index].tag[0] & VALID_FLAG))
|
||||
if ((paddr & ~0xFFF) == (pCache[index].tag[0] & ~0xfff) && (pCache[index].tag[0] & VALID_FLAG))
|
||||
{
|
||||
way = 0;
|
||||
}
|
||||
else if((paddr & ~0xFFF) == (pCache[index].tag[1] & ~0xfff) && (pCache[index].tag[1] & VALID_FLAG))
|
||||
else if ((paddr & ~0xFFF) == (pCache[index].tag[1] & ~0xfff) && (pCache[index].tag[1] & VALID_FLAG))
|
||||
{
|
||||
way = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CACHE_LOG("CACHE DHIN NO HIT addr %x, index %d, phys %x tag0 %x tag1 %x",addr,index, paddr, pCache[index].tag[0], pCache[index].tag[1]);
|
||||
CACHE_LOG("CACHE DHIN NO HIT addr %x, index %d, phys %x tag0 %x tag1 %x", addr, index, paddr, pCache[index].tag[0], pCache[index].tag[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
CACHE_LOG("CACHE DHIN addr %x, index %d, way %d, Flags %x OP %x",addr,index,way,pCache[index].tag[way] & 0x78, cpuRegs.code);
|
||||
|
||||
pCache[index].tag[way] &= LRF_FLAG;
|
||||
pCache[index].data[way][0].b8._u64[0] = 0;
|
||||
pCache[index].data[way][0].b8._u64[1] = 0;
|
||||
pCache[index].data[way][1].b8._u64[0] = 0;
|
||||
pCache[index].data[way][1].b8._u64[1] = 0;
|
||||
pCache[index].data[way][2].b8._u64[0] = 0;
|
||||
pCache[index].data[way][2].b8._u64[1] = 0;
|
||||
pCache[index].data[way][3].b8._u64[0] = 0;
|
||||
pCache[index].data[way][3].b8._u64[1] = 0;
|
||||
CACHE_LOG("CACHE DHIN addr %x, index %d, way %d, Flags %x OP %x", addr, index, way, pCache[index].tag[way] & 0x78, cpuRegs.code);
|
||||
|
||||
clear_cache(index, way);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x18: //DHWBIN (Data Cache Hit WriteBack with Invalidate)
|
||||
{
|
||||
int index = (addr >> 6) & 0x3F;
|
||||
const int index = (addr >> 6) & 0x3F;
|
||||
int way = 0;
|
||||
u32 pfnaddr = addr;
|
||||
u32 vmv=vtlbdata.vmap[pfnaddr>>VTLB_PAGE_BITS];
|
||||
s32 ppf=(pfnaddr+vmv) & ~0x3F;
|
||||
u32 hand=(u8)vmv;
|
||||
u32 paddr=ppf-hand+0x80000000;
|
||||
const u32 pfnaddr = addr;
|
||||
const u32 vmv = vtlbdata.vmap[pfnaddr >> VTLB_PAGE_BITS];
|
||||
s32 ppf = (pfnaddr + vmv) & ~0x3F;
|
||||
const u32 hand = (u8)vmv;
|
||||
const u32 paddr = ppf - hand + 0x80000000;
|
||||
|
||||
if ((pCache[index].tag[0] & ~0xFFF) == (paddr & ~0xFFF) && (pCache[index].tag[0] & VALID_FLAG))
|
||||
{
|
||||
way = 0;
|
||||
}
|
||||
else if((pCache[index].tag[1] & ~0xFFF) == (paddr & ~0xFFF) && (pCache[index].tag[1] & VALID_FLAG))
|
||||
else if ((pCache[index].tag[1] & ~0xFFF) == (paddr & ~0xFFF) && (pCache[index].tag[1] & VALID_FLAG))
|
||||
{
|
||||
way = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CACHE_LOG("CACHE DHWBIN NO HIT addr %x, index %d, phys %x tag0 %x tag1 %x",addr,index, paddr, pCache[index].tag[0], pCache[index].tag[1]);
|
||||
CACHE_LOG("CACHE DHWBIN NO HIT addr %x, index %d, phys %x tag0 %x tag1 %x", addr, index, paddr, pCache[index].tag[0], pCache[index].tag[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
CACHE_LOG("CACHE DHWBIN addr %x, index %d, phys %x tag0 %x tag1 %x way %x",addr,index, paddr, pCache[index].tag[0], pCache[index].tag[1], way );
|
||||
CACHE_LOG("CACHE DHWBIN addr %x, index %d, phys %x tag0 %x tag1 %x way %x", addr, index, paddr, pCache[index].tag[0], pCache[index].tag[1], way );
|
||||
|
||||
if((pCache[index].tag[way] & (DIRTY_FLAG|VALID_FLAG)) == (DIRTY_FLAG|VALID_FLAG)) // Dirty
|
||||
if ((pCache[index].tag[way] & (DIRTY_FLAG|VALID_FLAG)) == (DIRTY_FLAG|VALID_FLAG)) // Dirty
|
||||
{
|
||||
CACHE_LOG("DHWBIN Dirty WriteBack PPF %x", ppf);
|
||||
|
||||
|
@ -341,46 +362,37 @@ void CACHE() {
|
|||
*reinterpret_cast<mem64_t*>(ppf+56) = pCache[index].data[way][3].b8._u64[1];
|
||||
}
|
||||
|
||||
pCache[index].tag[way] &= LRF_FLAG;
|
||||
|
||||
pCache[index].data[way][0].b8._u64[0] = 0;
|
||||
pCache[index].data[way][0].b8._u64[1] = 0;
|
||||
pCache[index].data[way][1].b8._u64[0] = 0;
|
||||
pCache[index].data[way][1].b8._u64[1] = 0;
|
||||
pCache[index].data[way][2].b8._u64[0] = 0;
|
||||
pCache[index].data[way][2].b8._u64[1] = 0;
|
||||
pCache[index].data[way][3].b8._u64[0] = 0;
|
||||
pCache[index].data[way][3].b8._u64[1] = 0;
|
||||
|
||||
clear_cache(index, way);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x1c: //DHWOIN (Data Cache Hit WriteBack Without Invalidate)
|
||||
{
|
||||
int index = (addr >> 6) & 0x3F;
|
||||
const int index = (addr >> 6) & 0x3F;
|
||||
int way = 0;
|
||||
u32 pfnaddr = (pCache[index].tag[way] & ~0x80000fff) | (addr & 0xfc0);
|
||||
u32 vmv=vtlbdata.vmap[pfnaddr>>VTLB_PAGE_BITS];
|
||||
s32 ppf=(pfnaddr+vmv) & ~0x3F;
|
||||
u32 hand=(u8)vmv;
|
||||
u32 paddr=ppf-hand+0x80000000;
|
||||
const u32 pfnaddr = (pCache[index].tag[way] & ~0x80000fff) | (addr & 0xfc0);
|
||||
const u32 vmv = vtlbdata.vmap[pfnaddr >> VTLB_PAGE_BITS];
|
||||
s32 ppf = (pfnaddr + vmv) & ~0x3F;
|
||||
const u32 hand = (u8)vmv;
|
||||
const u32 paddr = ppf - hand + 0x80000000;
|
||||
|
||||
CACHE_LOG("CACHE DHWOIN addr %x, index %d, way %d, Flags %x OP %x",addr,index,way,pCache[index].tag[way] & 0x78, cpuRegs.code);
|
||||
CACHE_LOG("CACHE DHWOIN addr %x, index %d, way %d, Flags %x OP %x", addr, index, way, pCache[index].tag[way] & 0x78, cpuRegs.code);
|
||||
|
||||
if ((pCache[index].tag[0] & ~0xFFF) == (paddr & ~0xFFF) && (pCache[index].tag[0] & VALID_FLAG))
|
||||
{
|
||||
way = 0;
|
||||
}
|
||||
else if((pCache[index].tag[1] & ~0xFFF) == (paddr & ~0xFFF) && (pCache[index].tag[1] & VALID_FLAG))
|
||||
else if ((pCache[index].tag[1] & ~0xFFF) == (paddr & ~0xFFF) && (pCache[index].tag[1] & VALID_FLAG))
|
||||
{
|
||||
way = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CACHE_LOG("CACHE DHWOIN NO HIT addr %x, index %d, phys %x tag0 %x tag1 %x",addr,index, paddr, pCache[index].tag[0], pCache[index].tag[1]);
|
||||
CACHE_LOG("CACHE DHWOIN NO HIT addr %x, index %d, phys %x tag0 %x tag1 %x", addr, index, paddr, pCache[index].tag[0], pCache[index].tag[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if((pCache[index].tag[way] & (DIRTY_FLAG|VALID_FLAG)) == (DIRTY_FLAG|VALID_FLAG)) // Dirty
|
||||
if ((pCache[index].tag[way] & (DIRTY_FLAG|VALID_FLAG)) == (DIRTY_FLAG|VALID_FLAG)) // Dirty
|
||||
{
|
||||
CACHE_LOG("DHWOIN Dirty WriteBack! PPF %x", ppf);
|
||||
*reinterpret_cast<mem64_t*>(ppf) = pCache[index].data[way][0].b8._u64[0];
|
||||
|
@ -394,50 +406,42 @@ void CACHE() {
|
|||
|
||||
pCache[index].tag[way] &= ~DIRTY_FLAG;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x16: //DXIN (Data Cache Index Invalidate)
|
||||
{
|
||||
int index = (addr >> 6) & 0x3F;
|
||||
int way = addr & 0x1;
|
||||
const int index = (addr >> 6) & 0x3F;
|
||||
const int way = addr & 0x1;
|
||||
|
||||
CACHE_LOG("CACHE DXIN addr %x, index %d, way %d, flag %x\n",addr,index,way,pCache[index].tag[way] & 0x78);
|
||||
|
||||
pCache[index].tag[way] &= LRF_FLAG;
|
||||
|
||||
pCache[index].data[way][0].b8._u64[0] = 0;
|
||||
pCache[index].data[way][0].b8._u64[1] = 0;
|
||||
pCache[index].data[way][1].b8._u64[0] = 0;
|
||||
pCache[index].data[way][1].b8._u64[1] = 0;
|
||||
pCache[index].data[way][2].b8._u64[0] = 0;
|
||||
pCache[index].data[way][2].b8._u64[1] = 0;
|
||||
pCache[index].data[way][3].b8._u64[0] = 0;
|
||||
pCache[index].data[way][3].b8._u64[1] = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x11: //DXLDT (Data Cache Load Data into TagLo)
|
||||
{
|
||||
int index = (addr >> 6) & 0x3F;
|
||||
int way = addr & 0x1;
|
||||
|
||||
cpuRegs.CP0.n.TagLo = pCache[index].data[way][(addr>>4) & 0x3].b8._u32[(addr&0xf)>>2];
|
||||
|
||||
CACHE_LOG("CACHE DXLDT addr %x, index %d, way %d, DATA %x OP %x",addr,index,way,cpuRegs.CP0.r[28], cpuRegs.code);
|
||||
CACHE_LOG("CACHE DXIN addr %x, index %d, way %d, flag %x\n", addr, index, way, pCache[index].tag[way] & 0x78);
|
||||
|
||||
clear_cache(index, way);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x11: //DXLDT (Data Cache Load Data into TagLo)
|
||||
{
|
||||
const int index = (addr >> 6) & 0x3F;
|
||||
const int way = addr & 0x1;
|
||||
|
||||
cpuRegs.CP0.n.TagLo = pCache[index].data[way][(addr >> 4) & 0x3].b8._u32[(addr & 0xf) >> 2];
|
||||
|
||||
CACHE_LOG("CACHE DXLDT addr %x, index %d, way %d, DATA %x OP %x", addr, index, way, cpuRegs.CP0.r[28], cpuRegs.code);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x10: //DXLTG (Data Cache Load Tag into TagLo)
|
||||
{
|
||||
int index = (addr >> 6) & 0x3F;
|
||||
int way = addr & 0x1;
|
||||
const int index = (addr >> 6) & 0x3F;
|
||||
const int way = addr & 0x1;
|
||||
|
||||
//DXLTG demands that SYNC.L is called before this command, which forces the cache to write back, so presumably games are checking the cache has updated the memory
|
||||
//For speed, we will do it here.
|
||||
u32 pfnaddr = (pCache[index].tag[way] & ~0x80000fff) | (addr & 0xfc0);
|
||||
u32 vmv = vtlbdata.vmap[pfnaddr >> VTLB_PAGE_BITS];
|
||||
const u32 pfnaddr = (pCache[index].tag[way] & ~0x80000fff) | (addr & 0xfc0);
|
||||
const u32 vmv = vtlbdata.vmap[pfnaddr >> VTLB_PAGE_BITS];
|
||||
s32 ppf = (pfnaddr + vmv) & ~0x3F;
|
||||
|
||||
if ((pCache[index].tag[way] & (DIRTY_FLAG | VALID_FLAG)) == (DIRTY_FLAG | VALID_FLAG)) // Dirty
|
||||
{
|
||||
CACHE_LOG("DXLTG Dirty WriteBack! PPF %x", ppf);
|
||||
|
@ -455,43 +459,43 @@ void CACHE() {
|
|||
//DevCon.Warning("DXLTG way %x index %x addr %x tagdata=%x", way, index, addr, pCache[index].tag[way]);
|
||||
cpuRegs.CP0.n.TagLo = pCache[index].tag[way];
|
||||
|
||||
CACHE_LOG("CACHE DXLTG addr %x, index %d, way %d, DATA %x OP %x ",addr,index,way,cpuRegs.CP0.r[28], cpuRegs.code);
|
||||
|
||||
CACHE_LOG("CACHE DXLTG addr %x, index %d, way %d, DATA %x OP %x ", addr, index, way, cpuRegs.CP0.r[28], cpuRegs.code);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x13: //DXSDT (Data Cache Store 32bits from TagLo)
|
||||
{
|
||||
int index = (addr >> 6) & 0x3F;
|
||||
int way = addr & 0x1;
|
||||
const int index = (addr >> 6) & 0x3F;
|
||||
const int way = addr & 0x1;
|
||||
|
||||
pCache[index].data[way][(addr>>4) & 0x3].b8._u32[(addr&0xf)>>2] = cpuRegs.CP0.n.TagLo;
|
||||
|
||||
CACHE_LOG("CACHE DXSDT addr %x, index %d, way %d, DATA %x OP %x",addr,index,way,cpuRegs.CP0.r[28], cpuRegs.code);
|
||||
pCache[index].data[way][(addr >> 4) & 0x3].b8._u32[(addr & 0xf) >> 2] = cpuRegs.CP0.n.TagLo;
|
||||
|
||||
CACHE_LOG("CACHE DXSDT addr %x, index %d, way %d, DATA %x OP %x", addr, index, way, cpuRegs.CP0.r[28], cpuRegs.code);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x12: //DXSTG (Data Cache Store Tag from TagLo)
|
||||
{
|
||||
int index = (addr >> 6) & 0x3F;
|
||||
int way = addr & 0x1;
|
||||
const int index = (addr >> 6) & 0x3F;
|
||||
const int way = addr & 0x1;
|
||||
pCache[index].tag[way] = cpuRegs.CP0.n.TagLo;
|
||||
|
||||
CACHE_LOG("CACHE DXSTG addr %x, index %d, way %d, DATA %x OP %x",addr,index,way,cpuRegs.CP0.r[28] & 0x6F, cpuRegs.code);
|
||||
|
||||
CACHE_LOG("CACHE DXSTG addr %x, index %d, way %d, DATA %x OP %x", addr, index, way, cpuRegs.CP0.r[28] & 0x6F, cpuRegs.code);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x14: //DXWBIN (Data Cache Index WriteBack Invalidate)
|
||||
{
|
||||
int index = (addr >> 6) & 0x3F;
|
||||
int way = addr & 0x1;
|
||||
u32 pfnaddr = (pCache[index].tag[way] & ~0x80000fff) + (addr & 0xFC0);
|
||||
u32 vmv=vtlbdata.vmap[pfnaddr >>VTLB_PAGE_BITS];
|
||||
s32 ppf=pfnaddr+vmv;
|
||||
u32 hand=(u8)vmv;
|
||||
u32 paddr=ppf-hand+0x80000000;
|
||||
const int index = (addr >> 6) & 0x3F;
|
||||
const int way = addr & 0x1;
|
||||
const u32 pfnaddr = (pCache[index].tag[way] & ~0x80000fff) + (addr & 0xFC0);
|
||||
const u32 vmv = vtlbdata.vmap[pfnaddr >> VTLB_PAGE_BITS];
|
||||
s32 ppf = pfnaddr + vmv;
|
||||
const u32 hand = (u8)vmv;
|
||||
const u32 paddr = ppf - hand + 0x80000000;
|
||||
|
||||
CACHE_LOG("CACHE DXWBIN addr %x, index %d, way %d, Flags %x Paddr %x tag %x",addr,index,way,pCache[index].tag[way] & 0x78, paddr, pCache[index].tag[way]);
|
||||
if((pCache[index].tag[way] & (DIRTY_FLAG|VALID_FLAG)) == (DIRTY_FLAG|VALID_FLAG)) // Dirty
|
||||
CACHE_LOG("CACHE DXWBIN addr %x, index %d, way %d, Flags %x Paddr %x tag %x", addr, index, way, pCache[index].tag[way] & 0x78, paddr, pCache[index].tag[way]);
|
||||
if ((pCache[index].tag[way] & (DIRTY_FLAG|VALID_FLAG)) == (DIRTY_FLAG|VALID_FLAG)) // Dirty
|
||||
{
|
||||
ppf = (ppf & 0x7fffffff);
|
||||
CACHE_LOG("DXWBIN Dirty WriteBack! PPF %x", ppf);
|
||||
|
@ -504,33 +508,26 @@ void CACHE() {
|
|||
*reinterpret_cast<mem64_t*>(ppf+40) = pCache[index].data[way][2].b8._u64[1];
|
||||
*reinterpret_cast<mem64_t*>(ppf+48) = pCache[index].data[way][3].b8._u64[0];
|
||||
*reinterpret_cast<mem64_t*>(ppf+56) = pCache[index].data[way][3].b8._u64[1];
|
||||
|
||||
}
|
||||
|
||||
pCache[index].tag[way] &= LRF_FLAG;
|
||||
|
||||
pCache[index].data[way][0].b8._u64[0] = 0;
|
||||
pCache[index].data[way][0].b8._u64[1] = 0;
|
||||
pCache[index].data[way][1].b8._u64[0] = 0;
|
||||
pCache[index].data[way][1].b8._u64[1] = 0;
|
||||
pCache[index].data[way][2].b8._u64[0] = 0;
|
||||
pCache[index].data[way][2].b8._u64[1] = 0;
|
||||
pCache[index].data[way][3].b8._u64[0] = 0;
|
||||
pCache[index].data[way][3].b8._u64[1] = 0;
|
||||
clear_cache(index, way);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x7: //IXIN (Instruction Cache Index Invalidate)
|
||||
{
|
||||
//Not Implemented as we do not have instruction cache
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xC: //BFH (BTAC Flush)
|
||||
{
|
||||
//Not Implemented as we do not cache Branch Target Addresses.
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
DevCon.Warning("Cache mode %x not impemented", _Rt_);
|
||||
DevCon.Warning("Cache mode %x not implemented", _Rt_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue