commit aa062e07de6159fcbcffcc141a6c35967221afca
parent 62c887ef33ee4efb936a4c4b0eda8818b2011721
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Sun, 7 Jul 2024 19:23:14 +0200
rework DSP boot to no longer rely on the speed of a thread that feeds the HDI08 port, do it via callback now
Diffstat:
6 files changed, 68 insertions(+), 44 deletions(-)
diff --git a/source/virusLib/device.cpp b/source/virusLib/device.cpp
@@ -564,7 +564,7 @@ namespace virusLib
std::thread Device::bootDSP(DspSingle& _dsp, const ROMFile& _rom, const bool _createDebugger)
{
- auto res = _rom.bootDSP(_dsp.getDSP(), _dsp.getHDI08());
+ auto res = _rom.bootDSP(_dsp);
_dsp.startDSPThread(_createDebugger);
return res;
}
diff --git a/source/virusLib/dspSingle.cpp b/source/virusLib/dspSingle.cpp
@@ -130,4 +130,45 @@ namespace virusLib
while(!outs.empty())
outs.pop_front();
}
+
+ std::thread DspSingle::boot(const ROMFile::BootRom& _bootRom, const std::vector<dsp56k::TWord>& _commandStream)
+ {
+ // Copy BootROM to DSP memory
+ for (uint32_t i=0; i<_bootRom.data.size(); i++)
+ {
+ const auto p = _bootRom.offset + i;
+ getMemory().set(dsp56k::MemArea_P, p, _bootRom.data[i]);
+ getJIT().notifyProgramMemWrite(p);
+ }
+
+// dsp.memory().saveAssembly((m_file + "_BootROM.asm").c_str(), bootRom.offset, bootRom.size, false, false, &periph);
+
+ // Write command stream to HDI08 RX
+ m_commandStream = _commandStream;
+ m_commandStreamReadIndex = 0;
+
+ while(!getHDI08().dataRXFull() && m_commandStreamReadIndex < m_commandStream.size())
+ getHDI08().writeRX(&m_commandStream[m_commandStreamReadIndex++], 1);
+
+ getHDI08().setReadRxCallback([this]
+ {
+ if(m_commandStreamReadIndex >= m_commandStream.size())
+ {
+ getHDI08().setReadRxCallback(nullptr);
+ return;
+ }
+
+ getHDI08().writeRX(&m_commandStream[m_commandStreamReadIndex++], 1);
+ });
+
+ std::thread waitForCommandStreamWrite([this]()
+ {
+ while(m_commandStreamReadIndex < m_commandStream.size())
+ std::this_thread::yield();
+ });
+
+ // Initialize the DSP
+ getDSP().setPC(_bootRom.offset);
+ return waitForCommandStreamWrite;
+ }
}
diff --git a/source/virusLib/dspSingle.h b/source/virusLib/dspSingle.h
@@ -1,5 +1,7 @@
#pragma once
+#include "romfile.h"
+
#include "dsp56kEmu/dspthread.h"
#include "dsp56kEmu/memory.h"
#include "dsp56kEmu/peripherals.h"
@@ -39,6 +41,8 @@ namespace virusLib
void disableESSI1();
void drainESSI1();
+ std::thread boot(const ROMFile::BootRom& _bootRom, const std::vector<dsp56k::TWord>& _commandStream);
+
template<typename T> static void ensureSize(std::vector<T>& _buf, size_t _size)
{
if(_buf.size() >= _size)
@@ -72,5 +76,8 @@ namespace virusLib
dsp56k::Jit* m_jit = nullptr;
std::unique_ptr<dsp56k::DSPThread> m_dspThread;
+
+ std::vector<dsp56k::TWord> m_commandStream;
+ uint32_t m_commandStreamReadIndex = 0;
};
}
diff --git a/source/virusLib/romfile.cpp b/source/virusLib/romfile.cpp
@@ -14,8 +14,7 @@
#include <cstring> // memcpy
#include "demoplaybackTI.h"
-#include "dsp56kEmu/memory.h"
-#include "dsp56kEmu/threadtools.h"
+#include "dspSingle.h"
namespace virusLib
{
@@ -25,7 +24,7 @@ ROMFile::ROMFile(std::vector<uint8_t> _data, std::string _name, const DeviceMode
if(initialize())
return;
m_romFileData.clear();
- bootRom.size = 0;
+ m_bootRom.size = 0;
}
ROMFile ROMFile::invalid()
@@ -59,15 +58,15 @@ bool ROMFile::initialize()
if (chunks.empty())
return false;
- bootRom.size = chunks[0].items[0];
- bootRom.offset = chunks[0].items[1];
- bootRom.data = std::vector<uint32_t>(bootRom.size);
+ m_bootRom.size = chunks[0].items[0];
+ m_bootRom.offset = chunks[0].items[1];
+ m_bootRom.data = std::vector<uint32_t>(m_bootRom.size);
// The first chunk contains the bootrom
uint32_t i = 2;
- for (; i < bootRom.size + 2; i++)
+ for (; i < m_bootRom.size + 2; i++)
{
- bootRom.data[i-2] = chunks[0].items[i];
+ m_bootRom.data[i-2] = chunks[0].items[i];
}
// The rest of the chunks is made up of the command stream
@@ -78,8 +77,8 @@ bool ROMFile::initialize()
i = 0;
}
- printf("Program BootROM size = 0x%x\n", bootRom.size);
- printf("Program BootROM offset = 0x%x\n", bootRom.offset);
+ printf("Program BootROM size = 0x%x\n", m_bootRom.size);
+ printf("Program BootROM offset = 0x%x\n", m_bootRom.offset);
printf("Program CommandStream size = 0x%x\n", static_cast<uint32_t>(m_commandStream.size()));
#if VIRUS_SUPPORT_TI
@@ -127,7 +126,7 @@ bool ROMFile::initialize()
if(j == searchSize-1)
{
TPreset preset;
- memcpy(&preset[0], &fw.DSP[i - 4], std::size(preset));
+ memcpy(preset.data(), &fw.DSP[i - 4], std::size(preset));
// validate that we found the correct data by checking part volumes. It might just be a string somewhere in the data
for(size_t k=0; k<16; ++k)
@@ -137,7 +136,7 @@ bool ROMFile::initialize()
if(k == 15)
{
- for(size_t k=0; k<getPresetsPerBank(); ++k)
+ for(size_t p=0; p<getPresetsPerBank(); ++p)
m_multis.push_back(preset);
}
}
@@ -331,35 +330,9 @@ bool ROMFile::loadPresetFile(std::istream& _file, DeviceModel _model)
return true;
}
-std::thread ROMFile::bootDSP(dsp56k::DSP& dsp, dsp56k::HDI08& _hdi08) const
+std::thread ROMFile::bootDSP(DspSingle& _dsp) const
{
- // Load BootROM in DSP memory
- for (uint32_t i=0; i<bootRom.data.size(); i++)
- {
- const auto p = bootRom.offset + i;
- dsp.memory().set(dsp56k::MemArea_P, p, bootRom.data[i]);
- dsp.getJit().notifyProgramMemWrite(p);
- }
-
-// dsp.memory().saveAssembly((m_file + "_BootROM.asm").c_str(), bootRom.offset, bootRom.size, false, false, &periph);
-
- // Attach command stream
- size_t i=0;
- while(!_hdi08.dataRXFull() && i < m_commandStream.size())
- _hdi08.writeRX(&m_commandStream[i++], 1);
-
- std::thread feedCommandStream([&_hdi08, this, i]()
- {
- if(i >= m_commandStream.size())
- return;
-
- dsp56k::ThreadTools::setCurrentThreadPriority(dsp56k::ThreadPriority::Highest);
- _hdi08.writeRX(&m_commandStream[i], m_commandStream.size() - i);
- });
-
- // Initialize the DSP
- dsp.setPC(bootRom.offset);
- return feedCommandStream;
+ return _dsp.boot(m_bootRom, m_commandStream);
}
std::string ROMFile::getModelName() const
diff --git a/source/virusLib/romfile.h b/source/virusLib/romfile.h
@@ -18,6 +18,8 @@ namespace dsp56k
namespace virusLib
{
+class DspSingle;
+
class ROMFile
{
public:
@@ -50,9 +52,9 @@ public:
static std::string getMultiName(const TPreset& _preset);
static std::string getPresetName(const TPreset& _preset, uint32_t _first, uint32_t _last);
- std::thread bootDSP(dsp56k::DSP& dsp, dsp56k::HDI08& _hdi08) const;
+ std::thread bootDSP(DspSingle& _dsp) const;
- bool isValid() const { return bootRom.size > 0; }
+ bool isValid() const { return m_bootRom.size > 0; }
DeviceModel getModel() const { return m_model; }
@@ -124,7 +126,7 @@ private:
bool initialize();
- BootRom bootRom;
+ BootRom m_bootRom;
std::vector<uint32_t> m_commandStream;
DeviceModel m_model = DeviceModel::Invalid;
diff --git a/temp/cmake_win64/gearmulator.sln.DotSettings b/temp/cmake_win64/gearmulator.sln.DotSettings
@@ -23,6 +23,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Abbreviations/=SSH/@EntryIndexedValue">SSH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Abbreviations/=SSL/@EntryIndexedValue">SSL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Abbreviations/=TI/@EntryIndexedValue">TI</s:String>
+ <s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Abbreviations/=TX/@EntryIndexedValue">TX</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Abbreviations/=XY/@EntryIndexedValue">XY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Classes_0020and_0020structs/@EntryIndexedValue"><NamingElement Priority="1"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="__interface" /><type Name="class" /><type Name="struct" /></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020fields/@EntryIndexedValue"><NamingElement Priority="11"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="class field" /><type Name="struct field" /></Descriptor><Policy Inspect="True" Prefix="m_" Suffix="" Style="aaBb" /></NamingElement></s:String>