aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ARM.h4
-rw-r--r--DMA.cpp118
-rw-r--r--DMA.h8
-rw-r--r--GPU3D.cpp7
-rw-r--r--NDS.cpp56
-rw-r--r--NDS.h1
-rw-r--r--melonDS.depend14
7 files changed, 175 insertions, 33 deletions
diff --git a/ARM.h b/ARM.h
index bf354a7..79c2bce 100644
--- a/ARM.h
+++ b/ARM.h
@@ -125,7 +125,7 @@ public:
else
val = NDS::ARM7Read8(addr);
- Cycles += Waitstates[3][(addr>>24)&0xF];
+ Cycles += Waitstates[2][(addr>>24)&0xF];
return val;
}
@@ -171,7 +171,7 @@ public:
else
NDS::ARM7Write8(addr, val);
- Cycles += Waitstates[3][(addr>>24)&0xF];
+ Cycles += Waitstates[2][(addr>>24)&0xF];
}
void DataWrite16(u32 addr, u16 val, u32 forceuser=0)
diff --git a/DMA.cpp b/DMA.cpp
index dbedc01..28f7ddc 100644
--- a/DMA.cpp
+++ b/DMA.cpp
@@ -34,6 +34,66 @@ DMA::DMA(u32 cpu, u32 num)
CPU = cpu;
Num = num;
+ if (cpu == 0)
+ CountMask = 0x001FFFFF;
+ else
+ CountMask = (num==3 ? 0x0000FFFF : 0x00003FFF);
+
+ // TODO: merge with the one in ARM.cpp, somewhere
+ for (int i = 0; i < 16; i++)
+ {
+ Waitstates[0][i] = 1;
+ Waitstates[1][i] = 1;
+ }
+
+ if (!num)
+ {
+ // ARM9
+ // note: 33MHz cycles
+ Waitstates[0][0x2] = 1;
+ Waitstates[0][0x3] = 1;
+ Waitstates[0][0x4] = 1;
+ Waitstates[0][0x5] = 1;
+ Waitstates[0][0x6] = 1;
+ Waitstates[0][0x7] = 1;
+ Waitstates[0][0x8] = 6;
+ Waitstates[0][0x9] = 6;
+ Waitstates[0][0xA] = 10;
+ Waitstates[0][0xF] = 1;
+
+ Waitstates[1][0x2] = 2;
+ Waitstates[1][0x3] = 1;
+ Waitstates[1][0x4] = 1;
+ Waitstates[1][0x5] = 2;
+ Waitstates[1][0x6] = 2;
+ Waitstates[1][0x7] = 1;
+ Waitstates[1][0x8] = 12;
+ Waitstates[1][0x9] = 12;
+ Waitstates[1][0xA] = 10;
+ Waitstates[1][0xF] = 1;
+ }
+ else
+ {
+ // ARM7
+ Waitstates[0][0x0] = 1;
+ Waitstates[0][0x2] = 1;
+ Waitstates[0][0x3] = 1;
+ Waitstates[0][0x4] = 1;
+ Waitstates[0][0x6] = 1;
+ Waitstates[0][0x8] = 6;
+ Waitstates[0][0x9] = 6;
+ Waitstates[0][0xA] = 10;
+
+ Waitstates[1][0x0] = 1;
+ Waitstates[1][0x2] = 2;
+ Waitstates[1][0x3] = 1;
+ Waitstates[1][0x4] = 1;
+ Waitstates[1][0x6] = 2;
+ Waitstates[1][0x8] = 12;
+ Waitstates[1][0x9] = 12;
+ Waitstates[1][0xA] = 10;
+ }
+
Reset();
}
@@ -51,8 +111,11 @@ void DMA::Reset()
CurSrcAddr = 0;
CurDstAddr = 0;
RemCount = 0;
+ IterCount = 0;
SrcAddrInc = 0;
DstAddrInc = 0;
+
+ Running = false;
}
void DMA::WriteCnt(u32 val)
@@ -90,16 +153,16 @@ void DMA::WriteCnt(u32 val)
Start();
else if (StartMode == 0x07)
GPU3D::CheckFIFODMA();
- //else
- // printf("SPECIAL ARM%d DMA%d START MODE %02X\n", CPU?7:9, Num, StartMode);
+
if ((StartMode&7)!=0x00 && (StartMode&7)!=0x1 && StartMode!=2 && StartMode!=0x05 && StartMode!=0x12 && StartMode!=0x07)
printf("UNIMPLEMENTED ARM%d DMA%d START MODE %02X\n", CPU?7:9, Num, StartMode);
- //if (StartMode==2)printf("HBLANK DMA %08X -> %08X\n", SrcAddr, DstAddr);
}
}
void DMA::Start()
{
+ if (Running) return;
+
u32 countmask;
if (CPU == 0)
countmask = 0x001FFFFF;
@@ -110,6 +173,11 @@ void DMA::Start()
if (!RemCount)
RemCount = countmask+1;
+ if (StartMode == 0x07 && RemCount > 112)
+ IterCount = 112;
+ else
+ IterCount = RemCount;
+
if ((Cnt & 0x00600000) == 0x00600000)
CurDstAddr = DstAddr;
@@ -126,24 +194,33 @@ void DMA::Start()
NDS::TriggerIRQ(CPU, NDS::IRQ_DMA0 + Num);
return;
}
- //if (StartMode == 0x07)printf("GXFIFO DMA %08X %08X\n", Cnt, CurSrcAddr);
- u32 num = RemCount;
- if (StartMode == 0x07 && num > 112)
- num = 112;
- // TODO: NOT MAKE THE DMA INSTANT!!
+ // TODO eventually: not stop if we're running code in ITCM
+
+ Running = true;
+ NDS::StopCPU(CPU, true);
+}
+
+s32 DMA::Run(s32 cycles)
+{
+ if (!Running)
+ return cycles;
+
+ u32 zorp = IterCount;
+
if (!(Cnt & 0x04000000))
{
u16 (*readfn)(u32) = CPU ? NDS::ARM7Read16 : NDS::ARM9Read16;
void (*writefn)(u32,u16) = CPU ? NDS::ARM7Write16 : NDS::ARM9Write16;
- while (num > 0)
+ while (IterCount > 0 && cycles > 0)
{
writefn(CurDstAddr, readfn(CurSrcAddr));
+ cycles -= (Waitstates[0][(CurSrcAddr >> 24) & 0xF] + Waitstates[0][(CurDstAddr >> 24) & 0xF]);
CurSrcAddr += SrcAddrInc<<1;
CurDstAddr += DstAddrInc<<1;
- num--;
+ IterCount--;
RemCount--;
}
}
@@ -152,22 +229,30 @@ void DMA::Start()
u32 (*readfn)(u32) = CPU ? NDS::ARM7Read32 : NDS::ARM9Read32;
void (*writefn)(u32,u32) = CPU ? NDS::ARM7Write32 : NDS::ARM9Write32;
- while (num > 0)
+ while (IterCount > 0 && cycles > 0)
{
writefn(CurDstAddr, readfn(CurSrcAddr));
+ cycles -= (Waitstates[1][(CurSrcAddr >> 24) & 0xF] + Waitstates[1][(CurDstAddr >> 24) & 0xF]);
CurSrcAddr += SrcAddrInc<<2;
CurDstAddr += DstAddrInc<<2;
- num--;
+ IterCount--;
RemCount--;
}
}
if (RemCount)
{
- Cnt &= ~countmask;
+ Cnt &= ~CountMask;
Cnt |= RemCount;
- return;
+
+ if (IterCount == 0)
+ {
+ Running = false;
+ NDS::StopCPU(CPU, false);
+ }
+
+ return cycles;
}
if (!(Cnt & 0x02000000))
@@ -175,4 +260,9 @@ void DMA::Start()
if (Cnt & 0x40000000)
NDS::TriggerIRQ(CPU, NDS::IRQ_DMA0 + Num);
+
+ Running = false;
+ NDS::StopCPU(CPU, false);
+
+ return cycles - 2;
}
diff --git a/DMA.h b/DMA.h
index 619b163..59a7f03 100644
--- a/DMA.h
+++ b/DMA.h
@@ -32,6 +32,8 @@ public:
void WriteCnt(u32 val);
void Start();
+ s32 Run(s32 cycles);
+
void StartIfNeeded(u32 mode)
{
if ((mode == StartMode) && (Cnt & 0x80000000))
@@ -45,12 +47,18 @@ public:
private:
u32 CPU, Num;
+ s32 Waitstates[2][16];
+
u32 StartMode;
u32 CurSrcAddr;
u32 CurDstAddr;
u32 RemCount;
+ u32 IterCount;
u32 SrcAddrInc;
u32 DstAddrInc;
+ u32 CountMask;
+
+ bool Running;
};
#endif
diff --git a/GPU3D.cpp b/GPU3D.cpp
index 4d0dd7b..c28ebd0 100644
--- a/GPU3D.cpp
+++ b/GPU3D.cpp
@@ -841,6 +841,8 @@ void SubmitVertex()
+int logflag = 0;
+
void CmdFIFOWrite(CmdFIFOEntry& entry)
{
if (CmdFIFO->IsEmpty() && !CmdPIPE->IsFull())
@@ -852,7 +854,8 @@ void CmdFIFOWrite(CmdFIFOEntry& entry)
{
if (CmdFIFO->IsFull())
{
- printf("!!! GX FIFO FULL\n");
+ if (!logflag) printf("!!! GX FIFO FULL\n");
+ logflag = 1;
//NDS::debug(0);
return;
}
@@ -876,6 +879,8 @@ CmdFIFOEntry CmdFIFORead()
CheckFIFOIRQ();
}
+ logflag = 0;
+
return ret;
}
diff --git a/NDS.cpp b/NDS.cpp
index 8b911d3..655e7ab 100644
--- a/NDS.cpp
+++ b/NDS.cpp
@@ -54,6 +54,8 @@ s32 ARM7Offset;
SchedEvent SchedList[Event_MAX];
u32 SchedListMask;
+u32 CPUStop;
+
u8 ARM9BIOS[0x1000];
u8 ARM7BIOS[0x4000];
@@ -278,6 +280,8 @@ void Reset()
ARM7->Reset();
CP15::Reset();
+ CPUStop = 0;
+
memset(Timers, 0, 8*sizeof(Timer));
for (i = 0; i < 8; i++) DMAs[i]->Reset();
@@ -307,7 +311,7 @@ void Reset()
// test
//LoadROM();
//LoadFirmware();
- if (NDSCart::LoadROM("rom/nsmb.nds"))
+ if (NDSCart::LoadROM("rom/raving.nds"))
Running = true; // hax
}
@@ -364,17 +368,45 @@ void RunFrame()
while (Running && framecycles>0)
{
- CalcIterationCycles();
+ s32 ndscyclestorun;
+ s32 ndscycles = 0;
- ARM9->CyclesToRun = CurIterationCycles << 1;
+ CalcIterationCycles();
- ARM9->Execute();
- s32 ndscyclestorun = ARM9->Cycles >> 1;
- s32 ndscycles = 0;
+ if (CPUStop & 0x1)
+ {
+ s32 cycles = CurIterationCycles;
+ cycles = DMAs[0]->Run(cycles);
+ if (cycles > 0) cycles = DMAs[1]->Run(cycles);
+ if (cycles > 0) cycles = DMAs[2]->Run(cycles);
+ if (cycles > 0) cycles = DMAs[3]->Run(cycles);
+ ndscyclestorun = CurIterationCycles - cycles;
+
+ // TODO: run other timing critical shit, like timers
+ GPU3D::Run(ndscyclestorun);
+ }
+ else
+ {
+ ARM9->CyclesToRun = CurIterationCycles << 1;
+ ARM9->Execute();
+ ndscyclestorun = ARM9->Cycles >> 1;
+ }
- ARM7->CyclesToRun = ndscyclestorun - ARM7Offset;
- ARM7->Execute();
- ARM7Offset = ARM7->Cycles - ARM7->CyclesToRun;
+ if (CPUStop & 0x2)
+ {
+ s32 cycles = ndscyclestorun - ARM7Offset;
+ cycles = DMAs[4]->Run(cycles);
+ if (cycles > 0) cycles = DMAs[5]->Run(cycles);
+ if (cycles > 0) cycles = DMAs[6]->Run(cycles);
+ if (cycles > 0) cycles = DMAs[7]->Run(cycles);
+ ARM7Offset = cycles;
+ }
+ else
+ {
+ ARM7->CyclesToRun = ndscyclestorun - ARM7Offset;
+ ARM7->Execute();
+ ARM7Offset = ARM7->Cycles - ARM7->CyclesToRun;
+ }
RunSystem(ndscyclestorun);
//GPU3D::Run(ndscyclestorun);
@@ -520,6 +552,12 @@ bool HaltInterrupted(u32 cpu)
return false;
}
+void StopCPU(u32 cpu, bool stop)
+{
+ if (stop) CPUStop |= (1<<cpu);
+ else CPUStop &= ~(1<<cpu);
+}
+
void CheckDMAs(u32 cpu, u32 mode)
diff --git a/NDS.h b/NDS.h
index 6f46e93..fdd2af6 100644
--- a/NDS.h
+++ b/NDS.h
@@ -142,6 +142,7 @@ void MapSharedWRAM(u8 val);
void TriggerIRQ(u32 cpu, u32 irq);
bool HaltInterrupted(u32 cpu);
+void StopCPU(u32 cpu, bool stop);
void CheckDMAs(u32 cpu, u32 mode);
diff --git a/melonDS.depend b/melonDS.depend
index cdf281d..d862460 100644
--- a/melonDS.depend
+++ b/melonDS.depend
@@ -5,12 +5,12 @@
"NDS.h"
"GPU.h"
-1486822548 c:\documents\sources\melonds\nds.h
+1487303037 c:\documents\sources\melonds\nds.h
"types.h"
1481161027 c:\documents\sources\melonds\types.h
-1487299879 source:c:\documents\sources\melonds\nds.cpp
+1487304040 source:c:\documents\sources\melonds\nds.cpp
<stdio.h>
<string.h>
"NDS.h"
@@ -31,7 +31,7 @@
"ARMInterpreter.h"
"GPU3D.h"
-1486261220 c:\documents\sources\melonds\arm.h
+1487302172 c:\documents\sources\melonds\arm.h
"types.h"
"NDS.h"
"CP15.h"
@@ -109,14 +109,14 @@
1486511075 c:\documents\sources\melonds\fifo.h
"types.h"
-1486823366 source:c:\documents\sources\melonds\dma.cpp
+1487305720 source:c:\documents\sources\melonds\dma.cpp
<stdio.h>
"NDS.h"
"DMA.h"
"NDSCart.h"
"GPU3D.h"
-1484698068 c:\documents\sources\melonds\dma.h
+1487305393 c:\documents\sources\melonds\dma.h
"types.h"
1487102235 source:c:\documents\sources\melonds\gpu.cpp
@@ -148,14 +148,14 @@
1487287868 c:\documents\sources\melonds\gpu3d.h
-1487299939 source:c:\documents\sources\melonds\gpu3d.cpp
+1487305740 source:c:\documents\sources\melonds\gpu3d.cpp
<stdio.h>
<string.h>
"NDS.h"
"GPU.h"
"FIFO.h"
-1487300098 source:c:\documents\sources\melonds\gpu3d_soft.cpp
+1487300658 source:c:\documents\sources\melonds\gpu3d_soft.cpp
<stdio.h>
<string.h>
"NDS.h"