From 0a720dc906f5d2c16e2c34196c5b05899f3aca7e Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 2 Sep 2022 22:29:44 +0200 Subject: [PATCH] Setup SPU --- include/PSX/System/IOPorts/DMA_IO.hpp | 142 ++++++++++++++++++++++++ src/Library/src/BootLoader/boot_spu.cpp | 6 +- 2 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 include/PSX/System/IOPorts/DMA_IO.hpp diff --git a/include/PSX/System/IOPorts/DMA_IO.hpp b/include/PSX/System/IOPorts/DMA_IO.hpp new file mode 100644 index 00000000..8b787ed6 --- /dev/null +++ b/include/PSX/System/IOPorts/DMA_IO.hpp @@ -0,0 +1,142 @@ +#ifndef __JABYENGINE_DMA_IO_HPP__ +#define __JABYENGINE_DMA_IO_HPP__ +#include "IOPort.hpp" + +namespace DMA { + struct __no_align MADR : public IOPort { + __io_port_inherit(MADR); + + static constexpr BitRange MemoryAdr = BitRange::from_to(0, 23); + }; + + struct __no_align BCR : public IOPort { + __io_port_inherit(BCR); + + struct __no_align SyncMode0 { + static constexpr BitRange NumberOfWords = BitRange::from_to(0, 15); + static constexpr Bit CD_OneBlock = 16; + }; + + struct __no_align SyncMode1 { + static constexpr BitRange BlockSize = BitRange::from_to(0, 15); + static constexpr BitRange BlockAmount = BitRange::from_to(16, 31); + }; + + struct __no_align SyncMode2 { + }; + }; + + struct __no_align CHCHR : public IOPort { + __io_port_inherit(CHCHR); + + enum _SyncMode { + Sync0 = 0, //Start immediately, + Sync1 = 1, //Sync blocks to DMA requests + Sync2 = 2, //Linked List + }; + + static constexpr Bit ManualStart = 28; + + static constexpr Bit Start = 24; + static constexpr auto Busy = Start; + + static constexpr BitRange ChoppingCPUWindowSize = BitRange::from_to(20, 22); + static constexpr BitRange ChoppingDMAWindowSize = BitRange::from_to(16, 18); + + static constexpr BitRange<_SyncMode> SyncMode = BitRange<_SyncMode>::from_to(9, 10); + static constexpr auto UseSyncMode0 = (SyncMode << Sync0); + static constexpr auto UseSyncMode1 = (SyncMode << Sync1); + static constexpr auto UseSyncMode2 = (SyncMode << Sync2); + + static constexpr Bit UseChopping = 8; + + static constexpr Bit MemoryAdrDecreaseBy4 = 1; + static constexpr auto MemoryAdrIncreaseBy4 = !MemoryAdrDecreaseBy4; + + static constexpr Bit FromMainRAM = 0; + static constexpr auto ToMainRAM = !FromMainRAM; + + static constexpr CHCHR StartMDECin() { + return CHCHR(0x01000201); + } + + static constexpr CHCHR StartMDECout() { + return CHCHR(0x01000200); + } + + static constexpr CHCHR StartGPUReceive() { + return CHCHR(0x01000201); + } + + static constexpr CHCHR StartCDROM() { + return CHCHR(0x11000000); + } + + static constexpr CHCHR StartSPUReceive() { + return CHCHR(0x01000201); + } + + static constexpr CHCHR StartOTC() { + return CHCHR(0x11000002); + } + }; + + struct __no_align Registers { + MADR adr; + BCR block_ctrl; + CHCHR channel_ctrl; + }; + + //0: Highest, 7: Lowest + typedef uint32_t Priority; + static constexpr Priority HighestPriority = 0; + static constexpr Priority LowestPriority = 7; + + struct __no_align DMAControlRegister : public IOPort { + __io_port_inherit(DMAControlRegister); + + static constexpr Bit OTCEnable = 27; + static constexpr BitRange OTCPriority = BitRange::from_to(24, 26); + + static constexpr Bit PIOEnable = 23; + static constexpr BitRange PIOPriority = BitRange::from_to(20, 22); + + static constexpr Bit SPUEnable = 19; + static constexpr BitRange SPUPriority = BitRange::from_to(16, 18); + + static constexpr Bit CDROMEnable = 15; + static constexpr BitRange CDROMPriority = BitRange::from_to(12, 14); + + static constexpr Bit GPUEnable = 11; + static constexpr BitRange GPUPriority = BitRange::from_to(8, 10); + + static constexpr Bit MDECoutEnable = 7; + static constexpr BitRange MDECoutPriority = BitRange::from_to(4, 6); + + static constexpr Bit MDECinEnable = 3; + static constexpr BitRange MDECinPriority = BitRange::from_to(0, 2); + }; + + struct __no_align DMAInterruptRegister : public IOPort { + __io_port_inherit(DMAInterruptRegister); + + static constexpr Bit MasterEnable = 31; + static constexpr BitRange Flags = BitRange::from_to(24, 30); + static constexpr Bit MasterEnableDPCR = 23; + static constexpr BitRange EnableDPCR = BitRange::from_to(16, 22); + static constexpr Bit ForceIRQ = 15; + }; + + __declare_io_port_global(Registers, MDECin, 0x1F801080); + __declare_io_port_global(Registers, MDECout, 0x1F801090); + __declare_io_port_global(Registers, GPU, 0x1F8010A0); + __declare_io_port_global(Registers, CDROM, 0x1F8010B0); + __declare_io_port_global(Registers, SPU, 0x1F8010C0); + __declare_io_port_global(Registers, PIO, 0x1F8010D0); + __declare_io_port_global(Registers, OTC, 0x1F8010E0); + + __declare_io_port_global(DMAControlRegister, DPCR, 0x1F8010F0); + __declare_io_port_global(DMAInterruptRegister, DICR, 0x1F8010F4); +} + +#endif //!__JABYENGINE_DMA_IO_HPP__ \ No newline at end of file diff --git a/src/Library/src/BootLoader/boot_spu.cpp b/src/Library/src/BootLoader/boot_spu.cpp index 86b0d3ec..d898e67d 100644 --- a/src/Library/src/BootLoader/boot_spu.cpp +++ b/src/Library/src/BootLoader/boot_spu.cpp @@ -1,8 +1,9 @@ #include -#include +#include namespace SPU { using namespace Port; + using namespace DMA; static void clear_key() { Key::off.write(UI32_MAX); @@ -79,6 +80,7 @@ namespace SPU { setup_data_transfer_control(); setup_control_register(); - //DPCR missing + // Enable SPU DMA + DPCR.write(DPCR.read() | DMAControlRegister::SPUEnable); } } \ No newline at end of file