diff --git a/desmume/src/GPU_osd.cpp b/desmume/src/GPU_osd.cpp index 392553dbf..75fe34c36 100644 --- a/desmume/src/GPU_osd.cpp +++ b/desmume/src/GPU_osd.cpp @@ -505,6 +505,7 @@ void DrawHUD() if (CommonSettings.hud.FpsDisplay) { osd->addFixed(Hud.FpsDisplay.x, Hud.FpsDisplay.y, "Fps:%02d/%02d (%02d%%)%s", Hud.fps, Hud.fps3d, Hud.arm9load, driver->EMU_IsEmulationPaused() ? " (paused)" : ""); + osd->addFixed(Hud.FpsDisplay.x, Hud.FpsDisplay.y+20, "[%07d]", Hud.cpuloopIterationCount); } if (CommonSettings.hud.FrameCounterDisplay) diff --git a/desmume/src/GPU_osd.h b/desmume/src/GPU_osd.h index 722642ce4..c479d6c98 100644 --- a/desmume/src/GPU_osd.h +++ b/desmume/src/GPU_osd.h @@ -57,6 +57,7 @@ public: fps = 0; fps3d = 0; arm9load = 0; + cpuloopIterationCount = 0; clicked = false; } @@ -72,7 +73,7 @@ public: HudCoordinates &hud(int i) { return ((HudCoordinates*)this)[i]; } void reset(); - int fps, fps3d, arm9load; + int fps, fps3d, arm9load, cpuloopIterationCount; bool clicked; }; diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 4b80542d7..d7f42e8f1 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -41,6 +41,7 @@ #include "movie.h" #include "Disassembler.h" #include "readwrite.h" +#include "debug.h" #include "path.h" @@ -52,6 +53,8 @@ PathInfo path; #endif #endif +//#undef EXPERIMENTAL_WIFI + TCommonSettings CommonSettings; static BaseDriver _stub_driver; BaseDriver* driver = &_stub_driver; @@ -1544,6 +1547,7 @@ struct TSequenceItem_GXFIFO : public TSequenceItem FORCEINLINE void exec() { + IF_DEVELOPER(DEBUG_statistics.sequencerExecutionCounters[4]++); while(isTriggered()) { enabled = false; gfx3d_execute3D(); @@ -1571,14 +1575,12 @@ template struct TSequenceItem_Timer : public TSequenceItem FORCEINLINE u64 next() { - //todo - change this to go through an entire overflow cycle instead of a single increment - //however, in order to do this, we need to change the counter read emulation to calculate its value - //instead of just plucking the uptodate value (which would no longer be kept uptodate) return nds.timerCycle[procnum][num]; } FORCEINLINE void exec() { + IF_DEVELOPER(DEBUG_statistics.sequencerExecutionCounters[13+procnum*4+num]++); u8* regs = procnum==0?MMU.ARM9_REG:MMU.ARM7_REG; bool first = true, over; //we'll need to check chained timers.. @@ -1646,6 +1648,8 @@ template struct TSequenceItem_DMA : public TSequenceItem FORCEINLINE void exec() { + IF_DEVELOPER(DEBUG_statistics.sequencerExecutionCounters[5+procnum*4+chan]++); + //printf("exec from TSequenceItem_DMA: %d %d\n",procnum,chan); controller->exec(); // //give gxfifo dmas a chance to re-trigger @@ -1698,6 +1702,7 @@ struct TSequenceItem_divider : public TSequenceItem void exec() { + IF_DEVELOPER(DEBUG_statistics.sequencerExecutionCounters[2]++); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A0, (u32)MMU.divResult); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A4, (u32)(MMU.divResult >> 32)); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A8, (u32)MMU.divMod); @@ -1724,6 +1729,7 @@ struct TSequenceItem_sqrtunit : public TSequenceItem FORCEINLINE void exec() { + IF_DEVELOPER(DEBUG_statistics.sequencerExecutionCounters[3]++); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B4, MMU.sqrtResult); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B0, MMU.sqrtCnt); MMU.sqrtRunning = FALSE; @@ -2029,6 +2035,7 @@ static void execHardware_hstart() void NDS_Reschedule() { + DEBUG_statistics.sequencerExecutionCounters[0]++; sequencer.reschedule = true; } @@ -2091,6 +2098,9 @@ void Sequencer::execHardware() { if(dispcnt.isTriggered()) { + + IF_DEVELOPER(DEBUG_statistics.sequencerExecutionCounters[1]++); + switch(dispcnt.param) { case ESI_DISPCNT_HStart: @@ -2280,6 +2290,10 @@ void NDS_exec(s32 nb) sequencer.nds_vblankEnded = false; + nds.cpuloopIterationCount = 0; + + IF_DEVELOPER(for(int i=0;i<32;i++) DEBUG_statistics.sequencerExecutionCounters[i] = 0); + if(nds.sleeping) { gpu_UpdateRender(); @@ -2292,6 +2306,7 @@ void NDS_exec(s32 nb) { for(;;) { + nds.cpuloopIterationCount++; sequencer.execHardware(); //break out once per frame @@ -2334,6 +2349,8 @@ void NDS_exec(s32 nb) } } + //DEBUG_statistics.printSequencerExecutionCounters(); + //end of frame emulation housekeeping if(LagFrameFlag) { diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 3d64c5c07..416ad1ac1 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -179,6 +179,7 @@ typedef struct s32 idleCycles; s32 runCycleCollector[16]; s32 idleFrameCounter; + s32 cpuloopIterationCount; //counts the number of times during a frame that a reschedule happened //if the game was booted on a debug console, this is set BOOL debugConsole; diff --git a/desmume/src/debug.cpp b/desmume/src/debug.cpp index ddceac9c7..610ca6bb0 100644 --- a/desmume/src/debug.cpp +++ b/desmume/src/debug.cpp @@ -124,6 +124,12 @@ void DebugStatistics::print() } } +void DebugStatistics::printSequencerExecutionCounters() +{ + for(int i=0;i<21;i++) printf("%06d ",sequencerExecutionCounters[i]); + printf("\n"); +} + void DEBUG_reset() { DEBUG_statistics = DebugStatistics(); diff --git a/desmume/src/debug.h b/desmume/src/debug.h index 15963a610..de712f0f3 100644 --- a/desmume/src/debug.h +++ b/desmume/src/debug.h @@ -36,7 +36,10 @@ struct DebugStatistics u32 arm[4096]; } instructionHits[2]; //one for each cpu + s32 sequencerExecutionCounters[32]; + void print(); + void printSequencerExecutionCounters(); }; extern DebugStatistics DEBUG_statistics; diff --git a/desmume/src/types.h b/desmume/src/types.h index 0fc41753c..150a13d2f 100644 --- a/desmume/src/types.h +++ b/desmume/src/types.h @@ -26,6 +26,12 @@ #include "config.h" #endif +#ifdef DEVELOPER +#define IF_DEVELOPER(X) X +#else +#define IF_DEVELOPER(X) +#endif + #ifdef _MSC_VER #define ENABLE_SSE #define ENABLE_SSE2 diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 9fc2fcd9f..e9eda43a8 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -1279,6 +1279,8 @@ static void StepRunLoop_User() load = std::min(100,std::max(0,(int)(load*100/1120380))); Hud.arm9load = load; } + + Hud.cpuloopIterationCount = nds.cpuloopIterationCount; } static void StepRunLoop_Throttle(bool allowSleep = true, int forceFrameSkip = -1)