コード例 #1
0
ファイル: cpuexec.c プロジェクト: matthewbauer/snes9x-next
static INLINE bool8 HDMAReadLineCount (int d)
{
	/* CPU.InDMA is set, so S9xGetXXX() / S9xSetXXX() incur no charges. */

	uint8	line;

	line = S9xGetByte((DMA[d].ABank << 16) + DMA[d].Address);
	CPU.Cycles += SLOW_ONE_CYCLE;

	DMA[d].LineCount = 128;

	if (!line)
	{
		DMA[d].Repeat = FALSE;

		if (DMA[d].HDMAIndirectAddressing)
		{
			if (PPU.HDMA & (0xfe << d))
			{
				DMA[d].Address++;
				CPU.Cycles += (SLOW_ONE_CYCLE << 1);
			}
			else
				CPU.Cycles += SLOW_ONE_CYCLE;

			DMA[d].IndirectAddress = S9xGetWord((DMA[d].ABank << 16) + DMA[d].Address, WRAP_NONE);
			DMA[d].Address++;
		}

		DMA[d].Address++;
		HDMAMemPointers[d] = NULL;

		return (FALSE);
	}
	else
	if (line == 0x80)
		DMA[d].Repeat = TRUE;
	else
	{
		DMA[d].Repeat = !(line & 0x80);
		DMA[d].LineCount = line & 0x7f;
	}

	DMA[d].Address++;
	DMA[d].DoTransfer = TRUE;

	if (DMA[d].HDMAIndirectAddressing)
	{
		CPU.Cycles += (SLOW_ONE_CYCLE << 1);
		DMA[d].IndirectAddress = S9xGetWord((DMA[d].ABank << 16) + DMA[d].Address, WRAP_NONE);
		DMA[d].Address += 2;
		HDMAMemPointers[d] = S9xGetMemPointer((DMA[d].IndirectBank << 16) + DMA[d].IndirectAddress);
	}
	else
		HDMAMemPointers[d] = S9xGetMemPointer((DMA[d].ABank << 16) + DMA[d].Address);

	return (TRUE);
}
コード例 #2
0
ファイル: c4.cpp プロジェクト: Alexander--/SNesoid
void C4LoaDMem(char *C4RAM)
{
  memmove(C4RAM+(READ_WORD(C4RAM+0x1f45)&0x1fff), 
          S9xGetMemPointer(READ_3WORD(C4RAM+0x1f40)),
          READ_WORD(C4RAM+0x1f43));
}
コード例 #3
0
ファイル: cpuexec.c プロジェクト: matthewbauer/snes9x-next
static uint8 S9xDoHDMA (uint8 byte)
{
	uint8 mask;
	uint32	ShiftedIBank;
	uint16	IAddr;
	bool8	temp;
	int32	tmpch;
	int d;
	struct SDMA *p;

	p = &DMA[0];

	d = 0;

	CPU.InHDMA = TRUE;
	CPU.InDMAorHDMA = TRUE;
	CPU.HDMARanInDMA = CPU.InDMA ? byte : 0;
	temp = CPU.InWRAMDMAorHDMA;
	tmpch = CPU.CurrentDMAorHDMAChannel;

	/* XXX: Not quite right... */
	CPU.Cycles += Timings.DMACPUSync;

	for ( mask = 1; mask; mask <<= 1, p++, d++)
	{
		if (byte & mask)
		{
			CPU.InWRAMDMAorHDMA = FALSE;
			CPU.CurrentDMAorHDMAChannel = d;

			if (p->HDMAIndirectAddressing)
			{
				ShiftedIBank = (p->IndirectBank << 16);
				IAddr = p->IndirectAddress;
			}
			else
			{
				ShiftedIBank = (p->ABank << 16);
				IAddr = p->Address;
			}

			if (!HDMAMemPointers[d])
				HDMAMemPointers[d] = S9xGetMemPointer(ShiftedIBank + IAddr);

			if (p->DoTransfer)
			{
				/* XXX: Hack for Uniracers, because we don't understand 
				OAM Address Invalidation */
				if (p->BAddress == 0x04 && SNESGameFixes.Uniracers)
				{
					PPU.OAMAddr = 0x10c;
					PPU.OAMFlip = 0;
				}


				if (!p->ReverseTransfer)
				{
					if ((IAddr & MEMMAP_MASK) + HDMA_ModeByteCounts[p->TransferMode] >= MEMMAP_BLOCK_SIZE)
					{
						/* HDMA REALLY-SLOW PATH */
						HDMAMemPointers[d] = NULL;

						#define DOBYTE(Addr, RegOff) \
							CPU.InWRAMDMAorHDMA = (ShiftedIBank == 0x7e0000 || ShiftedIBank == 0x7f0000 || \
								(!(ShiftedIBank & 0x400000) && ((uint16) (Addr)) < 0x2000)); \
							S9xSetPPU(S9xGetByte(ShiftedIBank + ((uint16) (Addr))), 0x2100 + p->BAddress + (RegOff));

						DOBYTE(IAddr, 0);
						CPU.Cycles += SLOW_ONE_CYCLE;
						switch (p->TransferMode)
						{
							case 0:
								break;

							case 5:
								DOBYTE(IAddr + 1, 1);
								CPU.Cycles += SLOW_ONE_CYCLE;
								DOBYTE(IAddr + 2, 0);
								CPU.Cycles += SLOW_ONE_CYCLE;
								DOBYTE(IAddr + 3, 1);
								CPU.Cycles += SLOW_ONE_CYCLE;
								break;

							case 1:
								DOBYTE(IAddr + 1, 1);
								CPU.Cycles += SLOW_ONE_CYCLE;
								break;

							case 2:
							case 6:
								DOBYTE(IAddr + 1, 0);
								CPU.Cycles += SLOW_ONE_CYCLE;
								break;

							case 3:
							case 7:
								DOBYTE(IAddr + 1, 0);
								CPU.Cycles += SLOW_ONE_CYCLE;
								DOBYTE(IAddr + 2, 1);
								CPU.Cycles += SLOW_ONE_CYCLE;
								DOBYTE(IAddr + 3, 1);
								CPU.Cycles += SLOW_ONE_CYCLE;
								break;

							case 4:
								DOBYTE(IAddr + 1, 1);
								CPU.Cycles += SLOW_ONE_CYCLE;
								DOBYTE(IAddr + 2, 2);
								CPU.Cycles += SLOW_ONE_CYCLE;
								DOBYTE(IAddr + 3, 3);
								CPU.Cycles += SLOW_ONE_CYCLE;
								break;
						}

						#undef DOBYTE
					}
					else
					{
						CPU.InWRAMDMAorHDMA = (ShiftedIBank == 0x7e0000 || ShiftedIBank == 0x7f0000 ||
							(!(ShiftedIBank & 0x400000) && IAddr < 0x2000));

						if (!HDMAMemPointers[d])
						{
							/* HDMA SLOW PATH */
							uint32	Addr = ShiftedIBank + IAddr;

							switch (p->TransferMode)
							{
								case 0:
									S9xSetPPU(S9xGetByte(Addr), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									break;

								case 5:
									S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(S9xGetByte(Addr + 1), 0x2101 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									Addr += 2;
									/* fall through */
								case 1:
									S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(S9xGetByte(Addr + 1), 0x2101 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									break;

								case 2:
								case 6:
									S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(S9xGetByte(Addr + 1), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									break;

								case 3:
								case 7:
									S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(S9xGetByte(Addr + 1), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(S9xGetByte(Addr + 2), 0x2101 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(S9xGetByte(Addr + 3), 0x2101 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									break;

								case 4:
									S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(S9xGetByte(Addr + 1), 0x2101 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(S9xGetByte(Addr + 2), 0x2102 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(S9xGetByte(Addr + 3), 0x2103 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									break;
							}
						}
						else
						{
							/* HDMA FAST PATH */
							switch (p->TransferMode)
							{
								case 0:
									S9xSetPPU(*HDMAMemPointers[d]++, 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									break;

								case 5:
									S9xSetPPU(*(HDMAMemPointers[d]), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2101 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									HDMAMemPointers[d] += 2;
									/* fall through */
								case 1:
									S9xSetPPU(*(HDMAMemPointers[d]), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2101 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									HDMAMemPointers[d] += 2;
									break;

								case 2:
								case 6:
									S9xSetPPU(*(HDMAMemPointers[d]), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									HDMAMemPointers[d] += 2;
									break;

								case 3:
								case 7:
									S9xSetPPU(*(HDMAMemPointers[d]), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(*(HDMAMemPointers[d] + 2), 0x2101 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(*(HDMAMemPointers[d] + 3), 0x2101 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									HDMAMemPointers[d] += 4;
									break;

								case 4:
									S9xSetPPU(*(HDMAMemPointers[d]), 0x2100 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2101 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(*(HDMAMemPointers[d] + 2), 0x2102 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									S9xSetPPU(*(HDMAMemPointers[d] + 3), 0x2103 + p->BAddress);
									CPU.Cycles += SLOW_ONE_CYCLE;
									HDMAMemPointers[d] += 4;
									break;
							}
						}
					}
				}

				if (p->HDMAIndirectAddressing)
					p->IndirectAddress += HDMA_ModeByteCounts[p->TransferMode];
				else
					p->Address += HDMA_ModeByteCounts[p->TransferMode];
			}

			p->DoTransfer = !p->Repeat;

			if (!--p->LineCount)
			{
				if (!HDMAReadLineCount(d))
				{
					byte &= ~mask;
					PPU.HDMAEnded |= mask;
					p->DoTransfer = FALSE;
					continue;
				}
			}
			else
				CPU.Cycles += SLOW_ONE_CYCLE;
		}
	}

	CPU.InHDMA = FALSE;
	CPU.InDMAorHDMA = CPU.InDMA;
	CPU.InWRAMDMAorHDMA = temp;
	CPU.CurrentDMAorHDMAChannel = tmpch;

	return (byte);
}