From 877374109b87a12a79285afa39f8fb113d5de49e Mon Sep 17 00:00:00 2001 From: rawpowerlaxity Date: Wed, 13 Dec 2023 22:48:51 +0100 Subject: [PATCH] [minor] Added utility function to inspect sid write order and calculate 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. --- .../runtime/editor/driver/driver_utils.cpp | 85 +++++++++++++++++++ .../runtime/editor/driver/driver_utils.h | 8 ++ .../runtime/editor/screens/screen_edit.cpp | 12 +-- .../source/runtime/emulation/cpumos6510.cpp | 6 ++ .../source/runtime/emulation/cpumos6510.h | 1 + 5 files changed, 107 insertions(+), 5 deletions(-) diff --git a/SIDFactoryII/source/runtime/editor/driver/driver_utils.cpp b/SIDFactoryII/source/runtime/editor/driver/driver_utils.cpp index 1d595dfd..44998894 100644 --- a/SIDFactoryII/source/runtime/editor/driver/driver_utils.cpp +++ b/SIDFactoryII/source/runtime/editor/driver/driver_utils.cpp @@ -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 +#include + namespace Editor { namespace DriverUtils @@ -338,6 +342,87 @@ namespace Editor { return GetEndOfMusicDataAddress(inDriverInfo, inMemoryReader); } + + + std::vector 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 result; + std::unordered_map 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(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(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) diff --git a/SIDFactoryII/source/runtime/editor/driver/driver_utils.h b/SIDFactoryII/source/runtime/editor/driver/driver_utils.h index a137ad07..6d5645e1 100644 --- a/SIDFactoryII/source/runtime/editor/driver/driver_utils.h +++ b/SIDFactoryII/source/runtime/editor/driver/driver_utils.h @@ -18,6 +18,12 @@ namespace Editor { class DataSourceTable; + struct SIDWriteInformation + { + unsigned char m_AddressLow; + unsigned char m_CycleOffset; + }; + namespace DriverUtils { std::shared_ptr CreateTableDataSource(const DriverInfo::TableDefinition& inTableDefinition, Emulation::CPUMemory* inCPUMemory); @@ -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 GetSIDWriteInformationFromDriver(Emulation::CPUMemory& inCPUMemory, const DriverInfo& inDriverInfo); + void InsertIRQ(const Editor::DriverInfo& inDriverInfo, Utility::C64FileWriter& inFileWriter); } } diff --git a/SIDFactoryII/source/runtime/editor/screens/screen_edit.cpp b/SIDFactoryII/source/runtime/editor/screens/screen_edit.cpp index 7d0c235e..19f4f79c 100644 --- a/SIDFactoryII/source/runtime/editor/screens/screen_edit.cpp +++ b/SIDFactoryII/source/runtime/editor/screens/screen_edit.cpp @@ -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" @@ -60,6 +55,7 @@ #include #include "foundation/base/assert.h" #include "runtime/editor/components/component_pulse_filter_visualizer.h" +#include "utils/logging.h" #include @@ -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(m_Viewport, &*m_ComponentsManager, m_CPUMemory, m_MainTextField->GetDimensions(), m_DriverInfo); diff --git a/SIDFactoryII/source/runtime/emulation/cpumos6510.cpp b/SIDFactoryII/source/runtime/emulation/cpumos6510.cpp index 7f717850..65291b67 100644 --- a/SIDFactoryII/source/runtime/emulation/cpumos6510.cpp +++ b/SIDFactoryII/source/runtime/emulation/cpumos6510.cpp @@ -383,6 +383,12 @@ namespace Emulation } + const unsigned char CPUmos6510::GetOpcodeCycles(const unsigned char inOpcode) + { + return ms_aInstructions[inOpcode].m_ucBaseCycles; + } + + //------------------------------------------------------------------------------------------------------------------------------ //--------------------------------------------------------------------------- diff --git a/SIDFactoryII/source/runtime/emulation/cpumos6510.h b/SIDFactoryII/source/runtime/emulation/cpumos6510.h index 5ea80fa1..92a847bf 100644 --- a/SIDFactoryII/source/runtime/emulation/cpumos6510.h +++ b/SIDFactoryII/source/runtime/emulation/cpumos6510.h @@ -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