Пример #1
0
bool _VIF0chain()
{
	u32 *pMem;

	if (vif0ch.qwc == 0)
	{
		vif0.inprogress = 0;
		return true;
	}

	pMem = (u32*)dmaGetAddr(vif0ch.madr, false);
	if (pMem == NULL)
	{
		vif0.cmd = 0;
		vif0.tag.size = 0;
		vif0ch.qwc = 0;
		return true;
	}

	VIF_LOG("VIF0chain size=%d, madr=%lx, tadr=%lx",
	        vif0ch.qwc, vif0ch.madr, vif0ch.tadr);

	if (vif0.irqoffset.enabled)
		return VIF0transfer(pMem + vif0.irqoffset.value, vif0ch.qwc * 4 - vif0.irqoffset.value);
	else
		return VIF0transfer(pMem, vif0ch.qwc * 4);
}
Пример #2
0
void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value)
{
	jASSUME( (mem >= 0x10004000) && (mem < 0x10005000) );

	VIF_LOG("WriteFIFO/VIF0, addr=0x%08X\n", mem);
	
	//psHu64(mem  ) = value[0];
	//psHu64(mem+8) = value[1];

	psHu64(0x4000) = value[0];
	psHu64(0x4008) = value[1];
	
	vif0ch->qwc += 1;
	int ret = VIF0transfer((u32*)value, 4, 0);
	assert( ret == 0 ); // vif stall code not implemented
}
Пример #3
0
//////////////////////////////////////////////////////////////////////////
// WriteFIFO Pages
//
void __fastcall WriteFIFO_VIF0(const mem128_t *value)
{
    VIF_LOG("WriteFIFO/VIF0 <- %ls", value->ToString().c_str());

    vif0ch.qwc += 1;
    if(vif0.irqoffset.value != 0 && vif0.vifstalled.enabled == true) DevCon.Warning("Offset on VIF0 FIFO start!");
    bool ret = VIF0transfer((u32*)value, 4);

    if (vif0.cmd)
    {
        if(vif0.done && vif0ch.qwc == 0)	vif0Regs.stat.VPS = VPS_WAITING;
    }
    else
    {
        vif0Regs.stat.VPS = VPS_IDLE;
    }

    pxAssertDev( ret, "vif stall code not implemented" );
}
Пример #4
0
__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;
	}
}