diff --git a/include/PSX/GPU/GPU.hpp b/include/PSX/GPU/GPU.hpp index b752ecaf..698532a3 100644 --- a/include/PSX/GPU/GPU.hpp +++ b/include/PSX/GPU/GPU.hpp @@ -30,7 +30,11 @@ namespace GPU { } namespace Screen { - void set_offset(uint16_t x, uint16_t y); + extern uint8_t CurrentDisplayAreaID; + + namespace Range { + void set_offset(uint16_t x, uint16_t y); + } } } diff --git a/include/PSX/System/IOPorts/GPU_IO.hpp b/include/PSX/System/IOPorts/GPU_IO.hpp index 988a0f3c..a076e437 100644 --- a/include/PSX/System/IOPorts/GPU_IO.hpp +++ b/include/PSX/System/IOPorts/GPU_IO.hpp @@ -58,6 +58,22 @@ namespace GPU { return ComplexBitMap{(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 ComplexBitMap::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 ComplexBitMap{static_cast((y << 16u) | x)}; } diff --git a/src/Library/include/GPU/GPU.hpp b/src/Library/include/GPU/GPU.hpp index 85cf0bbd..bddb7c4d 100644 --- a/src/Library/include/GPU/GPU.hpp +++ b/src/Library/include/GPU/GPU.hpp @@ -45,14 +45,21 @@ namespace GPU { static constexpr uint16_t FirstVisiblePixelV = 0xA3; GP1.write(Command::GP1::DisplayMode(Mode::PAL())); - GPU::Screen::set_offset(78, 43); + GPU::Screen::Range::set_offset(0, 0); #else static constexpr uint16_t FirstVisiblePixelV = 0x88; GP1.write(Command::GP1::DisplayMode(Mode::NTSC())); - GPU::Screen::set_offset(78, 45); + GPU::Screen::set_offset(0, 5); //< Random values #endif } + + void exchange_buffer_and_display(); + } + + static void set_draw_area(uint16_t x, uint16_t y) { + GP0.write(Command::GP0::DrawAreaTopLeft(x, y)); + GP0.write(Command::GP0::DrawAreaBottomRight((x + Display::Width), (y + Display::Height))); } static void quick_fill_fast(const Color24& color, const PositionU16& pos, const SizeU16& size) { diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index 15bca7ce..622c2a55 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -18,8 +18,8 @@ namespace GPU { void setup() { GP1.write(Command::GP1::Reset()); Screen::configurate(); + Screen::exchange_buffer_and_display(); - quick_fill_fast(Color24::Black(), PositionU16(0, 0), SizeU16(640, 480)); - GP1.write(Command::GP1::DisplayArea(0, 0)); + quick_fill_fast(Color24::Black(), PositionU16(0, 0), SizeU16(640, 512)); } } \ No newline at end of file diff --git a/src/Library/src/GPU/GPU.cpp b/src/Library/src/GPU/GPU.cpp index bc2e363f..1aeaea3f 100644 --- a/src/Library/src/GPU/GPU.cpp +++ b/src/Library/src/GPU/GPU.cpp @@ -1,23 +1,36 @@ -#include +#include "../include/GPU/GPU.hpp" namespace GPU { namespace Screen { - #ifdef JABYENGINE_PAL - static constexpr uint16_t ScanlinesV = 288; - #else - static constexpr uint16_t ScanlinesV = 240; - #endif //JABYENGINE_PAL + uint8_t CurrentDisplayAreaID = 1; //< Setup will call exchange and set it to 0 -#ifndef USE_NO$PSX - void set_offset(uint16_t x, uint16_t y) { - GP1.write(Command::GP1::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3)); - GP1.write(Command::GP1::VerticalDisplayRange(y, y + Display::Height)); + namespace Range { + #ifdef JABYENGINE_PAL + static constexpr uint16_t ScanlinesV = 288; + #else + static constexpr uint16_t ScanlinesV = 240; + #endif //JABYENGINE_PAL + + #ifndef USE_NO$PSX + void set_offset(uint16_t x, uint16_t y) { + x += 78; + y += 43; + + GP1.write(Command::GP1::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3)); + GP1.write(Command::GP1::VerticalDisplayRange(y, y + Display::Height)); + } + #else + void 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))); + } + #endif //USE_NO$PSX } -#else - void 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))); + + void exchange_buffer_and_display() { + GPU::set_draw_area(0, (Display::Height*CurrentDisplayAreaID)); + CurrentDisplayAreaID ^= 1; + GP1.write(Command::GP1::DisplayArea(0, (Display::Height*CurrentDisplayAreaID))); } -#endif //USE_NO$PSX } } \ No newline at end of file