void __fastcall WriteFIFO_VIF1(const mem128_t *value) { VIF_LOG("WriteFIFO/VIF1 <- %ls", value->ToString().c_str()); if (vif1Regs.stat.FDR) { DevCon.Warning("writing to fifo when fdr is set!"); } if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) ) { DevCon.Warning("writing to vif1 fifo when stalled"); } if (vif1.irqoffset.value != 0 && vif1.vifstalled.enabled == true) { DevCon.Warning("Offset on VIF1 FIFO start!"); } vif1ch.qwc += 1; bool ret = VIF1transfer((u32*)value, 4); if (vif1.cmd) { if (vif1.done && !vif1ch.qwc) vif1Regs.stat.VPS = VPS_WAITING; } else vif1Regs.stat.VPS = VPS_IDLE; if( gifRegs.stat.APATH == 2 && gifUnit.gifPath[1].isDone()) { gifRegs.stat.APATH = 0; gifRegs.stat.OPH = 0; vif1Regs.stat.VGW = false; //Let vif continue if it's stuck on a flush if(gifUnit.checkPaths(1,0,1)) gifUnit.Execute(false, true); } pxAssertDev( ret, "vif stall code not implemented" ); }
void __fastcall WriteFIFO_VIF1(const mem128_t *value) { VIF_LOG("WriteFIFO/VIF1 <- %ls", value->ToString().c_str()); if (vif1Regs.stat.FDR) { DevCon.Warning("writing to fifo when fdr is set!"); } if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) ) { DevCon.Warning("writing to vif1 fifo when stalled"); } if (vif1.irqoffset != 0 && vif1.vifstalled == true) { DevCon.Warning("Offset on VIF1 FIFO start!"); } vif1ch.qwc += 1; bool ret = VIF1transfer((u32*)value, 4); if (vif1.cmd) { if (vif1.done && !vif1ch.qwc) vif1Regs.stat.VPS = VPS_WAITING; } else vif1Regs.stat.VPS = VPS_IDLE; pxAssertDev( ret, "vif stall code not implemented" ); }
void __fastcall WriteFIFO_VIF1(const mem128_t *value) { VIF_LOG("WriteFIFO/VIF1 <- %ls", value->ToString().c_str()); if (vif1Regs.stat.FDR) DevCon.Warning("writing to fifo when fdr is set!"); if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) ) DevCon.Warning("writing to vif1 fifo when stalled"); vif1ch.qwc += 1; if(vif1.irqoffset != 0 && vif1.vifstalled == true) DevCon.Warning("Offset on VIF1 FIFO start!"); bool ret = VIF1transfer((u32*)value, 4); if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2) { if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false; gifRegs.stat.APATH = GIF_APATH_IDLE; if(gifRegs.stat.P1Q) gsPath1Interrupt(); } if (vif1.cmd) { if(vif1.done == true && vif1ch.qwc == 0) vif1Regs.stat.VPS = VPS_WAITING; } else { vif1Regs.stat.VPS = VPS_IDLE; } pxAssertDev( ret, "vif stall code not implemented" ); }
bool _VIF1chain() { u32 *pMem; if (vif1ch.qwc == 0) { vif1.inprogress &= ~1; vif1.irqoffset.value = 0; vif1.irqoffset.enabled = false; return true; } // Clarification - this is TO memory mode, for some reason i used the other way round >.< if (vif1.dmamode == VIF_NORMAL_TO_MEM_MODE) { vif1TransferToMemory(); vif1.inprogress &= ~1; return true; } pMem = (u32*)dmaGetAddr(vif1ch.madr, !vif1ch.chcr.DIR); if (pMem == NULL) { vif1.cmd = 0; vif1.tag.size = 0; vif1ch.qwc = 0; return true; } VIF_LOG("VIF1chain size=%d, madr=%lx, tadr=%lx", vif1ch.qwc, vif1ch.madr, vif1ch.tadr); if (vif1.irqoffset.enabled) return VIF1transfer(pMem + vif1.irqoffset.value, vif1ch.qwc * 4 - vif1.irqoffset.value, false); else return VIF1transfer(pMem, vif1ch.qwc * 4, false); }
void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value) { jASSUME( (mem >= 0x10005000) && (mem < 0x10006000) ); VIF_LOG("WriteFIFO/VIF1, addr=0x%08X\n", mem); //psHu64(mem ) = value[0]; //psHu64(mem+8) = value[1]; psHu64(0x5000) = value[0]; psHu64(0x5008) = value[1]; if(vif1Regs->stat & VIF1_STAT_FDR) DevCon::Notice("writing to fifo when fdr is set!"); if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) ) DevCon::Notice("writing to vif1 fifo when stalled"); vif1ch->qwc += 1; int ret = VIF1transfer((u32*)value, 4, 0); assert( ret == 0 ); // vif stall code not implemented }
__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; } }