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
|
||||
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);
|
||||
else _nVifUnpack(1, (u8*)data, vifRegs.mode, isFill);
|
||||
}
|
||||
|
|
|
@ -188,11 +188,6 @@ _vifT void vifUnpackSetup(const u32 *data) {
|
|||
|
||||
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++;
|
||||
|
||||
if (GetVifX.unpackcalls > 3)
|
||||
|
@ -216,12 +211,14 @@ _vifT void vifUnpackSetup(const u32 *data) {
|
|||
|
||||
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;
|
||||
}
|
||||
else {
|
||||
int n = vifXRegs.cycle.cl * (vifNum / vifXRegs.cycle.wl) +
|
||||
_limit(vifNum % vifXRegs.cycle.wl, vifXRegs.cycle.cl);
|
||||
else { //Filling write
|
||||
int n = vifXRegs.cycle.cl * (vifNum / wl) +
|
||||
_limit(vifNum % wl, vifXRegs.cycle.cl);
|
||||
|
||||
vifX.tag.size = ((n * gsize) + 3) >> 2;
|
||||
}
|
||||
|
|
|
@ -61,9 +61,9 @@ struct __aligned16 nVifBlock {
|
|||
u8 num; // [00] Num Field
|
||||
u8 upkType; // [01] Unpack Type [usn*1:mask*1:upk*4]
|
||||
u8 mode; // [02] Mode Field
|
||||
u8 cl; // [03] CL Field
|
||||
u16 cl; // [03] CL Field
|
||||
u32 mask; // [04] Mask Field
|
||||
u8 wl; // [08] WL Field
|
||||
u16 wl; // [08] WL Field
|
||||
u8 aligned; // [09] Packet Alignment
|
||||
u8 padding[2];// [10] through [11]
|
||||
uptr startPtr; // [12] Start Ptr of RecGen Code
|
||||
|
|
|
@ -236,11 +236,6 @@ void VifUnpackSSE_Dynarec::CompileRoutine() {
|
|||
else {
|
||||
dstIndirect += (16 * skipSize);
|
||||
vCL = 0;
|
||||
// FIXME
|
||||
// temporary code to avoid an infinite loop until the code is correctly fixed
|
||||
if (blockSize == cycleSize && cycleSize == 0)
|
||||
break;
|
||||
// END FIXME
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,18 +248,14 @@ _vifT static __fi u8* dVifsetVUptr(uint cl, uint wl, bool isFill) {
|
|||
vifStruct& vif = MTVU_VifX;
|
||||
const VURegs& VU = vuRegs[idx];
|
||||
const uint vuMemLimit = idx ? 0x4000 : 0x1000;
|
||||
|
||||
|
||||
u8* startmem = VU.Mem + (vif.tag.addr & (vuMemLimit-0x10));
|
||||
u8* endmem = VU.Mem + vuMemLimit;
|
||||
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) {
|
||||
// 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 blocks = v.block.num / wl;
|
||||
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.mode = (u8&)vifRegs.mode;
|
||||
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!
|
||||
|
||||
if ((upkType & 0xf) != 9)
|
||||
|
|
|
@ -111,10 +111,11 @@ _vifT int nVifUnpack(const u8* data) {
|
|||
vifStruct& vif = GetVifX;
|
||||
VIFregisters& vifRegs = vifXRegs;
|
||||
|
||||
const uint wl = vifRegs.cycle.wl ? vifRegs.cycle.wl : 256;
|
||||
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;
|
||||
|
||||
|
||||
if (ret == vif.tag.size) { // Full Transfer
|
||||
if (v.bSize) { // Last transfer was partial
|
||||
memcpy(&v.buffer[v.bSize], data, size);
|
||||
|
@ -252,7 +253,7 @@ __ri void __fastcall _nVifUnpackLoop(const u8* data) {
|
|||
const UNPACKFUNCTYPE ft = VIFfuncTable[idx][doMode ? vifRegs.mode : 0][ ((usn*2*16) + upkNum) ];
|
||||
|
||||
pxAssume (vif.cl == 0);
|
||||
pxAssume (vifRegs.cycle.wl > 0);
|
||||
//pxAssume (vifRegs.cycle.wl > 0);
|
||||
|
||||
do {
|
||||
u8* dest = getVUptr(idx, vif.tag.addr);
|
||||
|
|
Loading…
Reference in New Issue