gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit 54e51e3de09608e2dc6b962c7a3822321f49e1f2
parent 79ee95b0336070c0e2c97b72a8827d91bcff9555
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Tue, 23 Jul 2024 00:04:18 +0200

support writing data to both DSPs at once

Diffstat:
Msource/nord/n2x/n2xLib/CMakeLists.txt | 1+
Asource/nord/n2x/n2xLib/n2xhdi08.cpp | 5+++++
Asource/nord/n2x/n2xLib/n2xhdi08.h | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msource/nord/n2x/n2xLib/n2xmc.cpp | 25++++++++++++++++++++-----
Msource/nord/n2x/n2xLib/n2xmc.h | 7+++----
Msource/nord/n2x/n2xLib/n2xtypes.h | 1+
6 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/source/nord/n2x/n2xLib/CMakeLists.txt b/source/nord/n2x/n2xLib/CMakeLists.txt @@ -10,6 +10,7 @@ set(SOURCES n2xdsp.cpp n2xdsp.h n2xfrontpanel.cpp n2xfrontpanel.h n2xhardware.cpp n2xhardware.h + n2xhdi08.cpp n2xhdi08.h n2xi2cflash.cpp n2xi2cflash.h n2xkeyboard.cpp n2xkeyboard.h n2xmc.cpp n2xmc.h diff --git a/source/nord/n2x/n2xLib/n2xhdi08.cpp b/source/nord/n2x/n2xLib/n2xhdi08.cpp @@ -0,0 +1,5 @@ +#include "n2xhdi08.h" + +namespace n2x +{ +} diff --git a/source/nord/n2x/n2xLib/n2xhdi08.h b/source/nord/n2x/n2xLib/n2xhdi08.h @@ -0,0 +1,66 @@ +#pragma once + +#include <cassert> + +#include "n2xtypes.h" + +#include "mc68k/hdi08periph.h" + +namespace n2x +{ + using Hdi08DspA = mc68k::Hdi08Periph<g_dspAAddress>; + using Hdi08DspB = mc68k::Hdi08Periph<g_dspBAddress>; + + class Hdi08DspBoth : public mc68k::PeripheralBase<g_dspBothAddress, g_dspAAddress - g_dspBothAddress> + { + public: + static constexpr uint32_t OffsetA = g_dspAAddress - base(); + static constexpr uint32_t OffsetB = g_dspBAddress - base(); + + Hdi08DspBoth(Hdi08DspA& _a, Hdi08DspB& _b) : m_a(_a), m_b(_b) + { + } + + void write8(const mc68k::PeriphAddress _addr, const uint8_t _val) override + { + m_a.write8(offA(_addr), _val); + m_b.write8(offB(_addr), _val); + } + + void write16(const mc68k::PeriphAddress _addr, const uint16_t _val) override + { + m_a.write16(offA(_addr), _val); + m_b.write16(offB(_addr), _val); + } + + uint8_t read8(const mc68k::PeriphAddress _addr) override + { + assert(false && "not readable"); + return m_a.read8(_addr); + } + + uint16_t read16(const mc68k::PeriphAddress _addr) override + { + assert(false && "not readable"); + return m_a.read16(_addr); + } + + static mc68k::PeriphAddress offA(const mc68k::PeriphAddress _addr) + { + return off<OffsetA>(_addr); + } + + static mc68k::PeriphAddress offB(const mc68k::PeriphAddress _addr) + { + return off<OffsetB>(_addr); + } + + template<uint32_t Off> static mc68k::PeriphAddress off(mc68k::PeriphAddress _addr) + { + return static_cast<mc68k::PeriphAddress>(static_cast<uint32_t>(_addr) + Off); + } + private: + Hdi08DspA& m_a; + Hdi08DspB& m_b; + }; +} diff --git a/source/nord/n2x/n2xLib/n2xmc.cpp b/source/nord/n2x/n2xLib/n2xmc.cpp @@ -20,7 +20,7 @@ namespace n2x static constexpr uint32_t g_maskResetDSP = 1 << g_bitResetDSP; static constexpr uint32_t g_maskResetDAC = 1 << g_bitResetDAC; - Microcontroller::Microcontroller(const Rom& _rom) : m_midi(getQSM()) + Microcontroller::Microcontroller(const Rom& _rom) : m_hdi08(m_hdi08A, m_hdi08B), m_midi(getQSM()) { if(!_rom.isValid()) return; @@ -132,6 +132,7 @@ namespace n2x const auto pa = static_cast<mc68k::PeriphAddress>(_addr); + assert(!m_hdi08.isInRange(pa)); assert(!m_hdi08A.isInRange(pa)); assert(!m_hdi08B.isInRange(pa)); assert(!m_panel.isInRange(pa)); @@ -156,8 +157,9 @@ namespace n2x const auto pa = static_cast<mc68k::PeriphAddress>(_addr); - if(m_hdi08A.isInRange(pa)) return m_hdi08A.read16(pa); - if(m_hdi08B.isInRange(pa)) return m_hdi08B.read16(pa); + if(m_hdi08A.isInRange(pa)) return m_hdi08A.read16(pa); + if(m_hdi08B.isInRange(pa)) return m_hdi08B.read16(pa); + if(m_hdi08.isInRange(pa)) return m_hdi08.read16(pa); if(m_panel.cs4().isInRange(pa)) { @@ -198,8 +200,9 @@ namespace n2x const auto pa = static_cast<mc68k::PeriphAddress>(_addr); - if(m_hdi08A.isInRange(pa)) return m_hdi08A.read8(pa); - if(m_hdi08B.isInRange(pa)) return m_hdi08B.read8(pa); + if(m_hdi08A.isInRange(pa)) return m_hdi08A.read8(pa); + if(m_hdi08B.isInRange(pa)) return m_hdi08B.read8(pa); + if(m_hdi08.isInRange(pa)) return m_hdi08.read8(pa); if(m_panel.cs4().isInRange(pa)) { @@ -251,6 +254,12 @@ namespace n2x return; } + if(m_hdi08.isInRange(pa)) + { + m_hdi08.write16(pa, _val); + return; + } + if(m_panel.cs4().isInRange(pa)) { // LOG("Write Frontpanel CS4 " << HEX(_addr) << "=" << HEXN(_val, 4)); @@ -296,6 +305,12 @@ namespace n2x return; } + if(m_hdi08.isInRange(pa)) + { + m_hdi08.write8(pa, _val); + return; + } + if(m_panel.cs4().isInRange(pa)) { LOG("Write Frontpanel CS4 " << HEX(_addr) << "=" << HEXN(_val, 2)); diff --git a/source/nord/n2x/n2xLib/n2xmc.h b/source/nord/n2x/n2xLib/n2xmc.h @@ -1,10 +1,10 @@ #pragma once #include "n2xfrontpanel.h" +#include "n2xhdi08.h" #include "n2xi2cflash.h" #include "n2xtypes.h" #include "mc68k/hdi08.h" -#include "mc68k/hdi08periph.h" #include "mc68k/mc68k.h" #include "wLib/wMidi.h" @@ -12,9 +12,6 @@ namespace n2x { class Rom; - using Hdi08DspA = mc68k::Hdi08Periph<g_dspAAddress>; - using Hdi08DspB = mc68k::Hdi08Periph<g_dspBAddress>; - class Microcontroller : public mc68k::Mc68k { public: @@ -43,6 +40,8 @@ namespace n2x Hdi08DspA m_hdi08A; Hdi08DspB m_hdi08B; + Hdi08DspBoth m_hdi08; + FrontPanel m_panel; uint32_t m_prevPC; diff --git a/source/nord/n2x/n2xLib/n2xtypes.h b/source/nord/n2x/n2xLib/n2xtypes.h @@ -28,6 +28,7 @@ namespace n2x static constexpr uint32_t g_romAddress = 0; static constexpr uint32_t g_ramAddress = 0x100000; + static constexpr uint32_t g_dspBothAddress = 0x200000; static constexpr uint32_t g_dspAAddress = 0x200008; static constexpr uint32_t g_dspBAddress = 0x200010;