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); } }
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); }