Пример #1
0
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" );
}
Пример #2
0
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" );
}
Пример #3
0
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" );
}
Пример #4
0
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);
}
Пример #5
0
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
}
Пример #6
0
__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;
	}
}