commit 899cc9836ac454e7409f06dcccb8d4afad3a8441
parent 985e8061d7fd80fb547d95e9d73bfcf7ecba1685
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Tue, 23 Apr 2024 19:39:14 +0200
add model detection, also fixes VB OS 5.4 no longer working
Diffstat:
4 files changed, 64 insertions(+), 12 deletions(-)
diff --git a/source/virusLib/romfile.cpp b/source/virusLib/romfile.cpp
@@ -53,7 +53,7 @@ bool ROMFile::initialize()
dsp.reset(new imemstream(fw.DSP));
}
#endif
- const auto chunks = readChunks(*dsp, m_model);
+ const auto chunks = readChunks(*dsp);
if (chunks.empty())
return false;
@@ -185,7 +185,7 @@ uint32_t ROMFile::getRomBankCount(const DeviceModel _model)
}
}
-std::vector<ROMFile::Chunk> ROMFile::readChunks(std::istream& _file, const DeviceModel _wantedTIModel)
+std::vector<ROMFile::Chunk> ROMFile::readChunks(std::istream& _file) const
{
_file.seekg(0, std::ios_base::end);
const auto fileSize = _file.tellg();
@@ -195,14 +195,14 @@ std::vector<ROMFile::Chunk> ROMFile::readChunks(std::istream& _file, const Devic
if(fileSize == getRomSizeModelD())
{
- m_model = _wantedTIModel;
+ assert(isTIFamily());
offset = 0x70000;
lastChunkId = 14;
}
else if (fileSize == getRomSizeModelABC() || fileSize == getRomSizeModelABC()/2) // the latter is a ROM without presets
{
// ABC
- m_model = DeviceModel::C;
+ assert(isABCFamily(m_model));
offset = 0x18000;
lastChunkId = 4;
}
@@ -227,11 +227,8 @@ std::vector<ROMFile::Chunk> ROMFile::readChunks(std::istream& _file, const Devic
_file.read(reinterpret_cast<char*>(&chunk.size1), 1);
_file.read(reinterpret_cast<char*>(&chunk.size2), 1);
- if(i == 0 && chunk.chunk_id == 3 && lastChunkId == 4) // Virus A has one chunk less
- {
- m_model = DeviceModel::A;
+ if(i == 0 && chunk.chunk_id == 3 && lastChunkId == 4) // Virus A and old Virus B OSs have one chunk less
lastChunkId = 3;
- }
if(chunk.chunk_id != lastChunkId - i)
return {};
diff --git a/source/virusLib/romfile.h b/source/virusLib/romfile.h
@@ -118,7 +118,7 @@ public:
const auto& getHash() const { return m_romDataHash; }
private:
- std::vector<Chunk> readChunks(std::istream& _file, DeviceModel _wantedTIModel);
+ std::vector<Chunk> readChunks(std::istream& _file) const;
bool loadPresetFiles();
bool loadPresetFile(std::istream& _file, DeviceModel _model);
diff --git a/source/virusLib/romloader.cpp b/source/virusLib/romloader.cpp
@@ -1,5 +1,7 @@
#include "romloader.h"
+#include <algorithm>
+
#include "midiFileToRomData.h"
#include "../synthLib/os.h"
@@ -144,6 +146,48 @@ namespace virusLib
return data;
}
+ DeviceModel ROMLoader::detectModel(const std::vector<uint8_t>& _data)
+ {
+ // examples
+ // A: (C)ACCESS [08-20-2001-16:58:54][v280g]
+ // B: (C)ACCESS [12-23-2003-14:43:27][VB_490T]
+ // C: (C)ACCESS [11-10-2003-12:15:42][vc_650b]
+
+ const std::string key = "(C)ACCESS [";
+ const auto result = std::search(_data.begin(), _data.end(), std::begin(key), std::end(key));
+ if(result == _data.end())
+ return DeviceModel::Invalid;
+
+ const auto bracketOpen = std::find(result+static_cast<int32_t>(key.size())+1, _data.end(), '[');
+ if(bracketOpen == _data.end())
+ return DeviceModel::Invalid;
+
+ const auto bracketClose = std::find(bracketOpen+1, _data.end(), ']');
+ if(bracketClose == _data.end())
+ return DeviceModel::Invalid;
+
+ const auto versionString = synthLib::lowercase(std::string(bracketOpen+1, bracketClose-1));
+
+ const auto test = [&versionString](const char* _key)
+ {
+ return versionString.find(_key) == 0;
+ };
+
+ if(test("vb") || test("vcl") || test("vrt"))
+ return DeviceModel::B;
+
+ if(test("vc") || test("vr_6"))
+ return DeviceModel::C;
+
+ if(test("vr"))
+ return DeviceModel::B;
+
+ if(test("v2"))
+ return DeviceModel::A;
+
+ return DeviceModel::Invalid;
+ }
+
std::vector<ROMFile> ROMLoader::initializeRoms(const std::vector<std::string>& _files, const DeviceModel _model)
{
if(_files.empty())
@@ -180,10 +224,19 @@ namespace virusLib
if(fd.type == MidiPresets)
continue;
+ auto model = detectModel(fd.data);
+
+ if(model == DeviceModel::Invalid)
+ {
+ assert(false && "retry model detection for debugging purposes below");
+ detectModel(fd.data);
+ model = _model; // Must be based on DSP 56362 or hell breaks loose
+ }
+
if(fd.type == BinaryRom)
{
// load as-is
- auto& rom = roms.emplace_back(fd.data, fd.filename, _model);
+ auto& rom = roms.emplace_back(fd.data, fd.filename, model);
if(!rom.isValid())
roms.pop_back();
}
@@ -193,7 +246,7 @@ namespace virusLib
if(presets.empty())
{
// none available, use without presets
- auto& rom = roms.emplace_back(fd.data, fd.filename, _model);
+ auto& rom = roms.emplace_back(fd.data, fd.filename, model);
if(!rom.isValid())
roms.pop_back();
}
@@ -204,7 +257,7 @@ namespace virusLib
auto data = fd.data;
data.insert(data.end(), p.data.begin(), p.data.end());
- auto& rom = roms.emplace_back(data, fd.filename, _model);
+ auto& rom = roms.emplace_back(data, fd.filename, model);
if(!rom.isValid())
roms.pop_back();
else if(presets.size() > 1)
diff --git a/source/virusLib/romloader.h b/source/virusLib/romloader.h
@@ -36,6 +36,8 @@ namespace virusLib
static FileData loadFile(const std::string& _name);
+ static DeviceModel detectModel(const std::vector<uint8_t>& _data);
+
static std::vector<ROMFile> initializeRoms(const std::vector<std::string>& _files, DeviceModel _model);
};
}