Skip to content

Instantly share code, notes, and snippets.

@rw-r-r-0644
Last active May 31, 2019 16:26
Show Gist options
  • Save rw-r-r-0644/bfc751de93ffff7e19980d82d6bb6453 to your computer and use it in GitHub Desktop.
Save rw-r-r-0644/bfc751de93ffff7e19980d82d6bb6453 to your computer and use it in GitHub Desktop.
idk? Looks like another Wii U framebuffer library ...
/*
* Copyright (C) 2017 rw-r-r-0644, QuarkTheAwesome
* Code under GNU GPL license
*/
#include "fb.h"
#include <stdlib.h>
#include <malloc.h>
#include <system/memory.h>
#include <dynamic_libs/os_functions.h>
typedef enum
{
fbStateReg = 0x1821,
fbModeUpdateReg = 0x1840,
fbModeReg = 0x1841,
fbPhysAddrReg = 0x1844,
fbWidth1Reg = 0x1848,
fbWidth2Reg = 0x1866,
fbAddrUpdateReg = 0x1A45,
} fbRegisters_t;
u32* GX2Regs = NULL;
/* Utility function to get direct access to the virtual framebuffer */
u32* fbGetFramebuffer(fbDevice* device)
{
return device->buffer;
}
/* Enable screen buffer */
void fbSetEnable(fbDevice* device, int enable)
{
u32 regOffset = device->fbRegsOffset;
u32 gx2_state_reg = GX2Regs[regOffset + fbStateReg];
GX2Regs[regOffset + fbStateReg] = (gx2_state_reg & 0xFFFFFEFF) | (!enable * 0x100); // 0x100 is the SCREEN_DISABLE flag
}
/* Update framebuffer */
void fbFlush(fbDevice* device)
{
DCFlushRange(device->buffer, device->bufferSize);
}
/* Clear the screen */
void fbClear(fbDevice* device, u32 color)
{
u32 pixelCount = device->bufferSize / 4;
u32* buffer = device->buffer;
for (u32 i = 0; i < pixelCount; i++)
buffer[i] = color;
}
/* Setup hardware framebuffer */
void fbSetup(fbDevice* device)
{
u32 regOffset = device->fbRegsOffset;
// Set framebuffer mode
u32 gx2_mode_reg = GX2Regs[regOffset + fbModeReg];
GX2Regs[regOffset + fbModeReg] = (gx2_mode_reg & 0xFF0FF8FC) | 0x100002;
GX2Regs[regOffset + fbModeUpdateReg] = 1;
// Set framebuffer width
GX2Regs[regOffset + fbWidth1Reg] = device->width & 0x3FFF;
GX2Regs[regOffset + fbWidth2Reg] = device->width & 0x3FFF;
// Enable the framebuffer
fbSetEnable(device, 1);
// Clear the framebuffer
fbClear(device, 0);
// Set framebuffer physical address
u32 buffer_phys = (u32)OSEffectiveToPhysical(device->buffer);
GX2Regs[regOffset ^ fbAddrUpdateReg] = 0;
GX2Regs[regOffset ^ fbPhysAddrReg] = (buffer_phys & 0xFFFFFF00) | 1;
// Flush the framebuffer
fbFlush(device);
}
/* Init the TV framebuffer */
fbDevice* fbInitTV()
{
// Get GX2 registers virtual address
if(!GX2Regs)
GX2Regs = __OSPhysicalToEffectiveUncached((void*)0xC200000);
fbDevice* fbTV = malloc(sizeof(fbDevice));
// Setup the TV framebuffer structure
fbTV->width = 1280;
fbTV->height = 720;
fbTV->bufferSize = ((fbTV->width * 4 + 0xFF) & 0xFFFFFF00) * fbTV->height;
fbTV->buffer = MEM1_alloc(fbTV->bufferSize, 0x40);
fbTV->fbRegsOffset = 0;
// Hardware setup for the TV framebuffer
fbSetup(fbTV);
// Return the TV framebuffer structure
return fbTV;
}
/* Init the DRC framebuffer */
fbDevice* fbInitDRC()
{
// Get GX2 registers virtual address
if(!GX2Regs)
GX2Regs = __OSPhysicalToEffectiveUncached((void*)0xC200000);
fbDevice* fbDRC = malloc(sizeof(fbDevice));
// Setup the DRC framebuffer structure
fbDRC->width = 896;
fbDRC->height = 480;
fbDRC->bufferSize = ((fbDRC->width * 4 + 0xFF) & 0xFFFFFF00) * fbDRC->height;
fbDRC->buffer = MEM1_alloc(fbDRC->bufferSize, 0x40);
fbTV->fbRegsOffset = 512;
// Hardware setup for the DRC framebuffer
fbSetup(fbDRC);
// Return the DRC framebuffer structure
return fbDRC;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment