diff options
-rw-r--r-- | ARM.h | 4 | ||||
-rw-r--r-- | DMA.cpp | 118 | ||||
-rw-r--r-- | DMA.h | 8 | ||||
-rw-r--r-- | GPU3D.cpp | 7 | ||||
-rw-r--r-- | NDS.cpp | 56 | ||||
-rw-r--r-- | NDS.h | 1 | ||||
-rw-r--r-- | melonDS.depend | 14 |
7 files changed, 175 insertions, 33 deletions
@@ -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) @@ -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; } @@ -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 @@ -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; } @@ -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) @@ -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" |