/[pcsx2_0.9.7]/trunk/pcsx2/SPR.cpp
ViewVC logotype

Diff of /trunk/pcsx2/SPR.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

--- trunk/pcsx2/SPR.cpp	2010/09/07 03:24:11	31
+++ trunk/pcsx2/SPR.cpp	2010/09/07 11:08:22	62
@@ -51,95 +51,96 @@
 {
 	tDMA_TAG *pMem;
 
-	if (spr0->qwc == 0) return 0;
-	pMem = SPRdmaGetAddr(spr0->madr, true);
+	if (spr0ch.qwc == 0) return 0;
+	pMem = SPRdmaGetAddr(spr0ch.madr, true);
 	if (pMem == NULL) return -1;
 
-	switch (dmacRegs->ctrl.MFD)
+	switch (dmacRegs.ctrl.MFD)
 	{
 		case MFD_VIF1:
 		case MFD_GIF:
-			if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR)
+			if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR)
 				Console.WriteLn("SPR MFIFO Write outside MFIFO area");
 			else
-				mfifotransferred += spr0->qwc;
+				mfifotransferred += spr0ch.qwc;
 
-			hwMFIFOWrite(spr0->madr, &psSu8(spr0->sadr), spr0->qwc << 4);
-			spr0->madr += spr0->qwc << 4;
-			spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
+			hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc);
+			spr0ch.madr += spr0ch.qwc << 4;
+			spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK);
 			break;
 
 		case NO_MFD:
 		case MFD_RESERVED:
-			memcpy_fast((u8*)pMem, &psSu8(spr0->sadr), spr0->qwc << 4);
+			memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc);
 
 			// clear VU mem also!
-			TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
-			spr0->madr += spr0->qwc << 4;
+			TestClearVUs(spr0ch.madr, spr0ch.qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
+			spr0ch.madr += spr0ch.qwc << 4;
 			break;
 	}
 
-	spr0->sadr += spr0->qwc << 4;
+	spr0ch.sadr += spr0ch.qwc << 4;
 
-	return (spr0->qwc) * BIAS; // bus is 1/2 the ee speed
+	return (spr0ch.qwc); // bus is 1/2 the ee speed
 }
 
-__forceinline void SPR0chain()
+__fi void SPR0chain()
 {
-	_SPR0chain();
-	spr0->qwc = 0;
+	CPU_INT(DMAC_FROM_SPR, _SPR0chain() / BIAS);
+	spr0ch.qwc = 0;
 }
 
 void _SPR0interleave()
 {
-	int qwc = spr0->qwc;
-	int sqwc = dmacRegs->sqwc.SQWC;
-	int tqwc = dmacRegs->sqwc.TQWC;
+	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",
-	        spr0->qwc, tqwc, sqwc, spr0->madr, spr0->sadr);
+	        spr0ch.qwc, tqwc, sqwc, spr0ch.madr, spr0ch.sadr);
+
+	CPU_INT(DMAC_FROM_SPR, qwc / BIAS);
 
 	while (qwc > 0)
 	{
-		spr0->qwc = std::min(tqwc, qwc);
-		qwc -= spr0->qwc;
-		pMem = SPRdmaGetAddr(spr0->madr, true);
+		spr0ch.qwc = std::min(tqwc, qwc);
+		qwc -= spr0ch.qwc;
+		pMem = SPRdmaGetAddr(spr0ch.madr, true);
 
-		switch (dmacRegs->ctrl.MFD)
+		switch (dmacRegs.ctrl.MFD)
  		{
 			case MFD_VIF1:
 			case MFD_GIF:
-				hwMFIFOWrite(spr0->madr, &psSu8(spr0->sadr), spr0->qwc << 4);
-				mfifotransferred += spr0->qwc;
+				hwMFIFOWrite(spr0ch.madr, &psSu128(spr0ch.sadr), spr0ch.qwc);
+				mfifotransferred += spr0ch.qwc;
 				break;
 
 			case NO_MFD:
 			case MFD_RESERVED:
 				// clear VU mem also!
-				TestClearVUs(spr0->madr, spr0->qwc << 2);
-				memcpy_fast((u8*)pMem, &psSu8(spr0->sadr), spr0->qwc << 4);
+				TestClearVUs(spr0ch.madr, spr0ch.qwc << 2);
+				memcpy_qwc(pMem, &psSu128(spr0ch.sadr), spr0ch.qwc);
 				break;
  		}
-		spr0->sadr += spr0->qwc * 16;
-		spr0->madr += (sqwc + spr0->qwc) * 16;
+		spr0ch.sadr += spr0ch.qwc * 16;
+		spr0ch.madr += (sqwc + spr0ch.qwc) * 16;
 	}
 
