예제 #1
0
void get_ext_data() {
	int i;
	CHECK_INBLANK();
			i = 0;
			pkt_dword = dev.getdword();

			format_snesaccess(pkt_dword, &pkt);

			if (!pkt.apu && !pkt.read) {
				S9xSetPPU(pkt.data, pkt.addr | 0x2100);
			}
}
예제 #2
0
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);
}