コード例 #1
0
ファイル: sif2.cpp プロジェクト: AdmiralCurtiss/pcsx2
static __fi void Sif2End()
{
	psHu32(SBUS_F240) &= ~0x80;
	psHu32(SBUS_F240) &= ~0x8000;

	DMA_LOG("SIF2 DMA End");
}
コード例 #2
0
ファイル: Sif1.cpp プロジェクト: tsiru/pcsx2
static __fi void Sif1End()
{
	psHu32(SBUS_F240) &= ~0x40;
	psHu32(SBUS_F240) &= ~0x4000;

	DMA_LOG("SIF1 DMA End");
}
コード例 #3
0
ファイル: Sif0.cpp プロジェクト: docbray/pcsx2-online
static __fi void Sif0End()
{
	psHu32(SBUS_F240) &= ~0x20;
	psHu32(SBUS_F240) &= ~0x2000;

	DMA_LOG("SIF0 DMA End");
}
コード例 #4
0
ファイル: sif2.cpp プロジェクト: AdmiralCurtiss/pcsx2
__fi void dmaSIF2()
{
	DevCon.Warning("SIF2 EE CHCR %x", sif2dma.chcr._u32);
	SIF_LOG(wxString(L"dmaSIF2" + sif2dma.cmqt_to_str()).To8BitData());

	if (sif2.fifo.readPos != sif2.fifo.writePos)
	{
		SIF_LOG("warning, sif2.fifoReadPos != sif2.fifoWritePos");
	}

	//if(sif2dma.chcr.MOD == CHAIN_MODE && sif2dma.qwc > 0) DevCon.Warning(L"SIF2 QWC on Chain CHCR " + sif2dma.chcr.desc());
	psHu32(SBUS_F240) |= 0x8000;
	sif2.ee.busy = true;

	// Okay, this here is needed currently (r3644). 
	// FFX battles in the thunder plains map die otherwise, Phantasy Star 4 as well
	// These 2 games could be made playable again by increasing the time the EE or the IOP run,
	// showing that this is very timing sensible.
	// Doing this DMA unfortunately brings back an old warning in Legend of Legaia though, but it still works.

	//Updated 23/08/2011: The hangs are caused by the EE suspending SIF1 DMA and restarting it when in the middle 
	//of processing a "REFE" tag, so the hangs can be solved by forcing the ee.end to be false
	// (as it should always be at the beginning of a DMA).  using "if iop is busy" flags breaks Tom Clancy Rainbow Six.
	// Legend of Legaia doesn't throw a warning either :)
	//sif2.ee.end = false;
	
	SIF2Dma();

}
コード例 #5
0
ファイル: iCOP0.cpp プロジェクト: Aced14/pcsx2
// emits "setup" code for a COP0 branch test.  The instruction immediately following
// this should be a conditional Jump -- JZ or JNZ normally.
static void _setupBranchTest()
{
	_eeFlushAllUnused();

	// COP0 branch conditionals are based on the following equation:
	//  (((psHu16(DMAC_STAT) | ~psHu16(DMAC_PCR)) & 0x3ff) == 0x3ff)
	// BC0F checks if the statement is false, BC0T checks if the statement is true.

	// note: We only want to compare the 16 bit values of DMAC_STAT and PCR.
	// But using 32-bit loads here is ok (and faster), because we mask off
	// everything except the lower 10 bits away.

	xMOV(eax, ptr[(&psHu32(DMAC_PCR) )]);
	xMOV(ecx, 0x3ff );		// ECX is our 10-bit mask var
	xNOT(eax);
	xOR(eax, ptr[(&psHu32(DMAC_STAT) )]);
	xAND(eax, ecx);
	xCMP(eax, ecx);
}
コード例 #6
0
ファイル: LegacyDmac.cpp プロジェクト: mauzus/progenitor
__fi u32 dmacRead32( u32 mem )
{
	// Fixme: OPH hack. Toggle the flag on each GIF_STAT access. (rama)
	if (IsPageFor(mem) && (mem == GIF_STAT) && CHECK_OPHFLAGHACK)
	{
		gifRegs.stat.OPH = !gifRegs.stat.OPH;
	}
	
	return psHu32(mem);
}
コード例 #7
0
ファイル: LegacyDmac.cpp プロジェクト: mauzus/progenitor
// Returns true if the DMA is enabled and executed successfully.  Returns false if execution
// was blocked (DMAE or master DMA enabler).
static bool QuickDmaExec( void (*func)(), u32 mem)
{
	bool ret = false;
    DMACh& reg = (DMACh&)psHu32(mem);

	if (reg.chcr.STR && dmacRegs.ctrl.DMAE && !psHu8(DMAC_ENABLER+2))
	{
		func();
		ret = true;
	}

	return ret;
}
コード例 #8
0
ファイル: sif2.cpp プロジェクト: AdmiralCurtiss/pcsx2
__fi bool ReadFifoSingleWord()
{
	u32 ptag[4];

	//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif2dma.madr);
	SIF_LOG("Read Fifo SIF2 Single Word IOP Busy %x Fifo Size %x SIF2 CHCR %x", sif2.iop.busy, sif2.fifo.size, HW_DMA2_CHCR);


	sif2.fifo.read((u32*)&ptag[0], 1);
	psHu32(0x1000f3e0) = ptag[0];
	if (sif2.fifo.size == 0) psxHu32(0x1000f300) |= 0x4000000;
	if (sif2.iop.busy && sif2.fifo.size <= 8)SIF2Dma();
	return true;
}
コード例 #9
0
ファイル: LegacyDmac.cpp プロジェクト: AmbientMalice/pcsx2
__fi u32 dmacRead32( u32 mem )
{
	// Fixme: OPH hack. Toggle the flag on GIF_STAT access. (rama)
	if (IsPageFor(mem) && (mem == GIF_STAT) && CHECK_OPHFLAGHACK)
	{
		static unsigned counter = 1;
		if (++counter == 8)
			counter = 2;
		// Set OPH and APATH from counter, cycling paths and alternating OPH
		return gifRegs.stat._u32 & ~(7 << 9) | (counter & 1 ? counter << 9 : 0);
	}
	
	return psHu32(mem);
}
コード例 #10
0
ファイル: FiFo.cpp プロジェクト: mfitz21/pcsx2-rr
void __fastcall ReadFIFO_page_5(u32 mem, u64 *out)
{
	jASSUME( (mem >= 0x10005000) && (mem < 0x10006000) );

	VIF_LOG("ReadFIFO/VIF1, addr=0x%08X\n", mem);

	if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) )
		DevCon::Notice( "Reading from vif1 fifo when stalled" );

	if (vif1Regs->stat & 0x800000)
	{
		if (--psHu32(D1_QWC) == 0)
			vif1Regs->stat&= ~0x1f000000;
	}

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

	out[0] = psHu64(0x5000);
	out[1] = psHu64(0x5008);
}
コード例 #11
0
ファイル: LegacyDmac.cpp プロジェクト: mauzus/progenitor
static __ri void DmaExec( void (*func)(), u32 mem, u32 value )
{
	DMACh& reg = (DMACh&)psHu32(mem);
    tDMA_CHCR chcr(value);

	//It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
	if (reg.chcr.STR)
	{
		const uint channel = ChannelNumber(mem);

		if(psHu8(DMAC_ENABLER+2) == 1) //DMA is suspended so we can allow writes to anything
		{
			//If it stops the DMA, we need to clear any pending interrupts so the DMA doesnt continue.
			if(chcr.STR == 0)
			{
				//DevCon.Warning(L"32bit %s DMA Stopped on Suspend", ChcrName(mem));
				if(channel == 1)
				{
					cpuClearInt( 10 );
					QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel
				}
				else if(channel == 2)
				{
					cpuClearInt( 11 );
					QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel
				}
				
				cpuClearInt( channel );
				QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel
			}
			//Sanity Check for possible future bug fix0rs ;p
			//Spams on Persona 4 opening.
			//if(reg.chcr.TAG != chcr.TAG) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Active", ChcrName(mem), chcr.TAG, reg.chcr.TAG, reg.qwc);
			//Here we update the LOWER CHCR, if a chain is stopped half way through, it can be manipulated in to a different mode
			//But we need to preserve the existing tag for now
			reg.chcr.set((reg.chcr.TAG << 16) | chcr.lower());
			return;
		}
		else //Else the DMA is running (Not Suspended), so we cant touch it!
		{
			//As the manual states "Fields other than STR can only be written to when the DMA is stopped"
			//Also "The DMA may not stop properly just by writing 0 to STR"
			//So the presumption is that STR can be written to (ala force stop the DMA) but nothing else

			if(chcr.STR == 0)
			{
				//DevCon.Warning(L"32bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem), reg.chcr._u32, chcr._u32);
				reg.chcr.STR = 0;
				//We need to clear any existing DMA loops that are in progress else they will continue!

				if(channel == 1)
				{
					cpuClearInt( 10 );
					QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel
				}
				else if(channel == 2)
				{
					cpuClearInt( 11 );
					QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel
				}
				
				cpuClearInt( channel );
				QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel
			}
			//else DevCon.Warning(L"32bit Attempted to change %s CHCR (Currently %x) with %x while DMA active, ignoring QWC = %x", ChcrName(mem), reg.chcr._u32, chcr._u32, reg.qwc);
			return;
		}

	}

	//if(reg.chcr.TAG != chcr.TAG && chcr.MOD == CHAIN_MODE) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Not Active", ChcrName(mem), chcr.TAG, reg.chcr.TAG, reg.qwc);

	reg.chcr.set(value);

	if (reg.chcr.STR && dmacRegs.ctrl.DMAE && !psHu8(DMAC_ENABLER+2))
	{
		func();
	}
	else if(reg.chcr.STR)
	{
		//DevCon.Warning(L"32bit %s DMA Start while DMAC Disabled\n", ChcrName(mem));
		QueuedDMA._u16 |= (1 << ChannelNumber(mem)); //Queue the DMA up to be started then the DMA's are Enabled and or the Suspend is lifted
	} //else QueuedDMA._u16 &~= (1 << ChannelNumber(mem)); //
}
コード例 #12
0
ファイル: LegacyDmac.cpp プロジェクト: AmbientMalice/pcsx2
static __ri void DmaExec( void (*func)(), u32 mem, u32 value )
{
	DMACh& reg = (DMACh&)psHu32(mem);
    tDMA_CHCR chcr(value);

	//It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
	if (reg.chcr.STR)
	{
		const uint channel = ChannelNumber(mem);

		//As the manual states "Fields other than STR can only be written to when the DMA is stopped"
		//Also "The DMA may not stop properly just by writing 0 to STR"
		//So the presumption is that STR can be written to (ala force stop the DMA) but nothing else
		//If the developer wishes to alter any of the other fields, it must be done AFTER the STR has been written,
		//it will not work before or during this event.
		if(chcr.STR == 0)
		{
			//DevCon.Warning(L"32bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem), reg.chcr._u32, chcr._u32);
			reg.chcr.STR = 0;
			//We need to clear any existing DMA loops that are in progress else they will continue!

			if(channel == 1)
			{
				cpuClearInt( 10 );
				QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel
			}
			else if(channel == 2)
			{
				cpuClearInt( 11 );
				QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel
			}
				
			cpuClearInt( channel );
			QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel
		}
		//else DevCon.Warning(L"32bit Attempted to change %s CHCR (Currently %x) with %x while DMA active, ignoring QWC = %x", ChcrName(mem), reg.chcr._u32, chcr._u32, reg.qwc);
		return;
	}

	//if(reg.chcr.TAG != chcr.TAG && chcr.MOD == CHAIN_MODE) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Not Active", ChcrName(mem), chcr.TAG, reg.chcr.TAG, reg.qwc);

	reg.chcr.set(value);

	//Final Fantasy XII sets the DMA Mode to 3 which doesn't exist. On some channels (like SPR) this will break logic completely. so lets assume they mean chain.
	if (reg.chcr.MOD == 0x3)
	{
		static bool warned; //Check if the warning has already been output to console, to prevent constant spam.
		if (!warned)
		{
			DevCon.Warning(L"%s CHCR.MOD set to 3, assuming 1 (chain)", ChcrName(mem));
			warned = true;
		}
		reg.chcr.MOD = 0x1;
	}
	if (reg.chcr.STR && dmacRegs.ctrl.DMAE && !psHu8(DMAC_ENABLER+2))
	{
		func();
	}
	else if(reg.chcr.STR)
	{
		//DevCon.Warning(L"32bit %s DMA Start while DMAC Disabled\n", ChcrName(mem));
		QueuedDMA._u16 |= (1 << ChannelNumber(mem)); //Queue the DMA up to be started then the DMA's are Enabled and or the Suspend is lifted
	} //else QueuedDMA._u16 &~= (1 << ChannelNumber(mem)); //
}