-	spr0->qwc = 0;
-	spr0finished = true;
+	spr0ch.qwc = 0;
 }
 
-static __forceinline void _dmaSPR0()
+static __fi void _dmaSPR0()
 {
-	if (dmacRegs->ctrl.STS == STS_fromSPR)
+	if (dmacRegs.ctrl.STS == STS_fromSPR)
 	{
-		Console.WriteLn("SPR0 stall %d", dmacRegs->ctrl.STS);
+		Console.WriteLn("SPR0 stall %d", dmacRegs.ctrl.STS);
 	}
 
 	// Transfer Dn_QWC from SPR to Dn_MADR
-	switch(spr0->chcr.MOD)
+	switch(spr0ch.chcr.MOD)
 	{
 		case NORMAL_MODE:
 		{
@@ -150,26 +151,25 @@
 		case CHAIN_MODE:
 		{
 			tDMA_TAG *ptag;
-			bool done = FALSE;
+			bool done = false;
 
-			if (spr0->qwc > 0)
+			if (spr0ch.qwc > 0)
 			{
 				SPR0chain();
-				spr0finished = true;
 				return;
 			}
 			// Destination Chain Mode
-			ptag = (tDMA_TAG*)&psSu32(spr0->sadr);
-			spr0->sadr += 16;
+			ptag = (tDMA_TAG*)&psSu32(spr0ch.sadr);
+			spr0ch.sadr += 16;
 
-			spr0->unsafeTransfer(ptag);
+			spr0ch.unsafeTransfer(ptag);
 
-			spr0->madr = ptag[1]._u32;					//MADR = ADDR field + SPR
+			spr0ch.madr = ptag[1]._u32;					//MADR = ADDR field + SPR
 
 			SPR_LOG("spr0 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
-				ptag[1]._u32, ptag[0]._u32, spr0->qwc, ptag->ID, spr0->madr, spr0->sadr);
+				ptag[1]._u32, ptag[0]._u32, spr0ch.qwc, ptag->ID, spr0ch.madr, spr0ch.sadr);
 
-			if (dmacRegs->ctrl.STS == STS_fromSPR)   // STS == fromSPR
+			if (dmacRegs.ctrl.STS == STS_fromSPR)   // STS == fromSPR
 			{
 				Console.WriteLn("SPR stall control");
 			}
@@ -177,7 +177,7 @@
 			switch (ptag->ID)
 			{
 				case TAG_CNTS: // CNTS - Transfer QWC following the tag (Stall Control)
-					if (dmacRegs->ctrl.STS == STS_fromSPR) dmacRegs->stadr.ADDR = spr0->madr + (spr0->qwc * 16);					//Copy MADR to DMAC_STADR stall addr register
+					if (dmacRegs.ctrl.STS == STS_fromSPR) dmacRegs.stadr.ADDR = spr0ch.madr + (spr0ch.qwc * 16);					//Copy MADR to DMAC_STADR stall addr register
 					break;
 
 				case TAG_CNT: // CNT - Transfer QWC following the tag.
@@ -191,28 +191,22 @@
 
 			SPR0chain();
 
-			if (spr0->chcr.TIE && ptag->IRQ)  			 //Check TIE bit of CHCR and IRQ bit of tag
+			if (spr0ch.chcr.TIE && ptag->IRQ)  			 //Check TIE bit of CHCR and IRQ bit of tag
 			{
 				//Console.WriteLn("SPR0 TIE");
 				done = true;
 			}
 
 			spr0finished = done;
-
-			if (!done)
-			{
-				ptag = (tDMA_TAG*)&psSu32(spr0->sadr);		//Set memory pointer to SADR
-				CPU_INT(DMAC_FROM_SPR, /*ptag[0].QWC / BIAS*/ 4 ); // the lower 16bits of the tag / BIAS);
-				return;
-			}
 			SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
-				ptag[1]._u32, ptag[0]._u32, spr0->qwc, ptag->ID, spr0->madr);
+				ptag[1]._u32, ptag[0]._u32, spr0ch.qwc, ptag->ID, spr0ch.madr);
 			break;
 		}
 		//case INTERLEAVE_MODE:
 		default:
 		{
 			_SPR0interleave();
+			spr0finished = true;
 			break;
 		}
 	}
