From 237e0b2edfe8939d58a8f8be38fbcb45011e5771 Mon Sep 17 00:00:00 2001 From: Jaby Date: Sun, 29 Sep 2024 16:30:41 +0200 Subject: [PATCH] Convert DMA IO --- .../System/IOPorts/IOValues/dma_io_values.hpp | 152 +++++++++++++++ include/PSX/System/IOPorts/dma_io.hpp | 181 ++---------------- .../internal-include/GPU/gpu_internal.hpp | 6 +- .../internal-include/SPU/spu_internal.hpp | 6 +- src/Library/src/BootLoader/dma_boot.cpp | 6 +- src/Library/src/CD/cd.cpp | 4 +- src/Library/src/GPU/gpu.cpp | 4 +- 7 files changed, 186 insertions(+), 173 deletions(-) create mode 100644 include/PSX/System/IOPorts/IOValues/dma_io_values.hpp diff --git a/include/PSX/System/IOPorts/IOValues/dma_io_values.hpp b/include/PSX/System/IOPorts/IOValues/dma_io_values.hpp new file mode 100644 index 00000000..3e3e9cc3 --- /dev/null +++ b/include/PSX/System/IOPorts/IOValues/dma_io_values.hpp @@ -0,0 +1,152 @@ +#pragma once +#include "../ioport.hpp" + +namespace JabyEngine { + namespace DMA_IO_Values { + using Priority = uint32_t; + static constexpr Priority HighestPriority = 0; + static constexpr Priority LowestPriority = 7; + + __declare_io_value(BCR, uint32_t) { + struct SyncMode0 { + static constexpr auto NumberOfWords = BitRange::from_to(0, 15); + static constexpr auto CD_OneBlock = Bit(16); + + static constexpr BCR for_cd(size_t words) { + return BCR::from(SyncMode0::CD_OneBlock, SyncMode0::NumberOfWords.with(words)); + } + }; + + struct SyncMode1 { + static constexpr auto BlockSize = BitRange::from_to(0, 15); + static constexpr auto BlockAmount = BitRange::from_to(16, 31); + }; + + struct SyncMode2 { + static constexpr BCR for_gpu_cmd() { + return {0}; + } + }; + }; + + __declare_io_value(CHCHR, uint32_t) { + enum SyncMode_t { + Sync0 = 0, //Start immediately, + Sync1 = 1, //Sync blocks to DMA requests + Sync2 = 2, //Linked List + }; + + static constexpr auto ManualStart = Bit(28); + + static constexpr auto Start = Bit(24); + static constexpr auto Busy = Start; + + static constexpr auto ChoppingCPUWindowSize = BitRange::from_to(20, 22); + static constexpr auto ChoppingDMAWindowSize = BitRange::from_to(16, 18); + + static constexpr auto SyncMode = BitRange::from_to(9, 10); + static constexpr auto UseSyncMode0 = SyncMode.with(Sync0); + static constexpr auto UseSyncMode1 = SyncMode.with(Sync1); + static constexpr auto UseSyncMode2 = SyncMode.with(Sync2); + + static constexpr auto UseChopping = Bit(8); + + static constexpr auto MemoryAdrDecreaseBy4 = Bit(1); + static constexpr auto MemoryAdrIncreaseBy4 = !MemoryAdrDecreaseBy4; + + static constexpr auto FromMainRAM = Bit(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 StartGPULinked() { + return CHCHR{0x01000401}; + } + + static constexpr CHCHR StartCDROM() { + return CHCHR{0x11000000}; + } + + static constexpr CHCHR StartSPUReceive() { + return CHCHR{0x01000201}; + } + + static constexpr CHCHR StartOTC() { + return CHCHR{0x11000002}; + } + }; + + __declare_io_value(DICR, uint32_t) { + static constexpr auto MasterEnable = Bit(31); + static constexpr auto Flags = BitRange::from_to(24, 30); + static constexpr auto MasterEnableDPCR = Bit(23); + static constexpr auto EnableDPCR = BitRange::from_to(16, 22); + static constexpr auto ForceIRQ = Bit(15); + + static constexpr DICR empty() { + return DICR{0}; + } + }; + + __declare_io_value(DPCR, uint32_t) { + struct DMASetting { + uint16_t master_bit; + + static constexpr DMASetting create(uint16_t master_bit) { + return DMASetting{master_bit}; + } + + constexpr BitRange::RangeValuePair turn_on(uint8_t priority) const { + return BitRange::from_to(this->master_bit - 3, this->master_bit).with(static_cast(0b1000 + (priority & 0b111))); + } + + constexpr ClearBit turn_off() const { + return ClearBit(this->master_bit); + } + }; + + static constexpr const auto OTC = DMASetting(27); + static constexpr const auto PIO = DMASetting(23); + static constexpr const auto SPU = DMASetting(19); + static constexpr const auto CDROM = DMASetting(15); + static constexpr const auto GPU = DMASetting(11); + static constexpr const auto MDEC_Out = DMASetting(7); + static constexpr const auto MDEC_In = DMASetting(3); + + static constexpr auto OTCEnabled = Bit(27); + static constexpr auto OTCPriority = BitRange::from_to(24, 26); + + static constexpr auto PIOEnabled = Bit(23); + static constexpr auto PIOPriority = BitRange::from_to(20, 22); + + static constexpr auto SPUEnabled = Bit(19); + static constexpr auto SPUPriority = BitRange::from_to(16, 18); + + static constexpr auto CDROMEnabled = Bit(15); + static constexpr auto CDROMPriority = BitRange::from_to(12, 14); + + static constexpr auto GPUEnabled = Bit(11); + static constexpr auto GPUPriority = BitRange::from_to(8, 10); + + static constexpr auto MDECoutEnabled = Bit(7); + static constexpr auto MDECoutPriority = BitRange::from_to(4, 6); + + static constexpr auto MDECinEnabled = Bit(3); + static constexpr auto MDECinPriority = BitRange::from_to(0, 2); + }; + + __declare_io_value(MADR, uint32_t) { + static constexpr auto MemoryAdr = BitRange::from_to(0, 23); + }; + } +} \ No newline at end of file diff --git a/include/PSX/System/IOPorts/dma_io.hpp b/include/PSX/System/IOPorts/dma_io.hpp index f13576e9..98d491b7 100644 --- a/include/PSX/System/IOPorts/dma_io.hpp +++ b/include/PSX/System/IOPorts/dma_io.hpp @@ -1,180 +1,39 @@ #pragma once -#include "ioport.hpp" +#include "IOValues/dma_io_values.hpp" namespace JabyEngine { namespace DMA_IO { - __declare_io_value(MADR, uint32_t) { - static constexpr auto MemoryAdr = BitRange::from_to(0, 23); - }; - - __declare_io_value(BCR, uint32_t) { - struct SyncMode0 { - static constexpr auto NumberOfWords = BitRange::from_to(0, 15); - static constexpr auto CD_OneBlock = Bit(16); - - static constexpr BCR for_cd(size_t words) { - return BCR::from(SyncMode0::CD_OneBlock, SyncMode0::NumberOfWords.with(words)); - } - }; - - struct SyncMode1 { - static constexpr auto BlockSize = BitRange::from_to(0, 15); - static constexpr auto BlockAmount = BitRange::from_to(16, 31); - }; - - struct SyncMode2 { - static constexpr BCR for_gpu_cmd() { - return {0}; - } - }; - }; - - __declare_io_value(CHCHR, uint32_t) { - enum SyncMode_t { - Sync0 = 0, //Start immediately, - Sync1 = 1, //Sync blocks to DMA requests - Sync2 = 2, //Linked List - }; - - static constexpr auto ManualStart = Bit(28); - - static constexpr auto Start = Bit(24); - static constexpr auto Busy = Start; - - static constexpr auto ChoppingCPUWindowSize = BitRange::from_to(20, 22); - static constexpr auto ChoppingDMAWindowSize = BitRange::from_to(16, 18); - - static constexpr auto SyncMode = BitRange::from_to(9, 10); - static constexpr auto UseSyncMode0 = SyncMode.with(Sync0); - static constexpr auto UseSyncMode1 = SyncMode.with(Sync1); - static constexpr auto UseSyncMode2 = SyncMode.with(Sync2); - - static constexpr auto UseChopping = Bit(8); - - static constexpr auto MemoryAdrDecreaseBy4 = Bit(1); - static constexpr auto MemoryAdrIncreaseBy4 = !MemoryAdrDecreaseBy4; - - static constexpr auto FromMainRAM = Bit(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 StartGPULinked() { - return CHCHR{0x01000401}; - } - - static constexpr CHCHR StartCDROM() { - return CHCHR{0x11000000}; - } - - static constexpr CHCHR StartSPUReceive() { - return CHCHR{0x01000201}; - } - - static constexpr CHCHR StartOTC() { - return CHCHR{0x11000002}; - } - }; + using BCR_IO = IOPort; + using CHCHR_IO = IOPort; + using DICR_IO = IOPort; + using DPCR_IO = IOPort; + using MADR_IO = IOPort; #pragma pack(push, 1) struct Registers { - IOPort adr; - IOPort block_ctrl; - IOPort channel_ctrl; + MADR_IO adr; + BCR_IO block_ctrl; + CHCHR_IO channel_ctrl; inline void set_adr(uintptr_t adr) { - this->adr.write({bit::value::set_normalized(0u, MADR::MemoryAdr.with(adr))}); + this->adr.write({bit::value::set_normalized(0u, DMA_IO_Values::MADR::MemoryAdr.with(adr))}); } inline void wait() { - while(this->channel_ctrl.read().is_set(CHCHR::Busy)); + while(this->channel_ctrl.read().is_set(DMA_IO_Values::CHCHR::Busy)); } }; #pragma pack(pop) - //0: Highest, 7: Lowest - typedef uint32_t Priority; - static constexpr Priority HighestPriority = 0; - static constexpr Priority LowestPriority = 7; + static auto& MDECin = __new_declare_io_value(Registers, 0x1F801080); + static auto& MDECout = __new_declare_io_value(Registers, 0x1F801090); + static auto& GPU = __new_declare_io_value(Registers, 0x1F8010A0); + static auto& CDROM = __new_declare_io_value(Registers, 0x1F8010B0); + static auto& SPU = __new_declare_io_value(Registers, 0x1F8010C0); + static auto& PIO = __new_declare_io_value(Registers, 0x1F8010D0); + static auto& OTC = __new_declare_io_value(Registers, 0x1F8010E0); - __declare_io_value(DPCR, uint32_t) { - struct DMASetting { - uint16_t master_bit; - - static constexpr DMASetting create(uint16_t master_bit) { - return DMASetting{master_bit}; - } - - constexpr BitRange::RangeValuePair turn_on(uint8_t priority) const { - return BitRange::from_to(this->master_bit - 3, this->master_bit).with(static_cast(0b1000 + (priority & 0b111))); - } - - constexpr ClearBit turn_off() const { - return ClearBit(this->master_bit); - } - }; - - static constexpr const auto OTC = DMASetting(27); - static constexpr const auto PIO = DMASetting(23); - static constexpr const auto SPU = DMASetting(19); - static constexpr const auto CDROM = DMASetting(15); - static constexpr const auto GPU = DMASetting(11); - static constexpr const auto MDEC_Out = DMASetting(7); - static constexpr const auto MDEC_In = DMASetting(3); - - static constexpr auto OTCEnabled = Bit(27); - static constexpr auto OTCPriority = BitRange::from_to(24, 26); - - static constexpr auto PIOEnabled = Bit(23); - static constexpr auto PIOPriority = BitRange::from_to(20, 22); - - static constexpr auto SPUEnabled = Bit(19); - static constexpr auto SPUPriority = BitRange::from_to(16, 18); - - static constexpr auto CDROMEnabled = Bit(15); - static constexpr auto CDROMPriority = BitRange::from_to(12, 14); - - static constexpr auto GPUEnabled = Bit(11); - static constexpr auto GPUPriority = BitRange::from_to(8, 10); - - static constexpr auto MDECoutEnabled = Bit(7); - static constexpr auto MDECoutPriority = BitRange::from_to(4, 6); - - static constexpr auto MDECinEnabled = Bit(3); - static constexpr auto MDECinPriority = BitRange::from_to(0, 2); - }; - - __declare_io_value(DICR, uint32_t) { - static constexpr auto MasterEnable = Bit(31); - static constexpr auto Flags = BitRange::from_to(24, 30); - static constexpr auto MasterEnableDPCR = Bit(23); - static constexpr auto EnableDPCR = BitRange::from_to(16, 22); - static constexpr auto ForceIRQ = Bit(15); - - static constexpr DICR empty() { - return DICR{0}; - } - }; - - __declare_value_at(, Registers, MDECin, 0x1F801080); - __declare_value_at(, Registers, MDECout, 0x1F801090); - __declare_value_at(, Registers, GPU, 0x1F8010A0); - __declare_value_at(, Registers, CDROM, 0x1F8010B0); - __declare_value_at(, Registers, SPU, 0x1F8010C0); - __declare_value_at(, Registers, PIO, 0x1F8010D0); - __declare_value_at(, Registers, OTC, 0x1F8010E0); - - __declare_io_port(, DPCR, 0x1F8010F0); - __declare_io_port(, DICR, 0x1F8010F4); + static auto& DPCR = __new_declare_io_port(DPCR_IO, 0x1F8010F0); + static auto& DICR = __new_declare_io_port(DICR_IO, 0x1F8010F4); } } \ No newline at end of file diff --git a/src/Library/internal-include/GPU/gpu_internal.hpp b/src/Library/internal-include/GPU/gpu_internal.hpp index 7353ac81..bc55ba9c 100644 --- a/src/Library/internal-include/GPU/gpu_internal.hpp +++ b/src/Library/internal-include/GPU/gpu_internal.hpp @@ -98,14 +98,14 @@ namespace JabyEngine { } static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { - using SyncMode1 = DMA_IO::BCR::SyncMode1; + using SyncMode1 = DMA_IO_Values::BCR::SyncMode1; #ifdef __SUPPORT_PS3__ DMA_IO::GPU.set_adr(MADR); DMA::MADR += (blockCount * wordsPerBlock) << 2; #endif // __SUPPORT_PS3__ - DMA_IO::GPU.block_ctrl.write(DMA_IO::BCR::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount))); - DMA_IO::GPU.channel_ctrl.write(DMA_IO::CHCHR::StartGPUReceive()); + DMA_IO::GPU.block_ctrl.write(DMA_IO_Values::BCR::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount))); + DMA_IO::GPU.channel_ctrl.write(DMA_IO_Values::CHCHR::StartGPUReceive()); } }; }; diff --git a/src/Library/internal-include/SPU/spu_internal.hpp b/src/Library/internal-include/SPU/spu_internal.hpp index 7287d51c..dc2c7120 100644 --- a/src/Library/internal-include/SPU/spu_internal.hpp +++ b/src/Library/internal-include/SPU/spu_internal.hpp @@ -32,10 +32,10 @@ namespace JabyEngine { } static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { - using SyncMode1 = DMA_IO::BCR::SyncMode1; + using SyncMode1 = DMA_IO_Values::BCR::SyncMode1; - DMA_IO::SPU.block_ctrl.write(DMA_IO::BCR::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount))); - DMA_IO::SPU.channel_ctrl.write(DMA_IO::CHCHR::StartSPUReceive()); + DMA_IO::SPU.block_ctrl.write(DMA_IO_Values::BCR::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount))); + DMA_IO::SPU.channel_ctrl.write(DMA_IO_Values::CHCHR::StartSPUReceive()); } }; }; diff --git a/src/Library/src/BootLoader/dma_boot.cpp b/src/Library/src/BootLoader/dma_boot.cpp index 400b721f..b844393a 100644 --- a/src/Library/src/BootLoader/dma_boot.cpp +++ b/src/Library/src/BootLoader/dma_boot.cpp @@ -6,10 +6,12 @@ namespace JabyEngine { namespace boot { namespace DMA { void setup() { - static constexpr auto EnableDMA = DMA_IO::DPCR::from(DMA_IO::DPCR::SPU.turn_on(3), DMA_IO::DPCR::GPU.turn_on(3), DMA_IO::DPCR::CDROM.turn_on(3)); + static constexpr auto EnableDMA = DMA_IO_Values::DPCR::from( + DMA_IO_Values::DPCR::SPU.turn_on(3), DMA_IO_Values::DPCR::GPU.turn_on(3), DMA_IO_Values::DPCR::CDROM.turn_on(3) + ); DMA_IO::DPCR.write(EnableDMA); - DMA_IO::DICR.write(DMA_IO::DICR::empty()); + DMA_IO::DICR.write(DMA_IO_Values::DICR::empty()); // ACK IRQ DMA_IO::DICR.write(DMA_IO::DICR.read()); diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index a04f1bd8..f7286b53 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -74,8 +74,8 @@ namespace JabyEngine { static const auto ReadSector = [](uint32_t* dst, size_t bytes) { DMA_IO::CDROM.set_adr(reinterpret_cast(dst)); - DMA_IO::CDROM.block_ctrl.write(DMA_IO::BCR::SyncMode0::for_cd(bytes >> 2)); - DMA_IO::CDROM.channel_ctrl.write(DMA_IO::CHCHR::StartCDROM()); + DMA_IO::CDROM.block_ctrl.write(DMA_IO_Values::BCR::SyncMode0::for_cd(bytes >> 2)); + DMA_IO::CDROM.channel_ctrl.write(DMA_IO_Values::CHCHR::StartCDROM()); DMA_IO::CDROM.wait(); CD_IO::PortIndex0::change_to(); diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index 42ea622a..37aca7e3 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -74,10 +74,10 @@ namespace JabyEngine { DMA_IO::GPU.wait(); GPU_IO::GP1.set_dma_direction(GPU_IO_Values::GPUSTAT::DMADirection::CPU2GPU); DMA_IO::GPU.set_adr(reinterpret_cast(data)); - DMA_IO::GPU.block_ctrl.write(DMA_IO::BCR::SyncMode2::for_gpu_cmd()); + DMA_IO::GPU.block_ctrl.write(DMA_IO_Values::BCR::SyncMode2::for_gpu_cmd()); wait_ready_for_CMD(); - DMA_IO::GPU.channel_ctrl.write(DMA_IO::CHCHR::StartGPULinked()); + DMA_IO::GPU.channel_ctrl.write(DMA_IO_Values::CHCHR::StartGPULinked()); } }