diff options
-rw-r--r-- | src/DMA.cpp | 6 | ||||
-rw-r--r-- | src/DSi.cpp | 171 | ||||
-rw-r--r-- | src/DSi.h | 4 | ||||
-rw-r--r-- | src/DSi_NDMA.cpp | 301 | ||||
-rw-r--r-- | src/DSi_NDMA.h | 74 | ||||
-rw-r--r-- | src/NDS.cpp | 4 | ||||
-rw-r--r-- | src/NDS.h | 5 |
7 files changed, 556 insertions, 9 deletions
diff --git a/src/DMA.cpp b/src/DMA.cpp index 2814264..0826d7a 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -20,15 +20,9 @@ #include "NDS.h" #include "DSi.h" #include "DMA.h" -#include "NDSCart.h" #include "GPU.h" -// NOTES ON DMA SHIT -// -// * could use optimized code paths for common types of DMA transfers. for example, VRAM -// have to profile it to see if it's actually worth doing - // DMA TIMINGS // diff --git a/src/DSi.cpp b/src/DSi.cpp index abd3bd6..0c9c26c 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -25,6 +25,7 @@ #include "sha1/sha1.h" #include "Platform.h" +#include "DSi_NDMA.h" #include "DSi_I2C.h" #include "DSi_SD.h" @@ -57,6 +58,9 @@ u32 NWRAMStart[2][3]; u32 NWRAMEnd[2][3]; u32 NWRAMMask[2][3]; +u32 NDMACnt[2]; +DSi_NDMA* NDMAs[8]; + DSi_SDHost* SDMMC; DSi_SDHost* SDIO; @@ -68,6 +72,15 @@ bool Init() { if (!DSi_I2C::Init()) return false; + NDMAs[0] = new DSi_NDMA(0, 0); + NDMAs[1] = new DSi_NDMA(0, 1); + NDMAs[2] = new DSi_NDMA(0, 2); + NDMAs[3] = new DSi_NDMA(0, 3); + NDMAs[4] = new DSi_NDMA(1, 0); + NDMAs[5] = new DSi_NDMA(1, 1); + NDMAs[6] = new DSi_NDMA(1, 2); + NDMAs[7] = new DSi_NDMA(1, 3); + SDMMC = new DSi_SDHost(0); SDIO = new DSi_SDHost(1); @@ -78,6 +91,8 @@ void DeInit() { DSi_I2C::DeInit(); + for (int i = 0; i < 8; i++) delete NDMAs[i]; + delete SDMMC; delete SDIO; } @@ -91,6 +106,9 @@ void Reset() NDS::ARM9->JumpTo(BootAddr[0]); NDS::ARM7->JumpTo(BootAddr[1]); + NDMACnt[0] = 0; NDMACnt[1] = 0; + for (int i = 0; i < 8; i++) NDMAs[i]->Reset(); + DSi_I2C::Reset(); SDMMC->Reset(); @@ -279,6 +297,40 @@ bool LoadNAND() } +void RunNDMAs(u32 cpu) +{ + // TODO: round-robin mode (requires DMA channels to have a subblock delay set) + + if (cpu == 0) + { + if (NDS::ARM9Timestamp >= NDS::ARM9Target) return; + + // + } + else + { + if (NDS::ARM7Timestamp >= NDS::ARM7Target) return; + + // + } +} + +void StallNDMAs() +{ + // TODO +} + +bool NDMAsRunning(u32 cpu) +{ + cpu <<= 2; + if (NDMAs[cpu+0]->IsRunning()) return true; + if (NDMAs[cpu+1]->IsRunning()) return true; + if (NDMAs[cpu+2]->IsRunning()) return true; + if (NDMAs[cpu+3]->IsRunning()) return true; + return false; +} + + // new WRAM mapping // TODO: find out what happens upon overlapping slots!! @@ -872,6 +924,36 @@ u32 ARM9IORead32(u32 addr) switch (addr) { case 0x04004010: return 1; // todo + + case 0x04004100: return NDMACnt[0]; + case 0x04004104: return NDMAs[0]->SrcAddr; + case 0x04004108: return NDMAs[0]->DstAddr; + case 0x0400410C: return NDMAs[0]->TotalLength; + case 0x04004110: return NDMAs[0]->BlockLength; + case 0x04004114: return NDMAs[0]->SubblockTimer; + case 0x04004118: return NDMAs[0]->FillData; + case 0x0400411C: return NDMAs[0]->Cnt; + case 0x04004120: return NDMAs[1]->SrcAddr; + case 0x04004124: return NDMAs[1]->DstAddr; + case 0x04004128: return NDMAs[1]->TotalLength; + case 0x0400412C: return NDMAs[1]->BlockLength; + case 0x04004130: return NDMAs[1]->SubblockTimer; + case 0x04004134: return NDMAs[1]->FillData; + case 0x04004138: return NDMAs[1]->Cnt; + case 0x0400413C: return NDMAs[2]->SrcAddr; + case 0x04004140: return NDMAs[2]->DstAddr; + case 0x04004144: return NDMAs[2]->TotalLength; + case 0x04004148: return NDMAs[2]->BlockLength; + case 0x0400414C: return NDMAs[2]->SubblockTimer; + case 0x04004150: return NDMAs[2]->FillData; + case 0x04004154: return NDMAs[2]->Cnt; + case 0x04004158: return NDMAs[3]->SrcAddr; + case 0x0400415C: return NDMAs[3]->DstAddr; + case 0x04004160: return NDMAs[3]->TotalLength; + case 0x04004164: return NDMAs[3]->BlockLength; + case 0x04004168: return NDMAs[3]->SubblockTimer; + case 0x0400416C: return NDMAs[3]->FillData; + case 0x04004170: return NDMAs[3]->Cnt; } return NDS::ARM9IORead32(addr); @@ -899,6 +981,35 @@ void ARM9IOWrite32(u32 addr, u32 val) { switch (addr) { + case 0x04004100: NDMACnt[0] = val & 0x800F0000; return; + case 0x04004104: NDMAs[0]->SrcAddr = val & 0xFFFFFFFC; return; + case 0x04004108: NDMAs[0]->DstAddr = val & 0xFFFFFFFC; return; + case 0x0400410C: NDMAs[0]->TotalLength = val & 0x0FFFFFFF; return; + case 0x04004110: NDMAs[0]->BlockLength = val & 0x00FFFFFF; return; + case 0x04004114: NDMAs[0]->SubblockTimer = val & 0x0003FFFF; return; + case 0x04004118: NDMAs[0]->FillData = val; return; + case 0x0400411C: NDMAs[0]->WriteCnt(val); return; + case 0x04004120: NDMAs[1]->SrcAddr = val & 0xFFFFFFFC; return; + case 0x04004124: NDMAs[1]->DstAddr = val & 0xFFFFFFFC; return; + case 0x04004128: NDMAs[1]->TotalLength = val & 0x0FFFFFFF; return; + case 0x0400412C: NDMAs[1]->BlockLength = val & 0x00FFFFFF; return; + case 0x04004130: NDMAs[1]->SubblockTimer = val & 0x0003FFFF; return; + case 0x04004134: NDMAs[1]->FillData = val; return; + case 0x04004138: NDMAs[1]->WriteCnt(val); return; + case 0x0400413C: NDMAs[2]->SrcAddr = val & 0xFFFFFFFC; return; + case 0x04004140: NDMAs[2]->DstAddr = val & 0xFFFFFFFC; return; + case 0x04004144: NDMAs[2]->TotalLength = val & 0x0FFFFFFF; return; + case 0x04004148: NDMAs[2]->BlockLength = val & 0x00FFFFFF; return; + case 0x0400414C: NDMAs[2]->SubblockTimer = val & 0x0003FFFF; return; + case 0x04004150: NDMAs[2]->FillData = val; return; + case 0x04004154: NDMAs[2]->WriteCnt(val); return; + case 0x04004158: NDMAs[3]->SrcAddr = val & 0xFFFFFFFC; return; + case 0x0400415C: NDMAs[3]->DstAddr = val & 0xFFFFFFFC; return; + case 0x04004160: NDMAs[3]->TotalLength = val & 0x0FFFFFFF; return; + case 0x04004164: NDMAs[3]->BlockLength = val & 0x00FFFFFF; return; + case 0x04004168: NDMAs[3]->SubblockTimer = val & 0x0003FFFF; return; + case 0x0400416C: NDMAs[3]->FillData = val; return; + case 0x04004170: NDMAs[3]->WriteCnt(val); return; } return NDS::ARM9IOWrite32(addr, val); @@ -950,6 +1061,36 @@ u32 ARM7IORead32(u32 addr) case 0x0400021C: return NDS::IF2; case 0x04004008: return 0x80000000; // HAX + + case 0x04004100: return NDMACnt[1]; + case 0x04004104: return NDMAs[4]->SrcAddr; + case 0x04004108: return NDMAs[4]->DstAddr; + case 0x0400410C: return NDMAs[4]->TotalLength; + case 0x04004110: return NDMAs[4]->BlockLength; + case 0x04004114: return NDMAs[4]->SubblockTimer; + case 0x04004118: return NDMAs[4]->FillData; + case 0x0400411C: return NDMAs[4]->Cnt; + case 0x04004120: return NDMAs[5]->SrcAddr; + case 0x04004124: return NDMAs[5]->DstAddr; + case 0x04004128: return NDMAs[5]->TotalLength; + case 0x0400412C: return NDMAs[5]->BlockLength; + case 0x04004130: return NDMAs[5]->SubblockTimer; + case 0x04004134: return NDMAs[5]->FillData; + case 0x04004138: return NDMAs[5]->Cnt; + case 0x0400413C: return NDMAs[6]->SrcAddr; + case 0x04004140: return NDMAs[6]->DstAddr; + case 0x04004144: return NDMAs[6]->TotalLength; + case 0x04004148: return NDMAs[6]->BlockLength; + case 0x0400414C: return NDMAs[6]->SubblockTimer; + case 0x04004150: return NDMAs[6]->FillData; + case 0x04004154: return NDMAs[6]->Cnt; + case 0x04004158: return NDMAs[7]->SrcAddr; + case 0x0400415C: return NDMAs[7]->DstAddr; + case 0x04004160: return NDMAs[7]->TotalLength; + case 0x04004164: return NDMAs[7]->BlockLength; + case 0x04004168: return NDMAs[7]->SubblockTimer; + case 0x0400416C: return NDMAs[7]->FillData; + case 0x04004170: return NDMAs[7]->Cnt; } if (addr >= 0x04004800 && addr < 0x04004A00) @@ -1003,6 +1144,36 @@ void ARM7IOWrite32(u32 addr, u32 val) { case 0x04000218: NDS::IE2 = (val & 0x7FF7); NDS::UpdateIRQ(1); return; case 0x0400021C: NDS::IF2 &= ~(val & 0x7FF7); NDS::UpdateIRQ(1); return; + + case 0x04004100: NDMACnt[1] = val & 0x800F0000; return; + case 0x04004104: NDMAs[4]->SrcAddr = val & 0xFFFFFFFC; return; + case 0x04004108: NDMAs[4]->DstAddr = val & 0xFFFFFFFC; return; + case 0x0400410C: NDMAs[4]->TotalLength = val & 0x0FFFFFFF; return; + case 0x04004110: NDMAs[4]->BlockLength = val & 0x00FFFFFF; return; + case 0x04004114: NDMAs[4]->SubblockTimer = val & 0x0003FFFF; return; + case 0x04004118: NDMAs[4]->FillData = val; return; + case 0x0400411C: NDMAs[4]->WriteCnt(val); return; + case 0x04004120: NDMAs[5]->SrcAddr = val & 0xFFFFFFFC; return; + case 0x04004124: NDMAs[5]->DstAddr = val & 0xFFFFFFFC; return; + case 0x04004128: NDMAs[5]->TotalLength = val & 0x0FFFFFFF; return; + case 0x0400412C: NDMAs[5]->BlockLength = val & 0x00FFFFFF; return; + case 0x04004130: NDMAs[5]->SubblockTimer = val & 0x0003FFFF; return; + case 0x04004134: NDMAs[5]->FillData = val; return; + case 0x04004138: NDMAs[5]->WriteCnt(val); return; + case 0x0400413C: NDMAs[6]->SrcAddr = val & 0xFFFFFFFC; return; + case 0x04004140: NDMAs[6]->DstAddr = val & 0xFFFFFFFC; return; + case 0x04004144: NDMAs[6]->TotalLength = val & 0x0FFFFFFF; return; + case 0x04004148: NDMAs[6]->BlockLength = val & 0x00FFFFFF; return; + case 0x0400414C: NDMAs[6]->SubblockTimer = val & 0x0003FFFF; return; + case 0x04004150: NDMAs[6]->FillData = val; return; + case 0x04004154: NDMAs[6]->WriteCnt(val); return; + case 0x04004158: NDMAs[7]->SrcAddr = val & 0xFFFFFFFC; return; + case 0x0400415C: NDMAs[7]->DstAddr = val & 0xFFFFFFFC; return; + case 0x04004160: NDMAs[7]->TotalLength = val & 0x0FFFFFFF; return; + case 0x04004164: NDMAs[7]->BlockLength = val & 0x00FFFFFF; return; + case 0x04004168: NDMAs[7]->SubblockTimer = val & 0x0003FFFF; return; + case 0x0400416C: NDMAs[7]->FillData = val; return; + case 0x04004170: NDMAs[7]->WriteCnt(val); return; } if (addr >= 0x04004800 && addr < 0x04004A00) @@ -38,6 +38,10 @@ void Reset(); bool LoadBIOS(); bool LoadNAND(); +void RunNDMAs(u32 cpu); +void StallNDMAs(); +bool NDMAsRunning(u32 cpu); + void MapNWRAM_A(u32 num, u8 val); void MapNWRAM_B(u32 num, u8 val); void MapNWRAM_C(u32 num, u8 val); diff --git a/src/DSi_NDMA.cpp b/src/DSi_NDMA.cpp index 6a524dd..a8055eb 100644 --- a/src/DSi_NDMA.cpp +++ b/src/DSi_NDMA.cpp @@ -15,3 +15,304 @@ You should have received a copy of the GNU General Public License along with melonDS. If not, see http://www.gnu.org/licenses/. */ + +#include <stdio.h> +#include "NDS.h" +#include "DSi.h" +#include "DSi_NDMA.h" +#include "GPU.h" + + + +DSi_NDMA::DSi_NDMA(u32 cpu, u32 num) +{ + CPU = cpu; + Num = num; + + Reset(); +} + +DSi_NDMA::~DSi_NDMA() +{ +} + +void DSi_NDMA::Reset() +{ + SrcAddr = 0; + DstAddr = 0; + TotalLength = 0; + BlockLength = 0; + SubblockTimer = 0; + FillData = 0; + Cnt = 0; + + StartMode = 0; + CurSrcAddr = 0; + CurDstAddr = 0; + SubblockLength = 0; + RemCount = 0; + IterCount = 0; + TotalRemCount = 0; + SrcAddrInc = 0; + DstAddrInc = 0; + + Running = false; + InProgress = false; +} + +void DSi_NDMA::DoSavestate(Savestate* file) +{ + // TODO! +} + +void DSi_NDMA::WriteCnt(u32 val) +{ + u32 oldcnt = Cnt; + Cnt = val; + + if ((!(oldcnt & 0x80000000)) && (val & 0x80000000)) // checkme + { + CurSrcAddr = SrcAddr; + CurDstAddr = DstAddr; + TotalRemCount = TotalLength; + + switch ((Cnt >> 10) & 0x3) + { + case 0: DstAddrInc = 1; break; + case 1: DstAddrInc = -1; break; + case 2: DstAddrInc = 0; break; + case 3: DstAddrInc = 1; printf("BAD NDMA DST INC MODE 3\n"); break; + } + + switch ((Cnt >> 13) & 0x3) + { + case 0: SrcAddrInc = 1; break; + case 1: SrcAddrInc = -1; break; + case 2: SrcAddrInc = 0; break; + case 3: SrcAddrInc = 0; break; // fill mode + } + + StartMode = (Cnt >> 24) & 0x1F; + if (StartMode > 0x10) StartMode = 0x10; + if (CPU == 1) StartMode |= 0x20; + + if ((StartMode & 0x1F) == 0x10) + Start(); + + if (StartMode != 0x10 && StartMode != 0x30) + printf("UNIMPLEMENTED ARM%d NDMA%d START MODE %02X, %08X->%08X\n", CPU?7:9, Num, StartMode, SrcAddr, DstAddr); + } +} + +void DSi_NDMA::Start() +{ + if (Running) return; + + if (!InProgress) + { + RemCount = BlockLength; + if (!RemCount) + RemCount = 0x1000000; + } + + // TODO: how does GXFIFO DMA work with all the block shito? + IterCount = RemCount; + + if (IterCount > TotalRemCount) + IterCount = TotalRemCount; + + if (Cnt & (1<<12)) CurDstAddr = DstAddr; + if (Cnt & (1<<15)) CurSrcAddr = SrcAddr; + + printf("ARM%d NDMA%d %08X %02X %08X->%08X %d bytes\n", CPU?7:9, Num, Cnt, StartMode, CurSrcAddr, CurDstAddr, RemCount*4); + + //IsGXFIFODMA = (CPU == 0 && (CurSrcAddr>>24) == 0x02 && CurDstAddr == 0x04000400 && DstAddrInc == 0); + + // TODO eventually: not stop if we're running code in ITCM + + if (SubblockTimer & 0xFFFF) + printf("TODO! NDMA SUBBLOCK TIMER: %08X\n", SubblockTimer); + + if (NDS::DMAsRunning(CPU)) + Running = 1; + else + Running = 2; + + InProgress = true; + NDS::StopCPU(CPU, 1<<(Num+4)); +} + +void DSi_NDMA::Run() +{ + if (!Running) return; + if (CPU == 0) return Run9(); + else return Run7(); +} + +void DSi_NDMA::Run9() +{ + if (NDS::ARM9Timestamp >= NDS::ARM9Target) return; + + Executing = true; + + // add NS penalty for first accesses in burst + bool burststart = (Running == 2); + Running = 1; + + s32 unitcycles; + //s32 lastcycles = cycles; + + bool dofill = ((Cnt >> 13) & 0x3) == 3; + + if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02) + { + unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][2] + NDS::ARM9MemTimings[CurDstAddr >> 14][2]; + } + else + { + unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][3] + NDS::ARM9MemTimings[CurDstAddr >> 14][3]; + if ((CurSrcAddr >> 24) == (CurDstAddr >> 24)) + unitcycles++; + else if ((CurSrcAddr >> 24) == 0x02) + unitcycles--; + + /*if (burststart) + { + cycles -= 2; + cycles -= (NDS::ARM9MemTimings[CurSrcAddr >> 14][2] + NDS::ARM9MemTimings[CurDstAddr >> 14][2]); + cycles += unitcycles; + }*/ + } + + while (IterCount > 0 && !Stall) + { + NDS::ARM9Timestamp += (unitcycles << NDS::ARM9ClockShift); + + if (dofill) + DSi::ARM9Write32(CurDstAddr, FillData); + else + DSi::ARM9Write32(CurDstAddr, DSi::ARM9Read32(CurSrcAddr)); + + CurSrcAddr += SrcAddrInc<<2; + CurDstAddr += DstAddrInc<<2; + IterCount--; + RemCount--; + TotalRemCount--; + + if (NDS::ARM9Timestamp >= NDS::ARM9Target) break; + } + + Executing = false; + Stall = false; + + if (RemCount) + { + if (IterCount == 0) + { + Running = 0; + NDS::ResumeCPU(0, 1<<(Num+4)); + + //if (StartMode == 0x07) + // GPU3D::CheckFIFODMA(); + } + + return; + } + + if ((StartMode & 0x1F) == 0x10) // CHECKME + Cnt &= ~(1<<31); + else if (!(Cnt & (1<<29))) + { + if (TotalRemCount == 0) + Cnt &= ~(1<<31); + } + + if (Cnt & (1<<30)) + NDS::SetIRQ(0, NDS::IRQ_DSi_NDMA0 + Num); + + Running = 0; + InProgress = false; + NDS::ResumeCPU(0, 1<<(Num+4)); +} + +void DSi_NDMA::Run7() +{ + if (NDS::ARM7Timestamp >= NDS::ARM7Target) return; + + Executing = true; + + // add NS penalty for first accesses in burst + bool burststart = (Running == 2); + Running = 1; + + s32 unitcycles; + //s32 lastcycles = cycles; + + bool dofill = ((Cnt >> 13) & 0x3) == 3; + + if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02) + { + unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 15][2] + NDS::ARM7MemTimings[CurDstAddr >> 15][2]; + } + else + { + unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 15][3] + NDS::ARM7MemTimings[CurDstAddr >> 15][3]; + if ((CurSrcAddr >> 23) == (CurDstAddr >> 23)) + unitcycles++; + else if ((CurSrcAddr >> 24) == 0x02) + unitcycles--; + + /*if (burststart) + { + cycles -= 2; + cycles -= (NDS::ARM7MemTimings[CurSrcAddr >> 15][2] + NDS::ARM7MemTimings[CurDstAddr >> 15][2]); + cycles += unitcycles; + }*/ + } + + while (IterCount > 0 && !Stall) + { + NDS::ARM7Timestamp += unitcycles; + + if (dofill) + DSi::ARM7Write32(CurDstAddr, FillData); + else + DSi::ARM7Write32(CurDstAddr, DSi::ARM7Read32(CurSrcAddr)); + + CurSrcAddr += SrcAddrInc<<2; + CurDstAddr += DstAddrInc<<2; + IterCount--; + RemCount--; + + if (NDS::ARM7Timestamp >= NDS::ARM7Target) break; + } + + Executing = false; + Stall = false; + + if (RemCount) + { + if (IterCount == 0) + { + Running = 0; + NDS::ResumeCPU(1, 1<<(Num+4)); + } + + return; + } + + if ((StartMode & 0x1F) == 0x10) // CHECKME + Cnt &= ~(1<<31); + else if (!(Cnt & (1<<29))) + { + if (TotalRemCount == 0) + Cnt &= ~(1<<31); + } + + if (Cnt & (1<<30)) + NDS::SetIRQ(1, NDS::IRQ_DSi_NDMA0 + Num); + + Running = 0; + InProgress = false; + NDS::ResumeCPU(1, 1<<(Num+4)); +} diff --git a/src/DSi_NDMA.h b/src/DSi_NDMA.h index 6661652..d7b7483 100644 --- a/src/DSi_NDMA.h +++ b/src/DSi_NDMA.h @@ -19,6 +19,78 @@ #ifndef DSI_NDMA_H #define DSI_NDMA_H -// +#include "types.h" + +class DSi_NDMA +{ +public: + DSi_NDMA(u32 cpu, u32 num); + ~DSi_NDMA(); + + void Reset(); + + void DoSavestate(Savestate* file); + + void WriteCnt(u32 val); + void Start(); + + void Run(); + + void Run9(); + void Run7(); + + bool IsInMode(u32 mode) + { + return ((mode == StartMode) && (Cnt & 0x80000000)); + } + + bool IsRunning() { return Running!=0; } + + void StartIfNeeded(u32 mode) + { + if ((mode == StartMode) && (Cnt & 0x80000000)) + Start(); + } + + void StopIfNeeded(u32 mode) + { + if (mode == StartMode) + Cnt &= ~0x80000000; + } + + void StallIfRunning() + { + if (Executing) Stall = true; + } + + u32 SrcAddr; + u32 DstAddr; + u32 TotalLength; // total length, when transferring multiple blocks + u32 BlockLength; // length of one transfer + u32 SubblockTimer; // optional delay between subblocks (only in round-robin mode) + u32 FillData; + u32 Cnt; + +private: + u32 CPU, Num; + + u32 StartMode; + u32 CurSrcAddr; + u32 CurDstAddr; + u32 SubblockLength; // length transferred per run when delay is used + u32 RemCount; + u32 IterCount; + u32 TotalRemCount; + u32 SrcAddrInc; + u32 DstAddrInc; + + u32 Running; + bool InProgress; + + bool Executing; + bool Stall; + + bool IsGXFIFODMA; +}; #endif // DSI_NDMA_H diff --git a/src/NDS.cpp b/src/NDS.cpp index 414f87c..e20f62f 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -827,6 +827,7 @@ u32 RunFrame() if (!(CPUStop & 0x80000000)) DMAs[1]->Run(); if (!(CPUStop & 0x80000000)) DMAs[2]->Run(); if (!(CPUStop & 0x80000000)) DMAs[3]->Run(); + DSi::RunNDMAs(0); } else { @@ -849,6 +850,7 @@ u32 RunFrame() DMAs[5]->Run(); DMAs[6]->Run(); DMAs[7]->Run(); + DSi::RunNDMAs(1); } else { @@ -1153,6 +1155,7 @@ void GXFIFOStall() DMAs[1]->StallIfRunning(); DMAs[2]->StallIfRunning(); DMAs[3]->StallIfRunning(); + DSi::StallNDMAs(); } } @@ -1367,6 +1370,7 @@ bool DMAsRunning(u32 cpu) if (DMAs[cpu+1]->IsRunning()) return true; if (DMAs[cpu+2]->IsRunning()) return true; if (DMAs[cpu+3]->IsRunning()) return true; + if (DSi::NDMAsRunning(cpu>>2)) return true; return false; } @@ -101,7 +101,7 @@ enum IRQ2_DSi_GPIO18_0 = 0, IRQ2_DSi_GPIO18_1, IRQ2_DSi_GPIO18_2, - IRQ2_DSi_Unused35, + IRQ2_DSi_Unused3, IRQ2_DSi_GPIO33_0, IRQ2_DSi_Headphone, IRQ2_DSi_PowerButton, @@ -138,7 +138,6 @@ extern u64 ARM9Timestamp, ARM9Target; extern u64 ARM7Timestamp, ARM7Target; extern u32 ARM9ClockShift; -// hax extern u32 IME[2]; extern u32 IE[2]; extern u32 IF[2]; @@ -146,6 +145,8 @@ extern u32 IE2; extern u32 IF2; extern Timer Timers[8]; +extern u32 CPUStop; + extern u16 PowerControl9; extern u16 ExMemCnt[2]; |