Exemplo n.º 1
0
void CALLBACK SPU2readDMAMem(u16 *pMem, int size, int channel)
{
	u32 spuaddr = C_SPUADDR(channel);

	SPU2_LOG("SPU2 readDMAMem(%d) size %x, addr: %x\n", channel,  size, pMem);

	for (uint i = 0; i < (uint)size; i++)
	{
		*pMem++ = *(u16*)(spu2mem + spuaddr);
		if (spu2attr(channel).irq && (C_IRQA(channel) == spuaddr))
		{
			C_SPUADDR_SET(spuaddr, channel);
			IRQINFO |= (4 * (channel + 1));
			SPU2_LOG("SPU2readDMAMem(%d):interrupt\n", channel);
			irqCallbackSPU2();
		}

		spuaddr++;		   // inc spu addr
		if (spuaddr > 0x0fffff) spuaddr=0; // wrap at 2Mb
	}

	spuaddr += 19; //Transfer Local To Host TSAH/L + Data Size + 20 (already +1'd)
	C_SPUADDR_SET(spuaddr, channel);

	 // DMA complete
	spu2stat_clear_80(channel);
	SPUStartCycle[channel] = SPUCycles;
	SPUTargetCycle[channel] = size;
	interrupt |=  (1 << (1 + channel));
}
Exemplo n.º 2
0
void SPU2writeDMAMem(u16* pMem, int size, int channel)
{
	u32 spuaddr;
	ADMA *Adma = &adma[channel];
	s32 offset = (channel == 0) ? 0 : 0x400;

	SPU2_LOG("SPU2 writeDMAMem size %x, addr: %x(spu2:%x)"/*, ctrl: %x, adma: %x\n"*/, \
	size, pMem, C_SPUADDR(channel)/*, spu2Ru16(REG_C0_CTRL + offset), spu2Ru16(REG_C0_ADMAS + offset)*/);

	if (spu2admas(channel) && (spu2attr(channel).dma == 0) && size)
	{
		if (!Adma->Enabled ) Adma->Index = 0;

		Adma->MemAddr = pMem;
		Adma->AmountLeft = size;
		SPUTargetCycle[channel] = size;
		spu2stat_clear_80(channel);
		if (!Adma->Enabled || (Adma->Index > 384))
		{
			C_SPUADDR_SET(0, channel);
			if (ADMASWrite(channel))
			{
				SPUStartCycle[channel] = SPUCycles;
				interrupt |= (1 << (1 + channel));
			}
		}
		Adma->Enabled = 1;

		return;
	}

#ifdef ZEROSPU2_DEVBUILD
	if ((conf.Log && conf.options & OPTION_RECORDING) && (channel == 1))
		LogPacketSound(pMem, 0x8000);
#endif

	spuaddr = C_SPUADDR(channel);
	memcpy((u8*)(spu2mem + spuaddr),(u8*)pMem,size << 1);
	spuaddr += size;
	C_SPUADDR_SET(spuaddr, channel);

	if (spu2attr(channel).irq && (spuaddr < C_IRQA(channel) && (C_IRQA(channel) <= (spuaddr + 0x20))))
	{
		IRQINFO |= 4 * (channel + 1);
		SPU2_LOG("SPU2writeDMAMem:interrupt\n");
		irqCallbackSPU2();
	}

	if (spuaddr > 0xFFFFE) spuaddr = 0x2800;
	C_SPUADDR_SET(spuaddr, channel);

	MemAddr[channel] += size << 1;
	spu2stat_clear_80(channel);
	SPUStartCycle[channel] = SPUCycles;
	SPUTargetCycle[channel] = size;
	interrupt |= (1 << (channel + 1));
}
Exemplo n.º 3
0
s32 CALLBACK SPU2init()
{
	LOG_CALLBACK("SPU2init()\n");
	spu2Log = fopen("logs/spu2.txt", "w");
	if (spu2Log) setvbuf(spu2Log, NULL,  _IONBF, 0);

	SPU2_LOG("Spu2 null version %d,%d\n",SPU2_REVISION,SPU2_BUILD);
	SPU2_LOG("SPU2init\n");

#ifdef _WIN32
	QueryPerformanceFrequency(&g_counterfreq);
#endif

	InitApi();

	spu2regs = (s8*)malloc(0x10000);
	spu2mem = (u16*)malloc(0x200000); // 2Mb
	memset(spu2regs, 0, 0x10000);
	memset(spu2mem, 0, 0x200000);
	if ((spu2mem == NULL) || (spu2regs == NULL))
	{
		SysMessage("Error allocating Memory\n");
		return -1;
	}

	memset(dwEndChannel2, 0, sizeof(dwEndChannel2));
	memset(dwNewChannel2, 0, sizeof(dwNewChannel2));
	memset(iFMod, 0, sizeof(iFMod));
	memset(s_buffers, 0, sizeof(s_buffers));

	InitADSR();

	memset(voices, 0, sizeof(voices));
	// last 24 channels have higher mem offset
	for (s32 i = 0; i < 24; ++i)
		voices[i+24].memoffset = 0x400;

	// init each channel
	for (u32 i = 0; i < ArraySize(voices); ++i)
	{
		voices[i].init(i);
	}

	return 0;
}
Exemplo n.º 4
0
void CALLBACK SPU2interruptDMA(int channel)
{
	SPU2_LOG("SPU2 interruptDMA(%d)\n", channel);
	spu2attr(channel).dma = 0;
	spu2stat_set_80(channel);
}