#pragma once #include "common/bitfield.h" #include "types.h" #include class Bus; class DMA; class GPU { public: GPU(); ~GPU(); bool Initialize(Bus* bus, DMA* dma); void Reset(); u32 ReadRegister(u32 offset); void WriteRegister(u32 offset, u32 value); // DMA access u32 DMARead(); void DMAWrite(u32 value); private: static constexpr u32 MAX_GP0_COMMAND_LENGTH = 12; enum class DMADirection : u32 { Off = 0, FIFO = 1, CPUtoGP0 = 2, GPUREADtoCPU = 3 }; void SoftReset(); void UpdateDMARequest(); u32 ReadGPUREAD(); void WriteGP0(u32 value); void WriteGP1(u32 value); // Rendering commands, returns false if not enough data is provided bool HandleRenderPolygonCommand(); Bus* m_bus = nullptr; DMA* m_dma = nullptr; union GPUSTAT { u32 bits; BitField texture_page_x_base; BitField texture_page_y_base; BitField semi_transparency; BitField texture_page_colors; BitField dither_enable; BitField draw_to_display_area; BitField draw_set_mask_bit; BitField draw_to_masked_pixels; BitField interlaced_field; BitField reverse_flag; BitField texture_disable; BitField horizontal_resolution_2; BitField horizontal_resolution_1; BitField vetical_resolution; BitField pal_mode; BitField display_area_color_depth_24; BitField vertical_interlace; BitField display_enable; BitField interrupt_request; BitField dma_data_request; BitField ready_to_recieve_cmd; BitField ready_to_send_vram; BitField ready_to_recieve_dma; BitField dma_direction; BitField drawing_even_line; } m_GPUSTAT = {}; struct TextureConfig { u8 window_mask_x; // in 8 pixel steps u8 window_mask_y; // in 8 pixel steps u8 window_offset_x; // in 8 pixel steps u8 window_offset_y; // in 8 pixel steps bool x_flip; bool y_flip; } m_texture_config = {}; struct DrawingArea { u32 top_left_x, top_left_y; u32 bottom_right_x, bottom_right_y; } m_drawing_area = {}; struct DrawingOffset { s32 x; s32 y; } m_drawing_offset = {}; std::array m_GP0_command = {}; u32 m_GP0_command_length = 0; };