Beispiel #1
0
int  _SPR0chain()
{
	tDMA_TAG *pMem;
	int partialqwc = 0;
	if (spr0ch.qwc == 0) return 0;
	pMem = SPRdmaGetAddr(spr0ch.madr, true);
	if (pMem == NULL) return -1;

	switch (dmacRegs.ctrl.MFD)
	{
		case MFD_VIF1:
		case MFD_GIF:
			partialqwc = spr0ch.qwc;

			if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR)
				Console.WriteLn("SPR MFIFO Write outside MFIFO area");
			else
				mfifotransferred += partialqwc;

			hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), partialqwc);
			spr0ch.madr += partialqwc << 4;
			spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK);
			spr0ch.sadr += partialqwc << 4;
			spr0ch.qwc -= partialqwc;
			break;

		case NO_MFD:
		case MFD_RESERVED:
			
			//Taking an arbitary small value for games which like to check the QWC/MADR instead of STR, so get most of
			//the cycle delay out of the way before the end.
			partialqwc = spr0ch.qwc;
			memcpy_qwc(pMem, &psSu128(spr0ch.sadr), partialqwc);

			// clear VU mem also!
			TestClearVUs(spr0ch.madr, partialqwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)

			spr0ch.madr += partialqwc << 4;
			spr0ch.sadr += partialqwc << 4;
			spr0ch.qwc -= partialqwc;

			break;
	}

	

	return (partialqwc); // bus is 1/2 the ee speed
}
Beispiel #2
0
int  _SPR0chain()
{
	tDMA_TAG *pMem;
	int partialqwc = 0;
	if (spr0ch.qwc == 0) return 0;
	pMem = SPRdmaGetAddr(spr0ch.madr, true);
	if (pMem == NULL) return -1;

	if(spr0ch.madr >= dmacRegs.rbor.ADDR && spr0ch.madr < (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16))
	{
			partialqwc = spr0ch.qwc;

			if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR)
				Console.WriteLn("SPR MFIFO Write outside MFIFO area");
			else
				mfifotransferred += partialqwc;

			hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), partialqwc);
			spr0ch.madr += partialqwc << 4;
			spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK);
			spr0ch.sadr += partialqwc << 4;
			spr0ch.qwc -= partialqwc;
			
			spr0finished = true;
	}
	else
	{
			
			//Taking an arbitary small value for games which like to check the QWC/MADR instead of STR, so get most of
			//the cycle delay out of the way before the end.
			partialqwc = spr0ch.qwc;
			memcpy_qwc(pMem, &psSu128(spr0ch.sadr), partialqwc);

			// clear VU mem also!
			TestClearVUs(spr0ch.madr, partialqwc);

			spr0ch.madr += partialqwc << 4;
			spr0ch.sadr += partialqwc << 4;
			spr0ch.qwc -= partialqwc;

	}

	

	return (partialqwc); // bus is 1/2 the ee speed
}
Beispiel #3
0
void _SPR0interleave()
{
	int qwc = spr0ch.qwc;
	int sqwc = dmacRegs.sqwc.SQWC;
	int tqwc = dmacRegs.sqwc.TQWC;
	tDMA_TAG *pMem;

	if (tqwc == 0) tqwc = qwc;
	//Console.WriteLn("dmaSPR0 interleave");
	SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
	        spr0ch.qwc, tqwc, sqwc, spr0ch.madr, spr0ch.sadr);

	CPU_INT(DMAC_FROM_SPR, qwc * BIAS);

	while (qwc > 0)
	{
		spr0ch.qwc = std::min(tqwc, qwc);
		qwc -= spr0ch.qwc;
		pMem = SPRdmaGetAddr(spr0ch.madr, true);

		switch (dmacRegs.ctrl.MFD)
 		{
			case MFD_VIF1:
			case MFD_GIF:
				hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc);
				mfifotransferred += spr0ch.qwc;
				break;

			case NO_MFD:
			case MFD_RESERVED:
				// clear VU mem also!
				TestClearVUs(spr0ch.madr, spr0ch.qwc);
				memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc);
				break;
 		}
		spr0ch.sadr += spr0ch.qwc * 16;
		spr0ch.madr += (sqwc + spr0ch.qwc) * 16;
	}

	spr0ch.qwc = 0;
}