Exemple #1
0
void V_Core::StartADMAWrite(u16 *pMem, u32 sz)
{
#ifndef ENABLE_NEW_IOPDMA_SPU2
	int size = (sz)&(~511);

	if(MsgAutoDMA()) ConLog("* SPU2-X: DMA%c AutoDMA Transfer of %d bytes to %x (%02x %x %04x).\n",
		GetDmaIndexChar(), size<<1, TSA, DMABits, AutoDMACtrl, (~Regs.ATTR)&0x7fff);

	InputDataProgress = 0;
	if((AutoDMACtrl&(Index+1))==0)
	{
		TSA = 0x2000 + (Index<<10);
		DMAICounter = size;
	}
	else if(size>=512)
	{
		InputDataLeft = size;
		if(AdmaInProgress==0)
		{
#ifdef PCM24_S1_INTERLEAVE
			if((Index==1)&&((PlayMode&8)==8))
			{
				AutoDMAReadBuffer(Index,1);
			}
			else
			{
				AutoDMAReadBuffer(Index,0);
			}
#else
			if( ((PlayMode&4)==4) && (Index==0) )
				Cores[0].InputPosRead=0;

			AutoDMAReadBuffer(0);
#endif

			if(size==512)
				DMAICounter = size;
		}

		AdmaInProgress = 1;
	}
	else
	{
		InputDataLeft	= 0;
		DMAICounter		= 1;
	}
	TADR = MADR + (size<<1);
#endif
}
Exemple #2
0
void StartADMAWrite(int core,u16 *pMem, u32 sz)
{
	int size=(sz)&(~511);

	if(MsgAutoDMA()) ConLog(" * SPU2: DMA%c AutoDMA Transfer of %d bytes to %x (%02x %x %04x).\n",
		(core==0)?'4':'7',size<<1,Cores[core].TSA,Cores[core].DMABits,Cores[core].AutoDMACtrl,(~Cores[core].Regs.ATTR)&0x7fff);

	Cores[core].InputDataProgress=0;
	if((Cores[core].AutoDMACtrl&(core+1))==0)
	{
		Cores[core].TSA=0x2000+(core<<10);
		Cores[core].DMAICounter=size;
	}
	else if(size>=512)
	{
		Cores[core].InputDataLeft=size;
		if(Cores[core].AdmaInProgress==0)
		{
#ifdef PCM24_S1_INTERLEAVE
			if((core==1)&&((PlayMode&8)==8))
			{
				AutoDMAReadBuffer(core,1);
			}
			else
			{
				AutoDMAReadBuffer(core,0);
			}
#else
			if(((PlayMode&4)==4)&&(core==0))
				Cores[0].InputPos=0;

			AutoDMAReadBuffer(core,0);
#endif

			if(size==512)
				Cores[core].DMAICounter=size;
		}

		Cores[core].AdmaInProgress=1;
	}
	else
	{
		Cores[core].InputDataLeft=0;
		Cores[core].DMAICounter=1;
	}
	Cores[core].TADR=Cores[core].MADR+(size<<1);
}
Exemple #3
0
s32 V_Core::NewDmaWrite(u32* data, u32 bytesLeft, u32* bytesProcessed)
{
#ifdef ENABLE_NEW_IOPDMA_SPU2
	bool DmaStarting = !DmaStarted;
	DmaStarted = true;

	if(bytesLeft<2)
	{
		// execute interrupt code early
		NewDmaInterrupt();

		*bytesProcessed = bytesLeft;
		return 0;
	}

	if( IsDevBuild )
	{
		DebugCores[Index].lastsize = bytesLeft;
		DebugCores[Index].dmaFlag = 1;
	}

	TSA &= ~7;

	bool adma_enable = ((AutoDMACtrl&(Index+1))==(Index+1));

	if(adma_enable)
	{
		TSA&=0x1fff;

		if(MsgAutoDMA() && DmaStarting) ConLog("* SPU2-X: DMA%c AutoDMA Transfer of %d bytes to %x (%02x %x %04x).\n",
			GetDmaIndexChar(), bytesLeft<<1, TSA, DMABits, AutoDMACtrl, (~Regs.ATTR)&0x7fff);

		u32 processed = 0;
		while((AutoDmaFree>0)&&(bytesLeft>=0x400))
		{
			// copy block

			LogAutoDMA( Index ? ADMA7LogFile : ADMA4LogFile );

			// HACKFIX!! DMAPtr can be invalid after a savestate load, so the savestate just forces it
			// to NULL and we ignore it here.  (used to work in old VM editions of PCSX2 with fixed
			// addressing, but new PCSX2s have dynamic memory addressing).

			s16* mptr = (s16*)data;

			if(false)//(mode)
			{
				//memcpy((ADMATempBuffer+(InputPosWrite<<1)),mptr,0x400);
				memcpy(GetMemPtr(0x2000+(Index<<10)+InputPosWrite),mptr,0x400);
				mptr+=0x200;

				// Flag interrupt?  If IRQA occurs between start and dest, flag it.
				// Important: Test both core IRQ settings for either DMA!

				u32 dummyTSA = 0x2000+(Index<<10)+InputPosWrite;
				u32 dummyTDA = 0x2000+(Index<<10)+InputPosWrite+0x200;

				for( int i=0; i<2; i++ )
				{
					if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) )
					{
						SetIrqCall(i);
					}
				}
			}
			else
			{
				//memcpy((ADMATempBuffer+InputPosWrite),mptr,0x200);
				memcpy(GetMemPtr(0x2000+(Index<<10)+InputPosWrite),mptr,0x200);
				mptr+=0x100;

				// Flag interrupt?  If IRQA occurs between start and dest, flag it.
				// Important: Test both core IRQ settings for either DMA!

				u32 dummyTSA = 0x2000+(Index<<10)+InputPosWrite;
				u32 dummyTDA = 0x2000+(Index<<10)+InputPosWrite+0x100;

				for( int i=0; i<2; i++ )
				{
					if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) )
					{
						SetIrqCall(i);
					}
				}

				//memcpy((ADMATempBuffer+InputPosWrite+0x200),mptr,0x200);
				memcpy(GetMemPtr(0x2200+(Index<<10)+InputPosWrite),mptr,0x200);
				mptr+=0x100;

				// Flag interrupt?  If IRQA occurs between start and dest, flag it.
				// Important: Test both core IRQ settings for either DMA!

				dummyTSA = 0x2200+(Index<<10)+InputPosWrite;
				dummyTDA = 0x2200+(Index<<10)+InputPosWrite+0x100;

				for( int i=0; i<2; i++ )
				{
					if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) )
					{
						SetIrqCall(i);
					}
				}

			}
			// See ReadInput at mixer.cpp for explanation on the commented out lines
			//

			InputPosWrite = (InputPosWrite + 0x100) & 0x1ff;
			AutoDmaFree -= 0x200;
			processed += 0x400;
			bytesLeft -= 0x400;
		}

		if(processed==0)
		{
			*bytesProcessed = 0;
			return 768*15; // pause a bit
		}
		else
		{
			*bytesProcessed = processed;
			return 0; // auto pause
		}
	}
	else
	{
		if(MsgDMA() && DmaStarting) ConLog("* SPU2-X: DMA%c Transfer of %d bytes to %x (%02x %x %04x).\n",
			GetDmaIndexChar(),bytesLeft,TSA,DMABits,AutoDMACtrl,(~Regs.ATTR)&0x7fff);

		if(bytesLeft> 2048)
			bytesLeft = 2048;

		// TODO: Sliced transfers?
		PlainDMAWrite((u16*)data,bytesLeft/2);
	}
	Regs.STATX &= ~0x80;
	Regs.STATX |= 0x400;

#endif
	*bytesProcessed = bytesLeft;
	return 0;
}