diff --git a/CMakeLists.txt b/CMakeLists.txt index bf8236d..885cc7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,8 +37,8 @@ add_executable(unit_tests sources/Memory/MemoryShadow.hpp sources/Memory/IRectangleMemory.cpp sources/Memory/IRectangleMemory.hpp - sources/DSP/DSP.cpp - sources/DSP/DSP.hpp + sources/APU/DSP/DSP.cpp + sources/APU/DSP/DSP.hpp ) # include criterion & coverage @@ -73,8 +73,8 @@ add_executable(ComSquare sources/Memory/MemoryShadow.hpp sources/Memory/IRectangleMemory.cpp sources/Memory/IRectangleMemory.hpp - sources/DSP/DSP.cpp - sources/DSP/DSP.hpp + sources/APU/DSP/DSP.cpp + sources/APU/DSP/DSP.hpp sources/Renderer/IRenderer.hpp sources/Renderer/SFRenderer.hpp sources/Renderer/SFRenderer.cpp diff --git a/sources/APU/APU.hpp b/sources/APU/APU.hpp index e6a6fda..6c67a8f 100644 --- a/sources/APU/APU.hpp +++ b/sources/APU/APU.hpp @@ -6,7 +6,7 @@ #define COMSQUARE_APU_HPP #include -#include "../DSP/DSP.hpp" +#include "DSP/DSP.hpp" #include "../Memory/IMemory.hpp" namespace ComSquare::APU diff --git a/sources/APU/DSP/DSP.cpp b/sources/APU/DSP/DSP.cpp new file mode 100644 index 0000000..7775b40 --- /dev/null +++ b/sources/APU/DSP/DSP.cpp @@ -0,0 +1,584 @@ +// +// Created by Melefo on 28/01/2020. +// + +#include "DSP.hpp" +#include "../../Exceptions/InvalidAddress.hpp" + +namespace ComSquare::APU::DSP +{ + DSP::DSP() + { } + + uint8_t DSP::read(uint24_t addr) + { + switch (addr) { + case 0x00: + return this->_channels[0].volL; + case 0x10: + return this->_channels[1].volL; + case 0x20: + return this->_channels[2].volL; + case 0x30: + return this->_channels[3].volL; + case 0x40: + return this->_channels[4].volL; + case 0x50: + return this->_channels[5].volL; + case 0x60: + return this->_channels[6].volL; + case 0x70: + return this->_channels[7].volL; + case 0x01: + return this->_channels[0].volR; + case 0x11: + return this->_channels[1].volR; + case 0x21: + return this->_channels[2].volR; + case 0x31: + return this->_channels[3].volR; + case 0x41: + return this->_channels[4].volR; + case 0x51: + return this->_channels[5].volR; + case 0x61: + return this->_channels[6].volR; + case 0x71: + return this->_channels[7].volR; + case 0x02: + return this->_channels[0].pitchL; + case 0x12: + return this->_channels[1].pitchL; + case 0x22: + return this->_channels[2].pitchL; + case 0x32: + return this->_channels[3].pitchL; + case 0x42: + return this->_channels[4].pitchL; + case 0x52: + return this->_channels[5].pitchL; + case 0x62: + return this->_channels[6].pitchL; + case 0x72: + return this->_channels[7].pitchL; + case 0x03: + return this->_channels[0].pitchH; + case 0x13: + return this->_channels[1].pitchH; + case 0x23: + return this->_channels[2].pitchH; + case 0x33: + return this->_channels[3].pitchH; + case 0x43: + return this->_channels[4].pitchH; + case 0x53: + return this->_channels[5].pitchH; + case 0x63: + return this->_channels[6].pitchH; + case 0x73: + return this->_channels[7].pitchH; + case 0x04: + return this->_channels[0].srcn; + case 0x14: + return this->_channels[1].srcn; + case 0x24: + return this->_channels[2].srcn; + case 0x34: + return this->_channels[3].srcn; + case 0x44: + return this->_channels[4].srcn; + case 0x54: + return this->_channels[5].srcn; + case 0x64: + return this->_channels[6].srcn; + case 0x74: + return this->_channels[7].srcn; + case 0x05: + return this->_channels[0].adsr1; + case 0x15: + return this->_channels[1].adsr1; + case 0x25: + return this->_channels[2].adsr1; + case 0x35: + return this->_channels[3].adsr1; + case 0x45: + return this->_channels[4].adsr1; + case 0x55: + return this->_channels[5].adsr1; + case 0x65: + return this->_channels[6].adsr1; + case 0x75: + return this->_channels[7].adsr1; + case 0x06: + return this->_channels[0].adsr2; + case 0x16: + return this->_channels[1].adsr2; + case 0x26: + return this->_channels[2].adsr2; + case 0x36: + return this->_channels[3].adsr2; + case 0x46: + return this->_channels[4].adsr2; + case 0x56: + return this->_channels[5].adsr2; + case 0x66: + return this->_channels[6].adsr2; + case 0x76: + return this->_channels[7].adsr2; + case 0x07: + return this->_channels[0].gain; + case 0x17: + return this->_channels[1].gain; + case 0x27: + return this->_channels[2].gain; + case 0x37: + return this->_channels[3].gain; + case 0x47: + return this->_channels[4].gain; + case 0x57: + return this->_channels[5].gain; + case 0x67: + return this->_channels[6].gain; + case 0x77: + return this->_channels[7].gain; + case 0x08: + return this->_channels[0].envx; + case 0x18: + return this->_channels[1].envx; + case 0x28: + return this->_channels[2].envx; + case 0x38: + return this->_channels[3].envx; + case 0x48: + return this->_channels[4].envx; + case 0x58: + return this->_channels[5].envx; + case 0x68: + return this->_channels[6].envx; + case 0x78: + return this->_channels[7].envx; + case 0x09: + return this->_channels[0].outx; + case 0x19: + return this->_channels[1].outx; + case 0x29: + return this->_channels[2].outx; + case 0x39: + return this->_channels[3].outx; + case 0x49: + return this->_channels[4].outx; + case 0x59: + return this->_channels[5].outx; + case 0x69: + return this->_channels[6].outx; + case 0x79: + return this->_channels[7].outx; + case 0x0C: + return this->_registers.mvolL; + case 0x1C: + return this->_registers.mvolR; + case 0x2C: + return this->_registers.evolL; + case 0x3C: + return this->_registers.evolR; + case 0x4C: { + uint8_t kon = 0; + + for (int i = 0; i < 8; i++) + kon |= this->_channels[i].kon << i; + return kon; + } + case 0x5C: { + uint8_t kof = 0; + + for (int i = 0; i < 8; i++) + kof |= this->_channels[i].kof << i; + return kof; + } + case 0x6C: + return this->_registers.flg; + case 0x7C: { + uint8_t endx = 0; + + for (int i = 0; i < 8; i++) + endx |= this->_channels[i].endx << i; + return endx; + } + case 0x0D: + return this->_registers.efb; + case 0x1D: + return this->_registers.unused; + case 0x2D: { + uint8_t pmon = 0; + + for (int i = 0; i < 8; i++) + pmon |= this->_channels[i].pmon << i; + return pmon; + } + case 0x3D: { + uint8_t non = 0; + + for (int i = 0; i < 8; i++) + non |= this->_channels[i].non << i; + return non; + } + case 0x4D: { + uint8_t eon = 0; + + for (int i = 0; i < 8; i++) + eon |= this->_channels[i].eon << i; + return eon; + } + case 0x5D: + return this->_registers.dir; + case 0x6D: + return this->_registers.esa; + case 0x7D: + return this->_registers.edl; + case 0x0F: + return this->_channels[0].coeff; + case 0x1F: + return this->_channels[1].coeff; + case 0x2F: + return this->_channels[2].coeff; + case 0x3F: + return this->_channels[3].coeff; + case 0x4F: + return this->_channels[4].coeff; + case 0x5F: + return this->_channels[5].coeff; + case 0x6F: + return this->_channels[6].coeff; + case 0x7F: + return this->_channels[7].coeff; + default: + throw InvalidAddress("DSP Registers read", addr); + } + } + + void DSP::write(uint24_t addr, uint8_t data) + { + switch (addr) { + case 0x00: + this->_channels[0].volL = data; + break; + case 0x10: + this->_channels[1].volL = data; + break; + case 0x20: + this->_channels[2].volL = data; + break; + case 0x30: + this->_channels[3].volL = data; + break; + case 0x40: + this->_channels[4].volL = data; + break; + case 0x50: + this->_channels[5].volL = data; + break; + case 0x60: + this->_channels[6].volL = data; + break; + case 0x70: + this->_channels[7].volL = data; + break; + case 0x01: + this->_channels[0].volR = data; + break; + case 0x11: + this->_channels[1].volR = data; + break; + case 0x21: + this->_channels[2].volR = data; + break; + case 0x31: + this->_channels[3].volR = data; + break; + case 0x41: + this->_channels[4].volR = data; + break; + case 0x51: + this->_channels[5].volR = data; + break; + case 0x61: + this->_channels[6].volR = data; + break; + case 0x71: + this->_channels[7].volR = data; + break; + case 0x02: + this->_channels[0].pitchL = data; + break; + case 0x12: + this->_channels[1].pitchL = data; + break; + case 0x22: + this->_channels[2].pitchL = data; + break; + case 0x32: + this->_channels[3].pitchL = data; + break; + case 0x42: + this->_channels[4].pitchL = data; + break; + case 0x52: + this->_channels[5].pitchL = data; + break; + case 0x62: + this->_channels[6].pitchL = data; + break; + case 0x72: + this->_channels[7].pitchL = data; + break; + case 0x03: + this->_channels[0].pitchH = data; + break; + case 0x13: + this->_channels[1].pitchH = data; + break; + case 0x23: + this->_channels[2].pitchH = data; + break; + case 0x33: + this->_channels[3].pitchH = data; + break; + case 0x43: + this->_channels[4].pitchH = data; + break; + case 0x53: + this->_channels[5].pitchH = data; + break; + case 0x63: + this->_channels[6].pitchH = data; + break; + case 0x73: + this->_channels[7].pitchH = data; + break; + case 0x04: + this->_channels[0].srcn = data; + break; + case 0x14: + this->_channels[1].srcn = data; + break; + case 0x24: + this->_channels[2].srcn = data; + break; + case 0x34: + this->_channels[3].srcn = data; + break; + case 0x44: + this->_channels[4].srcn = data; + break; + case 0x54: + this->_channels[5].srcn = data; + break; + case 0x64: + this->_channels[6].srcn = data; + break; + case 0x74: + this->_channels[7].srcn = data; + break; + case 0x05: + this->_channels[0].adsr1 = data; + break; + case 0x15: + this->_channels[1].adsr1 = data; + break; + case 0x25: + this->_channels[2].adsr1 = data; + break; + case 0x35: + this->_channels[3].adsr1 = data; + break; + case 0x45: + this->_channels[4].adsr1 = data; + break; + case 0x55: + this->_channels[5].adsr1 = data; + break; + case 0x65: + this->_channels[6].adsr1 = data; + break; + case 0x75: + this->_channels[7].adsr1 = data; + break; + case 0x06: + this->_channels[0].adsr2 = data; + break; + case 0x16: + this->_channels[1].adsr2 = data; + break; + case 0x26: + this->_channels[2].adsr2 = data; + break; + case 0x36: + this->_channels[3].adsr2 = data; + break; + case 0x46: + this->_channels[4].adsr2 = data; + break; + case 0x56: + this->_channels[5].adsr2 = data; + break; + case 0x66: + this->_channels[6].adsr2 = data; + break; + case 0x76: + this->_channels[7].adsr2 = data; + break; + case 0x07: + this->_channels[0].gain = data; + break; + case 0x17: + this->_channels[1].gain = data; + break; + case 0x27: + this->_channels[2].gain = data; + break; + case 0x37: + this->_channels[3].gain = data; + break; + case 0x47: + this->_channels[4].gain = data; + break; + case 0x57: + this->_channels[5].gain = data; + break; + case 0x67: + this->_channels[6].gain = data; + break; + case 0x77: + this->_channels[7].gain = data; + break; + case 0x08: + this->_channels[0].envx = data; + break; + case 0x18: + this->_channels[1].envx = data; + break; + case 0x28: + this->_channels[2].envx = data; + break; + case 0x38: + this->_channels[3].envx = data; + break; + case 0x48: + this->_channels[4].envx = data; + break; + case 0x58: + this->_channels[5].envx = data; + break; + case 0x68: + this->_channels[6].envx = data; + break; + case 0x78: + this->_channels[7].envx = data; + break; + case 0x09: + this->_channels[0].outx = data; + break; + case 0x19: + this->_channels[1].outx = data; + break; + case 0x29: + this->_channels[2].outx = data; + break; + case 0x39: + this->_channels[3].outx = data; + break; + case 0x49: + this->_channels[4].outx = data; + break; + case 0x59: + this->_channels[5].outx = data; + break; + case 0x69: + this->_channels[6].outx = data; + break; + case 0x79: + this->_channels[7].outx = data; + break; + case 0x0C: + this->_registers.mvolL = data; + break; + case 0x1C: + this->_registers.mvolR = data; + break; + case 0x2C: + this->_registers.evolL = data; + break; + case 0x3C: + this->_registers.evolR = data; + break; + case 0x4C: + for (int i = 0; i < 8; i++) + this->_channels[i].kon |= data << i; + break; + case 0x5C: + for (int i = 0; i < 8; i++) + this->_channels[i].kof |= data << i; + break; + case 0x6C: + this->_registers.flg = data; + break; + case 0x7C: + for (int i = 0; i < 8; i++) + this->_channels[i].endx |= data << i; + break; + case 0x0D: + this->_registers.efb = data; + break; + case 0x1D: + this->_registers.unused = data; + break; + case 0x2D: + for (int i = 0; i < 8; i++) + this->_channels[i].pmon |= data << i; + break; + case 0x3D: + for (int i = 0; i < 8; i++) + this->_channels[i].non |= data << i; + break; + case 0x4D: + for (int i = 0; i < 8; i++) + this->_channels[i].eon |= data << i; + break; + case 0x5D: + this->_registers.dir = data; + break; + case 0x6D: + this->_registers.esa = data; + break; + case 0x7D: + this->_registers.edl = data; + break; + case 0x0F: + this->_channels[0].coeff = data; + break; + case 0x1F: + this->_channels[1].coeff = data; + break; + case 0x2F: + this->_channels[2].coeff = data; + break; + case 0x3F: + this->_channels[3].coeff = data; + break; + case 0x4F: + this->_channels[4].coeff = data; + break; + case 0x5F: + this->_channels[5].coeff = data; + break; + case 0x6F: + this->_channels[6].coeff = data; + break; + case 0x7F: + this->_channels[7].coeff = data; + break; + default: + throw InvalidAddress("DSP Registers write", addr); + } + } +} \ No newline at end of file diff --git a/sources/DSP/DSP.hpp b/sources/APU/DSP/DSP.hpp similarity index 60% rename from sources/DSP/DSP.hpp rename to sources/APU/DSP/DSP.hpp index faab2bd..084abca 100644 --- a/sources/DSP/DSP.hpp +++ b/sources/APU/DSP/DSP.hpp @@ -6,37 +6,13 @@ #define COMSQUARE_DSP_HPP #include -#include -#include "../Memory/IMemory.hpp" +#include +#include "../../Memory/IMemory.hpp" namespace ComSquare::APU::DSP { //! @brief All the registers of the DSP struct Registers { - //! @brief Left channel volume register - uint8_t volL[8]; - //! @brief Left channel volume register - uint8_t volR[8]; - - //! @brief Lower 8 bits of pitch register - uint8_t pitchL[8]; - //! @brief Higher 8 bits of pitch register - uint8_t pitchH[8]; - - //! @brief Source number register - uint8_t srcn[8]; - - //! @brief Envelope register - uint8_t adsr1[8]; - //! @brief Envelope controllers register - uint8_t adsr2[8]; - //! @brief Gain register - uint8_t gain[8]; - //! @brief Envelope value register - uint8_t envx[8]; - //! @brief Wave height register - uint8_t outx[8]; - //! @brief Left output of the Main Volume register uint8_t mvolL; //! @brief Right output of the Main Volume register @@ -47,102 +23,15 @@ namespace ComSquare::APU::DSP //! @brief Right output of the Echo Volume register uint8_t evolR; - //! @brief Key On register - union { - struct { - bool kon7 : 1; - bool kon6 : 1; - bool kon5 : 1; - bool kon4 : 1; - bool kon3 : 1; - bool kon2 : 1; - bool kon1 : 1; - bool kon0 : 1; - }; - uint8_t kon; - }; - //! @brief Key Off register - union { - struct { - bool kof7 : 1; - bool kof6 : 1; - bool kof5 : 1; - bool kof4 : 1; - bool kof3 : 1; - bool kof2 : 1; - bool kof1 : 1; - bool kof0 : 1; - }; - uint8_t kof; - }; - //! @brief Flags register uint8_t flg; - //! @brief Sample end register - union { - struct { - bool endx7 : 1; - bool endx6 : 1; - bool endx5 : 1; - bool endx4 : 1; - bool endx3 : 1; - bool endx2 : 1; - bool endx1 : 1; - bool endx0 : 1; - }; - uint8_t endx; - }; - //! @brief Echo feedback register uint8_t efb; //! @brief Not used register uint8_t unused; - //! @brief Pitch modulation register - union { - struct { - bool pmon7 : 1; - bool pmon6 : 1; - bool pmon5 : 1; - bool pmon4 : 1; - bool pmon3 : 1; - bool pmon2 : 1; - bool pmon1 : 1; - bool __ : 1; - }; - uint8_t pmon; - }; - - //! @brief Noise enable register - union { - struct { - bool non7 : 1; - bool non6 : 1; - bool non5 : 1; - bool non4 : 1; - bool non3 : 1; - bool non2 : 1; - bool non1 : 1; - bool non0 : 1; - }; - uint8_t non; - }; - //! @brief Echo enable register - union { - struct { - bool eon7 : 1; - bool eon6 : 1; - bool eon5 : 1; - bool eon4 : 1; - bool eon3 : 1; - bool eon2 : 1; - bool eon1 : 1; - bool eon0 : 1; - }; - uint8_t eon; - }; //! @brief Source Directory offset register uint8_t dir; @@ -150,8 +39,68 @@ namespace ComSquare::APU::DSP uint8_t esa; //! @brief Echo delay size register uint8_t edl; + }; + + struct Channel { + //! @brief BRR Header + union { + struct { + //! @brief Shift value range + unsigned range : 4; + //! @brief Decompression filter + unsigned filter : 2; + //! @brief Flag if the sample loops + bool loop : 1; + //! @brief Stop the sample (or restart from loop point) + bool end : 1; + }; + uint8_t brrHead; + }; + //! @brief Sample data inside BRR + uint64_t brrData; + + //! @brief Left channel volume register + uint8_t volL; + //! @brief Left channel volume register + uint8_t volR; + + //! @brief Lower 8 bits of pitch register + uint8_t pitchL; + //! @brief Higher 8 bits of pitch register + uint8_t pitchH; + + //! @brief Key On register + bool kon : 1; + //! @brief Key Off register + bool kof : 1; + + //! @brief Sample end register + bool endx : 1; + + //! @brief Noise enable register + bool non : 1; + //! @brief Echo enable register + bool eon : 1; + + //! @brief Pitch modulation register + bool pmon : 1; + + //! @brief Source number register + uint8_t srcn; + + //! @brief Envelope register + uint8_t adsr1; + //! @brief Envelope controllers register + uint8_t adsr2; + //! @brief Gain register + uint8_t gain; + //! @brief Envelope value register + uint8_t envx; + //! @brief Wave height register + uint8_t outx; + //! @brief Echo FIR filter coefficients - uint8_t coeff[8]; + uint8_t coeff; }; class DSP : public Memory::IMemory { @@ -160,10 +109,7 @@ namespace ComSquare::APU::DSP Registers _registers{}; //! @brief 8x channels of sample used to make sound - sf::Sound _channels[8]; - - //! @brief A buffer containing current wave - sf::SoundBuffer _soundBuffer; + std::array _channels{}; public: explicit DSP(); diff --git a/sources/DSP/DSP.cpp b/sources/DSP/DSP.cpp deleted file mode 100644 index a17c35a..0000000 --- a/sources/DSP/DSP.cpp +++ /dev/null @@ -1,554 +0,0 @@ -// -// Created by Melefo on 28/01/2020. -// - -#include "DSP.hpp" -#include "../Exceptions/InvalidAddress.hpp" - -namespace ComSquare::APU::DSP -{ - DSP::DSP() - { - for (auto & _channel : this->_channels) { - _channel.setBuffer(this->_soundBuffer); - _channel.setLoop(true); - _channel.play(); - } - } - - uint8_t DSP::read(uint24_t addr) - { - switch (addr) { - case 0x00: - return this->_registers.volL[0]; - case 0x10: - return this->_registers.volL[1]; - case 0x20: - return this->_registers.volL[2]; - case 0x30: - return this->_registers.volL[3]; - case 0x40: - return this->_registers.volL[4]; - case 0x50: - return this->_registers.volL[5]; - case 0x60: - return this->_registers.volL[6]; - case 0x70: - return this->_registers.volL[7]; - case 0x01: - return this->_registers.volR[0]; - case 0x11: - return this->_registers.volR[1]; - case 0x21: - return this->_registers.volR[2]; - case 0x31: - return this->_registers.volR[3]; - case 0x41: - return this->_registers.volR[4]; - case 0x51: - return this->_registers.volR[5]; - case 0x61: - return this->_registers.volR[6]; - case 0x71: - return this->_registers.volR[7]; - case 0x02: - return this->_registers.pitchL[0]; - case 0x12: - return this->_registers.pitchL[1]; - case 0x22: - return this->_registers.pitchL[2]; - case 0x32: - return this->_registers.pitchL[3]; - case 0x42: - return this->_registers.pitchL[4]; - case 0x52: - return this->_registers.pitchL[5]; - case 0x62: - return this->_registers.pitchL[6]; - case 0x72: - return this->_registers.pitchL[7]; - case 0x03: - return this->_registers.pitchH[0]; - case 0x13: - return this->_registers.pitchH[1]; - case 0x23: - return this->_registers.pitchH[2]; - case 0x33: - return this->_registers.pitchH[3]; - case 0x43: - return this->_registers.pitchH[4]; - case 0x53: - return this->_registers.pitchH[5]; - case 0x63: - return this->_registers.pitchH[6]; - case 0x73: - return this->_registers.pitchH[7]; - case 0x04: - return this->_registers.srcn[0]; - case 0x14: - return this->_registers.srcn[1]; - case 0x24: - return this->_registers.srcn[2]; - case 0x34: - return this->_registers.srcn[3]; - case 0x44: - return this->_registers.srcn[4]; - case 0x54: - return this->_registers.srcn[5]; - case 0x64: - return this->_registers.srcn[6]; - case 0x74: - return this->_registers.srcn[7]; - case 0x05: - return this->_registers.adsr1[0]; - case 0x15: - return this->_registers.adsr1[1]; - case 0x25: - return this->_registers.adsr1[2]; - case 0x35: - return this->_registers.adsr1[3]; - case 0x45: - return this->_registers.adsr1[4]; - case 0x55: - return this->_registers.adsr1[5]; - case 0x65: - return this->_registers.adsr1[6]; - case 0x75: - return this->_registers.adsr1[7]; - case 0x06: - return this->_registers.adsr2[0]; - case 0x16: - return this->_registers.adsr2[1]; - case 0x26: - return this->_registers.adsr2[2]; - case 0x36: - return this->_registers.adsr2[3]; - case 0x46: - return this->_registers.adsr2[4]; - case 0x56: - return this->_registers.adsr2[5]; - case 0x66: - return this->_registers.adsr2[6]; - case 0x76: - return this->_registers.adsr2[7]; - case 0x07: - return this->_registers.gain[0]; - case 0x17: - return this->_registers.gain[1]; - case 0x27: - return this->_registers.gain[2]; - case 0x37: - return this->_registers.gain[3]; - case 0x47: - return this->_registers.gain[4]; - case 0x57: - return this->_registers.gain[5]; - case 0x67: - return this->_registers.gain[6]; - case 0x77: - return this->_registers.gain[7]; - case 0x08: - return this->_registers.envx[0]; - case 0x18: - return this->_registers.envx[1]; - case 0x28: - return this->_registers.envx[2]; - case 0x38: - return this->_registers.envx[3]; - case 0x48: - return this->_registers.envx[4]; - case 0x58: - return this->_registers.envx[5]; - case 0x68: - return this->_registers.envx[6]; - case 0x78: - return this->_registers.envx[7]; - case 0x09: - return this->_registers.outx[0]; - case 0x19: - return this->_registers.outx[1]; - case 0x29: - return this->_registers.outx[2]; - case 0x39: - return this->_registers.outx[3]; - case 0x49: - return this->_registers.outx[4]; - case 0x59: - return this->_registers.outx[5]; - case 0x69: - return this->_registers.outx[6]; - case 0x79: - return this->_registers.outx[7]; - case 0x0C: - return this->_registers.mvolL; - case 0x1C: - return this->_registers.mvolR; - case 0x2C: - return this->_registers.evolL; - case 0x3C: - return this->_registers.evolR; - case 0x4C: - return this->_registers.kon; - case 0x5C: - return this->_registers.kof; - case 0x6C: - return this->_registers.flg; - case 0x7C: - return this->_registers.endx; - case 0x0D: - return this->_registers.efb; - case 0x1D: - return this->_registers.unused; - case 0x2D: - return this->_registers.pmon; - case 0x3D: - return this->_registers.non; - case 0x4D: - return this->_registers.eon; - case 0x5D: - return this->_registers.dir; - case 0x6D: - return this->_registers.esa; - case 0x7D: - return this->_registers.edl; - case 0x0F: - return this->_registers.coeff[0]; - case 0x1F: - return this->_registers.coeff[1]; - case 0x2F: - return this->_registers.coeff[2]; - case 0x3F: - return this->_registers.coeff[3]; - case 0x4F: - return this->_registers.coeff[4]; - case 0x5F: - return this->_registers.coeff[5]; - case 0x6F: - return this->_registers.coeff[6]; - case 0x7F: - return this->_registers.coeff[7]; - default: - throw InvalidAddress("DSP Registers read", addr); - } - } - - void DSP::write(uint24_t addr, uint8_t data) - { - switch (addr) { - case 0x00: - this->_registers.volL[0] = data; - break; - case 0x10: - this->_registers.volL[1] = data; - break; - case 0x20: - this->_registers.volL[2] = data; - break; - case 0x30: - this->_registers.volL[3] = data; - break; - case 0x40: - this->_registers.volL[4] = data; - break; - case 0x50: - this->_registers.volL[5] = data; - break; - case 0x60: - this->_registers.volL[6] = data; - break; - case 0x70: - this->_registers.volL[7] = data; - break; - case 0x01: - this->_registers.volR[0] = data; - break; - case 0x11: - this->_registers.volR[1] = data; - break; - case 0x21: - this->_registers.volR[2] = data; - break; - case 0x31: - this->_registers.volR[3] = data; - break; - case 0x41: - this->_registers.volR[4] = data; - break; - case 0x51: - this->_registers.volR[5] = data; - break; - case 0x61: - this->_registers.volR[6] = data; - break; - case 0x71: - this->_registers.volR[7] = data; - break; - case 0x02: - this->_registers.pitchL[0] = data; - break; - case 0x12: - this->_registers.pitchL[1] = data; - break; - case 0x22: - this->_registers.pitchL[2] = data; - break; - case 0x32: - this->_registers.pitchL[3] = data; - break; - case 0x42: - this->_registers.pitchL[4] = data; - break; - case 0x52: - this->_registers.pitchL[5] = data; - break; - case 0x62: - this->_registers.pitchL[6] = data; - break; - case 0x72: - this->_registers.pitchL[7] = data; - break; - case 0x03: - this->_registers.pitchH[0] = data; - break; - case 0x13: - this->_registers.pitchH[1] = data; - break; - case 0x23: - this->_registers.pitchH[2] = data; - break; - case 0x33: - this->_registers.pitchH[3] = data; - break; - case 0x43: - this->_registers.pitchH[4] = data; - break; - case 0x53: - this->_registers.pitchH[5] = data; - break; - case 0x63: - this->_registers.pitchH[6] = data; - break; - case 0x73: - this->_registers.pitchH[7] = data; - break; - case 0x04: - this->_registers.srcn[0] = data; - break; - case 0x14: - this->_registers.srcn[1] = data; - break; - case 0x24: - this->_registers.srcn[2] = data; - break; - case 0x34: - this->_registers.srcn[3] = data; - break; - case 0x44: - this->_registers.srcn[4] = data; - break; - case 0x54: - this->_registers.srcn[5] = data; - break; - case 0x64: - this->_registers.srcn[6] = data; - break; - case 0x74: - this->_registers.srcn[7] = data; - break; - case 0x05: - this->_registers.adsr1[0] = data; - break; - case 0x15: - this->_registers.adsr1[1] = data; - break; - case 0x25: - this->_registers.adsr1[2] = data; - break; - case 0x35: - this->_registers.adsr1[3] = data; - break; - case 0x45: - this->_registers.adsr1[4] = data; - break; - case 0x55: - this->_registers.adsr1[5] = data; - break; - case 0x65: - this->_registers.adsr1[6] = data; - break; - case 0x75: - this->_registers.adsr1[7] = data; - break; - case 0x06: - this->_registers.adsr2[0] = data; - break; - case 0x16: - this->_registers.adsr2[1] = data; - break; - case 0x26: - this->_registers.adsr2[2] = data; - break; - case 0x36: - this->_registers.adsr2[3] = data; - break; - case 0x46: - this->_registers.adsr2[4] = data; - break; - case 0x56: - this->_registers.adsr2[5] = data; - break; - case 0x66: - this->_registers.adsr2[6] = data; - break; - case 0x76: - this->_registers.adsr2[7] = data; - break; - case 0x07: - this->_registers.gain[0] = data; - break; - case 0x17: - this->_registers.gain[1] = data; - break; - case 0x27: - this->_registers.gain[2] = data; - break; - case 0x37: - this->_registers.gain[3] = data; - break; - case 0x47: - this->_registers.gain[4] = data; - break; - case 0x57: - this->_registers.gain[5] = data; - break; - case 0x67: - this->_registers.gain[6] = data; - break; - case 0x77: - this->_registers.gain[7] = data; - break; - case 0x08: - this->_registers.envx[0] = data; - break; - case 0x18: - this->_registers.envx[1] = data; - break; - case 0x28: - this->_registers.envx[2] = data; - break; - case 0x38: - this->_registers.envx[3] = data; - break; - case 0x48: - this->_registers.envx[4] = data; - break; - case 0x58: - this->_registers.envx[5] = data; - break; - case 0x68: - this->_registers.envx[6] = data; - break; - case 0x78: - this->_registers.envx[7] = data; - break; - case 0x09: - this->_registers.outx[0] = data; - break; - case 0x19: - this->_registers.outx[1] = data; - break; - case 0x29: - this->_registers.outx[2] = data; - break; - case 0x39: - this->_registers.outx[3] = data; - break; - case 0x49: - this->_registers.outx[4] = data; - break; - case 0x59: - this->_registers.outx[5] = data; - break; - case 0x69: - this->_registers.outx[6] = data; - break; - case 0x79: - this->_registers.outx[7] = data; - break; - case 0x0C: - this->_registers.mvolL = data; - break; - case 0x1C: - this->_registers.mvolR = data; - break; - case 0x2C: - this->_registers.evolL = data; - break; - case 0x3C: - this->_registers.evolR = data; - break; - case 0x4C: - this->_registers.kon = data; - break; - case 0x5C: - this->_registers.kof = data; - break; - case 0x6C: - this->_registers.flg = data; - break; - case 0x7C: - this->_registers.endx = data; - break; - case 0x0D: - this->_registers.efb = data; - break; - case 0x1D: - this->_registers.unused = data; - break; - case 0x2D: - this->_registers.pmon = data; - break; - case 0x3D: - this->_registers.non = data; - break; - case 0x4D: - this->_registers.eon = data; - break; - case 0x5D: - this->_registers.dir = data; - break; - case 0x6D: - this->_registers.esa = data; - break; - case 0x7D: - this->_registers.edl = data; - break; - case 0x0F: - this->_registers.coeff[0] = data; - break; - case 0x1F: - this->_registers.coeff[1] = data; - break; - case 0x2F: - this->_registers.coeff[2] = data; - break; - case 0x3F: - this->_registers.coeff[3] = data; - break; - case 0x4F: - this->_registers.coeff[4] = data; - break; - case 0x5F: - this->_registers.coeff[5] = data; - break; - case 0x6F: - this->_registers.coeff[6] = data; - break; - case 0x7F: - this->_registers.coeff[7] = data; - break; - default: - throw InvalidAddress("DSP Registers write", addr); - } - } -} \ No newline at end of file