aboutsummaryrefslogtreecommitdiff
path: root/src/DMA.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/DMA.cpp')
-rw-r--r--src/DMA.cpp31
1 files changed, 19 insertions, 12 deletions
diff --git a/src/DMA.cpp b/src/DMA.cpp
index 9a17f41..edd6f8b 100644
--- a/src/DMA.cpp
+++ b/src/DMA.cpp
@@ -186,18 +186,6 @@ void DMA::Start()
//printf("ARM%d DMA%d %08X %02X %08X->%08X %d bytes %dbit\n", CPU?7:9, Num, Cnt, StartMode, CurSrcAddr, CurDstAddr, RemCount*((Cnt&0x04000000)?4:2), (Cnt&0x04000000)?32:16);
- // special path for cart DMA. this is a gross hack.
- // emulating it properly requires emulating cart transfer delays, so uh... TODO
- if (CurSrcAddr==0x04100010 && RemCount==1 && (Cnt & 0x07E00000)==0x07000000 &&
- (StartMode==0x05 || StartMode==0x12))
- {
- NDSCart::DMA(CurDstAddr);
- Cnt &= ~0x80000000;
- if (Cnt & 0x40000000)
- NDS::SetIRQ(CPU, NDS::IRQ_DMA0 + Num);
- return;
- }
-
// special path for the display FIFO. another gross hack.
// the display FIFO seems to be more like a circular buffer that holds 16 pixels
// from which the display controller reads. DMA is triggered every 8 pixels to fill it
@@ -212,6 +200,8 @@ void DMA::Start()
return;
}
+ IsGXFIFODMA = (CPU == 0 && (CurSrcAddr>>24) == 0x02 && CurDstAddr == 0x04000400 && DstAddrInc == 0);
+
// TODO eventually: not stop if we're running code in ITCM
Running = true;
@@ -245,6 +235,23 @@ s32 DMA::Run(s32 cycles)
}
else
{
+ // optimized path for typical GXFIFO DMA
+ if (IsGXFIFODMA)
+ {
+ while (IterCount > 0 && cycles > 0)
+ {
+ GPU3D::WriteToGXFIFO(*(u32*)&NDS::MainRAM[CurSrcAddr&0x3FFFFF]);
+
+ s32 c = (Waitstates[1][0x2] + Waitstates[1][0x4]);
+ cycles -= c;
+ NDS::RunTimingCriticalDevices(0, c);
+
+ CurSrcAddr += SrcAddrInc<<2;
+ IterCount--;
+ RemCount--;
+ }
+ }
+
u32 (*readfn)(u32) = CPU ? NDS::ARM7Read32 : NDS::ARM9Read32;
void (*writefn)(u32,u32) = CPU ? NDS::ARM7Write32 : NDS::ARM9Write32;