Skip to content

Commit

Permalink
[minor] Added utility function to inspect sid write order and calcula…
Browse files Browse the repository at this point in the history
…te the cycle offset from the first write. The address range the inspection is done for is 0xd400 to and including 0xd406. The same write order can be assumed for the two other channels. Writes to 0xd415 to 0xd418 does not require any ordering or timing to function adequately.
  • Loading branch information
RawPowerLaxity committed Dec 13, 2023
1 parent ea15195 commit 8773741
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 5 deletions.
85 changes: 85 additions & 0 deletions SIDFactoryII/source/runtime/editor/driver/driver_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
#include "runtime/editor/auxilarydata/auxilary_data_songs.h"
#include "runtime/emulation/cpumemory.h"
#include "runtime/emulation/imemoryrandomreadaccess.h"
#include "runtime/emulation/cpumos6510.h"
#include "utils/c64file.h"
#include "foundation/base/assert.h"

#include <algorithm>
#include <unordered_map>

namespace Editor
{
namespace DriverUtils
Expand Down Expand Up @@ -338,6 +342,87 @@ namespace Editor
{
return GetEndOfMusicDataAddress(inDriverInfo, inMemoryReader);
}


std::vector<SIDWriteInformation> GetSIDWriteInformationFromDriver(Emulation::CPUMemory& inCPUMemory, const DriverInfo& inDriverInfo)
{
auto is_accessing_memory_address_with_offset = [](Emulation::CPUmos6510::AddressingMode inAddressingMode)
{
switch (inAddressingMode)
{
case Emulation::CPUmos6510::am_ABX:
case Emulation::CPUmos6510::am_ABY:
return true;
default:
break;
}

return false;
};

std::vector<SIDWriteInformation> result;
std::unordered_map<unsigned char, SIDWriteInformation> sid_write_information;

const int top_address = inDriverInfo.GetDescriptor().m_DriverCodeTop;
const int bottom_address = top_address + inDriverInfo.GetDescriptor().m_DriverCodeSize;

int address = top_address;

bool first_write_found = false;
unsigned char cycle_count = 0;

inCPUMemory.Lock();

while (address < bottom_address)
{
const unsigned char opcode = inCPUMemory[address];
const unsigned char opcode_size = Emulation::CPUmos6510::GetOpcodeByteSize(opcode);
const unsigned char opcode_cycles = Emulation::CPUmos6510::GetOpcodeCycles(opcode);

const Emulation::CPUmos6510::AddressingMode opcode_addressing_mode = Emulation::CPUmos6510::GetOpcodeAddressingMode(opcode);

if (is_accessing_memory_address_with_offset(opcode_addressing_mode))
{
FOUNDATION_ASSERT(opcode_size == 3);
;
const unsigned short accessing_address = inCPUMemory.GetWord(address + 1);
if (accessing_address >= 0xd400 && accessing_address <= 0xd406)
{
first_write_found = true;

unsigned char sid_register = static_cast<unsigned char>(accessing_address & 0xff);

auto it = sid_write_information.find(sid_register);
if(it != sid_write_information.end())
it->second.m_CycleOffset = cycle_count;
else
sid_write_information[sid_register] = { sid_register, cycle_count };
}
}

address += static_cast<unsigned short>(opcode_size);

if(first_write_found)
cycle_count += opcode_cycles;
}

inCPUMemory.Unlock();

// Push the collected information into the result vector
for(const auto it : sid_write_information)
result.push_back(it.second);

// Sort writes in cycle order
std::sort(result.begin(), result.end(), [](const auto& inA, const auto& inB) { return inA.m_CycleOffset < inB.m_CycleOffset; });

// Adjust cycle offset to start from the the lowest (and first) entry in the list
const unsigned char first_cycle = result.begin()->m_CycleOffset;
for (auto& it : result)
it.m_CycleOffset -= first_cycle;

// Return the result
return result;
}


void InsertIRQ(const Editor::DriverInfo& inDriverInfo, Utility::C64FileWriter& inFileWriter)
Expand Down
8 changes: 8 additions & 0 deletions SIDFactoryII/source/runtime/editor/driver/driver_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ namespace Editor
{
class DataSourceTable;

struct SIDWriteInformation
{
unsigned char m_AddressLow;
unsigned char m_CycleOffset;
};

namespace DriverUtils
{
std::shared_ptr<DataSourceTable> CreateTableDataSource(const DriverInfo::TableDefinition& inTableDefinition, Emulation::CPUMemory* inCPUMemory);
Expand All @@ -33,6 +39,8 @@ namespace Editor
unsigned short GetEndOfMusicDataAddress(const Editor::DriverInfo& inDriverInfo, const Emulation::IMemoryRandomReadAccess& inMemoryReader);
unsigned short GetEndOfFileAddress(const Editor::DriverInfo& inDriverInfo, const Emulation::IMemoryRandomReadAccess& inMemoryReader);

std::vector<SIDWriteInformation> GetSIDWriteInformationFromDriver(Emulation::CPUMemory& inCPUMemory, const DriverInfo& inDriverInfo);

void InsertIRQ(const Editor::DriverInfo& inDriverInfo, Utility::C64FileWriter& inFileWriter);
}
}
12 changes: 7 additions & 5 deletions SIDFactoryII/source/runtime/editor/screens/screen_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,14 @@
#include "runtime/editor/components/component_orderlistoverview.h"
#include "runtime/editor/components/component_string_list_selector.h"
#include "runtime/editor/datasources/datasource_track_components.h"
#include "runtime/editor/datasources/datasource_table_column_major.h"
#include "runtime/editor/datasources/datasource_table_row_major.h"
#include "runtime/editor/datasources/datasource_play_markers.h"
#include "runtime/editor/datasources/datasource_flightrecorder.h"
#include "runtime/editor/datasources/datasource_sequence.h"
#include "runtime/editor/datasources/datasource_table_text.h"
#include "runtime/editor/visualizer_components/vizualizer_component_emulation_state.h"
#include "runtime/editor/debug/debug_views.h"
#include "runtime/editor/dialog/dialog_utilities.h"
#include "runtime/editor/dialog/dialog_songs.h"
#include "runtime/editor/dialog/dialog_message.h"
#include "runtime/editor/dialog/dialog_message_yesno.h"
#include "runtime/editor/dialog/dialog_hex_value_input.h"
#include "runtime/editor/dialog/dialog_optimize.h"
#include "runtime/editor/dialog/dialog_packing_options.h"
#include "runtime/editor/dialog/dialog_text_input.h"
Expand All @@ -60,6 +55,7 @@
#include <cctype>
#include "foundation/base/assert.h"
#include "runtime/editor/components/component_pulse_filter_visualizer.h"
#include "utils/logging.h"

#include <algorithm>

Expand Down Expand Up @@ -182,6 +178,12 @@ namespace Editor

m_ExecutionHandler->Unlock();

// Get the write order and cycle timing from the driver
const auto SIDWriteInfoList = DriverUtils::GetSIDWriteInformationFromDriver(*m_CPUMemory, *m_DriverInfo);

for(const auto& SIDWriteInfo : SIDWriteInfoList)
Utility::Logging::instance().Info("Write to address $d4%02x at cycle offset: %02x", SIDWriteInfo.m_AddressLow, SIDWriteInfo.m_CycleOffset);

// Create debug views
m_DebugViews = std::make_unique<DebugViews>(m_Viewport, &*m_ComponentsManager, m_CPUMemory, m_MainTextField->GetDimensions(), m_DriverInfo);

Expand Down
6 changes: 6 additions & 0 deletions SIDFactoryII/source/runtime/emulation/cpumos6510.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,12 @@ namespace Emulation
}


const unsigned char CPUmos6510::GetOpcodeCycles(const unsigned char inOpcode)
{
return ms_aInstructions[inOpcode].m_ucBaseCycles;
}


//------------------------------------------------------------------------------------------------------------------------------

//---------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions SIDFactoryII/source/runtime/emulation/cpumos6510.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ namespace Emulation
// Opcode
static const unsigned char GetOpcodeByteSize(const unsigned char inOpcode);
static const AddressingMode GetOpcodeAddressingMode(const unsigned char inOpcode);
static const unsigned char GetOpcodeCycles(const unsigned char inOpcode);

private:
// CPU State
Expand Down

0 comments on commit 8773741

Please sign in to comment.