From bbfa7a24c823041677fafa897ecefa592b3505b5 Mon Sep 17 00:00:00 2001 From: Jaby Date: Mon, 20 Mar 2023 19:06:28 +0100 Subject: [PATCH] Port GPU IOs --- include/PSX/GPU/gpu.hpp | 4 +- include/PSX/System/IOPorts/gpu_io.hpp | 252 +++++++++++++---------- include/PSX/System/IOPorts/ioport.hpp | 8 +- src/Library/include/GPU/gpu_internal.hpp | 61 ++---- src/Library/src/BootLoader/gpu_boot.cpp | 2 +- src/Library/src/GPU/gpu.cpp | 10 +- 6 files changed, 173 insertions(+), 164 deletions(-) diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 2960d8e3..5952091a 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -22,11 +22,11 @@ namespace JabyEngine { #endif static void enable() { - GPU_IO::GP1.write(GPU_IO::Command::GP1::SetDisplayState(GPU_IO::DisplayState::On)); + GPU_IO::GP1 = *GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::On); } static void disable() { - GPU_IO::GP1.write(GPU_IO::Command::GP1::SetDisplayState(GPU_IO::DisplayState::Off)); + GPU_IO::GP1 = *GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::Off); } }; diff --git a/include/PSX/System/IOPorts/gpu_io.hpp b/include/PSX/System/IOPorts/gpu_io.hpp index b5f4bf0c..9e21b3a3 100644 --- a/include/PSX/System/IOPorts/gpu_io.hpp +++ b/include/PSX/System/IOPorts/gpu_io.hpp @@ -47,124 +47,162 @@ namespace JabyEngine { Off = 1 }; - struct Command { - struct GP0 : public ComplexBitMap { - - static constexpr GP0 QuickFill(GPU::Color24 color) { - return {(0x02 << 24) | color.raw()}; - } - - static constexpr GP0 CPU2VRAM_Blitting() { - return {(0b101u << 29)}; - } - - static constexpr GP0 DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) { - constexpr auto Command = BitRange::from_to(24, 31); - constexpr auto Y = BitRange::from_to(10, 18); - constexpr auto X = BitRange::from_to(0, 9); - - return {GP0::with(Command.with(code), Y.with(y), X.with(x))}; - } - - static constexpr GP0 DrawAreaTopLeft(uint16_t x, uint16_t y) { - return DrawAreaTemplate(0xE3, x, y); - } - - static constexpr GP0 DrawAreaBottomRight(uint16_t x, uint16_t y) { - return DrawAreaTemplate(0xE4, x, y); - } - - static constexpr GP0 TopLeftPosition(uint16_t x, uint16_t y) { - return {static_cast((y << 16u) | x)}; - } - - static constexpr GP0 WidthHeight(uint16_t w, uint16_t h) { - return {static_cast((h << 16u) | w)}; - } + __declare_io_type(DisplayMode, uint32_t, + enum struct TVEncoding { + NTSC = 0, + PAL = 1, }; - struct GP1 : public ComplexBitMap { + static constexpr auto HorizontalResolution368 = IOBitSet(6); + static constexpr auto VerticalInterlace = IOBitSet(5); + static constexpr auto DisplayAreaColorDepth = IOValueSet::from_to(4, 4); + static constexpr auto VideoMode = IOValueSet::from_to(3, 3); + static constexpr auto VerticalResolution = IOValueSet::from_to(2, 2); + static constexpr auto HorizontalResolution = IOValueSet::from_to(0, 1); + + static constexpr Self PAL() { + return Self::from( + HorizontalResolution.with(GPU_IO::HorizontalResolution::$320), + VerticalResolution.with(GPU_IO::VerticalResolution::$240), + VideoMode.with(TVEncoding::PAL), + DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit) + ); + } + + static constexpr Self NTSC() { + return Self::from( + HorizontalResolution.with(GPU_IO::HorizontalResolution::$320), + VerticalResolution.with(GPU_IO::VerticalResolution::$240), + VideoMode.with(TVEncoding::NTSC), + DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit) + ); + } + ); + + __declare_io_type(GP0, uint32_t, + ); + + __declare_io_type(GP1, uint32_t, + ); + + + struct Command { + struct Helper { + static constexpr GP0_t DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) { + constexpr auto Command = IOValueSet::from_to(24, 31); + constexpr auto Y = IOValueSet::from_to(10, 18); + constexpr auto X = IOValueSet::from_to(0, 9); + + return GP0_t::from(Command.with(code), Y.with(y), X.with(x)); + } + static constexpr uint32_t construct_cmd(uint8_t cmd, uint32_t value) { return ((cmd << 24) | value); } - - static constexpr GP1 Reset() { - return {0}; - } - - static constexpr GP1 ResetCMDBufer() { - return {construct_cmd(0x01, 0)}; - } - - static constexpr GP1 SetDisplayState(DisplayState state) { - return {construct_cmd(0x03, static_cast(state))}; - } - - static constexpr GP1 DMADirection(DMADirection dir) { - return {construct_cmd(0x04, static_cast(dir))}; - } - - static constexpr GP1 DisplayArea(uint16_t x, uint16_t y) { - constexpr auto X = BitRange::from_to(0, 9); - constexpr auto Y = BitRange::from_to(10, 18); - - return {construct_cmd(0x05, ComplexBitMap::with(X.with(x), Y.with(y)).raw)}; - } - - static constexpr GP1 HorizontalDisplayRange(uint32_t x1, uint32_t x2) { - constexpr auto X1 = BitRange::from_to(0, 11); - constexpr auto X2 = BitRange::from_to(12, 23); - - return {construct_cmd(0x06, ComplexBitMap::with(X1.with(x1), X2.with(x2)).raw)}; - } - - static constexpr GP1 VerticalDisplayRange(uint32_t y1, uint32_t y2) { - constexpr auto Y1 = BitRange::from_to(0, 9); - constexpr auto Y2 = BitRange::from_to(10, 19); - - return {construct_cmd(0x07, ComplexBitMap::with(Y1.with(y1), Y2.with(y2)).raw)}; - } - - static constexpr GP1 DisplayMode(uint32_t mode) { - return {construct_cmd(0x08, mode)}; - } }; + + static constexpr GP0_t QuickFill(GPU::Color24 color) { + return {(0x02 << 24) | color.raw()}; + } + + static constexpr GP0_t CPU2VRAM_Blitting() { + return {(0b101u << 29)}; + } + + static constexpr GP0_t DrawAreaTopLeft(uint16_t x, uint16_t y) { + return Helper::DrawAreaTemplate(0xE3, x, y); + } + + static constexpr GP0_t DrawAreaBottomRight(uint16_t x, uint16_t y) { + return Helper::DrawAreaTemplate(0xE4, x, y); + } + + static constexpr GP0_t TopLeftPosition(uint16_t x, uint16_t y) { + return {static_cast((y << 16u) | x)}; + } + + static constexpr GP0_t WidthHeight(uint16_t w, uint16_t h) { + return {static_cast((h << 16u) | w)}; + } + + static constexpr GP1_t Reset() { + return {0}; + } + + static constexpr GP1_t ResetCMDBufer() { + return {Helper::construct_cmd(0x01, 0)}; + } + + static constexpr GP1_t SetDisplayState(DisplayState state) { + return {Helper::construct_cmd(0x03, static_cast(state))}; + } + + static constexpr GP1_t DMADirection(DMADirection dir) { + return {Helper::construct_cmd(0x04, static_cast(dir))}; + } + + static constexpr GP1_t DisplayArea(uint16_t x, uint16_t y) { + constexpr auto X = BitRange::from_to(0, 9); + constexpr auto Y = BitRange::from_to(10, 18); + + return {Helper::construct_cmd(0x05, ComplexBitMap::with(X.with(x), Y.with(y)).raw)}; + } + + static constexpr GP1_t HorizontalDisplayRange(uint32_t x1, uint32_t x2) { + constexpr auto X1 = BitRange::from_to(0, 11); + constexpr auto X2 = BitRange::from_to(12, 23); + + return {Helper::construct_cmd(0x06, ComplexBitMap::with(X1.with(x1), X2.with(x2)).raw)}; + } + + static constexpr GP1_t VerticalDisplayRange(uint32_t y1, uint32_t y2) { + constexpr auto Y1 = BitRange::from_to(0, 9); + constexpr auto Y2 = BitRange::from_to(10, 19); + + return {Helper::construct_cmd(0x07, ComplexBitMap::with(Y1.with(y1), Y2.with(y2)).raw)}; + } + + static constexpr GP1_t DisplayMode(DisplayMode_t mode) { + return {Helper::construct_cmd(0x08, *mode)}; + } }; - struct GPUStatusRegister : public ComplexBitMap { - static constexpr auto DrawingOddLinesInterlaced = Bit(31); - static constexpr auto DMADirectionValue = BitRange::from_to(29, 30); - static constexpr auto DMAReady = Bit(28); - static constexpr auto VRAMtoCPUtransferReay = Bit(27); - static constexpr auto GP0ReadyForCMD = Bit(26); - static constexpr auto FifoNotFull = Bit(25); // Only for Fifo - static constexpr auto InterruptRequest = Bit(24); - static constexpr auto DisplayDisabled = Bit(23); - static constexpr auto VerticalInterlaceOn = Bit(22); - static constexpr auto DisplayAreaColorDepth = BitRange::from_to(21, 21); - static constexpr auto VideoModePal = Bit(20); - static constexpr auto VerticalResolutionValue = BitRange::from_to(19, 19); - static constexpr auto HorizontalResolutionValue = BitRange::from_to(17, 18); - static constexpr auto HorizontalResolution368 = Bit(16); - static constexpr auto TexturesDisabled = Bit(15); - static constexpr auto NotDrawingMaskedPixels = Bit(12); - static constexpr auto MaskBitSetDuringDrawEnabled = Bit(11); - static constexpr auto DrawingToDisplayAreadAllowed = Bit(10); - static constexpr auto DitherEnabled = Bit(9); - static constexpr auto TexturePageColorValue = BitRange::from_to(7, 8); - static constexpr auto SemiTransparencyValue = BitRange::from_to(5, 6); - static constexpr auto TexturePageY = BitRange::from_to(4, 4); // N*256 - static constexpr auto TexturePageX = BitRange::from_to(0, 3); // N*64 + __declare_io_type(GPUSTAT, uint32_t, + static constexpr auto DrawingOddLinesInterlaced = IOBitSet(31); + static constexpr auto DMADirectionValue = IOValueSet::from_to(29, 30); + static constexpr auto DMAReady = IOBitSet(28); + static constexpr auto VRAMtoCPUtransferReay = IOBitSet(27); + static constexpr auto GP0ReadyForCMD = IOBitSet(26); + static constexpr auto FifoNotFull = IOBitSet(25); // Only for Fifo + static constexpr auto InterruptRequest = IOBitSet(24); + static constexpr auto DisplayDisabled = IOBitSet(23); + static constexpr auto VerticalInterlaceOn = IOBitSet(22); + static constexpr auto DisplayAreaColorDepth = IOValueSet::from_to(21, 21); + static constexpr auto VideoModePal = IOBitSet(20); + static constexpr auto VerticalResolutionValue = IOValueSet::from_to(19, 19); + static constexpr auto HorizontalResolutionValue = IOValueSet::from_to(17, 18); + static constexpr auto HorizontalResolution368 = IOBitSet(16); + static constexpr auto TexturesDisabled = IOBitSet(15); + static constexpr auto NotDrawingMaskedPixels = IOBitSet(12); + static constexpr auto MaskBitSetDuringDrawEnabled = IOBitSet(11); + static constexpr auto DrawingToDisplayAreadAllowed = IOBitSet(10); + static constexpr auto DitherEnabled = IOBitSet(9); + static constexpr auto TexturePageColorValue = IOValueSet::from_to(7, 8); + static constexpr auto SemiTransparencyValue = IOValueSet::from_to(5, 6); + static constexpr auto TexturePageY = IOValueSet::from_to(4, 4); // N*256 + static constexpr auto TexturePageX = IOValueSet::from_to(0, 3); // N*64 - static constexpr auto VerticalResolution480 = Bit(19); - static constexpr auto TexturePageY256 = Bit(4); - }; + static constexpr auto VerticalResolution480 = IOBitSet(19); + static constexpr auto TexturePageY256 = IOBitSet(4); + ); - __declare_io_port_global(Command::GP0, GP0, 0x1F801810); - __declare_io_port_global(Command::GP1, GP1, 0x1F801814); + typedef volatile uint32_t GPUREAD_v; - __declare_io_port_global_const_simple(uint32_t, GPUREAD, 0x1F801810); - __declare_io_port_global_const(GPUStatusRegister, GPUSTAT, 0x1F801814); + __declare_new_io_port(GP0, 0x1F801810); + __declare_new_io_port(GP1, 0x1F801814); + + __declare_new_const_io_port(GPUREAD, 0x1F801810); + __declare_new_const_io_port(GPUSTAT, 0x1F801814); } } #endif //!__JABYENGINE_GPU_IO_HPP__ \ No newline at end of file diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 8d24f618..c3132268 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -57,6 +57,9 @@ namespace JabyEngine { #define __declare_new_io_port(name, adr) \ __declare_new_named_io_port(name, name, adr) + + #define __declare_new_const_io_port(name, adr) \ + __declare_new_named_io_port(const name, name, adr) #define __declare_new_io_port_array(name, adr, size) \ static inline auto& name = reinterpret_cast(*reinterpret_cast(adr)) @@ -88,8 +91,9 @@ namespace JabyEngine { return *this; \ } \ \ - constexpr name##_io_base& set(const IOValueSet::IOValueSetPair& value) { \ - this->set(value.first, value.second); \ + template \ + constexpr name##_io_base& set(const IOValueSet::IOValueSetPair& value) { \ + this->set(value.first, static_cast(value.second)); \ return *this; \ } \ \ diff --git a/src/Library/include/GPU/gpu_internal.hpp b/src/Library/include/GPU/gpu_internal.hpp index 7d2b89e2..fd042bca 100644 --- a/src/Library/include/GPU/gpu_internal.hpp +++ b/src/Library/include/GPU/gpu_internal.hpp @@ -8,50 +8,18 @@ namespace JabyEngine { namespace GPU { namespace internal { struct Screen { - struct Mode { - enum struct TVEncoding { - NTSC = 0, - PAL = 1, - }; - - static constexpr auto HorizontalResolution368 = Bit(6); - static constexpr auto VerticalInterlace = Bit(5); - static constexpr auto DisplayAreaColorDepth = BitRange::from_to(4, 4); - static constexpr auto VideoMode = BitRange::from_to(3, 3); - static constexpr auto VerticalResolution = BitRange::from_to(2, 2); - static constexpr auto HorizontalResolution = BitRange::from_to(0, 1); - - static constexpr uint32_t PAL() { - return ComplexBitMap::with( - Mode::HorizontalResolution.with(GPU_IO::HorizontalResolution::$320), - Mode::VerticalResolution.with(GPU_IO::VerticalResolution::$240), - Mode::VideoMode.with(TVEncoding::PAL), - Mode::DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit) - ).raw; - } - - static constexpr uint32_t NTSC() { - return ComplexBitMap::with( - Mode::HorizontalResolution.with(GPU_IO::HorizontalResolution::$320), - Mode::VerticalResolution.with(GPU_IO::VerticalResolution::$240), - Mode::VideoMode.with(TVEncoding::NTSC), - Mode::DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit) - ).raw; - } - }; - static void configurate() { static constexpr uint16_t FirstVisiblePixelH = 0x260; #ifdef JABYENGINE_PAL static constexpr uint16_t FirstVisiblePixelV = 0xA3; - GPU_IO::GP1.write(GPU_IO::Command::GP1::DisplayMode(Mode::PAL())); + GPU_IO::GP1 = *GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::PAL()); GPU::Screen::set_offset(0, 0); #else static constexpr uint16_t FirstVisiblePixelV = 0x88; - GPU_IO::GP1.write(GPU_IO::Command::GP1::DisplayMode(Mode::NTSC())); + GPU_IO::GP1 = *GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::NTSC()); GPU::Screen::set_offset(0, 5); //< Random values #endif } @@ -60,22 +28,22 @@ namespace JabyEngine { }; static void set_draw_area(uint16_t x, uint16_t y) { - GPU_IO::GP0.write(GPU_IO::Command::GP0::DrawAreaTopLeft(x, y)); - GPU_IO::GP0.write(GPU_IO::Command::GP0::DrawAreaBottomRight((x + Display::Width), (y + Display::Height))); + GPU_IO::GP0 = *GPU_IO::Command::DrawAreaTopLeft(x, y); + GPU_IO::GP0 = *GPU_IO::Command::DrawAreaBottomRight((x + Display::Width), (y + Display::Height)); } static void quick_fill_fast(const Color24& color, const PositionU16& pos, const SizeU16& size) { - GPU_IO::GP0.write(GPU_IO::Command::GP0::QuickFill(color)); - GPU_IO::GP0.write(GPU_IO::Command::GP0::TopLeftPosition(pos.x, pos.y)); - GPU_IO::GP0.write(GPU_IO::Command::GP0::WidthHeight(size.width, size.height)); + GPU_IO::GP0 = *GPU_IO::Command::QuickFill(color); + GPU_IO::GP0 = *GPU_IO::Command::TopLeftPosition(pos.x, pos.y); + GPU_IO::GP0 = *GPU_IO::Command::WidthHeight(size.width, size.height); } static void reset_cmd_buffer() { - GPU_IO::GP1.write(GPU_IO::Command::GP1::ResetCMDBufer()); + GPU_IO::GP1 = *GPU_IO::Command::ResetCMDBufer(); } static void wait_ready_for_CMD() { - while(!GPU_IO::GPUSTAT.read().is(GPU_IO::GPUStatusRegister::GP0ReadyForCMD)); + while(!GPU_IO::GPUSTAT.is_set(GPU_IO::GPUSTAT_t::GP0ReadyForCMD)); } namespace DMA { @@ -88,9 +56,8 @@ namespace JabyEngine { } namespace Receive { - static void prepare() - { - GPU_IO::GP1.write(GPU_IO::Command::GP1::DMADirection(GPU_IO::DMADirection::CPU2GPU)); + static void prepare() { + GPU_IO::GP1 = *GPU_IO::Command::DMADirection(GPU_IO::DMADirection::CPU2GPU); reset_cmd_buffer(); } @@ -100,9 +67,9 @@ namespace JabyEngine { static void set_dst(const PositionU16& position, const SizeU16& size) { wait_ready_for_CMD(); - GPU_IO::GP0.write(GPU_IO::Command::GP0::CPU2VRAM_Blitting()); - GPU_IO::GP0.write(GPU_IO::Command::GP0::TopLeftPosition(position.x, position.y)); - GPU_IO::GP0.write(GPU_IO::Command::GP0::WidthHeight(size.width, size.height)); + GPU_IO::GP0 = *GPU_IO::Command::CPU2VRAM_Blitting(); + GPU_IO::GP0 = *GPU_IO::Command::TopLeftPosition(position.x, position.y); + GPU_IO::GP0 = *GPU_IO::Command::WidthHeight(size.width, size.height); } static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index 9f4eca69..064961f8 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -49,7 +49,7 @@ namespace JabyEngine { } void setup() { - GPU_IO::GP1.write(GPU_IO::Command::GP1::Reset()); + GPU_IO::GP1 = *GPU_IO::Command::Reset(); internal::Screen::configurate(); internal::Screen::exchange_buffer_and_display(); diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index 31a1cc91..6474edf0 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -16,7 +16,7 @@ namespace JabyEngine { void Screen :: exchange_buffer_and_display() { GPU::internal::set_draw_area(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID)); PublicScreenClass::CurrentDisplayAreaID ^= 1; - GPU_IO::GP1.write(GPU_IO::Command::GP1::DisplayArea(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID))); + GPU_IO::GP1 = *GPU_IO::Command::DisplayArea(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID)); } } @@ -25,13 +25,13 @@ namespace JabyEngine { x += 78; y += 43; - GPU_IO::GP1.write(GPU_IO::Command::GP1::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3)); - GPU_IO::GP1.write(GPU_IO::Command::GP1::VerticalDisplayRange(y, y + Display::Height)); + GPU_IO::GP1 = *GPU_IO::Command::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3); + GPU_IO::GP1 = *GPU_IO::Command::VerticalDisplayRange(y, y + Display::Height); } #else void Screen :: set_offset(uint16_t x, uint16_t y) { - GP1.write(Command::GP1::HorizontalDisplayRange(x, (x + Display::Width*8))); - GP1.write(Command::GP1::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2))); + GPU_IO::GP1 = *GPU_IO::Command::HorizontalDisplayRange(x, (x + Display::Width*8)); + GPU_IO::GP1 = *GPU_IO::Command::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2)); } #endif //USE_NO$PSX }