mirror of https://github.com/PCSX2/pcsx2.git
Vif: Fix for Unpacks when WL = 0. (KH2 + Tests) Removes a long standing hack.
Note: CL = 0 behaviour is still not completely accurate, the first vector is incorrect, but will look at that another day, need a game that does it first really so we can see if it helps :)
This commit is contained in:
parent
393e56a604
commit
0147e6cb8d
|
@ -40,7 +40,8 @@ enum MTVU_EVENT {
|
||||||
// Calls the vif unpack functions from the MTVU thread
|
// Calls the vif unpack functions from the MTVU thread
|
||||||
static void MTVU_Unpack(void* data, VIFregisters& vifRegs)
|
static void MTVU_Unpack(void* data, VIFregisters& vifRegs)
|
||||||
{
|
{
|
||||||
bool isFill = vifRegs.cycle.cl < vifRegs.cycle.wl;
|
u16 wl = vifRegs.cycle.wl > 0 ? vifRegs.cycle.wl : 256;
|
||||||
|
bool isFill = vifRegs.cycle.cl < wl;
|
||||||
if (newVifDynaRec) dVifUnpack<1>((u8*)data, isFill);
|
if (newVifDynaRec) dVifUnpack<1>((u8*)data, isFill);
|
||||||
else _nVifUnpack(1, (u8*)data, vifRegs.mode, isFill);
|
else _nVifUnpack(1, (u8*)data, vifRegs.mode, isFill);
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,11 +188,6 @@ _vifT void vifUnpackSetup(const u32 *data) {
|
||||||
|
|
||||||
vifStruct& vifX = GetVifX;
|
vifStruct& vifX = GetVifX;
|
||||||
|
|
||||||
if ((vifXRegs.cycle.wl == 0) && (vifXRegs.cycle.wl < vifXRegs.cycle.cl)) {
|
|
||||||
//DevCon.WriteLn("Vif%d CL %d, WL %d Mode %x Mask %x Num %x", idx, vifXRegs.cycle.cl, vifXRegs.cycle.wl, vifXRegs.mode, vifXRegs.mask, (vifXRegs.code >> 16) & 0xff);
|
|
||||||
vifX.cmd = 0;
|
|
||||||
return; // Skipping write and 0 write-cycles, so do nothing!
|
|
||||||
}
|
|
||||||
GetVifX.unpackcalls++;
|
GetVifX.unpackcalls++;
|
||||||
|
|
||||||
if (GetVifX.unpackcalls > 3)
|
if (GetVifX.unpackcalls > 3)
|
||||||
|
@ -216,12 +211,14 @@ _vifT void vifUnpackSetup(const u32 *data) {
|
||||||
|
|
||||||
const u8& gsize = nVifT[vifX.cmd & 0x0f];
|
const u8& gsize = nVifT[vifX.cmd & 0x0f];
|
||||||
|
|
||||||
if (vifXRegs.cycle.wl <= vifXRegs.cycle.cl) {
|
uint wl = vifXRegs.cycle.wl ? vifXRegs.cycle.wl : 256;
|
||||||
|
|
||||||
|
if (wl <= vifXRegs.cycle.cl) { //Skipping write
|
||||||
vifX.tag.size = ((vifNum * gsize) + 3) / 4;
|
vifX.tag.size = ((vifNum * gsize) + 3) / 4;
|
||||||
}
|
}
|
||||||
else {
|
else { //Filling write
|
||||||
int n = vifXRegs.cycle.cl * (vifNum / vifXRegs.cycle.wl) +
|
int n = vifXRegs.cycle.cl * (vifNum / wl) +
|
||||||
_limit(vifNum % vifXRegs.cycle.wl, vifXRegs.cycle.cl);
|
_limit(vifNum % wl, vifXRegs.cycle.cl);
|
||||||
|
|
||||||
vifX.tag.size = ((n * gsize) + 3) >> 2;
|
vifX.tag.size = ((n * gsize) + 3) >> 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,9 +61,9 @@ struct __aligned16 nVifBlock {
|
||||||
u8 num; // [00] Num Field
|
u8 num; // [00] Num Field
|
||||||
u8 upkType; // [01] Unpack Type [usn*1:mask*1:upk*4]
|
u8 upkType; // [01] Unpack Type [usn*1:mask*1:upk*4]
|
||||||
u8 mode; // [02] Mode Field
|
u8 mode; // [02] Mode Field
|
||||||
u8 cl; // [03] CL Field
|
u16 cl; // [03] CL Field
|
||||||
u32 mask; // [04] Mask Field
|
u32 mask; // [04] Mask Field
|
||||||
u8 wl; // [08] WL Field
|
u16 wl; // [08] WL Field
|
||||||
u8 aligned; // [09] Packet Alignment
|
u8 aligned; // [09] Packet Alignment
|
||||||
u8 padding[2];// [10] through [11]
|
u8 padding[2];// [10] through [11]
|
||||||
uptr startPtr; // [12] Start Ptr of RecGen Code
|
uptr startPtr; // [12] Start Ptr of RecGen Code
|
||||||
|
|
|
@ -236,11 +236,6 @@ void VifUnpackSSE_Dynarec::CompileRoutine() {
|
||||||
else {
|
else {
|
||||||
dstIndirect += (16 * skipSize);
|
dstIndirect += (16 * skipSize);
|
||||||
vCL = 0;
|
vCL = 0;
|
||||||
// FIXME
|
|
||||||
// temporary code to avoid an infinite loop until the code is correctly fixed
|
|
||||||
if (blockSize == cycleSize && cycleSize == 0)
|
|
||||||
break;
|
|
||||||
// END FIXME
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,13 +253,9 @@ _vifT static __fi u8* dVifsetVUptr(uint cl, uint wl, bool isFill) {
|
||||||
u8* endmem = VU.Mem + vuMemLimit;
|
u8* endmem = VU.Mem + vuMemLimit;
|
||||||
uint length = (v.block.num > 0) ? (v.block.num * 16) : 4096; // 0 = 256
|
uint length = (v.block.num > 0) ? (v.block.num * 16) : 4096; // 0 = 256
|
||||||
|
|
||||||
|
//wl = wl ? wl : 256; //0 is taken as 256 (KH2)
|
||||||
|
//if (wl == 256) isFill = true;
|
||||||
if (!isFill) {
|
if (!isFill) {
|
||||||
// Accounting for skipping mode: Subtract the last skip cycle, since the skipped part of the run
|
|
||||||
// shouldn't count as wrapped data. Otherwise, a trailing skip can cause the emu to drop back
|
|
||||||
// to the interpreter. -- Refraction (test with MGS3)
|
|
||||||
// FIXME temporary solution to avoid a crash
|
|
||||||
if (wl == 0) wl = 1;
|
|
||||||
// END FIXME
|
|
||||||
uint skipSize = (cl - wl) * 16;
|
uint skipSize = (cl - wl) * 16;
|
||||||
uint blocks = v.block.num / wl;
|
uint blocks = v.block.num / wl;
|
||||||
length += (blocks-1) * skipSize;
|
length += (blocks-1) * skipSize;
|
||||||
|
@ -321,7 +312,7 @@ _vifT __fi void dVifUnpack(const u8* data, bool isFill) {
|
||||||
v.block.num = (u8&)vifRegs.num;
|
v.block.num = (u8&)vifRegs.num;
|
||||||
v.block.mode = (u8&)vifRegs.mode;
|
v.block.mode = (u8&)vifRegs.mode;
|
||||||
v.block.cl = vifRegs.cycle.cl;
|
v.block.cl = vifRegs.cycle.cl;
|
||||||
v.block.wl = vifRegs.cycle.wl;
|
v.block.wl = vifRegs.cycle.wl ? vifRegs.cycle.wl : 256;
|
||||||
v.block.aligned = vif.start_aligned; //MTVU doesn't have a packet size!
|
v.block.aligned = vif.start_aligned; //MTVU doesn't have a packet size!
|
||||||
|
|
||||||
if ((upkType & 0xf) != 9)
|
if ((upkType & 0xf) != 9)
|
||||||
|
|
|
@ -111,8 +111,9 @@ _vifT int nVifUnpack(const u8* data) {
|
||||||
vifStruct& vif = GetVifX;
|
vifStruct& vif = GetVifX;
|
||||||
VIFregisters& vifRegs = vifXRegs;
|
VIFregisters& vifRegs = vifXRegs;
|
||||||
|
|
||||||
|
const uint wl = vifRegs.cycle.wl ? vifRegs.cycle.wl : 256;
|
||||||
const uint ret = aMin(vif.vifpacketsize, vif.tag.size);
|
const uint ret = aMin(vif.vifpacketsize, vif.tag.size);
|
||||||
const bool isFill = (vifRegs.cycle.cl < vifRegs.cycle.wl);
|
const bool isFill = (vifRegs.cycle.cl < wl);
|
||||||
s32 size = ret << 2;
|
s32 size = ret << 2;
|
||||||
|
|
||||||
if (ret == vif.tag.size) { // Full Transfer
|
if (ret == vif.tag.size) { // Full Transfer
|
||||||
|
@ -252,7 +253,7 @@ __ri void __fastcall _nVifUnpackLoop(const u8* data) {
|
||||||
const UNPACKFUNCTYPE ft = VIFfuncTable[idx][doMode ? vifRegs.mode : 0][ ((usn*2*16) + upkNum) ];
|
const UNPACKFUNCTYPE ft = VIFfuncTable[idx][doMode ? vifRegs.mode : 0][ ((usn*2*16) + upkNum) ];
|
||||||
|
|
||||||
pxAssume (vif.cl == 0);
|
pxAssume (vif.cl == 0);
|
||||||
pxAssume (vifRegs.cycle.wl > 0);
|
//pxAssume (vifRegs.cycle.wl > 0);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
u8* dest = getVUptr(idx, vif.tag.addr);
|
u8* dest = getVUptr(idx, vif.tag.addr);
|
||||||
|
|
Loading…
Reference in New Issue