mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-05-22 14:32:03 +00:00
Moving DSP in its own folder
Implementing read & write with all registers for DSP Replacing APU registers with internal registers and vice-versa Associate DSP with APU in constructor
This commit is contained in:
+3
-1
@@ -44,4 +44,6 @@ add_executable(ComSquare
|
||||
sources/Ram/Ram.hpp
|
||||
sources/Memory/MemoryShadow.cpp
|
||||
sources/Memory/MemoryShadow.hpp
|
||||
)
|
||||
sources/DSP/DSP.cpp
|
||||
sources/DSP/DSP.hpp
|
||||
)
|
||||
|
||||
+27
-28
@@ -8,37 +8,36 @@
|
||||
|
||||
namespace ComSquare::APU
|
||||
{
|
||||
APU::APU()
|
||||
{
|
||||
}
|
||||
APU::APU() : _dsp(new DSP::DSP)
|
||||
{ }
|
||||
|
||||
uint8_t APU::read(uint24_t addr)
|
||||
{
|
||||
switch (addr) {
|
||||
case 0xF0:
|
||||
return this->_internalRegisters.unknown;
|
||||
return this->_registers.unknown;
|
||||
case 0xF2:
|
||||
return this->_internalRegisters.dspregAddr;
|
||||
return this->_registers.dspregAddr;
|
||||
case 0xF3:
|
||||
return this->_internalRegisters.dspregData;
|
||||
return this->_registers.dspregData;
|
||||
case 0xF4:
|
||||
return this->_internalRegisters.port0;
|
||||
return this->_registers.port0;
|
||||
case 0xF5:
|
||||
return this->_internalRegisters.port1;
|
||||
return this->_registers.port1;
|
||||
case 0xF6:
|
||||
return this->_internalRegisters.port2;
|
||||
return this->_registers.port2;
|
||||
case 0xF7:
|
||||
return this->_internalRegisters.port3;
|
||||
return this->_registers.port3;
|
||||
case 0xF8:
|
||||
return this->_internalRegisters.regmem1;
|
||||
return this->_registers.regmem1;
|
||||
case 0xF9:
|
||||
return this->_internalRegisters.regmem2;
|
||||
return this->_registers.regmem2;
|
||||
case 0xFD:
|
||||
return this->_internalRegisters.counter0;
|
||||
return this->_registers.counter0;
|
||||
case 0xFE:
|
||||
return this->_internalRegisters.counter1;
|
||||
return this->_registers.counter1;
|
||||
case 0xFF:
|
||||
return this->_internalRegisters.counter2;
|
||||
return this->_registers.counter2;
|
||||
default:
|
||||
throw InvalidAddress("APU Internal Registers read", addr);
|
||||
}
|
||||
@@ -48,43 +47,43 @@ namespace ComSquare::APU
|
||||
{
|
||||
switch (addr) {
|
||||
case 0xF0:
|
||||
this->_internalRegisters.unknown = data;
|
||||
this->_registers.unknown = data;
|
||||
break;
|
||||
case 0xF1:
|
||||
this->_internalRegisters.ctrlreg = data;
|
||||
this->_registers.ctrlreg = data;
|
||||
break;
|
||||
case 0xF2:
|
||||
this->_internalRegisters.dspregAddr = data;
|
||||
this->_registers.dspregAddr = data;
|
||||
break;
|
||||
case 0xF3:
|
||||
this->_internalRegisters.dspregData = data;
|
||||
this->_registers.dspregData = data;
|
||||
break;
|
||||
case 0xF4:
|
||||
this->_internalRegisters.port0 = data;
|
||||
this->_registers.port0 = data;
|
||||
break;
|
||||
case 0xF5:
|
||||
this->_internalRegisters.port1 = data;
|
||||
this->_registers.port1 = data;
|
||||
break;
|
||||
case 0xF6:
|
||||
this->_internalRegisters.port2 = data;
|
||||
this->_registers.port2 = data;
|
||||
break;
|
||||
case 0xF7:
|
||||
this->_internalRegisters.port3 = data;
|
||||
this->_registers.port3 = data;
|
||||
break;
|
||||
case 0xF8:
|
||||
this->_internalRegisters.regmem1 = data;
|
||||
this->_registers.regmem1 = data;
|
||||
break;
|
||||
case 0xF9:
|
||||
this->_internalRegisters.regmem2 = data;
|
||||
this->_registers.regmem2 = data;
|
||||
break;
|
||||
case 0xFA:
|
||||
this->_internalRegisters.timer0 = data;
|
||||
this->_registers.timer0 = data;
|
||||
break;
|
||||
case 0xFB:
|
||||
this->_internalRegisters.timer1 = data;
|
||||
this->_registers.timer1 = data;
|
||||
break;
|
||||
case 0xFC:
|
||||
this->_internalRegisters.timer2 = data;
|
||||
this->_registers.timer2 = data;
|
||||
break;
|
||||
default:
|
||||
throw InvalidAddress("APU Internal Registers write", addr);
|
||||
|
||||
+10
-10
@@ -6,11 +6,12 @@
|
||||
#define COMSQUARE_APU_HPP
|
||||
|
||||
#include <memory>
|
||||
#include "../DSP/DSP.hpp"
|
||||
#include "../Memory/IMemory.hpp"
|
||||
|
||||
namespace ComSquare::APU
|
||||
{
|
||||
struct Registers {
|
||||
struct InternalRegisters {
|
||||
|
||||
//! @brief The X index register
|
||||
uint8_t x;
|
||||
@@ -59,7 +60,7 @@ namespace ComSquare::APU
|
||||
};
|
||||
};
|
||||
|
||||
struct InternalRegisters
|
||||
struct Registers
|
||||
{
|
||||
//! @brief An undocumented register
|
||||
uint8_t unknown;
|
||||
@@ -102,25 +103,24 @@ namespace ComSquare::APU
|
||||
|
||||
};
|
||||
|
||||
class DSP {
|
||||
};
|
||||
|
||||
class APU : public IMemory {
|
||||
private:
|
||||
//! @brief All the registers of the APU CPU
|
||||
Registers _registers;
|
||||
InternalRegisters _internalRegisters{};
|
||||
public:
|
||||
explicit APU();
|
||||
//! @brief Internal registers of the CPU (accessible from the bus via addr $4200 to $421F).
|
||||
InternalRegisters _internalRegisters;
|
||||
|
||||
//! @brief The DSP component used to produce sound
|
||||
std::shared_ptr<DSP> _dsp;
|
||||
std::shared_ptr<DSP::DSP> _dsp;
|
||||
public:
|
||||
explicit APU();
|
||||
|
||||
//! @brief Read from the internal APU register.
|
||||
//! @param addr The address to read from. The address 0xF0 should refer to the first byte of the register.
|
||||
//! @throw InvalidAddress will be thrown if the address is more than $FF (the number of register).
|
||||
//! @return Return the value of the register.
|
||||
uint8_t read(uint24_t addr) override;
|
||||
//! @brief Write data to the internal APY register.
|
||||
//! @brief Write data to the internal APU register.
|
||||
//! @param addr The address to write to. The address 0xF0 should refer to the first byte of register.
|
||||
//! @param data The new value of the register.
|
||||
//! @throw InvalidAddress will be thrown if the address is more than $FF (the number of register).
|
||||
|
||||
@@ -0,0 +1,548 @@
|
||||
//
|
||||
// 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->_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 Internal 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 Internal Registers write", addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
//
|
||||
// Created by Melefo on 28/01/2020.
|
||||
//
|
||||
|
||||
#ifndef COMSQUARE_DSP_HPP
|
||||
#define COMSQUARE_DSP_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#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
|
||||
uint8_t mvolR;
|
||||
|
||||
//! @brief Left output of the Echo Volume register
|
||||
uint8_t evolL;
|
||||
//! @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;
|
||||
|
||||
//! @brief Echo data start register
|
||||
uint8_t esa;
|
||||
//! @brief Echo delay size register
|
||||
uint8_t edl;
|
||||
//! @brief Echo FIR filter coefficients
|
||||
uint8_t coeff[8];
|
||||
};
|
||||
|
||||
class DSP : public IMemory {
|
||||
private:
|
||||
Registers _registers{};
|
||||
public:
|
||||
explicit DSP();
|
||||
|
||||
//! @brief Read from the internal DSP register.
|
||||
//! @param addr The address to read from. The address 0x0 should refer to the first byte of the register.
|
||||
//! @throw InvalidAddress will be thrown if the address is more than $7F (the number of register).
|
||||
//! @return Return the value of the register.
|
||||
uint8_t read(uint24_t addr) override;
|
||||
//! @brief Write data to the internal DSP register.
|
||||
//! @param addr The address to write to. The address 0x0 should refer to the first byte of register.
|
||||
//! @param data The new value of the register.
|
||||
//! @throw InvalidAddress will be thrown if the address is more than $7F (the number of register).
|
||||
void write(uint24_t addr, uint8_t data) override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //COMSQUARE_DSP_HPP
|
||||
Reference in New Issue
Block a user