Update GPU IOs (What a pain)

This commit is contained in:
2024-09-28 17:49:04 +02:00
parent 54b12b13e9
commit 3fab693049
9 changed files with 319 additions and 239 deletions

View File

@@ -1,230 +1,93 @@
#pragma once
#include "ioport.hpp"
#include "../../GPU/gpu_types.hpp"
#include "IOValues/gpu_io_values.hpp"
namespace JabyEngine {
namespace GPU_IO {
enum struct DisplayAreaColorDepth {
$15bit = 0,
$24bit = 1,
};
using namespace GPU_IO_Values;
enum struct HorizontalResolution {
$256 = 0,
$320 = 1,
$512 = 2,
$640 = 3,
};
enum struct VerticalResolution {
$240 = 0,
$480 = 1
};
enum struct DMADirection {
Off = 0,
Fifo = 1,
CPU2GPU = 2,
GPU2CPU = 3,
};
enum struct DisplayState {
On = 0,
Off = 1
};
__declare_io_value(DisplayMode, uint32_t) {
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 DisplayMode PAL() {
return DisplayMode::from(
HorizontalResolution.with(GPU_IO::HorizontalResolution::$320),
VerticalResolution.with(GPU_IO::VerticalResolution::$240),
VideoMode.with(TVEncoding::PAL),
DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit)
);
struct GP0IO : public IOPort<GPU_IO_Values::GP0> {
void clear_cache() {
this->write(GPU_IO_Values::GP0::ClearCache());
}
static constexpr DisplayMode NTSC() {
return DisplayMode::from(
HorizontalResolution.with(GPU_IO::HorizontalResolution::$320),
VerticalResolution.with(GPU_IO::VerticalResolution::$240),
VideoMode.with(TVEncoding::NTSC),
DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit)
);
void quick_fill(GPU::Color24 color) {
this->write(GPU_IO_Values::GP0::QuickFill(color));
}
void set_vram2vram_blitting() {
this->write(GPU_IO_Values::GP0::VRAM2VRAMBlitting());
}
void set_cpu2vram_blitting() {
this->write(GPU_IO_Values::GP0::CPU2VRAMBlitting());
}
void set_tex_page(const GPU::PositionU16& page_pos, GPU::SemiTransparency transparency, GPU::TextureColorMode tex_color, bool dither, bool draw_on_display_area) {
this->write(GPU_IO_Values::GP0::TexPage(page_pos, transparency, tex_color, dither, draw_on_display_area));
}
void set_draw_area_top_left(const GPU::PositionU16& position) {
this->write(GPU_IO_Values::GP0::DrawAreaTopLeft(position));
}
void set_draw_area_bottom_right(const GPU::PositionU16& position) {
this->write(GPU_IO_Values::GP0::DrawAreaBottomRight(position));
}
void set_draw_offset(const GPU::PositionI16& offset) {
this->write(GPU_IO_Values::GP0::DrawOffset(offset));
}
void pass_top_left_position(const GPU::PositionU16& position) {
this->write(GPU_IO_Values::GP0::PostionTopLeft(position));
}
void pass_width_height(const GPU::SizeU16& size) {
this->write(GPU_IO_Values::GP0::WidthHeight(size));
}
};
__declare_io_value(GP0, uint32_t) {
static constexpr auto ID = BitRange::from_to(24, 31);
static constexpr auto Value = BitRange::from_to(0, 23);
};
__declare_io_value(GP1, uint32_t) {
static constexpr auto ID = BitRange::from_to(24, 31);
static constexpr auto Value = BitRange::from_to(0, 23);
};
struct Command {
struct Helper {
template<typename T>
static constexpr T construct_cmd(uint32_t cmd, uint32_t value) {
return T::from(T::ID.with(cmd), T::Value.with(value));
}
static constexpr struct 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 construct_cmd<struct GP0>(code, Y.as_value(static_cast<uint32_t>(y)) | X.as_value(static_cast<uint32_t>(x)));
}
};
static constexpr struct GP0 ClearCache() {
return Helper::construct_cmd<struct GP0>(0x01, 0x0);
struct GP1IO : public IOPort<GPU_IO_Values::GP1> {
void reset() {
this->write(GPU_IO_Values::GP1::Reset());
}
static constexpr struct GP0 QuickFill(GPU::Color24 color) {
return Helper::construct_cmd<struct GP0>(0x02, color.raw());
void reset_cmd_buffer() {
this->write(GPU_IO_Values::GP1::ResetCMDBuffer());
}
static constexpr struct GP0 VRAM2VRAM_Blitting() {
return Helper::construct_cmd<struct GP0>(0x80, 0);
void set_display_state(GPU_IO_Values::DisplayMode::State state) {
this->write(GPU_IO_Values::GP1::DisplayState(state));
}
static constexpr struct GP0 CPU2VRAM_Blitting() {
return Helper::construct_cmd<struct GP0>(0xA0, 0);
void set_dma_direction(GPU_IO_Values::GPUSTAT::DMADirection dir) {
this->write(GPU_IO_Values::GP1::DMADirection(dir));
}
static constexpr struct 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 Helper::construct_cmd<struct GP0>(0xE1,
TexXRange.as_value(page_pos.x >> 6) | TexYRange.as_value(page_pos.y >> 8) |
TransparencyRange.as_value(static_cast<uint32_t>(transparency)) | TextureColorRange.as_value(static_cast<uint32_t>(tex_color)) |
DitherBit.as_value(static_cast<uint32_t>(dither)) | DrawOnDisplayAreaBit.as_value(static_cast<uint32_t>(draw_on_display_area))
);
void set_display_area(const GPU::PositionU16& position) {
this->write(GPU_IO_Values::GP1::DisplayArea(position));
}
static constexpr struct GP0 DrawAreaTopLeft(const GPU::PositionU16& position) {
return Helper::DrawAreaTemplate(0xE3, position.x, position.y);
void set_horizontal_display_range(uint16_t x1, uint16_t x2) {
this->write(GPU_IO_Values::GP1::HorizontalDisplayRange(x1, x2));
}
static constexpr struct GP0 DrawAreaBottomRight(const GPU::PositionU16& position) {
return Helper::DrawAreaTemplate(0xE4, position.x, position.y);
void set_vertical_display_range(uint16_t y1, uint16_t y2) {
this->write(GPU_IO_Values::GP1::VerticalDisplayRange(y1, y2));
}
static constexpr struct GP0 SetDrawOffset(const GPU::PositionI16& offset) {
constexpr auto X = BitRange::from_to(0, 10);
constexpr auto Y = BitRange::from_to(11, 21);
return Helper::construct_cmd<struct GP0>(0xE5, X.as_value(static_cast<int32_t>(offset.x)) | Y.as_value(static_cast<int32_t>(offset.y)));
}
static constexpr struct GP0 TopLeftPosition(const GPU::PositionU16& position) {
return {(static_cast<uint32_t>(position.y) << 16u) | position.x};
}
static constexpr struct GP0 WidthHeight(const GPU::SizeU16& size) {
return {(static_cast<uint32_t>(size.height) << 16u) | size.width};
}
static constexpr struct GP1 Reset() {
return {0};
}
static constexpr struct GP1 ResetCMDBufer() {
return Helper::construct_cmd<struct GP1>(0x01, 0);
}
static constexpr struct GP1 SetDisplayState(DisplayState state) {
return Helper::construct_cmd<struct GP1>(0x03, static_cast<uint32_t>(state));
}
static constexpr struct GP1 DMADirection(DMADirection dir) {
return Helper::construct_cmd<struct GP1>(0x04, static_cast<uint32_t>(dir));
}
static constexpr struct GP1 DisplayArea(const GPU::PositionU16& position) {
constexpr auto X = BitRange::from_to(0, 9);
constexpr auto Y = BitRange::from_to(10, 18);
return Helper::construct_cmd<struct GP1>(0x05, X.as_value(static_cast<uint32_t>(position.x)) | Y.as_value(static_cast<uint32_t>(position.y)));
}
static constexpr struct 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 Helper::construct_cmd<struct GP1>(0x06, X1.as_value(static_cast<uint32_t>(x1)) | X2.as_value(static_cast<uint32_t>(x2)));
}
static constexpr struct 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 Helper::construct_cmd<struct GP1>(0x07, Y1.as_value(static_cast<uint32_t>(y1)) | Y2.as_value(static_cast<uint32_t>(y2)));
}
static constexpr struct GP1 DisplayMode(DisplayMode mode) {
return Helper::construct_cmd<struct GP1>(0x08, mode.raw);
void set_display_mode(GPU_IO_Values::DisplayMode mode) {
this->write(GPU_IO_Values::GP1::DisplayMode(mode));
}
};
__declare_io_value(GPUREAD, uint32_t) {
};
__declare_io_value(GPUSTAT, uint32_t) {
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);
};
using GPUREAD_IO = IOPort<GPU_IO_Values::GPUREAD>;
using GPUSTAT_IO = IOPort<GPU_IO_Values::GPUSTAT>;
static constexpr size_t FIFOWordSize = 16;
__declare_io_port(, GP0, 0x1F801810);
__declare_io_port(, GP1, 0x1F801814);
__declare_io_port(const, GPUREAD, 0x1F801810);
__declare_io_port(const, GPUSTAT, 0x1F801814);
static auto& GP0 = __new_declare_io_port(GP0IO, 0x1F801810);
static const auto& GPUREAD = __new_declare_io_port(GPUREAD_IO, 0x1F801810);
static auto& GP1 = __new_declare_io_port(GP1IO, 0x1F801814);
static const auto& GPUSTAT = __new_declare_io_port(GPUSTAT_IO, 0x1F801814);
}
}