From e3b4350f44a51d0012457a556dc04dfd0ba267d4 Mon Sep 17 00:00:00 2001 From: purringChaos Date: Sun, 6 Jun 2021 17:27:26 +0100 Subject: Add PoroCYon's DSP code. (#1123) * Add PoroCYon's DSP code. * Remove some teakra iles that we dont need. * make some requested changes. * move DataMemoryOffset into namespace. * use deault param. * ad the switch change * forget about the default parameter --- src/teakra/include/teakra/disassembler.h | 23 +++++++++ src/teakra/include/teakra/disassembler_c.h | 17 +++++++ src/teakra/include/teakra/teakra.h | 81 ++++++++++++++++++++++++++++++ src/teakra/include/teakra/teakra_c.h | 79 +++++++++++++++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100644 src/teakra/include/teakra/disassembler.h create mode 100644 src/teakra/include/teakra/disassembler_c.h create mode 100644 src/teakra/include/teakra/teakra.h create mode 100644 src/teakra/include/teakra/teakra_c.h (limited to 'src/teakra/include') diff --git a/src/teakra/include/teakra/disassembler.h b/src/teakra/include/teakra/disassembler.h new file mode 100644 index 0000000..f6af37e --- /dev/null +++ b/src/teakra/include/teakra/disassembler.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace Teakra::Disassembler { + +struct ArArpSettings { + std::array ar; + std::array arp; +}; + +bool NeedExpansion(std::uint16_t opcode); +bool NeedExpansion(std::uint16_t opcode); +std::vector GetTokenList(std::uint16_t opcode, std::uint16_t expansion = 0, + std::optional ar_arp = std::nullopt); +std::string Do(std::uint16_t opcode, std::uint16_t expansion = 0, + std::optional ar_arp = std::nullopt); + +} // namespace Teakra::Disassembler diff --git a/src/teakra/include/teakra/disassembler_c.h b/src/teakra/include/teakra/disassembler_c.h new file mode 100644 index 0000000..8222a74 --- /dev/null +++ b/src/teakra/include/teakra/disassembler_c.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +bool Teakra_Disasm_NeedExpansion(uint16_t opcode); + +size_t Teakra_Disasm_Do(char* dst, size_t dstlen, + uint16_t opcode, uint16_t expansion /*= 0*/); + +#ifdef __cplusplus +} +#endif diff --git a/src/teakra/include/teakra/teakra.h b/src/teakra/include/teakra/teakra.h new file mode 100644 index 0000000..32b9064 --- /dev/null +++ b/src/teakra/include/teakra/teakra.h @@ -0,0 +1,81 @@ +#pragma once + +#include +#include +#include +#include + +namespace Teakra { + +struct AHBMCallback { + std::function read8; + std::function write8; + + std::function read16; + std::function write16; + + std::function read32; + std::function write32; +}; + +class Teakra { +public: + Teakra(); + ~Teakra(); + + void Reset(); + + std::array& GetDspMemory(); + const std::array& GetDspMemory() const; + + // APBP Data + bool SendDataIsEmpty(std::uint8_t index) const; + void SendData(std::uint8_t index, std::uint16_t value); + bool RecvDataIsReady(std::uint8_t index) const; + std::uint16_t RecvData(std::uint8_t index); + std::uint16_t PeekRecvData(std::uint8_t index); + void SetRecvDataHandler(std::uint8_t index, std::function handler); + + // APBP Semaphore + void SetSemaphore(std::uint16_t value); + void ClearSemaphore(std::uint16_t value); + void MaskSemaphore(std::uint16_t value); + void SetSemaphoreHandler(std::function handler); + std::uint16_t GetSemaphore() const; + + // for implementing DSP_PDATA/PADR DMA transfers + std::uint16_t ProgramRead(std::uint32_t address) const; + void ProgramWrite(std::uint32_t address, std::uint16_t value); + std::uint16_t DataRead(std::uint16_t address, bool bypass_mmio = false); + void DataWrite(std::uint16_t address, std::uint16_t value, bool bypass_mmio = false); + std::uint16_t DataReadA32(std::uint32_t address) const; + void DataWriteA32(std::uint32_t address, std::uint16_t value); + std::uint16_t MMIORead(std::uint16_t address); + void MMIOWrite(std::uint16_t address, std::uint16_t value); + + // DSP_PADR is only 16-bit, so this is where the DMA interface gets the + // upper 16-bits from + std::uint16_t DMAChan0GetSrcHigh(); + std::uint16_t DMAChan0GetDstHigh(); + + std::uint16_t AHBMGetUnitSize(std::uint16_t i) const; + std::uint16_t AHBMGetDirection(std::uint16_t i) const; + std::uint16_t AHBMGetDmaChannel(std::uint16_t i) const; + // we need these as AHBM does some weird stuff on unaligned accesses internally + std::uint16_t AHBMRead16(std::uint32_t addr); + void AHBMWrite16(std::uint32_t addr, std::uint16_t value); + std::uint16_t AHBMRead32(std::uint32_t addr); + void AHBMWrite32(std::uint32_t addr, std::uint32_t value); + + // core + void Run(unsigned cycle); + + void SetAHBMCallback(const AHBMCallback& callback); + + void SetAudioCallback(std::function)> callback); + +private: + struct Impl; + std::unique_ptr impl; +}; +} // namespace Teakra diff --git a/src/teakra/include/teakra/teakra_c.h b/src/teakra/include/teakra/teakra_c.h new file mode 100644 index 0000000..d52a9f1 --- /dev/null +++ b/src/teakra/include/teakra/teakra_c.h @@ -0,0 +1,79 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct TeakraObject; +typedef struct TeakraObject TeakraContext; + +typedef void (*Teakra_InterruptCallback)(void* userdata); +typedef void (*Teakra_AudioCallback)(void* userdata, int16_t samples[2]); + +typedef uint8_t (*Teakra_AHBMReadCallback8)(void* userdata, uint32_t address); +typedef void (*Teakra_AHBMWriteCallback8)(void* userdata, uint32_t address, uint8_t value); + +typedef uint16_t (*Teakra_AHBMReadCallback16)(void* userdata, uint32_t address); +typedef void (*Teakra_AHBMWriteCallback16)(void* userdata, uint32_t address, uint16_t value); + +typedef uint32_t (*Teakra_AHBMReadCallback32)(void* userdata, uint32_t address); +typedef void (*Teakra_AHBMWriteCallback32)(void* userdata, uint32_t address, uint32_t value); + +TeakraContext* Teakra_Create(); +void Teakra_Destroy(TeakraContext* context); +void Teakra_Reset(TeakraContext* context); +uint8_t* Teakra_GetDspMemory(TeakraContext* context); + +int Teakra_SendDataIsEmpty(const TeakraContext* context, uint8_t index); +void Teakra_SendData(TeakraContext* context, uint8_t index, uint16_t value); +int Teakra_RecvDataIsReady(const TeakraContext* context, uint8_t index); +uint16_t Teakra_RecvData(TeakraContext* context, uint8_t index); +uint16_t Teakra_PeekRecvData(TeakraContext* context, uint8_t index); +void Teakra_SetRecvDataHandler(TeakraContext* context, uint8_t index, + Teakra_InterruptCallback handler, void* userdata); + +void Teakra_SetSemaphore(TeakraContext* context, uint16_t value); +void Teakra_ClearSemaphore(TeakraContext* context, uint16_t value); +void Teakra_MaskSemaphore(TeakraContext* context, uint16_t value); +void Teakra_SetSemaphoreHandler(TeakraContext* context, Teakra_InterruptCallback handler, + void* userdata); +uint16_t Teakra_GetSemaphore(const TeakraContext* context); + +uint16_t Teakra_ProgramRead(TeakraContext* context, uint32_t address); +void Teakra_ProgramWrite(TeakraContext* context, uint32_t address, uint16_t value); +uint16_t Teakra_DataRead(TeakraContext* context, uint16_t address, bool bypass_mmio); +void Teakra_DataWrite(TeakraContext* context, uint16_t address, uint16_t value, bool bypass_mmio); +uint16_t Teakra_DataReadA32(TeakraContext* context, uint32_t address); +void Teakra_DataWriteA32(TeakraContext* context, uint32_t address, uint16_t value); +uint16_t Teakra_MMIORead(TeakraContext* context, uint16_t address); +void Teakra_MMIOWrite(TeakraContext* context, uint16_t address, uint16_t value); + +uint16_t Teakra_DMAChan0GetSrcHigh(TeakraContext* context); +uint16_t Teakra_DMAChan0GetDstHigh(TeakraContext* context); + +uint16_t Teakra_AHBMGetUnitSize(TeakraContext* context, uint16_t i); +uint16_t Teakra_AHBMGetDirection(TeakraContext* context, uint16_t i); +uint16_t Teakra_AHBMGetDmaChannel(TeakraContext* context, uint16_t i); + +uint16_t Teakra_AHBMRead16(TeakraContext* context, uint32_t addr); +void Teakra_AHBMWrite16(TeakraContext* context, uint32_t addr, uint16_t value); +uint16_t Teakra_AHBMRead32(TeakraContext* context, uint32_t addr); +void Teakra_AHBMWrite32(TeakraContext* context, uint32_t addr, uint32_t value); + + +void Teakra_Run(TeakraContext* context, unsigned cycle); + +void Teakra_SetAHBMCallback(TeakraContext* context, + Teakra_AHBMReadCallback8 read8 , Teakra_AHBMWriteCallback8 write8 , + Teakra_AHBMReadCallback16 read16, Teakra_AHBMWriteCallback16 write16, + Teakra_AHBMReadCallback32 read32, Teakra_AHBMWriteCallback32 write32, + void* userdata); + + +void Teakra_SetAudioCallback(TeakraContext* context, Teakra_AudioCallback callback, void* userdata); +#ifdef __cplusplus +} +#endif -- cgit v1.2.3