diff --git a/src/apple2.cpp b/src/apple2.cpp index 2a1858e..8b6a36f 100755 --- a/src/apple2.cpp +++ b/src/apple2.cpp @@ -188,6 +188,7 @@ WriteLog("CPU: Execute65C02(&mainCPU, cycles);\n"); } #endif +WriteLog("CPUThread: Supposedly end of frame...\n"); #ifdef THREAD_DEBUGGING WriteLog("CPU: SDL_mutexP(cpuMutex);\n"); @@ -1155,6 +1156,8 @@ Z $DA $9A $DA $9A ESC $9B $9B $9B $9B No xlation */ +static uint64_t lastCPUCycles = 0; +static uint32_t frameCount = 0; static void FrameCallback(void) { SDL_Event event; @@ -1297,7 +1300,7 @@ else if (event.key.keysym.sym == SDLK_F10) } } -#warning "!!! Taking MAJOR time hit with the video frame rendering !!!" +//#warning "!!! Taking MAJOR time hit with the video frame rendering !!!" RenderVideoFrame(); SetCallbackTime(FrameCallback, 16666.66666667); @@ -1321,10 +1324,26 @@ if (counter == 60) //Actually, slows things down too much... //SDL_Delay(10); // while (SDL_GetTicks() - startTicks < 16); // Wait for next frame... - while (SDL_GetTicks() - startTicks < 16) + +// This is the problem: If you set the interval to 16, it runs faster than +// 1/60s per frame. If you set it to 17, it runs slower. What we need is to +// have it do 16 for one frame, then 17 for two others. Then it should average +// out to 1/60s per frame every 3 frames. + frameCount = (frameCount + 1) % 3; + + uint32_t waitFrameTime = 17 - (frameCount == 0 ? 1 : 0); + + while (SDL_GetTicks() - startTicks < waitFrameTime) SDL_Delay(1); // Wait for next frame... startTicks = SDL_GetTicks(); +#if 1 + uint64_t cpuCycles = GetCurrentV65C02Clock(); + uint32_t cyclesBurned = (uint32_t)(cpuCycles - lastCPUCycles); + WriteLog("FrameCallback: used %i cycles\n", cyclesBurned); + lastCPUCycles = cpuCycles; +#endif + //let's wait, then signal... //works longer, but then still falls behind... #ifdef THREADED_65C02 diff --git a/src/sound.cpp b/src/sound.cpp index fd6754d..0d794c9 100755 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -162,7 +162,7 @@ static void SDLSoundCallback(void * /*userdata*/, Uint8 * buffer8, int length8) // Let's try using a mutex for shared resource consumption... //Actually, I think Lock/UnlockAudio() does this already... -//WriteLog("SDLSoundCallback(): SDL_mutexP(mutex2)\n"); +WriteLog("SDLSoundCallback: soundBufferPos = %i\n", soundBufferPos); SDL_mutexP(mutex2); // Recast this as a 16-bit type... diff --git a/src/v65c02.cpp b/src/v65c02.cpp index 216a0af..7f86895 100755 --- a/src/v65c02.cpp +++ b/src/v65c02.cpp @@ -2850,6 +2850,9 @@ bool dumpDis = false; //bleh. //static uint32_t limit = 0; +// This should be in the regs struct, in case we have multiple CPUs... +#warning "!!! Move overflow into regs struct !!!" +static uint64_t overflow = 0; // // Function to execute 65C02 for "cycles" cycles // @@ -2875,7 +2878,7 @@ Let's see... if (regs.clock + cycles > 0xFFFFFFFF) wraparound = true; */ - uint64_t endCycles = regs.clock + (uint64_t)cycles; + uint64_t endCycles = regs.clock + (uint64_t)cycles - overflow; while (regs.clock < endCycles) { @@ -3020,6 +3023,12 @@ WriteLog("\n*** IRQ ***\n\n"); } } + // If we went longer than the passed in cycles, make a note of it so we can + // subtract it out from a subsequent run. It's guaranteed to be positive, + // because the condition that exits the main loop above is written such + // that regs.clock has to be larger than endCycles to exit from it. + overflow = regs.clock - endCycles; + myMemcpy(context, ®s, sizeof(V65C02REGS)); }