Ejemplo n.º 1
0
static void S9xEndScreenRefresh (void)
{
	FLUSH_REDRAW();

   PPU.GunVLatch = 1000; /* i.e., never latch */
   PPU.GunHLatch = 0;

   if (!Settings.NormalControls && pad_read)
      S9xControlEOF();

	pad_read      = FALSE;

	if(Settings.SpeedhackGameID > SPEEDHACK_NONE)
		speedhacks_manager();

	if (!(GFX.DoInterlace && GFX.InterlaceFrame == 0))
		S9xDeinitUpdate(IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight);

	S9xApplyCheats();
}
Ejemplo n.º 2
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;
    }
Ejemplo n.º 3
0
void S9xSetPPU (uint8 Byte, uint16 Address)
{
	// MAP_PPU: $2000-$3FFF

	if (CPU.InDMAorHDMA)
	{
		if (CPU.CurrentDMAorHDMAChannel >= 0 && DMA[CPU.CurrentDMAorHDMAChannel].ReverseTransfer)
		{
			// S9xSetPPU() is called to write to DMA[].AAddress
			if ((Address & 0xff00) == 0x2100)
			{
				// Cannot access to Address Bus B ($2100-$21ff) via (H)DMA
				return;
			}
			else
			{
				// 0x2000-0x3FFF is connected to Address Bus A
				// SA1, SuperFX and SRTC are mapped here
				// I don't bother for now...
				return;
			}
		}
		else
		{
			// S9xSetPPU() is called to read from $21xx
			// Take care of DMA wrapping
			if (Address > 0x21ff)
				Address = 0x2100 + (Address & 0xff);
		}
	}

#ifdef DEBUGGER
	if (CPU.InHDMA)
		S9xTraceFormattedMessage("--- HDMA PPU %04X -> %02X", Address, Byte);
#endif

	if (Settings.MSU1 && (Address & 0xfff8) == 0x2000) // MSU-1
		S9xMSU1WritePort(Address & 7, Byte);
	else
	if ((Address & 0xffc0) == 0x2140) // APUIO0, APUIO1, APUIO2, APUIO3
		// write_port will run the APU until given clock before writing value
		S9xAPUWritePort(Address & 3, Byte);
	else
	if (Address <= 0x2183)
	{
		switch (Address)
		{
			case 0x2100: // INIDISP
				if (Byte != Memory.FillRAM[0x2100])
				{
					FLUSH_REDRAW();

					if (PPU.Brightness != (Byte & 0xf))
					{
						IPPU.ColorsChanged = TRUE;
						IPPU.DirectColourMapsNeedRebuild = TRUE;
						PPU.Brightness = Byte & 0xf;
						S9xFixColourBrightness();
						if (PPU.Brightness > IPPU.MaxBrightness)
							IPPU.MaxBrightness = PPU.Brightness;
					}

					if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80))
					{
						IPPU.ColorsChanged = TRUE;
						PPU.ForcedBlanking = (Byte >> 7) & 1;
					}
				}

				if ((Memory.FillRAM[0x2100] & 0x80) && CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE)
				{
					PPU.OAMAddr = PPU.SavedOAMAddr;

					uint8 tmp = 0;
					if (PPU.OAMPriorityRotation)
						tmp = (PPU.OAMAddr & 0xfe) >> 1;
					if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp)
					{
						PPU.FirstSprite = tmp;
						IPPU.OBJChanged = TRUE;
					}

					PPU.OAMFlip = 0;
				}
Ejemplo n.º 4
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;
		}
	}