Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified SIDFactoryII/drivers/sf2driver11_05.prg
Binary file not shown.
4 changes: 2 additions & 2 deletions SIDFactoryII/source/runtime/editor/driver/driver_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ namespace Editor
m_DriverCommon.m_TempoCounterAddress = inReader.ReadWord();
m_DriverCommon.m_TriggerSyncAddress = inReader.ReadWord();
m_DriverCommon.m_NoteEventTriggerSyncValue = inReader.ReadByte();
m_DriverCommon.m_ReservedByte = inReader.ReadByte();
m_DriverCommon.m_ReservedWord = inReader.ReadWord();
m_DriverCommon.m_UpdatesPerFrameAddress = inReader.ReadWord();
m_DriverCommon.m_MaxUpdatesPerFrame = inReader.ReadByte();
}


Expand Down
4 changes: 2 additions & 2 deletions SIDFactoryII/source/runtime/editor/driver/driver_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ namespace Editor
unsigned short m_TempoCounterAddress;
unsigned short m_TriggerSyncAddress;
unsigned char m_NoteEventTriggerSyncValue;
unsigned char m_ReservedByte;
unsigned short m_ReservedWord;
unsigned short m_UpdatesPerFrameAddress;
unsigned char m_MaxUpdatesPerFrame;
};


Expand Down
18 changes: 18 additions & 0 deletions SIDFactoryII/source/runtime/editor/screens/screen_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,24 @@ namespace Editor
if (m_EditState.IsFollowPlayMode() && m_PlaybackCurrentEventPos >= 0)
m_TracksComponent->SetEventPosition(m_PlaybackCurrentEventPos, true);
}

// Constantly refresh update per frame
unsigned char update_per_frame = [&]()
{
unsigned short updates_per_frame_vector = m_DriverInfo->GetDriverCommon().m_UpdatesPerFrameAddress;
if (updates_per_frame_vector != 0)
{
m_CPUMemory->Lock();
unsigned char value = m_CPUMemory->GetByte(updates_per_frame_vector) + 1;
m_CPUMemory->Unlock();

return value;
}

return (unsigned char)(0);
}();

m_ExecutionHandler->SetUpdatesPerFrame(update_per_frame < 1 ? 1 : update_per_frame);
}


Expand Down
35 changes: 28 additions & 7 deletions SIDFactoryII/source/runtime/emulation/cpuframecapture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,36 @@ namespace Emulation

void CPUFrameCapture::Capture(unsigned short inStartAddress, unsigned char inAccumulatorValue)
{
// Set program counter
m_CPU->SetPC(inStartAddress);
m_CPU->SetAccumulator(inAccumulatorValue);
Capture(inStartAddress, inAccumulatorValue, 1);
}

void CPUFrameCapture::Capture(unsigned short inStartAddress, unsigned char inAccumulatorValue, int inEventlySpreadRepetitions)
{
FOUNDATION_ASSERT(inEventlySpreadRepetitions > 0);

// Set the CPU to be not suspended
m_CPU->SetSuspended(false);
const int cyclesPerRepetition = m_uiMaxCycles / inEventlySpreadRepetitions;

// Execute instructions until suspending!
while (!m_CPU->IsSuspended() && static_cast<unsigned int>(m_CPU->CycleCounterGetCurrent()) < m_uiMaxCycles)
m_CPU->ExecuteInstruction();
for(int i=0; i< inEventlySpreadRepetitions; ++i)
{
// Set program counter
m_CPU->SetPC(inStartAddress);
m_CPU->SetAccumulator(inAccumulatorValue);

// Set the CPU to be not suspended
m_CPU->SetSuspended(false);

if(i > 0)
{
const int startCycle = cyclesPerRepetition * i;
FOUNDATION_ASSERT(m_CPU->CycleCounterGetCurrent() <= startCycle);

m_CPU->CycleCounterSetCurrent(startCycle);
}

while (!m_CPU->IsSuspended() && static_cast<unsigned int>(m_CPU->CycleCounterGetCurrent()) < m_uiMaxCycles)
m_CPU->ExecuteInstruction();
}

// Record the number of cycles spend on the executing code before the CPU was suspended!
m_uiCyclesSpend = static_cast<unsigned int>(m_CPU->CycleCounterGetCurrent());
Expand All @@ -48,6 +68,7 @@ namespace Emulation
m_ReachedMaxCycleCount = m_uiCyclesSpend >= m_uiMaxCycles;
}


