Keep track of actual speed to ensure emulated CPU goes at the right speed (and keeps audio on track).
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
parent
ad335e2a5c
commit
48146f4c34
6 changed files with 68 additions and 11 deletions
|
@ -6,6 +6,7 @@ add_library(common2 STATIC
|
|||
programoptions.cpp
|
||||
utils.cpp
|
||||
timer.cpp
|
||||
speed.cpp
|
||||
)
|
||||
|
||||
find_package(Boost REQUIRED
|
||||
|
|
35
source/frontends/common2/speed.cpp
Normal file
35
source/frontends/common2/speed.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include "frontends/common2/speed.h"
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "CPU.h"
|
||||
#include "AppleWin.h"
|
||||
|
||||
Speed::Speed()
|
||||
: myStartTime(std::chrono::steady_clock::now())
|
||||
, myStartCycles(g_nCumulativeCycles)
|
||||
{
|
||||
}
|
||||
|
||||
size_t Speed::getCyclesTillNext(const size_t milliseconds) const
|
||||
{
|
||||
const uint64_t currentCycles = g_nCumulativeCycles;
|
||||
const auto currentTime = std::chrono::steady_clock::now();
|
||||
|
||||
const auto currentDelta = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - myStartTime).count();
|
||||
// target the next time we will be called
|
||||
const auto targetDeltaInMillis = currentDelta + milliseconds;
|
||||
|
||||
const uint64_t targetCycles = static_cast<uint64_t>(targetDeltaInMillis * g_fCurrentCLK6502 * 1.0e-3) + myStartCycles;
|
||||
if (targetCycles > currentCycles)
|
||||
{
|
||||
// number of cycles to fill this period
|
||||
const uint64_t cyclesToExecute = targetCycles - currentCycles;
|
||||
return cyclesToExecute;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we got ahead, nothing to do this time
|
||||
// CpuExecute will still execute 1 instruction, which does not cause any issues
|
||||
return 0;
|
||||
}
|
||||
}
|
18
source/frontends/common2/speed.h
Normal file
18
source/frontends/common2/speed.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class Speed
|
||||
{
|
||||
public:
|
||||
Speed();
|
||||
|
||||
// calculate the number of cycles to execute in the current period
|
||||
// assuming the next call will happen in x milliseconds
|
||||
size_t getCyclesTillNext(const size_t milliseconds) const;
|
||||
|
||||
private:
|
||||
|
||||
std::chrono::time_point<std::chrono::steady_clock> myStartTime;
|
||||
uint64_t myStartCycles;
|
||||
};
|
|
@ -141,23 +141,22 @@ Emulator::Emulator(
|
|||
, myTexture(texture)
|
||||
, myMultiplier(1)
|
||||
, myFullscreen(false)
|
||||
, myExtraCycles(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Emulator::executeCycles(const int targetCycles)
|
||||
void Emulator::execute(const size_t next)
|
||||
{
|
||||
const size_t cyclesToExecute = mySpeed.getCyclesTillNext(next);
|
||||
|
||||
const bool bVideoUpdate = true;
|
||||
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame();
|
||||
|
||||
const DWORD executedCycles = CpuExecute(targetCycles + myExtraCycles, bVideoUpdate);
|
||||
const DWORD executedCycles = CpuExecute(cyclesToExecute, bVideoUpdate);
|
||||
|
||||
g_dwCyclesThisFrame = (g_dwCyclesThisFrame + executedCycles) % dwClksPerFrame;
|
||||
GetCardMgr().GetDisk2CardMgr().UpdateDriveState(executedCycles);
|
||||
MB_PeriodicUpdate(executedCycles);
|
||||
SpkrUpdate(executedCycles);
|
||||
|
||||
myExtraCycles = targetCycles - executedCycles;
|
||||
}
|
||||
|
||||
SDL_Rect Emulator::updateTexture()
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <SDL.h>
|
||||
#include <memory>
|
||||
|
||||
#include "frontends/common2/speed.h"
|
||||
|
||||
class Emulator
|
||||
{
|
||||
public:
|
||||
|
@ -12,7 +14,7 @@ public:
|
|||
const std::shared_ptr<SDL_Texture> & texture
|
||||
);
|
||||
|
||||
void executeCycles(const int cycles);
|
||||
void execute(const size_t milliseconds);
|
||||
void refreshVideo();
|
||||
SDL_Rect updateTexture();
|
||||
void refreshVideo(const SDL_Rect & rect);
|
||||
|
@ -30,5 +32,6 @@ private:
|
|||
|
||||
int myMultiplier;
|
||||
bool myFullscreen;
|
||||
int myExtraCycles;
|
||||
|
||||
Speed mySpeed;
|
||||
};
|
||||
|
|
|
@ -152,8 +152,7 @@ namespace
|
|||
SDL_LockMutex(data->mutex);
|
||||
|
||||
data->timer->tic();
|
||||
const int uCyclesToExecute = int(g_fCurrentCLK6502 * interval * 0.001);
|
||||
data->emulator->executeCycles(uCyclesToExecute);
|
||||
data->emulator->execute(interval);
|
||||
data->timer->toc();
|
||||
|
||||
SDL_UnlockMutex(data->mutex);
|
||||
|
@ -325,7 +324,9 @@ void run_sdl(int argc, const char * argv [])
|
|||
updateTextureTimerTag = "0 .";
|
||||
|
||||
bool quit = false;
|
||||
const int uCyclesToExecute = int(g_fCurrentCLK6502 / fps);
|
||||
|
||||
// it does not need to be exact
|
||||
const size_t oneFrame = 1000 / fps;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -335,7 +336,7 @@ void run_sdl(int argc, const char * argv [])
|
|||
eventTimer.toc();
|
||||
|
||||
cpuTimer.tic();
|
||||
emulator.executeCycles(uCyclesToExecute);
|
||||
emulator.execute(oneFrame);
|
||||
cpuTimer.toc();
|
||||
|
||||
updateTextureTimer.tic();
|
||||
|
|
Loading…
Add table
Reference in a new issue