@@ -220,118 +214,119 @@
 
 void SPRFROMinterrupt()
 {
-	_dmaSPR0();
-
-	if(mfifotransferred != 0)
+	
+	if (!spr0finished || spr0ch.qwc > 0) 
 	{
-        switch (dmacRegs->ctrl.MFD)
+		_dmaSPR0();
+
+		if(mfifotransferred != 0)
 		{
-			case MFD_VIF1: // Most common case.
-			{
-				if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("VIF MFIFO Write outside MFIFO area");
-				spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
-				//Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr);
-				mfifoVIF1transfer(mfifotransferred);
-				mfifotransferred = 0;
-				if (vif1ch->chcr.STR) return;
-				break;
-			}
-			case MFD_GIF:
+			switch (dmacRegs.ctrl.MFD)
 			{
-				if ((spr0->madr & ~dmacRegs->rbsr.RMSK) != dmacRegs->rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area");
-				spr0->madr = dmacRegs->rbor.ADDR + (spr0->madr & dmacRegs->rbsr.RMSK);
-				//Console.WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr);
-				mfifoGIFtransfer(mfifotransferred);
-				mfifotransferred = 0;
-				if (gif->chcr.STR) return;
-				break;
+				case MFD_VIF1: // Most common case.
+				{
+					if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("VIF MFIFO Write outside MFIFO area");
+					spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK);
+					//Console.WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", vif1ch.chcr._u32, vif1ch.madr, vif1ch.tadr);
+					mfifoVIF1transfer(mfifotransferred);
+					mfifotransferred = 0;
+					break;
+				}
+				case MFD_GIF:
+				{
+					if ((spr0ch.madr & ~dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("GIF MFIFO Write outside MFIFO area");
+					spr0ch.madr = dmacRegs.rbor.ADDR + (spr0ch.madr & dmacRegs.rbsr.RMSK);
+					//Console.WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr);
+					mfifoGIFtransfer(mfifotransferred);
+					mfifotransferred = 0;
+					break;
+				}
+				default:
+					break;
 			}
-			default:
-				break;
 		}
+		return;
 	}
-	if (!spr0finished) return;
 
 
-	spr0->chcr.STR = false;
+	spr0ch.chcr.STR = false;
 	hwDmacIrq(DMAC_FROM_SPR);
 }
 
 void dmaSPR0()   // fromSPR
 {
 	SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc  = %lx, sadr = %lx",
-	        spr0->chcr._u32, spr0->madr, spr0->qwc, spr0->sadr);
+	        spr0ch.chcr._u32, spr0ch.madr, spr0ch.qwc, spr0ch.sadr);
+
+	
+	spr0finished = false; //Init
 
-	if ((spr0->chcr.MOD == CHAIN_MODE) && spr0->qwc == 0)
+	if(spr0ch.chcr.MOD == CHAIN_MODE && spr0ch.qwc > 0) 
 	{
-		tDMA_TAG *ptag;
-		ptag = (tDMA_TAG*)&psSu32(spr0->sadr);		//Set memory pointer to SADR
-		CPU_INT(DMAC_FROM_SPR, /*ptag[0].QWC / BIAS*/ 4 );
-		return;
+		//DevCon.Warning(L"SPR0 QWC on Chain " + spr0ch.chcr.desc());
+		if (spr0ch.chcr.tag().ID == TAG_END) // but not TAG_REFE?
+		{
+			spr0finished = true;
+		}
 	}
-	if(spr0->chcr.MOD == CHAIN_MODE && spr0->qwc > 0) DevCon.Warning(L"SPR0 QWC on Chain " + spr0->chcr.desc());
-	// COMPLETE HACK!!! For now at least..  FFX Videos dont rely on interrupts or reading DMA values
-	// It merely assumes that the last one has finished then starts another one (broke with the DMA fix)
-	// This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction)
-	CPU_INT(DMAC_FROM_SPR, /*spr0->qwc / BIAS*/ 4 );
+
+	SPRFROMinterrupt();
 }
 
