Beispiel #1
0
void S9xDoDMA (uint8 Channel)
{
    uint8 Work;

    if (Channel > 7 || CPU.InDMA)
	return;

    CPU.InDMA = TRUE;
    bool8 in_sa1_dma = FALSE;
    uint8 *in_sdd1_dma = NULL;
    SDMA *d = &DMA[Channel];

    int count = d->TransferBytes;

    if (count == 0)
	count = 0x10000;

    int inc = d->AAddressFixed ? 0 : (!d->AAddressDecrement ? 1 : -1);

    switch (d->BAddress)
    {
    case 0x18:
    case 0x19:
	if (IPPU.RenderThisFrame)
	    FLUSH_REDRAW ();
	break;
    }

    if (Settings.SDD1)
    {
	if (d->AAddressFixed && Memory.FillRAM [0x4801] > 0)
	{
	    // Hacky support for pre-decompressed S-DD1 data
	    inc = !d->AAddressDecrement ? 1 : -1;
	    uint32 address = (((d->ABank << 16) | d->AAddress) & 0xfffff) << 4;

	    address |= Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)];
		if(Settings.SDD1Pack)
		{
			uint8* in_ptr=GetBasePointer(((d->ABank << 16) | d->AAddress));
			in_ptr+=d->AAddress;

			SDD1_decompress(buffer,in_ptr,d->TransferBytes);
			in_sdd1_dma=buffer;
		}
		else
		{

			void *ptr = bsearch (&address, Memory.SDD1Index, 
					 Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries);
			if (ptr)
			in_sdd1_dma = *(uint32 *) ((uint8 *) ptr + 4) + Memory.SDD1Data;

/*
	    if (!in_sdd1_dma)
	    {
		// No matching decompressed data found. Must be some new 
		// graphics not encountered before. Log it if it hasn't been
		// already.
		uint8 *p = Memory.SDD1LoggedData;
		bool8 found = FALSE;
		uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0;

		for (uint32 i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8)
		{
		    if (*p == d->ABank ||
			*(p + 1) == (d->AAddress >> 8) &&
			*(p + 2) == (d->AAddress & 0xff) &&
			*(p + 3) == (count >> 8) &&
			*(p + 4) == (count & 0xff) &&
			*(p + 7) == SDD1Bank)
		    {
			found = TRUE;
			break;
		    }
		}
		if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES)
		{
		    *p = d->ABank;
		    *(p + 1) = d->AAddress >> 8;
		    *(p + 2) = d->AAddress & 0xff;
		    *(p + 3) = count >> 8;
		    *(p + 4) = count & 0xff;
		    *(p + 7) = SDD1Bank;
		    Memory.SDD1LoggedDataCount += 1;
		}
*/	    }
	}
	Memory.FillRAM [0x4801] = 0;
    }
Beispiel #2
0
bool8 S9xDoDMA (uint8 Channel)
{
	CPU.InDMA = TRUE;
    CPU.InDMAorHDMA = TRUE;
	CPU.CurrentDMAorHDMAChannel = Channel;

    SDMA	*d = &DMA[Channel];

	// Check invalid DMA first
	if ((d->ABank == 0x7E || d->ABank == 0x7F) && d->BAddress == 0x80 && !d->ReverseTransfer)
	{
		// Attempting a DMA from WRAM to $2180 will not work, WRAM will not be written.
		// Attempting a DMA from $2180 to WRAM will similarly not work,
		// the value written is (initially) the OpenBus value.
		// In either case, the address in $2181-3 is not incremented.

		// Does an invalid DMA actually take time?
		// I'd say yes, since 'invalid' is probably just the WRAM chip
		// not being able to read and write itself at the same time
		// And no, PPU.WRAM should not be updated.

		int32	c = d->TransferBytes;
		// Writing $0000 to $43x5 actually results in a transfer of $10000 bytes, not 0.
		if (c == 0)
			c = 0x10000;

		// 8 cycles per channel
		ADD_CYCLES(SLOW_ONE_CYCLE);
		// 8 cycles per byte
		while (c)
		{
			d->TransferBytes--;
			d->AAddress++;
			c--;
			if (!addCyclesInDMA(Channel))
			{
				CPU.InDMA = FALSE;
				CPU.InDMAorHDMA = FALSE;
				CPU.CurrentDMAorHDMAChannel = -1;
				return (FALSE);
			}
		}

	#ifdef DEBUGGER
		if (Settings.TraceDMA)
		{
			sprintf(String, "DMA[%d]: WRAM Bank:%02X->$2180", Channel, d->ABank);
			S9xMessage(S9X_TRACE, S9X_DMA_TRACE, String);
		}
	#endif

		CPU.InDMA = FALSE;
		CPU.InDMAorHDMA = FALSE;
		CPU.CurrentDMAorHDMAChannel = -1;
		return (TRUE);
	}

	// Prepare for accessing $2118-2119
	switch (d->BAddress)
	{
		case 0x18:
		case 0x19:
			if (IPPU.RenderThisFrame)
				FLUSH_REDRAW();
			break;
	}

	int32	inc = d->AAddressFixed ? 0 : (!d->AAddressDecrement ? 1 : -1);
	int32	count = d->TransferBytes;
	// Writing $0000 to $43x5 actually results in a transfer of $10000 bytes, not 0.
	if (count == 0)
		count = 0x10000;

	// Prepare for custom chip DMA

	// S-DD1

	uint8	*in_sdd1_dma = NULL;

	if (Settings.SDD1)
	{
		if (d->AAddressFixed && Memory.FillRAM[0x4801] > 0)
		{
			// XXX: Should probably verify that we're DMAing from ROM?
			// And somewhere we should make sure we're not running across a mapping boundary too.
			// Hacky support for pre-decompressed S-DD1 data
			inc = !d->AAddressDecrement ? 1 : -1;

			uint8	*in_ptr = S9xGetBasePointer(((d->ABank << 16) | d->AAddress));
			if (in_ptr)
			{
				in_ptr += d->AAddress;
				SDD1_decompress(sdd1_decode_buffer, in_ptr, d->TransferBytes);
			}
		#ifdef DEBUGGER
			else
			{
				sprintf(String, "S-DD1: DMA from non-block address $%02X:%04X", d->ABank, d->AAddress);
				S9xMessage(S9X_WARNING, S9X_DMA_TRACE, String);
			}
		#endif

			in_sdd1_dma = sdd1_decode_buffer;
		}

		Memory.FillRAM[0x4801] = 0;
	}

	// SPC7110

	uint8	*spc7110_dma = NULL;

	if (Settings.SPC7110)
	{
		if (d->AAddress == 0x4800 || d->ABank == 0x50)
		{
			spc7110_dma = new uint8[d->TransferBytes];
			for (int i = 0; i < d->TransferBytes; i++)
				spc7110_dma[i] = s7emu.decomp.read();

			int32	icount = s7emu.r4809 | (s7emu.r480a << 8);
			icount -= d->TransferBytes;
			s7emu.r4809 =  icount & 0x00ff;
			s7emu.r480a = (icount & 0xff00) >> 8;

			inc = 1;
			d->AAddress -= count;
		}
	}