sa2: add some logic to implement Full Speed.

Because we run a frame at a time, this is a bit different than in AppleWin.
Run up to 5 extra frames.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2021-05-28 19:07:58 +01:00
parent 96e3f37b76
commit db2f9be009
4 changed files with 58 additions and 13 deletions

View file

@ -19,12 +19,17 @@ namespace common2
myStartCycles = g_nCumulativeCycles;
}
uint64_t Speed::getCyclesAtFixedSpeed(const size_t microseconds) const
{
const uint64_t cycles = static_cast<uint64_t>(microseconds * g_fCurrentCLK6502 * 1.0e-6);
return cycles;
}
uint64_t Speed::getCyclesTillNext(const size_t microseconds) const
{
if (myFixedSpeed)
{
const uint64_t cycles = static_cast<uint64_t>(microseconds * g_fCurrentCLK6502 * 1.0e-6);
return cycles;
return getCyclesAtFixedSpeed(microseconds);
}
else
{

View file

@ -15,6 +15,7 @@ namespace common2
// calculate the number of cycles to execute in the current period
// assuming the next call will happen in x microseconds
uint64_t getCyclesTillNext(const size_t microseconds) const;
uint64_t getCyclesAtFixedSpeed(const size_t microseconds) const;
private:

View file

@ -32,6 +32,11 @@
namespace
{
bool canDoFullSpeed()
{
return GetCardMgr().GetDisk2CardMgr().IsConditionForFullSpeed() && !Spkr_IsActive() && !MB_IsActive();
}
void processAppleKey(const SDL_KeyboardEvent & key, const bool forceCapsLock)
{
// using keycode (or scan code) one takes a physical view of the keyboard
@ -493,7 +498,7 @@ namespace sa2
void SDLFrame::Execute(const DWORD cyclesToExecute)
{
const bool bVideoUpdate = true;
const bool bVideoUpdate = !g_bFullSpeed;
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame();
const DWORD executedCycles = CpuExecute(cyclesToExecute, bVideoUpdate);
@ -504,28 +509,59 @@ namespace sa2
SpkrUpdate(executedCycles);
}
void SDLFrame::ExecuteInRunningMode(const size_t msNextFrame)
{
// 1 frame at normal speed
const uint64_t cyclesToExecute = mySpeed.getCyclesTillNext(msNextFrame * 1000);
Execute(cyclesToExecute);
// up to 5x more as maximum speed
const int maximumFrames = 5;
const uint64_t cyclesToExecutePerFrame = mySpeed.getCyclesAtFixedSpeed(msNextFrame * 1000);
int count = maximumFrames;
while (g_bFullSpeed = (count && canDoFullSpeed()))
{
Execute(cyclesToExecutePerFrame);
--count;
}
if (count < maximumFrames)
{
// we have run something in full speed
// Redraw and Reset
VideoRedrawScreenDuringFullSpeed(g_dwCyclesThisFrame);
ResetSpeed();
}
}
void SDLFrame::ExecuteInDebugMode(const size_t msNextFrame)
{
// In AppleWin this is called without a timer for just one iteration
// because we run a "frame" at a time, we need a bit of ingenuity
const uint64_t cyclesToExecute = mySpeed.getCyclesTillNext(msNextFrame * 1000);
const uint64_t target = g_nCumulativeCycles + cyclesToExecute;
while (g_nAppMode == MODE_STEPPING && g_nCumulativeCycles < target)
{
DebugContinueStepping();
}
}
void SDLFrame::ExecuteOneFrame(const size_t msNextFrame)
{
// when running in adaptive speed
// the value msNextFrame is only a hint for when the next frame will arrive
const uint64_t cyclesToExecute = mySpeed.getCyclesTillNext(msNextFrame * 1000);
switch (g_nAppMode)
{
case MODE_RUNNING:
{
Execute(cyclesToExecute);
ExecuteInRunningMode(msNextFrame);
break;
}
case MODE_STEPPING:
{
// In AppleWin this is called without a timer for just one iteration
// because we run a "frame" at a time, we need a bit of ingenuity
const uint64_t target = g_nCumulativeCycles + cyclesToExecute;
while (g_nAppMode == MODE_STEPPING && g_nCumulativeCycles < target)
{
DebugContinueStepping();
}
ExecuteInDebugMode(msNextFrame);
break;
}
};

View file

@ -52,6 +52,9 @@ namespace sa2
void ProcessMouseButton(const SDL_MouseButtonEvent & button);
void ProcessMouseMotion(const SDL_MouseMotionEvent & motion);
void ExecuteInRunningMode(const size_t msNextFrame);
void ExecuteInDebugMode(const size_t msNextFrame);
std::shared_ptr<SDL_Window> myWindow;
bool myForceCapsLock;