Ejemplo n.º 1
0
void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value)
{
	jASSUME( (mem >= 0x10006000) && (mem < 0x10007000) );
	GIF_LOG("WriteFIFO/GIF, addr=0x%08X\n", mem);

	//psHu64(mem  ) = value[0];
	//psHu64(mem+8) = value[1];

	psHu64(0x6000) = value[0];
	psHu64(0x6008) = value[1];

	if( mtgsThread != NULL )
	{
		const uint count = mtgsThread->PrepDataPacket( GIF_PATH_3, value, 1 );
		jASSUME( count == 1 );
		u64* data = (u64*)mtgsThread->GetDataPacketPtr();
		data[0] = value[0];
		data[1] = value[1];
		mtgsThread->SendDataPacket();
	}
	else
	{
		FreezeXMMRegs(1);
		FreezeMMXRegs(1);
		GSGIFTRANSFER3((u32*)value, 1);
		FreezeMMXRegs(0);
		FreezeXMMRegs(0);
	}
}
Ejemplo n.º 2
0
static __fi bool checkTieBit(tDMA_TAG* &ptag)
{
	if (gifch.chcr.TIE && ptag->IRQ) {
		GIF_LOG("dmaIrq Set");
		gspath3done = true;
		return true;
	}
	return false;
}
Ejemplo n.º 3
0
static u16 QWCinGIFMFIFO(u32 DrainADDR)
{
	u32 ret;

	GIF_LOG("GIF MFIFO Requesting %x QWC from the MFIFO Base %x, SPR MADR %x Drain %x", gifch.qwc, dmacRegs.rbor.ADDR, spr0ch.madr, DrainADDR);
	//Calculate what we have in the fifo.
	if(DrainADDR <= spr0ch.madr) {
		//Drain is below the tadr, calculate the difference between them
		ret = (spr0ch.madr - DrainADDR) >> 4;
	}
Ejemplo n.º 4
0
bool CheckPaths() {
	// Can't do Path 3, so try dma again later...
	if (!CHECK_GIFFIFOHACK) {
		if (!gifUnit.CanDoPath3()) {
			if (!gifUnit.Path3Masked())
			{
				GIF_LOG("Path3 stalled");
				GifDMAInt(128);
			}
			return false;
		}
	}
	return true;
}
Ejemplo n.º 5
0
void __fastcall WriteFIFO_GIF(const mem128_t *value)
{
	GIF_LOG("WriteFIFO/GIF <- %ls", value->ToString().c_str());

	//CopyQWC(&psHu128(GIF_FIFO), value);
	//CopyQWC(&nloop0_packet, value);

	GetMTGS().PrepDataPacket(GIF_PATH_3, 1);
	GIFPath_CopyTag( GIF_PATH_3, value, 1 );
	GetMTGS().SendDataPacket();
	if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH3 )
	{
		if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false;
		gifRegs.stat.APATH = GIF_APATH_IDLE;
		if(gifRegs.stat.P1Q) gsPath1Interrupt();
	}
}
Ejemplo n.º 6
0
void GIFdma()
{
	tDMA_TAG *ptag;
	gscycles = prevcycles;

	if (gifRegs.ctrl.PSE) { // temporarily stop
		Console.WriteLn("Gif dma temp paused? (non MFIFO GIF)");
		GifDMAInt(16);
		return;
	}

	if ((dmacRegs.ctrl.STD == STD_GIF) && (prevcycles != 0)) {
		//Console.WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gifch.madr, psHu32(DMAC_STADR));
		if ((gifch.madr + (gifch.qwc * 16)) > dmacRegs.stadr.ADDR) {
			GifDMAInt(4);
			gscycles = 0;
			return;
		}
		prevcycles = 0;
		gifch.qwc = 0;
	}

	if ((gifch.chcr.MOD == CHAIN_MODE) && (!gspath3done) && gifch.qwc == 0) // Chain Mode
	{
        ptag = ReadTag();
        if (ptag == NULL) return;
		//DevCon.Warning("GIF Reading Tag MSK = %x", vif1Regs.mskpath3);
		GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx tadr=%lx", ptag[1]._u32, ptag[0]._u32, gifch.qwc, ptag->ID, gifch.madr, gifch.tadr);
		if (!CHECK_GIFFIFOHACK)gifRegs.stat.FQC = std::min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
		if (dmacRegs.ctrl.STD == STD_GIF)
		{
			// there are still bugs, need to also check if gifch.madr +16*qwc >= stadr, if not, stall
			if ((ptag->ID == TAG_REFS) && ((gifch.madr + (gifch.qwc * 16)) > dmacRegs.stadr.ADDR))
			{
				// stalled.
				// We really need to test this. Pay attention to prevcycles, as it used to trigger GIFchains in the code above. (rama)
				//Console.WriteLn("GS Stall Control start Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gifch.madr, psHu32(DMAC_STADR));
				prevcycles = gscycles;
				gifch.tadr -= 16;
				gifch.qwc = 0;
				hwDmacIrq(DMAC_STALL_SIS);
				GifDMAInt(gscycles);
				gscycles = 0;
				return;
			}
		}

		checkTieBit(ptag);
	}
	else if (dmacRegs.ctrl.STD == STD_GIF && gifch.chcr.MOD == NORMAL_MODE)
	{
		Console.WriteLn("GIF DMA Stall in Normal mode not implemented - Report which game to PCSX2 Team");
	}


	if (!CHECK_GIFFIFOHACK) {
		gifRegs.stat.FQC = std::min((u16)0x10, gifch.qwc);// FQC=31, hack ;) (for values of 31 that equal 16) [ used to be 0xE00; // APATH=3]
		clearFIFOstuff(true);
	}

	// Transfer Dn_QWC from Dn_MADR to GIF
	if (gifch.qwc > 0) // Normal Mode
	{
		if (CheckPaths() == false) return;

		GIFchain();	//Transfers the data set by the switch
		//if (gscycles < 8) DevCon.Warning("GSCycles = %d", gscycles);
		GifDMAInt(gscycles);
		return;
	} else if(!gspath3done) GIFdma(); //Loop round if there was a blank tag, causes hell otherwise with P3 masking games.

	//QWC == 0 && gspath3done == true - End of DMA
	prevcycles = 0;
	//if (gscycles < 8) DevCon.Warning("1 GSCycles = %d", gscycles);
	GifDMAInt(16);
}
Ejemplo n.º 7
0
__fi void gifInterrupt()
{
	GIF_LOG("gifInterrupt caught!");
	gifCheckPathStatus();

	if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE)
	{
		if(vif1Regs.stat.VGW)
		{
			//Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back.
			if(!(cpuRegs.interrupt & (1<<DMAC_VIF1)))
				CPU_INT(DMAC_VIF1, 1);

			//Make sure it loops if the GIF packet is empty to prepare for the next packet
			//or end if it was the end of a packet.
			//This must trigger after VIF retriggers as VIf might instantly mask Path3
			if (!gifUnit.Path3Masked() || gifch.qwc == 0) {
				GifDMAInt(16);
			}
			return;
		}
		
	}

	if (dmacRegs.ctrl.MFD == MFD_GIF) { // GIF MFIFO
		//Console.WriteLn("GIF MFIFO");
		gifMFIFOInterrupt();
		return;
	}	

	if (CHECK_GIFFIFOHACK) {

		if (int amtRead = gif_fifo.read(true)) {

			if (!gifUnit.Path3Masked() || gifRegs.stat.FQC < 16) {
				GifDMAInt(amtRead * BIAS);
				return;
			}
		}
		else {

			if (!gifUnit.CanDoPath3() && gifRegs.stat.FQC == 16)
			{
				if (gifch.qwc > 0 || gspath3done == false) {
					if (!gifUnit.Path3Masked()) {
						GifDMAInt(128);
					}
					return;
				}
			}
		}
	}
	

	if (gifUnit.gsSIGNAL.queued) {
		GIF_LOG("Path 3 Paused");
		GifDMAInt(128);
		return;
	}
	
	if (!(gifch.chcr.STR)) return;

	if ((gifch.qwc > 0) || (!gspath3done)) {
		if (!dmacRegs.ctrl.DMAE) {
			Console.Warning("gs dma masked, re-scheduling...");
			// re-raise the int shortly in the future
			GifDMAInt( 64 );
			return;
		}
		GIFdma();
		
		return;
	}

	//Double check as we might have read the fifo as it's ending the DMA
	gifCheckPathStatus();

	if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE)
	{
		if (vif1Regs.stat.VGW)
		{
			//Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back.
			if (!(cpuRegs.interrupt & (1 << DMAC_VIF1))) {
				CPU_INT(DMAC_VIF1, 1);
			}
		}
	}
	if (!CHECK_GIFFIFOHACK)
	{
		gifRegs.stat.FQC = 0;
		clearFIFOstuff(false);
	}
	gscycles		 = 0;
	gspath3done		 = false;
	gifch.chcr.STR	 = false;

	hwDmacIrq(DMAC_GIF);
	GIF_LOG("GIF DMA End QWC in fifo %x APATH = %x OPH = %x state = %x", gifRegs.stat.FQC, gifRegs.stat.APATH, gifRegs.stat.OPH, gifUnit.gifPath[GIF_PATH_3].state);
}
Ejemplo n.º 8
0
__fi void gifInterrupt()
{
	GIF_LOG("gifInterrupt caught!");
	if( gifRegs.stat.APATH == 3 )
	{
		gifRegs.stat.APATH = 0;
		gifRegs.stat.OPH = 0;
		if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE || gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT) 
		{
			if(gifUnit.checkPaths(1,1,0)) gifUnit.Execute(false, true);
		}

	}

	//Required for Path3 Masking timing!
	if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
			gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;

	if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE)
	{
		if(vif1Regs.stat.VGW)
		{
			//Check if VIF is in a cycle or is currently "idle" waiting for GIF to come back.
			if(!(cpuRegs.interrupt & (1<<DMAC_VIF1)))
				CPU_INT(DMAC_VIF1, 1);

			//Make sure it loops if the GIF packet is empty to prepare for the next packet
			//or end if it was the end of a packet.
			if(!gifUnit.Path3Masked() || gifch.qwc == 0) 
				CPU_INT(DMAC_GIF, 16);
			return;
		}
		
	}

	if (dmacRegs.ctrl.MFD == MFD_GIF) { // GIF MFIFO
		//Console.WriteLn("GIF MFIFO");
		gifMFIFOInterrupt();
		return;
	}	

	if (gifUnit.gsSIGNAL.queued) {
		//DevCon.WriteLn("Path 3 Paused");
		CPU_INT(DMAC_GIF, 128);
		return;
	}
	
	if (!(gifch.chcr.STR)) return;

	if ((gifch.qwc > 0) || (!gspath3done)) {
		if (!dmacRegs.ctrl.DMAE) {
			Console.Warning("gs dma masked, re-scheduling...");
			// re-raise the int shortly in the future
			CPU_INT( DMAC_GIF, 64 );
			return;
		}
		GIFdma();
		return;
	}

	gifRegs.stat.FQC = 0;
	gscycles		 = 0;
	gspath3done		 = false;
	gifch.chcr.STR	 = false;
	clearFIFOstuff(false);
	hwDmacIrq(DMAC_GIF);
	DMA_LOG("GIF DMA End");
}