void CPUFrameCapture::Write(unsigned short usAddress, unsigned char ucVal, int iCycle)
{
if (usAddress >= m_usCaptureRangeBegin && usAddress <= m_usCaptureRangeEnd)
Expand Down
1 change: 1 addition & 0 deletions SIDFactoryII/source/runtime/emulation/cpuframecapture.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace Emulation
~CPUFrameCapture();

void Capture(unsigned short inStartAddress, unsigned char inAccumulatorValue);
void Capture(unsigned short inStartAddress, unsigned char inAccumulatorValue, int inEventlySpreadRepetitions);

virtual void Write(unsigned short usAddress, unsigned char ucVal, int iCycle);

Expand Down
15 changes: 12 additions & 3 deletions SIDFactoryII/source/runtime/execution/executionhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ namespace Emulation
, m_SampleBufferReadCursor(0)
, m_SampleBufferWriteCursor(0)
, m_CPUFrameCounter(0)
, m_UpdatesPerFrame(1)
, m_UpdateEnabled(false)
, m_ErrorState(false)
{
Expand Down Expand Up @@ -316,6 +317,14 @@ namespace Emulation
Unlock();
}

void ExecutionHandler::SetUpdatesPerFrame(unsigned char inUpdatesPerFrame)
{
Lock();
m_UpdatesPerFrame = inUpdatesPerFrame;
Unlock();
}


void ExecutionHandler::StartWriteOutputToFile(const std::string& inFilename)
{
FOUNDATION_ASSERT(m_SIDProxy != nullptr);
Expand Down Expand Up @@ -429,7 +438,7 @@ namespace Emulation
break;
case ActionType::Update:
if (!m_ErrorState)
frameCapture.Capture(GetAddressFromActionType(action.m_ActionType), action.m_ActionArgument);
frameCapture.Capture(GetAddressFromActionType(action.m_ActionType), action.m_ActionArgument, static_cast<int>(m_UpdatesPerFrame));
default:
break;
}
Expand All @@ -447,7 +456,7 @@ namespace Emulation

if (!error)
{
frameCapture.Capture(GetAddressFromActionType(ActionType::Update), 0);
frameCapture.Capture(GetAddressFromActionType(ActionType::Update), 0, static_cast<int>(m_UpdatesPerFrame));
error = frameCapture.IsMaxCycleCountReached();

if (m_PostUpdateCallback)
Expand All @@ -462,7 +471,7 @@ namespace Emulation
if (m_CyclesPerFrame - frameCapture.GetCyclesSpend() < m_CyclesPerFrame >> 2)
break;

frameCapture.Capture(GetAddressFromActionType(ActionType::Update), 0);
frameCapture.Capture(GetAddressFromActionType(ActionType::Update), 0, static_cast<int>(m_UpdatesPerFrame));
if (m_PostUpdateCallback)
m_PostUpdateCallback(m_Memory);

Expand Down
2 changes: 2 additions & 0 deletions SIDFactoryII/source/runtime/execution/executionhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ namespace Emulation
void SetStopVector(unsigned short inVector);
void SetUpdateVector(unsigned short inVector);
void SetPostUpdateCallback(const std::function<void(CPUMemory*)>& inPostUpdateCallback);
void SetUpdatesPerFrame(unsigned char inUpdatesPerFrame);

// Cycles
unsigned int GetCPUCyclesSpendLastFrame() const { return m_CPUCyclesSpend; }
Expand Down Expand Up @@ -147,6 +148,7 @@ namespace Emulation
bool m_UpdateEnabled;
unsigned int m_FastForwardUpdateCount;
std::function<void(CPUMemory*)> m_PostUpdateCallback;
unsigned char m_UpdatesPerFrame;

// Driver vectors
unsigned short m_InitVector;
Expand Down