📄 dma.cpp
字号:
Work = S9xGetPPU (0x2100 + d->BAddress); S9xSetByte (Work, (d->ABank << 16) + d->AAddress); d->AAddress += inc; if (!--count) break; Work = S9xGetPPU (0x2101 + d->BAddress); S9xSetByte (Work, (d->ABank << 16) + d->AAddress); d->AAddress += inc; if (!--count) break; Work = S9xGetPPU (0x2101 + d->BAddress); S9xSetByte (Work, (d->ABank << 16) + d->AAddress); d->AAddress += inc; count--; break; case 4: Work = S9xGetPPU (0x2100 + d->BAddress); S9xSetByte (Work, (d->ABank << 16) + d->AAddress); d->AAddress += inc; if (!--count) break; Work = S9xGetPPU (0x2101 + d->BAddress); S9xSetByte (Work, (d->ABank << 16) + d->AAddress); d->AAddress += inc; if (!--count) break; Work = S9xGetPPU (0x2102 + d->BAddress); S9xSetByte (Work, (d->ABank << 16) + d->AAddress); d->AAddress += inc; if (!--count) break; Work = S9xGetPPU (0x2103 + d->BAddress); S9xSetByte (Work, (d->ABank << 16) + d->AAddress); d->AAddress += inc; count--; break; default:#ifdef DEBUGGER if (1) //Settings.TraceDMA) { sprintf (String, "Unknown DMA transfer mode: %d on channel %d\n", d->TransferMode, Channel); S9xMessage (S9X_TRACE, S9X_DMA_TRACE, String); }#endif count = 0; break; } CHECK_SOUND(); } while (count); } #ifdef SPC700_C IAPU.APUExecuting = Settings.APUEnabled; APU_EXECUTE ();#endif while (CPU.Cycles > CPU.NextEvent) S9xDoHBlankProcessing (); S9xUpdateAPUTimer(); if(Settings.SPC7110&&spc7110_dma) { if(spc7110_dma&&s7_wrap) delete [] spc7110_dma; }update_address: // Super Punch-Out requires that the A-BUS address be updated after the // DMA transfer. Memory.FillRAM[0x4302 + (Channel << 4)] = (uint8) d->AAddress; Memory.FillRAM[0x4303 + (Channel << 4)] = d->AAddress >> 8; // Secret of the Mana requires that the DMA bytes transfer count be set to // zero when DMA has completed. Memory.FillRAM [0x4305 + (Channel << 4)] = 0; Memory.FillRAM [0x4306 + (Channel << 4)] = 0; DMA[Channel].IndirectAddress = 0; d->TransferBytes = 0; CPU.InDMA = FALSE;}void S9xStartHDMA (){ if (Settings.DisableHDMA) IPPU.HDMA = 0; else missing.hdma_this_frame = IPPU.HDMA = Memory.FillRAM [0x420c]; //per anomie timing post if(IPPU.HDMA!=0) { CPU.Cycles+=ONE_CYCLE*3; S9xUpdateAPUTimer(); } IPPU.HDMAStarted = TRUE; for (uint8 i = 0; i < 8; i++) { if (IPPU.HDMA & (1 << i)) { CPU.Cycles+=SLOW_ONE_CYCLE ; S9xUpdateAPUTimer(); DMA [i].LineCount = 0; DMA [i].FirstLine = TRUE; DMA [i].Address = DMA [i].AAddress; if(DMA[i].HDMAIndirectAddressing) { CPU.Cycles+=(SLOW_ONE_CYCLE <<2); S9xUpdateAPUTimer(); } } HDMAMemPointers [i] = NULL;#ifdef SETA010_HDMA_FROM_CART HDMARawPointers [i] = 0;#endif }}#ifdef DEBUGGERvoid S9xTraceSoundDSP (const char *s, int i1 = 0, int i2 = 0, int i3 = 0, int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0);#endifuint8 S9xDoHDMA (uint8 byte){ struct SDMA *p = &DMA [0]; int d = 0; CPU.InDMA = TRUE; CPU.Cycles+=ONE_CYCLE*3; S9xUpdateAPUTimer(); for (uint8 mask = 1; mask; mask <<= 1, p++, d++) { if (byte & mask) { if (!p->LineCount) { //remember, InDMA is set. //Get/Set incur no charges! CPU.Cycles+=SLOW_ONE_CYCLE; S9xUpdateAPUTimer(); uint8 line = S9xGetByte ((p->ABank << 16) + p->Address); if (line == 0x80) { p->Repeat = TRUE; p->LineCount = 128; } else { p->Repeat = !(line & 0x80); p->LineCount = line & 0x7f; } // Disable H-DMA'ing into V-RAM (register 2118) for Hook /* XXX: instead of p->BAddress == 0x18, make S9xSetPPU fail * XXX: writes to $2118/9 when appropriate */#ifdef SETA010_HDMA_FROM_CART if (!p->LineCount)#else if (!p->LineCount || p->BAddress == 0x18)#endif { byte &= ~mask; p->IndirectAddress += HDMAMemPointers [d] - HDMABasePointers [d]; Memory.FillRAM [0x4305 + (d << 4)] = (uint8) p->IndirectAddress; Memory.FillRAM [0x4306 + (d << 4)] = p->IndirectAddress >> 8; continue; } p->Address++; p->FirstLine = 1; if (p->HDMAIndirectAddressing) { p->IndirectBank = Memory.FillRAM [0x4307 + (d << 4)]; //again, no cycle charges while InDMA is set! CPU.Cycles+=SLOW_ONE_CYCLE<<2; S9xUpdateAPUTimer(); p->IndirectAddress = S9xGetWord ((p->ABank << 16) + p->Address); p->Address += 2; } else { p->IndirectBank = p->ABank; p->IndirectAddress = p->Address; } HDMABasePointers [d] = HDMAMemPointers [d] = S9xGetMemPointer ((p->IndirectBank << 16) + p->IndirectAddress);#ifdef SETA010_HDMA_FROM_CART HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress;#endif } else { CPU.Cycles += SLOW_ONE_CYCLE; S9xUpdateAPUTimer(); } if (!HDMAMemPointers [d]) { if (!p->HDMAIndirectAddressing) { p->IndirectBank = p->ABank; p->IndirectAddress = p->Address; }#ifdef SETA010_HDMA_FROM_CART HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress;#endif if (!(HDMABasePointers [d] = HDMAMemPointers [d] = S9xGetMemPointer ((p->IndirectBank << 16) + p->IndirectAddress))) { /* XXX: Instead of this, goto a slow path that first * XXX: verifies src!=Address Bus B, then uses * XXX: S9xGetByte(). Or make S9xGetByte return OpenBus * XXX: (probably?) for Address Bus B while inDMA. */ byte &= ~mask; continue; } // Uncommenting the following line breaks Punchout - it starts // H-DMA during the frame. //p->FirstLine = TRUE; } if (p->Repeat && !p->FirstLine) { p->LineCount--; continue; } if (p->BAddress == 0x04){ if(SNESGameFixes.Uniracers){ PPU.OAMAddr = 0x10c; PPU.OAMFlip=0; } }#ifdef DEBUGGER if (Settings.TraceSoundDSP && p->FirstLine && p->BAddress >= 0x40 && p->BAddress <= 0x43) S9xTraceSoundDSP ("Spooling data!!!\n"); if (Settings.TraceHDMA && p->FirstLine) { sprintf (String, "H-DMA[%d] (%d) 0x%02X%04X->0x21%02X %s, Count: %3d, Rep: %s, V-LINE: %3ld %02X%04X", p-DMA, p->TransferMode, p->IndirectBank, p->IndirectAddress, p->BAddress, p->HDMAIndirectAddressing ? "ind" : "abs", p->LineCount, p->Repeat ? "yes" : "no ", CPU.V_Counter, p->ABank, p->Address); S9xMessage (S9X_TRACE, S9X_HDMA_TRACE, String); }#endif switch (p->TransferMode) { case 0: CPU.Cycles += SLOW_ONE_CYCLE; S9xUpdateAPUTimer();#ifdef SETA010_HDMA_FROM_CART S9xSetPPU (S9xGetByte (HDMARawPointers [d]++), 0x2100 + p->BAddress); HDMAMemPointers [d]++;#else S9xSetPPU (*HDMAMemPointers [d]++, 0x2100 + p->BAddress);#endif break; case 5: CPU.Cycles += 2*SLOW_ONE_CYCLE; S9xUpdateAPUTimer();#ifdef SETA010_HDMA_FROM_CART S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress); HDMARawPointers [d] += 2;#else S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress);#endif HDMAMemPointers [d] += 2; /* fall through */ case 1: CPU.Cycles += 2*SLOW_ONE_CYCLE; S9xUpdateAPUTimer();#ifdef SETA010_HDMA_FROM_CART S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress); HDMARawPointers [d] += 2;#else S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress);#endif HDMAMemPointers [d] += 2; break; case 2: case 6: CPU.Cycles += 2*SLOW_ONE_CYCLE; S9xUpdateAPUTimer();#ifdef SETA010_HDMA_FROM_CART S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2100 + p->BAddress); HDMARawPointers [d] += 2;#else S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress);#endif HDMAMemPointers [d] += 2; break; case 3: case 7: CPU.Cycles += 4*SLOW_ONE_CYCLE; S9xUpdateAPUTimer();#ifdef SETA010_HDMA_FROM_CART S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2100 + p->BAddress); S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 2), 0x2101 + p->BAddress); S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 3), 0x2101 + p->BAddress); HDMARawPointers [d] += 4;#else S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); S9xSetPPU (*(HDMAMemPointers [d] + 2), 0x2101 + p->BAddress); S9xSetPPU (*(HDMAMemPointers [d] + 3), 0x2101 + p->BAddress);#endif HDMAMemPointers [d] += 4; break; case 4: CPU.Cycles += 4*SLOW_ONE_CYCLE; S9xUpdateAPUTimer();#ifdef SETA010_HDMA_FROM_CART S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress); S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 2), 0x2102 + p->BAddress); S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 3), 0x2103 + p->BAddress); HDMARawPointers [d] += 4;#else S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); S9xSetPPU (*(HDMAMemPointers [d] + 2), 0x2102 + p->BAddress); S9xSetPPU (*(HDMAMemPointers [d] + 3), 0x2103 + p->BAddress);#endif HDMAMemPointers [d] += 4; break; } if (!p->HDMAIndirectAddressing) p->Address += HDMA_ModeByteCounts [p->TransferMode]; p->IndirectAddress += HDMA_ModeByteCounts [p->TransferMode]; /* XXX: Check for p->IndirectAddress crossing a mapping boundry, * XXX: and invalidate HDMAMemPointers[d] */ p->FirstLine = FALSE; p->LineCount--; } } CPU.InDMA=FALSE; return (byte);}void S9xResetDMA (){ int d; for (d = 0; d < 8; d++) { DMA [d].TransferDirection = FALSE; DMA [d].HDMAIndirectAddressing = FALSE; DMA [d].AAddressFixed = TRUE; DMA [d].AAddressDecrement = FALSE; DMA [d].TransferMode = 0xff; DMA [d].ABank = 0xff; DMA [d].AAddress = 0xffff; DMA [d].Address = 0xffff; DMA [d].BAddress = 0xff; DMA [d].TransferBytes = 0xffff; } for (int c = 0x4300; c < 0x4380; c += 0x10) { for (d = c; d < c + 12; d++) Memory.FillRAM [d] = 0xff; Memory.FillRAM [c + 0xf] = 0xff; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -