static __fi tDMA_TAG* ReadTag2() { tDMA_TAG* ptag = dmaGetAddr(gifch.tadr, false); //Set memory pointer to TADR gifch.unsafeTransfer(ptag); gifch.madr = ptag[1]._u32; gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID); return ptag; }
static __fi tDMA_TAG* ReadTag() { tDMA_TAG* ptag = dmaGetAddr(gifch.tadr, false); //Set memory pointer to TADR if (!(gifch.transfer("Gif", ptag))) return NULL; gifch.madr = ptag[1]._u32; //MADR = ADDR field + SPR gscycles += 2; // Add 1 cycles from the QW read for the tag gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID); return ptag; }
__fi void vif1SetupTransfer() { tDMA_TAG *ptag; switch (vif1.dmamode) { case VIF_CHAIN_MODE: ptag = dmaGetAddr(vif1ch.tadr, false); //Set memory pointer to TADR if (!(vif1ch.transfer("Vif1 Tag", ptag))) return; vif1ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR g_vif1Cycles += 1; // Add 1 g_vifCycles from the QW read for the tag VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx", ptag[1]._u32, ptag[0]._u32, vif1ch.qwc, ptag->ID, vif1ch.madr, vif1ch.tadr); if (!vif1.done && ((dmacRegs.ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1 { // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall if ((vif1ch.madr + vif1ch.qwc * 16) >= dmacRegs.stadr.ADDR) { // stalled hwDmacIrq(DMAC_STALL_SIS); return; } } vif1.inprogress &= ~1; if (vif1ch.chcr.TTE) { // Transfer dma tag if tte is set bool ret; static __aligned16 u128 masked_tag; masked_tag._u64[0] = 0; masked_tag._u64[1] = *((u64*)ptag + 1); VIF_LOG("\tVIF1 SrcChain TTE=1, data = 0x%08x.%08x", masked_tag._u32[3], masked_tag._u32[2]); if (vif1.irqoffset.enabled) { ret = VIF1transfer((u32*)&masked_tag + vif1.irqoffset.value, 4 - vif1.irqoffset.value, true); //Transfer Tag on stall //ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset); //Transfer Tag on stall } else { //Some games (like killzone) do Tags mid unpack, the nops will just write blank data //to the VU's, which breaks stuff, this is where the 128bit packet will fail, so we ignore the first 2 words vif1.irqoffset.value = 2; vif1.irqoffset.enabled = true; ret = VIF1transfer((u32*)&masked_tag + 2, 2, true); //Transfer Tag //ret = VIF1transfer((u32*)ptag + 2, 2); //Transfer Tag } if (!ret && vif1.irqoffset.enabled) { vif1.inprogress &= ~1; //Better clear this so it has to do it again (Jak 1) return; //IRQ set by VIFTransfer } } vif1.irqoffset.value = 0; vif1.irqoffset.enabled = false; vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID); if(vif1ch.qwc > 0) vif1.inprogress |= 1; //Check TIE bit of CHCR and IRQ bit of tag if (vif1ch.chcr.TIE && ptag->IRQ) { VIF_LOG("dmaIrq Set"); //End Transfer vif1.done = true; return; } break; } }
__fi void vif0SetupTransfer() { tDMA_TAG *ptag; switch (vif0.dmamode) { case VIF_NORMAL_TO_MEM_MODE: vif0.inprogress = 1; vif0.done = true; g_vif0Cycles = 2; break; case VIF_CHAIN_MODE: ptag = dmaGetAddr(vif0ch.tadr, false); //Set memory pointer to TADR if (!(vif0ch.transfer("vif0 Tag", ptag))) return; vif0ch.madr = ptag[1]._u32; //MADR = ADDR field + SPR g_vif0Cycles += 1; // Add 1 g_vifCycles from the QW read for the tag // Transfer dma tag if tte is set VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx", ptag[1]._u32, ptag[0]._u32, vif0ch.qwc, ptag->ID, vif0ch.madr, vif0ch.tadr); vif0.inprogress = 0; if (vif0ch.chcr.TTE) { // Transfer dma tag if tte is set bool ret; static __aligned16 u128 masked_tag; masked_tag._u64[0] = 0; masked_tag._u64[1] = *((u64*)ptag + 1); VIF_LOG("\tVIF0 SrcChain TTE=1, data = 0x%08x.%08x", masked_tag._u32[3], masked_tag._u32[2]); if (vif0.irqoffset.enabled) { ret = VIF0transfer((u32*)&masked_tag + vif0.irqoffset.value, 4 - vif0.irqoffset.value, true); //Transfer Tag on stall //ret = VIF0transfer((u32*)ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset); //Transfer Tag on stall } else { //Some games (like killzone) do Tags mid unpack, the nops will just write blank data //to the VU's, which breaks stuff, this is where the 128bit packet will fail, so we ignore the first 2 words vif0.irqoffset.value = 2; vif0.irqoffset.enabled = true; ret = VIF0transfer((u32*)&masked_tag + 2, 2, true); //Transfer Tag //ret = VIF0transfer((u32*)ptag + 2, 2); //Transfer Tag } if (!ret && vif0.irqoffset.enabled) { vif0.inprogress = 0; //Better clear this so it has to do it again (Jak 1) return; //IRQ set by VIFTransfer } } vif0.irqoffset.value = 0; vif0.irqoffset.enabled = false; vif0.done |= hwDmacSrcChainWithStack(vif0ch, ptag->ID); if(vif0ch.qwc > 0) vif0.inprogress = 1; //Check TIE bit of CHCR and IRQ bit of tag if (vif0ch.chcr.TIE && ptag->IRQ) { VIF_LOG("dmaIrq Set"); //End Transfer vif0.done = true; return; } break; } }