#pragma once #include "../../../GPU/gpu_types.hpp" #include "ioport.hpp" namespace JabyEngine { namespace GPU_IO_Values { namespace internal { template static constexpr T construct_cmd(uint32_t cmd, uint32_t value) { return T::from(T::ID.with(cmd), T::Value.with(value)); } } __declare_io_struct(DisplayMode, uint32_t) { enum AreaColorDepth { $15bit = 0, $24bit = 1, }; enum State { On = 0, Off = 1 }; enum HorizontalResolution { $256 = 0, $320 = 1, $512 = 2, $640 = 3, }; enum struct TVEncoding { NTSC = 0, PAL = 1, }; enum VerticalResolution { $240 = 0, $480 = 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 DisplayMode PAL() { return DisplayMode::from( HorizontalResolution.with(HorizontalResolution::$320), VerticalResolution.with(VerticalResolution::$240), VideoMode.with(TVEncoding::PAL), DisplayAreaColorDepth.with(AreaColorDepth::$15bit) ); } static constexpr DisplayMode NTSC() { return DisplayMode::from( HorizontalResolution.with(HorizontalResolution::$320), VerticalResolution.with(VerticalResolution::$240), VideoMode.with(TVEncoding::NTSC), DisplayAreaColorDepth.with(AreaColorDepth::$15bit) ); } }; __declare_io_struct(GPUREAD, uint32_t) { }; __declare_io_struct(GPUSTAT, uint32_t) { enum DMADirection { Off = 0, Fifo = 1, CPU2GPU = 2, GPU2CPU = 3, }; 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 static constexpr auto VerticalResolution480 = Bit(19); static constexpr auto TexturePageY256 = Bit(4); }; __declare_io_struct(GP0, uint32_t) { static constexpr auto ID = BitRange::from_to(24, 31); static constexpr auto Value = BitRange::from_to(0, 23); 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 internal::construct_cmd(code, Y.as_value(static_cast(y)) | X.as_value(static_cast(x))); } static constexpr GP0 ClearCache() { return internal::construct_cmd(0x01, 0x0); } static constexpr GP0 QuickFill(GPU::Color24 color) { return internal::construct_cmd(0x02, color.raw()); } static constexpr GP0 VRAM2VRAMBlitting() { return internal::construct_cmd(0x80, 0); } static constexpr GP0 CPU2VRAMBlitting() { return internal::construct_cmd(0xA0, 0); } static constexpr GP0 TexPage(const GPU::PositionU16& page_pos, GPU::SemiTransparency transparency, GPU::TextureColorMode tex_color, bool dither, bool draw_on_display_area) { constexpr auto TexXRange = BitRange::from_to(0, 3); constexpr auto TexYRange = BitRange::from_to(4, 4); constexpr auto TransparencyRange = BitRange::from_to(5, 6); constexpr auto TextureColorRange = BitRange::from_to(7, 8); constexpr auto DitherBit = BitRange::from_to(9, 9); constexpr auto DrawOnDisplayAreaBit = BitRange::from_to(10, 10); return internal::construct_cmd(0xE1, TexXRange.as_value(page_pos.x >> 6) | TexYRange.as_value(page_pos.y >> 8) | TransparencyRange.as_value(static_cast(transparency)) | TextureColorRange.as_value(static_cast(tex_color)) | DitherBit.as_value(static_cast(dither)) | DrawOnDisplayAreaBit.as_value(static_cast(draw_on_display_area)) ); } static constexpr GP0 DrawAreaTopLeft(const GPU::PositionU16& position) { return GP0::DrawAreaTemplate(0xE3, position.x, position.y); } static constexpr GP0 DrawAreaBottomRight(const GPU::PositionU16& position) { return GP0::DrawAreaTemplate(0xE4, position.x, position.y); } static constexpr GP0 DrawOffset(const GPU::PositionI16& offset) { constexpr auto X = BitRange::from_to(0, 10); constexpr auto Y = BitRange::from_to(11, 21); return internal::construct_cmd(0xE5, X.as_value(static_cast(offset.x)) | Y.as_value(static_cast(offset.y))); } static constexpr GP0 PostionTopLeft(const GPU::PositionU16& position) { return GP0{(static_cast(position.y) << 16u) | position.x}; } static constexpr GP0 WidthHeight(const GPU::SizeU16& size) { return GP0{(static_cast(size.height) << 16u) | size.width}; } }; __declare_io_struct(GP1, uint32_t) { static constexpr auto ID = BitRange::from_to(24, 31); static constexpr auto Value = BitRange::from_to(0, 23); static constexpr GP1 Reset() { return GP1{0}; } static constexpr GP1 ResetCMDBuffer() { return internal::construct_cmd(0x01, 0); } static constexpr GP1 DisplayState(DisplayMode::State state) { return internal::construct_cmd(0x03, static_cast(state)); } static constexpr GP1 DMADirection(GPUSTAT::DMADirection dir) { return internal::construct_cmd(0x04, dir); } static constexpr GP1 DisplayArea(const GPU::PositionU16& position) { constexpr auto X = BitRange::from_to(0, 9); constexpr auto Y = BitRange::from_to(10, 18); return internal::construct_cmd(0x05, X.as_value(static_cast(position.x)) | Y.as_value(static_cast(position.y))); } static constexpr GP1 HorizontalDisplayRange(uint16_t x1, uint16_t x2) { constexpr auto X1 = BitRange::from_to(0, 11); constexpr auto X2 = BitRange::from_to(12, 23); return internal::construct_cmd(0x06, X1.as_value(static_cast(x1)) | X2.as_value(static_cast(x2))); } static constexpr GP1 VerticalDisplayRange(uint16_t y1, uint16_t y2) { constexpr auto Y1 = BitRange::from_to(0, 9); constexpr auto Y2 = BitRange::from_to(10, 19); return internal::construct_cmd(0x07, Y1.as_value(static_cast(y1)) | Y2.as_value(static_cast(y2))); } static constexpr GP1 DisplayMode(GPU_IO_Values::DisplayMode mode) { return internal::construct_cmd(0x08, mode.raw); } }; } }