-__forceinline static void SPR1transfer(u32 *data, int size)
+__fi static void SPR1transfer(const void* data, int qwc)
 {
-	memcpy_fast(&psSu8(spr1->sadr), (u8*)data, size << 2);
-
-	spr1->sadr += size << 2;
+	memcpy_qwc(&psSu128(spr1ch.sadr), data, qwc);
+	spr1ch.sadr += qwc * 16;
 }
 
 int  _SPR1chain()
 {
 	tDMA_TAG *pMem;
 
-	if (spr1->qwc == 0) return 0;
+	if (spr1ch.qwc == 0) return 0;
 
-	pMem = SPRdmaGetAddr(spr1->madr, false);
+	pMem = SPRdmaGetAddr(spr1ch.madr, false);
 	if (pMem == NULL) return -1;
 
-	SPR1transfer((u32*)pMem, spr1->qwc << 2);
-	spr1->madr += spr1->qwc << 4;
+	SPR1transfer(pMem, spr1ch.qwc);
+	spr1ch.madr += spr1ch.qwc * 16;
 
-	return (spr1->qwc) * BIAS;
+	return (spr1ch.qwc);
 }
 
-__forceinline void SPR1chain()
+__fi void SPR1chain()
 {
-	_SPR1chain();
-	spr1->qwc = 0;
+	CPU_INT(DMAC_TO_SPR, _SPR1chain() / BIAS);
+	spr1ch.qwc = 0;
 }
 
 void _SPR1interleave()
 {
-	int qwc = spr1->qwc;
-	int sqwc = dmacRegs->sqwc.SQWC;
-	int tqwc =  dmacRegs->sqwc.TQWC;
+	int qwc = spr1ch.qwc;
+	int sqwc = dmacRegs.sqwc.SQWC;
+	int tqwc =  dmacRegs.sqwc.TQWC;
 	tDMA_TAG *pMem;
 
 	if (tqwc == 0) tqwc = qwc;
 	SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
-	        spr1->qwc, tqwc, sqwc, spr1->madr, spr1->sadr);
-
+	        spr1ch.qwc, tqwc, sqwc, spr1ch.madr, spr1ch.sadr);
+	CPU_INT(DMAC_TO_SPR, qwc / BIAS);
 	while (qwc > 0)
 	{
-		spr1->qwc = std::min(tqwc, qwc);
-		qwc -= spr1->qwc;
-		pMem = SPRdmaGetAddr(spr1->madr, false);
-		memcpy_fast(&psSu8(spr1->sadr), (u8*)pMem, spr1->qwc << 4);
-		spr1->sadr += spr1->qwc * 16;
-		spr1->madr += (sqwc + spr1->qwc) * 16;
+		spr1ch.qwc = std::min(tqwc, qwc);
+		qwc -= spr1ch.qwc;
+		pMem = SPRdmaGetAddr(spr1ch.madr, false);
+		memcpy_qwc(&psSu128(spr1ch.sadr), pMem, spr1ch.qwc);
+		spr1ch.sadr += spr1ch.qwc * 16;
+		spr1ch.madr += (sqwc + spr1ch.qwc) * 16;
 	}
 
