commit 69257e42ba951b33b7aaf836e3ce378e63e4b2e9
parent de35d682077fad28e41a3e5a33643f8695d5030d
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Tue, 6 Aug 2024 21:58:02 +0200
rework all/create rom loaders that verify that a found rom is for the correct synth
Diffstat:
20 files changed, 143 insertions(+), 30 deletions(-)
diff --git a/source/mqLib/CMakeLists.txt b/source/mqLib/CMakeLists.txt
@@ -24,6 +24,7 @@ set(SOURCES
lcd.cpp lcd.h
leds.cpp leds.h
rom.cpp rom.h
+ romloader.cpp romloader.h
microq.cpp microq.h
mqbuildconfig.h
mqdsp.cpp mqdsp.h
diff --git a/source/mqLib/microq.cpp b/source/mqLib/microq.cpp
@@ -7,6 +7,7 @@
#include "dsp56kEmu/threadtools.h"
#include "mqhardware.h"
+#include "romloader.h"
#include "mc68k/logging.h"
@@ -14,14 +15,11 @@ namespace mqLib
{
MicroQ::MicroQ(BootMode _bootMode/* = BootMode::Default*/)
{
- // create hardware, will use in-memory ROM if no ROM provided
-// auto romFile = synthLib::findROM(512 * 1024); // TODO: validate the found ROMs before use, check if it starts with "2.23". Otherwise, a Virus ROM might be found and booted
-// if(romFile.empty())
- const auto romFile = synthLib::findFile(".mid", 300 * 1024, 400 * 1024);
- if(romFile.empty())
+ const auto romFile = RomLoader::findROM();
+ if(!romFile.isValid())
throw synthLib::DeviceException(synthLib::DeviceError::FirmwareMissing, "Failed to find device operating system file mq_2_23.mid.");
- MCLOG("Boot using ROM " << romFile);
+ MCLOG("Boot using ROM " << romFile.getFilename());
m_hw.reset(new Hardware(romFile));
diff --git a/source/mqLib/mqhardware.cpp b/source/mqLib/mqhardware.cpp
@@ -7,9 +7,9 @@
namespace mqLib
{
- Hardware::Hardware(const std::string& _romFilename)
+ Hardware::Hardware(const ROM& _rom)
: wLib::Hardware(44100)
- , m_rom(_romFilename)
+ , m_rom(_rom)
, m_uc(m_rom)
#if MQ_VOICE_EXPANSION
, m_dsps{MqDsp(*this, m_uc.getHdi08A().getHdi08(), 0), MqDsp(*this, m_uc.getHdi08B().getHdi08(), 1) , MqDsp(*this, m_uc.getHdi08C().getHdi08(), 2)}
diff --git a/source/mqLib/mqhardware.h b/source/mqLib/mqhardware.h
@@ -21,7 +21,7 @@ namespace mqLib
static constexpr uint32_t g_dspCount = g_useVoiceExpansion ? 3 : 1;
public:
- explicit Hardware(const std::string& _romFilename);
+ explicit Hardware(const ROM& _rom);
~Hardware();
void process();
diff --git a/source/mqLib/rom.cpp b/source/mqLib/rom.cpp
@@ -2,4 +2,15 @@
namespace mqLib
{
+ ROM::ROM(const std::string& _filename) : wLib::ROM(_filename, g_romSize)
+ {
+ if(getSize() < 5)
+ return;
+
+ auto* d = reinterpret_cast<const char*>(getData());
+
+ // OS version is right at the start of the ROM, as zero-terminated ASCII
+ if(strstr(d, "2.23") != d)
+ clear();
+ }
}
diff --git a/source/mqLib/rom.h b/source/mqLib/rom.h
@@ -9,9 +9,8 @@ namespace mqLib
public:
static constexpr uint32_t g_romSize = 524288;
- explicit ROM(const std::string& _filename) : wLib::ROM(_filename, g_romSize)
- {
- }
+ ROM() = default;
+ explicit ROM(const std::string& _filename);
static constexpr uint32_t size() { return g_romSize; }
diff --git a/source/mqLib/romloader.cpp b/source/mqLib/romloader.cpp
@@ -0,0 +1,28 @@
+#include "romloader.h"
+
+#include "synthLib/os.h"
+
+namespace mqLib
+{
+ ROM RomLoader::findROM()
+ {
+ const auto midiFiles = findFiles(".mid", 300 * 1024, 400 * 1024);
+
+ for (const auto& midiFile : midiFiles)
+ {
+ ROM rom(midiFile);
+ if(rom.isValid())
+ return rom;
+ }
+
+ const auto binFiles = findFiles(".bin", 512 * 1024, 512 * 1024);
+
+ for (const auto& binFile : binFiles)
+ {
+ ROM rom(binFile);
+ if(rom.isValid())
+ return rom;
+ }
+ return {};
+ }
+}
diff --git a/source/mqLib/romloader.h b/source/mqLib/romloader.h
@@ -0,0 +1,12 @@
+#pragma once
+#include "rom.h"
+#include "synthLib/romLoader.h"
+
+namespace mqLib
+{
+ class RomLoader : synthLib::RomLoader
+ {
+ public:
+ static ROM findROM();
+ };
+}
diff --git a/source/nord/n2x/n2xLib/CMakeLists.txt b/source/nord/n2x/n2xLib/CMakeLists.txt
@@ -15,6 +15,7 @@ set(SOURCES
n2xmiditypes.h
n2xrom.cpp n2xrom.h
n2xromdata.cpp n2xromdata.h
+ n2xromloader.cpp n2xromloader.h
n2xstate.cpp n2xstate.h
n2xtypes.h
)
diff --git a/source/nord/n2x/n2xLib/n2xhardware.cpp b/source/nord/n2x/n2xLib/n2xhardware.cpp
@@ -1,5 +1,6 @@
#include "n2xhardware.h"
+#include "n2xromloader.h"
#include "dsp56kEmu/threadtools.h"
namespace n2x
@@ -11,7 +12,8 @@ namespace n2x
static_assert(g_syncHaltDspEsaiThreshold >= g_syncEsaiFrameRate * 2, "esai DSP halt threshold must be greater than two times the sync rate");
Hardware::Hardware()
- : m_uc(*this, m_rom)
+ : m_rom(RomLoader::findROM())
+ , m_uc(*this, m_rom)
, m_dspA(*this, m_uc.getHdi08A(), 0)
, m_dspB(*this, m_uc.getHdi08B(), 1)
, m_samplerateInv(1.0 / g_samplerate)
diff --git a/source/nord/n2x/n2xLib/n2xrom.cpp b/source/nord/n2x/n2xLib/n2xrom.cpp
@@ -8,10 +8,21 @@ namespace n2x
{
Rom::Rom() : RomData()
{
- constexpr uint8_t key[] = {'n', 'r', '2', 0, 'n', 'L', '2', 0};
+ if(!isValidRom(data()))
+ invalidate();
+ }
- const auto it = std::search(data().begin(), data().end(), std::begin(key), std::end(key));
- if(it == data().end())
+ Rom::Rom(const std::string& _filename) : RomData(_filename)
+ {
+ if(!isValidRom(data()))
invalidate();
}
+
+ bool Rom::isValidRom(std::array<unsigned char, 524288>& _data)
+ {
+ constexpr uint8_t key[] = {'n', 'r', '2', 0, 'n', 'L', '2', 0};
+
+ const auto it = std::search(_data.begin(), _data.end(), std::begin(key), std::end(key));
+ return it != _data.end();
+ }
}
diff --git a/source/nord/n2x/n2xLib/n2xrom.h b/source/nord/n2x/n2xLib/n2xrom.h
@@ -9,5 +9,8 @@ namespace n2x
{
public:
Rom();
+ Rom(const std::string& _filename);
+
+ static bool isValidRom(std::array<uint8_t, g_romSize>& _data);
};
}
diff --git a/source/nord/n2x/n2xLib/n2xromdata.cpp b/source/nord/n2x/n2xLib/n2xromdata.cpp
@@ -6,18 +6,21 @@
namespace n2x
{
- template <uint32_t Size> RomData<Size>::RomData()
+ template <uint32_t Size> RomData<Size>::RomData() : RomData(synthLib::findROM(MySize, MySize))
{
- const auto filename = synthLib::findROM(m_data.size(), m_data.size());
- if(filename.empty())
+ }
+
+ template <uint32_t Size> RomData<Size>::RomData(const std::string& _filename)
+ {
+ if(_filename.empty())
return;
std::vector<uint8_t> data;
- if(!synthLib::readFile(data, filename))
+ if(!synthLib::readFile(data, _filename))
return;
if(data.size() != m_data.size())
return;
std::copy(data.begin(), data.end(), m_data.begin());
- m_filename = filename;
+ m_filename = _filename;
}
template <uint32_t Size> void RomData<Size>::saveAs(const std::string& _filename)
diff --git a/source/nord/n2x/n2xLib/n2xromdata.h b/source/nord/n2x/n2xLib/n2xromdata.h
@@ -10,7 +10,9 @@ namespace n2x
class RomData
{
public:
+ static constexpr uint32_t MySize = Size;
RomData();
+ RomData(const std::string& _filename);
bool isValid() const { return !m_filename.empty(); }
const auto& data() const { return m_data; }
diff --git a/source/nord/n2x/n2xLib/n2xromloader.cpp b/source/nord/n2x/n2xLib/n2xromloader.cpp
@@ -0,0 +1,20 @@
+#include "n2xromloader.h"
+
+namespace n2x
+{
+ Rom RomLoader::findROM()
+ {
+ const auto files = findFiles(".bin", g_romSize, g_romSize);
+
+ if(files.empty())
+ return {};
+
+ for (const auto& file : files)
+ {
+ auto rom = Rom(file);
+ if(rom.isValid())
+ return rom;
+ }
+ return {};
+ }
+}
diff --git a/source/nord/n2x/n2xLib/n2xromloader.h b/source/nord/n2x/n2xLib/n2xromloader.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "n2xrom.h"
+
+#include "synthLib/romLoader.h"
+
+namespace n2x
+{
+ class RomLoader : synthLib::RomLoader
+ {
+ public:
+ static Rom findROM();
+ };
+}
diff --git a/source/nord/n2x/n2xTestConsole/n2xTestConsole.cpp b/source/nord/n2x/n2xTestConsole/n2xTestConsole.cpp
@@ -1,7 +1,6 @@
#include <iostream>
#include "n2xLib/n2xhardware.h"
-#include "n2xLib/n2xrom.h"
#include "synthLib/wavWriter.h"
@@ -14,17 +13,15 @@ namespace n2x
int main()
{
- const n2x::Rom rom;
+ std::unique_ptr<n2x::Hardware> hw;
+ hw.reset(new n2x::Hardware());
- if(!rom.isValid())
+ if(!hw->isValid())
{
std::cout << "Failed to load rom file\n";
return -1;
}
- std::unique_ptr<n2x::Hardware> hw;
- hw.reset(new n2x::Hardware());
-
hw->getDSPA().getDSPThread().setLogToStdout(true);
hw->getDSPB().getDSPThread().setLogToStdout(true);
diff --git a/source/virusLib/romloader.cpp b/source/virusLib/romloader.cpp
@@ -216,9 +216,11 @@ namespace virusLib
if(model == DeviceModel::Invalid)
{
- assert(false && "retry model detection for debugging purposes below");
+ // disable load if model is not detected, because we now have other synths that have roms of the same size
+// assert(false && "retry model detection for debugging purposes below");
detectModel(fd.data);
- model = _model; // Must be based on DSP 56362 or hell breaks loose
+ continue;
+// model = _model; // Must be based on DSP 56362 or hell breaks loose
}
}
diff --git a/source/wLib/wRom.cpp b/source/wLib/wRom.cpp
@@ -27,7 +27,10 @@ namespace wLib
m_buffer.resize(_expectedSize, 0xff);
}
- return m_buffer.size() == _expectedSize;
+ if(m_buffer.size() != _expectedSize)
+ return false;
+ m_filename = _filename;
+ return true;
}
bool ROM::loadFromMidi(std::vector<unsigned char>& _buffer, const std::string& _filename)
diff --git a/source/wLib/wRom.h b/source/wLib/wRom.h
@@ -9,6 +9,7 @@ namespace wLib
class ROM
{
public:
+ ROM() = default;
explicit ROM(const std::string& _filename, const uint32_t _expectedSize, std::vector<uint8_t> _data = {}) : m_buffer(std::move(_data))
{
if (m_buffer.size() != _expectedSize)
@@ -20,6 +21,10 @@ namespace wLib
bool isValid() const { return !m_buffer.empty(); }
virtual uint32_t getSize() const = 0;
+ void clear() { m_buffer.clear(); }
+
+ const auto& getFilename() const { return m_filename; }
+
static bool loadFromMidi(std::vector<uint8_t>& _buffer, const std::string& _filename);
static bool loadFromMidiData(std::vector<uint8_t>& _buffer, const std::vector<uint8_t>& _midiData);
static bool loadFromSysExFile(std::vector<uint8_t>& _buffer, const std::string& _filename);
@@ -29,5 +34,6 @@ namespace wLib
bool loadFromFile(const std::string& _filename, uint32_t _expectedSize);
std::vector<uint8_t> m_buffer;
+ std::string m_filename;
};
}