diff --git a/Core/BaseCartridge.cpp b/Core/BaseCartridge.cpp index c142121..ec30afb 100644 --- a/Core/BaseCartridge.cpp +++ b/Core/BaseCartridge.cpp @@ -188,6 +188,8 @@ void BaseCartridge::LoadRom() _coprocessorRamSize = 0x10000; } + LoadEmbeddedFirmware(); + _saveRamSize = _cartInfo.SramSize > 0 ? 1024 * (1 << _cartInfo.SramSize) : 0; _saveRam = new uint8_t[_saveRamSize]; _console->GetSettings()->InitializeRam(_saveRam, _saveRamSize); @@ -367,9 +369,26 @@ void BaseCartridge::RegisterHandlers(MemoryMappings &mm) } } +void BaseCartridge::LoadEmbeddedFirmware() +{ + //Attempt to detect/load the firmware from the end of the rom file, if it exists + if((_coprocessorType >= CoprocessorType::DSP1 && _coprocessorType <= CoprocessorType::DSP4) || (_coprocessorType >= CoprocessorType::ST010 && _coprocessorType <= CoprocessorType::ST011)) { + uint32_t firmwareSize = 0; + if((_prgRomSize & 0x7FFF) == 0x2000) { + firmwareSize = 0x2000; + } else if((_prgRomSize & 0xFFFF) == 0xD000) { + firmwareSize = 0xD000; + } + + _embeddedFirmware.resize(firmwareSize); + memcpy(_embeddedFirmware.data(), _prgRom + (_prgRomSize - firmwareSize), firmwareSize); + _prgRomSize -= firmwareSize; + } +} + void BaseCartridge::InitCoprocessor() { - _coprocessor.reset(NecDsp::InitCoprocessor(_coprocessorType, _console)); + _coprocessor.reset(NecDsp::InitCoprocessor(_coprocessorType, _console, _embeddedFirmware)); _necDsp = dynamic_cast(_coprocessor.get()); if(_coprocessorType == CoprocessorType::SA1) { diff --git a/Core/BaseCartridge.h b/Core/BaseCartridge.h index 0f8a046..9d69511 100644 --- a/Core/BaseCartridge.h +++ b/Core/BaseCartridge.h @@ -44,6 +44,7 @@ private: uint32_t _coprocessorRamSize = 0; shared_ptr _spcData; + vector _embeddedFirmware; void LoadBattery(); @@ -59,6 +60,7 @@ private: void LoadRom(); void LoadSpc(); void InitCoprocessor(); + void LoadEmbeddedFirmware(); string GetCartName(); string GetGameCode(); diff --git a/Core/FirmwareHelper.h b/Core/FirmwareHelper.h index 1047df6..22270ce 100644 --- a/Core/FirmwareHelper.h +++ b/Core/FirmwareHelper.h @@ -36,9 +36,13 @@ private: return false; } public: - static bool LoadDspFirmware(Console *console, CoprocessorType coprocessorType, string combinedFilename, string splitFilenameProgram, string splitFilenameData, vector &programRom, vector &dataRom, uint32_t programSize = 0x1800, uint32_t dataSize = 0x800) + static bool LoadDspFirmware(Console *console, CoprocessorType coprocessorType, string combinedFilename, string splitFilenameProgram, string splitFilenameData, vector &programRom, vector &dataRom, vector &embeddedFirware, uint32_t programSize = 0x1800, uint32_t dataSize = 0x800) { - if(AttemptLoadDspFirmware(combinedFilename, splitFilenameProgram, splitFilenameData, programRom, dataRom, programSize, dataSize)) { + if(embeddedFirware.size() == programSize + dataSize) { + programRom.insert(programRom.end(), embeddedFirware.begin(), embeddedFirware.begin() + programSize); + dataRom.insert(dataRom.end(), embeddedFirware.begin() + programSize, embeddedFirware.end()); + return true; + } else if(AttemptLoadDspFirmware(combinedFilename, splitFilenameProgram, splitFilenameData, programRom, dataRom, programSize, dataSize)) { return true; } diff --git a/Core/NecDsp.cpp b/Core/NecDsp.cpp index 2d80b34..5e39265 100644 --- a/Core/NecDsp.cpp +++ b/Core/NecDsp.cpp @@ -77,19 +77,19 @@ NecDsp::NecDsp(CoprocessorType type, Console* console, vector &programR } } -NecDsp* NecDsp::InitCoprocessor(CoprocessorType type, Console *console) +NecDsp* NecDsp::InitCoprocessor(CoprocessorType type, Console *console, vector &embeddedFirware) { bool firmwareLoaded = false; vector programRom; vector dataRom; switch(type) { - case CoprocessorType::DSP1: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "dsp1.rom", "dsp1.program.rom", "dsp1.data.rom", programRom, dataRom); break; - case CoprocessorType::DSP1B: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "dsp1b.rom", "dsp1b.program.rom", "dsp1b.data.rom", programRom, dataRom); break; - case CoprocessorType::DSP2: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "dsp2.rom", "dsp2.program.rom", "dsp2.data.rom", programRom, dataRom); break; - case CoprocessorType::DSP3: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "dsp3.rom", "dsp3.program.rom", "dsp3.data.rom", programRom, dataRom); break; - case CoprocessorType::DSP4: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "dsp4.rom", "dsp4.program.rom", "dsp4.data.rom", programRom, dataRom); break; - case CoprocessorType::ST010: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "st010.rom", "st010.program.rom", "st010.data.rom", programRom, dataRom, 0xC000, 0x1000); break; - case CoprocessorType::ST011: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "st011.rom", "st011.program.rom", "st011.data.rom", programRom, dataRom, 0xC000, 0x1000); break; + case CoprocessorType::DSP1: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "dsp1.rom", "dsp1.program.rom", "dsp1.data.rom", programRom, dataRom, embeddedFirware); break; + case CoprocessorType::DSP1B: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "dsp1b.rom", "dsp1b.program.rom", "dsp1b.data.rom", programRom, dataRom, embeddedFirware); break; + case CoprocessorType::DSP2: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "dsp2.rom", "dsp2.program.rom", "dsp2.data.rom", programRom, dataRom, embeddedFirware); break; + case CoprocessorType::DSP3: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "dsp3.rom", "dsp3.program.rom", "dsp3.data.rom", programRom, dataRom, embeddedFirware); break; + case CoprocessorType::DSP4: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "dsp4.rom", "dsp4.program.rom", "dsp4.data.rom", programRom, dataRom, embeddedFirware); break; + case CoprocessorType::ST010: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "st010.rom", "st010.program.rom", "st010.data.rom", programRom, dataRom, embeddedFirware, 0xC000, 0x1000); break; + case CoprocessorType::ST011: firmwareLoaded = FirmwareHelper::LoadDspFirmware(console, type, "st011.rom", "st011.program.rom", "st011.data.rom", programRom, dataRom, embeddedFirware, 0xC000, 0x1000); break; default: break; } diff --git a/Core/NecDsp.h b/Core/NecDsp.h index 1f36366..fdb0ec3 100644 --- a/Core/NecDsp.h +++ b/Core/NecDsp.h @@ -51,7 +51,7 @@ private: NecDsp(CoprocessorType type, Console* console, vector &programRom, vector &dataRom); public: - static NecDsp* InitCoprocessor(CoprocessorType type, Console* console); + static NecDsp* InitCoprocessor(CoprocessorType type, Console* console, vector &embeddedFirmware); void Reset() override; void Run();