-	spr1->qwc = 0;
-	spr1finished = true;
+	spr1ch.qwc = 0;
 }
 
 void _dmaSPR1()   // toSPR work function
 {
-	switch(spr1->chcr.MOD)
+	switch(spr1ch.chcr.MOD)
 	{
 		case NORMAL_MODE:
 		{
@@ -346,39 +341,39 @@
 			tDMA_TAG *ptag;
 			bool done = false;
 
-			if (spr1->qwc > 0)
+			if (spr1ch.qwc > 0)
 			{
+				SPR_LOG("spr1 Normal or in Progress size=%d, addr=%lx taddr=%lx saddr=%lx", spr1ch.qwc, spr1ch.madr, spr1ch.tadr, spr1ch.sadr);
 				// Transfer Dn_QWC from Dn_MADR to SPR1
 				SPR1chain();
-				spr1finished = true;
 				return;
 			}
 			// Chain Mode
 
-			ptag = SPRdmaGetAddr(spr1->tadr, false);		//Set memory pointer to TADR
+			ptag = SPRdmaGetAddr(spr1ch.tadr, false);		//Set memory pointer to TADR
 
-			if (!spr1->transfer("SPR1 Tag", ptag))
+			if (!spr1ch.transfer("SPR1 Tag", ptag))
 			{
 				done = true;
 				spr1finished = done;
 			}
 
-			spr1->madr = ptag[1]._u32;						//MADR = ADDR field + SPR
+			spr1ch.madr = ptag[1]._u32;						//MADR = ADDR field + SPR
 
 			// Transfer dma tag if tte is set
-			if (spr1->chcr.TTE)
+			if (spr1ch.chcr.TTE)
 			{
 				SPR_LOG("SPR TTE: %x_%x\n", ptag[3]._u32, ptag[2]._u32);
-				SPR1transfer((u32*)ptag, 4);				//Transfer Tag
+				SPR1transfer(ptag, 1);				//Transfer Tag
 			}
 
-			SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx",
-				ptag[1]._u32, ptag[0]._u32, spr1->qwc, ptag->ID, spr1->madr);
+			SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx taddr=%lx saddr=%lx",
+				ptag[1]._u32, ptag[0]._u32, spr1ch.qwc, ptag->ID, spr1ch.madr, spr1ch.tadr, spr1ch.sadr);
 
-			done = (hwDmacSrcChain(spr1, ptag->ID));
+			done = (hwDmacSrcChain(spr1ch, ptag->ID));
 			SPR1chain();										//Transfers the data set by the switch
 
-			if (spr1->chcr.TIE && ptag->IRQ)  			//Check TIE bit of CHCR and IRQ bit of tag
+			if (spr1ch.chcr.TIE && ptag->IRQ)  			//Check TIE bit of CHCR and IRQ bit of tag
 			{
 				SPR_LOG("dmaIrq Set");
 
@@ -387,17 +382,13 @@
 			}
 
 			spr1finished = done;
-			if (!done)
-			{
-				ptag = SPRdmaGetAddr(spr1->tadr, false);		//Set memory pointer to TADR
-				CPU_INT(DMAC_TO_SPR, /*(ptag[0].QWC / BIAS)*/ 4 );// the lower 16 bits of the tag / BIAS);
-			}
 			break;
 		}
 		//case INTERLEAVE_MODE:
 		default:
 		{
 			_SPR1interleave();
+			spr1finished = true;
 			break;
 		}
 	}
@@ -407,29 +398,34 @@
 {
 	SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc  = 0x%x\n"
 	        "        tadr = 0x%x, sadr = 0x%x",
-	        spr1->chcr._u32, spr1->madr, spr1->qwc,
-	        spr1->tadr, spr1->sadr);
-
-	if ((spr1->chcr.MOD == CHAIN_MODE) && (spr1->qwc == 0))
+	        spr1ch.chcr._u32, spr1ch.madr, spr1ch.qwc,
+	        spr1ch.tadr, spr1ch.sadr);
+	
+	spr1finished = false; //Init
+	
+	if(spr1ch.chcr.MOD == CHAIN_MODE && spr1ch.qwc > 0) 
 	{
-		tDMA_TAG *ptag;
-		ptag = SPRdmaGetAddr(spr1->tadr, false);		//Set memory pointer to TADR
-		CPU_INT(DMAC_TO_SPR, /*ptag[0].QWC / BIAS*/ 4 );
-		return;
+		//DevCon.Warning(L"SPR1 QWC on Chain " + spr1ch.chcr.desc());
+		if ((spr1ch.chcr.tag().ID == TAG_END) || (spr1ch.chcr.tag().ID == TAG_REFE))
+		{
+			spr1finished = true;
+		}
 	}
-	if(spr1->chcr.MOD == CHAIN_MODE && spr1->qwc > 0) DevCon.Warning(L"SPR1 QWC on Chain " + spr1->chcr.desc());
-	// COMPLETE HACK!!! For now at least..  FFX Videos dont rely on interrupts or reading DMA values
-	// It merely assumes that the last one has finished then starts another one (broke with the DMA fix)
-	// This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction)
-	CPU_INT(DMAC_TO_SPR, /*spr1->qwc / BIAS*/ 4 );
+
+	SPRTOinterrupt();
 }
 
 void SPRTOinterrupt()
 {
-	_dmaSPR1();
-	if (!spr1finished) return;
+	SPR_LOG("SPR1 Interrupt");
+	if (!spr1finished || spr1ch.qwc > 0)
+	{
+		_dmaSPR1();
+		return;
+	}
 
-	spr1->chcr.STR = false;
+	SPR_LOG("SPR1 End");
+	spr1ch.chcr.STR = false;
 	hwDmacIrq(DMAC_TO_SPR);
 }
 

 

  ViewVC Help
Powered by ViewVC 1.1.22