mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-25 21:22:47 +00:00
fixed screen init, hopefully the last commmit
- properly performs gpu/backlight reset - nukes vram so the initrd had to be moved to arm9 memory, and have its size (at least temporarily) limited to 256k
This commit is contained in:
parent
f20d2657fa
commit
30f0b004c2
6
Makefile
6
Makefile
@ -83,14 +83,14 @@ vram0:
|
||||
@$(MAKE) --no-print-directory -C $(@D)
|
||||
|
||||
firm: $(ELF) vram0
|
||||
@test `wc -c <$(VRAM_OUT)` -le 3145728
|
||||
@test `wc -c <$(VRAM_OUT)` -le 262144
|
||||
@mkdir -p $(call dirname,"$(FIRM)") $(call dirname,"$(FIRMD)")
|
||||
@echo "[FLAVOR] $(FLAVOR)"
|
||||
@echo "[VERSION] $(VERSION)"
|
||||
@echo "[BUILD] $(DBUILTL)"
|
||||
@echo "[FIRM] $(FIRM)"
|
||||
@$(PY3) -m firmtool build $(FIRM) $(FTFLAGS) -g -A 0x18000000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy
|
||||
@$(PY3) -m firmtool build $(FIRM) $(FTFLAGS) -g -A 0x80C0000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy
|
||||
@echo "[FIRM] $(FIRMD)"
|
||||
@$(PY3) -m firmtool build $(FIRMD) $(FTDFLAGS) -g -A 0x18000000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy
|
||||
@$(PY3) -m firmtool build $(FIRMD) $(FTDFLAGS) -g -A 0x80C0000 -D $(ELF) $(VRAM_OUT) -C NDMA XDMA memcpy
|
||||
|
||||
.FORCE:
|
||||
|
@ -30,3 +30,7 @@
|
||||
#define CLK_MS_TO_TICKS(m) (((BASE_CLKRATE / 1000) * (m)) - 1)
|
||||
|
||||
void TIMER_WaitTicks(u32 ticks);
|
||||
|
||||
static inline void TIMER_WaitMS(u32 ms) {
|
||||
TIMER_WaitTicks(CLK_MS_TO_TICKS(ms));
|
||||
}
|
||||
|
@ -16,212 +16,284 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <types.h>
|
||||
#include <vram.h>
|
||||
|
||||
#include "arm/timer.h"
|
||||
|
||||
#include "hw/i2c.h"
|
||||
#include "hw/mcu.h"
|
||||
#include "hw/gpulcd.h"
|
||||
|
||||
/* LCD Configuration Registers */
|
||||
#define REG_LCD(x) ((vu32*)(0x10202000 + (x)))
|
||||
void LCD_SetBrightness(u8 brightness)
|
||||
static struct
|
||||
{
|
||||
*REG_LCD(0x240) = brightness;
|
||||
*REG_LCD(0xA40) = brightness;
|
||||
u16 lcdIds; // Bits 0-7 top screen, 8-15 bottom screen.
|
||||
bool lcdIdsRead;
|
||||
u8 lcdPower; // 1 = on. Bit 4 top light, bit 2 bottom light, bit 0 LCDs.
|
||||
u8 lcdLights[2]; // LCD backlight brightness. Top, bottom.
|
||||
u32 framebufs[2]; // For each screen
|
||||
u8 doubleBuf[2]; // Top, bottom, 1 = enable.
|
||||
u16 strides[2]; // Top, bottom
|
||||
u32 formats[2]; // Top, bottom
|
||||
} g_gfxState = {0};
|
||||
|
||||
static void setupDisplayController(u8 lcd);
|
||||
static void resetLcdsMaybe(void);
|
||||
static void waitLcdsReady(void);
|
||||
|
||||
static u32 gxModeWidth(unsigned c) {
|
||||
switch(c) {
|
||||
case 0: return 4;
|
||||
case 1: return 3;
|
||||
default: return 2;
|
||||
}
|
||||
}
|
||||
|
||||
u8 LCD_GetBrightness(void)
|
||||
unsigned GFX_init(GfxFbFmt mode)
|
||||
{
|
||||
return *REG_LCD(0x240);
|
||||
unsigned err = 0;
|
||||
|
||||
REG_CFG11_GPUPROT = 0;
|
||||
|
||||
// Reset
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E;
|
||||
waitClks(12);
|
||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E | PDN_GPU_CNT_RST_ALL;
|
||||
REG_GX_GPU_CLK = 0x100;
|
||||
REG_GX_PSC_VRAM = 0;
|
||||
REG_GX_PSC_FILL0_CNT = 0;
|
||||
REG_GX_PSC_FILL1_CNT = 0;
|
||||
REG_GX_PPF_CNT = 0;
|
||||
|
||||
// LCD framebuffer setup.
|
||||
|
||||
g_gfxState.strides[0] = 240 * gxModeWidth(mode);
|
||||
g_gfxState.strides[1] = 240 * gxModeWidth(mode);
|
||||
|
||||
g_gfxState.framebufs[0] = VRAM_TOP_LA;
|
||||
g_gfxState.framebufs[1] = VRAM_BOT_A;
|
||||
|
||||
g_gfxState.formats[0] = mode | BIT(6) | BIT(9);
|
||||
g_gfxState.formats[1] = mode | BIT(9);
|
||||
|
||||
setupDisplayController(0);
|
||||
setupDisplayController(1);
|
||||
REG_LCD_PDC0_SWAP = 0; // Select framebuf 0.
|
||||
REG_LCD_PDC1_SWAP = 0;
|
||||
REG_LCD_PDC0_CNT = PDC_CNT_OUT_E | PDC_CNT_I_MASK_ERR | PDC_CNT_I_MASK_H | PDC_CNT_E; // Start
|
||||
REG_LCD_PDC1_CNT = PDC_CNT_OUT_E | PDC_CNT_I_MASK_ERR | PDC_CNT_I_MASK_H | PDC_CNT_E;
|
||||
|
||||
// LCD reg setup.
|
||||
REG_LCD_ABL0_FILL = 1u<<24; // Force blackscreen
|
||||
REG_LCD_ABL1_FILL = 1u<<24; // Force blackscreen
|
||||
REG_LCD_PARALLAX_CNT = 0;
|
||||
REG_LCD_PARALLAX_PWM = 0xA390A39;
|
||||
REG_LCD_RST = 0;
|
||||
REG_LCD_UNK00C = 0x10001;
|
||||
|
||||
// Clear used VRAM
|
||||
REG_GX_PSC_FILL0_S_ADDR = VRAM_TOP_LA >> 3;
|
||||
REG_GX_PSC_FILL0_E_ADDR = VRAM_END >> 3;
|
||||
REG_GX_PSC_FILL0_VAL = 0;
|
||||
REG_GX_PSC_FILL0_CNT = BIT(9) | BIT(0);
|
||||
|
||||
// Backlight and other stuff.
|
||||
REG_LCD_ABL0_LIGHT = 0;
|
||||
REG_LCD_ABL0_CNT = 0;
|
||||
REG_LCD_ABL0_LIGHT_PWM = 0;
|
||||
REG_LCD_ABL1_LIGHT = 0;
|
||||
REG_LCD_ABL1_CNT = 0;
|
||||
REG_LCD_ABL1_LIGHT_PWM = 0;
|
||||
|
||||
REG_LCD_RST = 1;
|
||||
REG_LCD_UNK00C = 0;
|
||||
TIMER_WaitMS(10);
|
||||
resetLcdsMaybe();
|
||||
MCU_controlLCDPower(2u); // Power on LCDs.
|
||||
if(MCU_waitEvents(0x3Fu<<24) != 2u<<24) __builtin_trap();
|
||||
|
||||
waitLcdsReady();
|
||||
REG_LCD_ABL0_LIGHT_PWM = 0x1023E;
|
||||
REG_LCD_ABL1_LIGHT_PWM = 0x1023E;
|
||||
MCU_controlLCDPower(0x28u); // Power on backlights.
|
||||
if(MCU_waitEvents(0x3Fu<<24) != 0x28u<<24) __builtin_trap();
|
||||
g_gfxState.lcdPower = 0x15; // All on.
|
||||
|
||||
// Make sure the fills finished.
|
||||
REG_LCD_ABL0_FILL = 0;
|
||||
REG_LCD_ABL1_FILL = 0;
|
||||
|
||||
// GPU stuff.
|
||||
REG_GX_GPU_CLK = 0x70100;
|
||||
*((vu32*)0x10400050) = 0x22221200;
|
||||
*((vu32*)0x10400054) = 0xFF2;
|
||||
|
||||
GFX_setBrightness(0x80, 0x80);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void LCD_Initialize(u8 brightness)
|
||||
static u16 getLcdIds(void)
|
||||
{
|
||||
*REG_LCD(0x014) = 1;
|
||||
*REG_LCD(0x00C) = 0;
|
||||
TIMER_WaitTicks(CLK_MS_TO_TICKS(10));
|
||||
u16 ids;
|
||||
|
||||
*REG_LCD(0x240) = brightness;
|
||||
*REG_LCD(0xA40) = brightness;
|
||||
*REG_LCD(0x244) = 0x1023E;
|
||||
*REG_LCD(0xA44) = 0x1023E;
|
||||
}
|
||||
|
||||
void LCD_Deinitialize(void)
|
||||
if(!g_gfxState.lcdIdsRead)
|
||||
{
|
||||
*REG_LCD(0x244) = 0;
|
||||
*REG_LCD(0xA44) = 0;
|
||||
*REG_LCD(0x00C) = 0x10001;
|
||||
*REG_LCD(0x014) = 0;
|
||||
g_gfxState.lcdIdsRead = true;
|
||||
|
||||
u16 top, bot;
|
||||
I2C_writeReg(I2C_DEV_LCD0, 0x40, 0xFF);
|
||||
I2C_readRegBuf(I2C_DEV_LCD0, 0x40, (u8*)&top, 2);
|
||||
I2C_writeReg(I2C_DEV_LCD1, 0x40, 0xFF);
|
||||
I2C_readRegBuf(I2C_DEV_LCD1, 0x40, (u8*)&bot, 2);
|
||||
|
||||
ids = top>>8;
|
||||
ids |= bot & 0xFF00u;
|
||||
g_gfxState.lcdIds = ids;
|
||||
}
|
||||
else ids = g_gfxState.lcdIds;
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
/* GPU Control Registers */
|
||||
#define REG_GPU_CNT ((vu32*)(0x10141200))
|
||||
|
||||
|
||||
/* GPU DMA */
|
||||
#define REG_GPU_PSC(n, x) ((vu32*)(0x10400010 + ((n) * 0x10) + (x)))
|
||||
#define GPU_PSC_START (0x00)
|
||||
#define GPU_PSC_END (0x04)
|
||||
#define GPU_PSC_FILLVAL (0x08)
|
||||
#define GPU_PSC_CNT (0x0C)
|
||||
|
||||
#define GPUDMA_ADDR(x) ((x) >> 3)
|
||||
#define PSC_START (BIT(0))
|
||||
#define PSC_DONE (BIT(1))
|
||||
#define PSC_32BIT (2 << 8)
|
||||
#define PSC_24BIT (1 << 8)
|
||||
#define PSC_16BIT (0 << 8)
|
||||
|
||||
void GPU_PSCFill(u32 start, u32 end, u32 fv)
|
||||
static void resetLcdsMaybe(void)
|
||||
{
|
||||
u32 mp;
|
||||
if (start > end)
|
||||
return;
|
||||
const u16 ids = getLcdIds();
|
||||
|
||||
start = GPUDMA_ADDR(start);
|
||||
end = GPUDMA_ADDR(end);
|
||||
mp = (start + end) / 2;
|
||||
|
||||
*REG_GPU_PSC(0, GPU_PSC_START) = start;
|
||||
*REG_GPU_PSC(0, GPU_PSC_END) = mp;
|
||||
*REG_GPU_PSC(0, GPU_PSC_FILLVAL) = fv;
|
||||
*REG_GPU_PSC(0, GPU_PSC_CNT) = PSC_START | PSC_32BIT;
|
||||
|
||||
*REG_GPU_PSC(1, GPU_PSC_START) = mp;
|
||||
*REG_GPU_PSC(1, GPU_PSC_END) = end;
|
||||
*REG_GPU_PSC(1, GPU_PSC_FILLVAL) = fv;
|
||||
*REG_GPU_PSC(1, GPU_PSC_CNT) = PSC_START | PSC_32BIT;
|
||||
|
||||
while(!((*REG_GPU_PSC(0, GPU_PSC_CNT) | *REG_GPU_PSC(1, GPU_PSC_CNT)) & PSC_DONE));
|
||||
}
|
||||
|
||||
/* GPU Display Registers */
|
||||
#define GPU_PDC(n, x) ((vu32*)(0x10400400 + ((n) * 0x100) + x))
|
||||
#define PDC_PARALLAX (BIT(5))
|
||||
#define PDC_MAINSCREEN (BIT(6))
|
||||
#define PDC_FIXSTRIP (BIT(7))
|
||||
|
||||
void GPU_SetFramebuffers(const u32 *framebuffers)
|
||||
// Top screen
|
||||
if(ids & 0xFFu) I2C_writeReg(I2C_DEV_LCD0, 0xFE, 0xAA);
|
||||
else
|
||||
{
|
||||
*GPU_PDC(0, 0x68) = framebuffers[0];
|
||||
*GPU_PDC(0, 0x6C) = framebuffers[1];
|
||||
*GPU_PDC(0, 0x94) = framebuffers[2];
|
||||
*GPU_PDC(0, 0x98) = framebuffers[3];
|
||||
*GPU_PDC(1, 0x68) = framebuffers[4];
|
||||
*GPU_PDC(1, 0x6C) = framebuffers[5];
|
||||
*GPU_PDC(0, 0x78) = 0;
|
||||
*GPU_PDC(1, 0x78) = 0;
|
||||
I2C_writeReg(I2C_DEV_LCD0, 0x11, 0x10);
|
||||
I2C_writeReg(I2C_DEV_LCD0, 0x50, 1);
|
||||
}
|
||||
|
||||
void GPU_SetFramebufferMode(u32 screen, u8 mode)
|
||||
// Bottom screen
|
||||
if(ids>>8) I2C_writeReg(I2C_DEV_LCD1, 0xFE, 0xAA);
|
||||
else I2C_writeReg(I2C_DEV_LCD1, 0x11, 0x10);
|
||||
|
||||
I2C_writeReg(I2C_DEV_LCD0, 0x60, 0);
|
||||
I2C_writeReg(I2C_DEV_LCD1, 0x60, 0);
|
||||
I2C_writeReg(I2C_DEV_LCD0, 1, 0x10);
|
||||
I2C_writeReg(I2C_DEV_LCD1, 1, 0x10);
|
||||
}
|
||||
|
||||
static void waitLcdsReady(void)
|
||||
{
|
||||
u32 stride, cfg;
|
||||
vu32 *fbcfg_reg, *fbstr_reg;
|
||||
const u16 ids = getLcdIds();
|
||||
|
||||
mode &= 7;
|
||||
screen &= 1;
|
||||
cfg = PDC_FIXSTRIP | mode;
|
||||
if (screen) {
|
||||
fbcfg_reg = GPU_PDC(1, 0x70);
|
||||
fbstr_reg = GPU_PDC(1, 0x90);
|
||||
} else {
|
||||
fbcfg_reg = GPU_PDC(0, 0x70);
|
||||
fbstr_reg = GPU_PDC(0, 0x90);
|
||||
cfg |= PDC_MAINSCREEN;
|
||||
}
|
||||
|
||||
stride = 240;
|
||||
switch(mode) {
|
||||
case PDC_RGBA8:
|
||||
stride *= 4;
|
||||
break;
|
||||
case PDC_RGB24:
|
||||
stride *= 3;
|
||||
break;
|
||||
default:
|
||||
stride *= 2;
|
||||
break;
|
||||
}
|
||||
|
||||
*fbcfg_reg = cfg;
|
||||
*fbstr_reg = stride;
|
||||
}
|
||||
|
||||
void GPU_Init(void)
|
||||
if((ids & 0xFFu) == 0 || (ids>>8) == 0) // Unknown LCD?
|
||||
{
|
||||
MCU_PushToLCD(true);
|
||||
|
||||
LCD_Initialize(0x20);
|
||||
|
||||
*REG_GPU_CNT = 0x1007F;
|
||||
*GPU_PDC(0, 0x00) = 0x000001C2;
|
||||
*GPU_PDC(0, 0x04) = 0x000000D1;
|
||||
*GPU_PDC(0, 0x08) = 0x000001C1;
|
||||
*GPU_PDC(0, 0x0C) = 0x000001C1;
|
||||
*GPU_PDC(0, 0x10) = 0x00000000;
|
||||
*GPU_PDC(0, 0x14) = 0x000000CF;
|
||||
*GPU_PDC(0, 0x18) = 0x000000D1;
|
||||
*GPU_PDC(0, 0x1C) = 0x01C501C1;
|
||||
*GPU_PDC(0, 0x20) = 0x00010000;
|
||||
*GPU_PDC(0, 0x24) = 0x0000019D;
|
||||
*GPU_PDC(0, 0x28) = 0x00000002;
|
||||
*GPU_PDC(0, 0x2C) = 0x00000192;
|
||||
*GPU_PDC(0, 0x30) = 0x00000192;
|
||||
*GPU_PDC(0, 0x34) = 0x00000192;
|
||||
*GPU_PDC(0, 0x38) = 0x00000001;
|
||||
*GPU_PDC(0, 0x3C) = 0x00000002;
|
||||
*GPU_PDC(0, 0x40) = 0x01960192;
|
||||
*GPU_PDC(0, 0x44) = 0x00000000;
|
||||
*GPU_PDC(0, 0x48) = 0x00000000;
|
||||
*GPU_PDC(0, 0x5C) = 0x00F00190;
|
||||
*GPU_PDC(0, 0x60) = 0x01C100D1;
|
||||
*GPU_PDC(0, 0x64) = 0x01920002;
|
||||
*GPU_PDC(0, 0x68) = VRAM_START;
|
||||
*GPU_PDC(0, 0x6C) = VRAM_START;
|
||||
*GPU_PDC(0, 0x70) = 0x00080340;
|
||||
*GPU_PDC(0, 0x74) = 0x00010501;
|
||||
*GPU_PDC(0, 0x78) = 0x00000000;
|
||||
*GPU_PDC(0, 0x90) = 0x000003C0;
|
||||
*GPU_PDC(0, 0x94) = VRAM_START;
|
||||
*GPU_PDC(0, 0x98) = VRAM_START;
|
||||
*GPU_PDC(0, 0x9C) = 0x00000000;
|
||||
|
||||
for (u32 i = 0; i < 256; i++)
|
||||
*GPU_PDC(0, 0x84) = 0x10101 * i;
|
||||
|
||||
*GPU_PDC(1, 0x00) = 0x000001C2;
|
||||
*GPU_PDC(1, 0x04) = 0x000000D1;
|
||||
*GPU_PDC(1, 0x08) = 0x000001C1;
|
||||
*GPU_PDC(1, 0x0C) = 0x000001C1;
|
||||
*GPU_PDC(1, 0x10) = 0x000000CD;
|
||||
*GPU_PDC(1, 0x14) = 0x000000CF;
|
||||
*GPU_PDC(1, 0x18) = 0x000000D1;
|
||||
*GPU_PDC(1, 0x1C) = 0x01C501C1;
|
||||
*GPU_PDC(1, 0x20) = 0x00010000;
|
||||
*GPU_PDC(1, 0x24) = 0x0000019D;
|
||||
*GPU_PDC(1, 0x28) = 0x00000052;
|
||||
*GPU_PDC(1, 0x2C) = 0x00000192;
|
||||
*GPU_PDC(1, 0x30) = 0x00000192;
|
||||
*GPU_PDC(1, 0x34) = 0x0000004F;
|
||||
*GPU_PDC(1, 0x38) = 0x00000050;
|
||||
*GPU_PDC(1, 0x3C) = 0x00000052;
|
||||
*GPU_PDC(1, 0x40) = 0x01980194;
|
||||
*GPU_PDC(1, 0x44) = 0x00000000;
|
||||
*GPU_PDC(1, 0x48) = 0x00000011;
|
||||
*GPU_PDC(1, 0x5C) = 0x00F00140;
|
||||
*GPU_PDC(1, 0x60) = 0x01C100d1;
|
||||
*GPU_PDC(1, 0x64) = 0x01920052;
|
||||
*GPU_PDC(1, 0x68) = VRAM_START;
|
||||
*GPU_PDC(1, 0x6C) = VRAM_START;
|
||||
*GPU_PDC(1, 0x70) = 0x00080300;
|
||||
*GPU_PDC(1, 0x74) = 0x00010501;
|
||||
*GPU_PDC(1, 0x78) = 0x00000000;
|
||||
*GPU_PDC(1, 0x90) = 0x000003C0;
|
||||
*GPU_PDC(1, 0x9C) = 0x00000000;
|
||||
|
||||
for (u32 i = 0; i < 256; i++)
|
||||
*GPU_PDC(1, 0x84) = 0x10101 * i;
|
||||
TIMER_WaitMS(150);
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 i = 0;
|
||||
do
|
||||
{
|
||||
u16 top, bot;
|
||||
I2C_writeReg(I2C_DEV_LCD0, 0x40, 0x62);
|
||||
I2C_readRegBuf(I2C_DEV_LCD0, 0x40, (u8*)&top, 2);
|
||||
I2C_writeReg(I2C_DEV_LCD1, 0x40, 0x62);
|
||||
I2C_readRegBuf(I2C_DEV_LCD1, 0x40, (u8*)&bot, 2);
|
||||
|
||||
if((top>>8) == 1 && (bot>>8) == 1) break;
|
||||
|
||||
TIMER_WaitMS(33);
|
||||
} while(i++ < 10);
|
||||
}
|
||||
}
|
||||
|
||||
void GFX_powerOnBacklights(GfxBlight mask)
|
||||
{
|
||||
g_gfxState.lcdPower |= mask;
|
||||
|
||||
mask <<= 1;
|
||||
MCU_controlLCDPower(mask); // Power on backlights.
|
||||
if(MCU_waitEvents(0x3Fu<<24) != (u32)mask<<24)
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
void GFX_powerOffBacklights(GfxBlight mask)
|
||||
{
|
||||
g_gfxState.lcdPower &= ~mask;
|
||||
|
||||
MCU_controlLCDPower(mask); // Power off backlights.
|
||||
if(MCU_waitEvents(0x3Fu<<24) != (u32)mask<<24)
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
u8 GFX_getBrightness(void)
|
||||
{
|
||||
return REG_LCD_ABL0_LIGHT;
|
||||
}
|
||||
|
||||
void GFX_setBrightness(u8 top, u8 bot)
|
||||
{
|
||||
g_gfxState.lcdLights[0] = top;
|
||||
g_gfxState.lcdLights[1] = bot;
|
||||
REG_LCD_ABL0_LIGHT = top;
|
||||
REG_LCD_ABL1_LIGHT = bot;
|
||||
}
|
||||
|
||||
void GFX_setForceBlack(bool top, bool bot)
|
||||
{
|
||||
REG_LCD_ABL0_FILL = (u32)top<<24; // Force blackscreen
|
||||
REG_LCD_ABL1_FILL = (u32)bot<<24; // Force blackscreen
|
||||
}
|
||||
|
||||
static void setupDisplayController(u8 lcd)
|
||||
{
|
||||
if(lcd > 1) return;
|
||||
|
||||
static const u32 displayCfgs[2][24] =
|
||||
{
|
||||
{
|
||||
// PDC0 regs 0-0x4C.
|
||||
450, 209, 449, 449, 0, 207, 209, 453<<16 | 449,
|
||||
1<<16 | 0, 413, 2, 402, 402, 402, 1, 2,
|
||||
406<<16 | 402, 0, 0<<4 | 0, 0<<16 | 0xFF<<8 | 0,
|
||||
// PDC0 regs 0x5C-0x64.
|
||||
400<<16 | 240, // Width and height.
|
||||
449<<16 | 209,
|
||||
402<<16 | 2,
|
||||
// PDC0 reg 0x9C.
|
||||
0<<16 | 0
|
||||
},
|
||||
{
|
||||
// PDC1 regs 0-0x4C.
|
||||
450, 209, 449, 449, 205, 207, 209, 453<<16 | 449,
|
||||
1<<16 | 0, 413, 82, 402, 402, 79, 80, 82,
|
||||
408<<16 | 404, 0, 1<<4 | 1, 0<<16 | 0<<8 | 0xFF,
|
||||
// PDC1 regs 0x5C-0x64.
|
||||
320<<16 | 240, // Width and height.
|
||||
449<<16 | 209,
|
||||
402<<16 | 82,
|
||||
// PDC1 reg 0x9C.
|
||||
0<<16 | 0
|
||||
}
|
||||
};
|
||||
|
||||
const u32 *const cfg = displayCfgs[lcd];
|
||||
vu32 *const regs = (vu32*)(GX_REGS_BASE + 0x400 + (0x100u * lcd));
|
||||
|
||||
for (unsigned i = 0; i < 0x50/4; i++)
|
||||
regs[i] = cfg[i];
|
||||
|
||||
for (unsigned i = 0; i < 0xC/4; i++)
|
||||
regs[23 + i] = cfg[20 + i];
|
||||
|
||||
regs[36] = g_gfxState.strides[lcd]; // PDC reg 0x90 stride.
|
||||
regs[39] = cfg[23]; // PDC reg 0x9C.
|
||||
|
||||
// PDC regs 0x68, 0x6C, 0x94, 0x98 and 0x70.
|
||||
regs[26] = g_gfxState.framebufs[lcd]; // Framebuffer A first address.
|
||||
regs[27] = g_gfxState.framebufs[lcd]; // Framebuffer A second address.
|
||||
regs[37] = g_gfxState.framebufs[lcd]; // Framebuffer B first address.
|
||||
regs[38] = g_gfxState.framebufs[lcd]; // Framebuffer B second address.
|
||||
regs[28] = g_gfxState.formats[lcd]; // Format
|
||||
|
||||
regs[32] = 0; // Gamma table index 0.
|
||||
for(u32 i = 0; i < 256; i++) regs[33] = 0x10101u * i;
|
||||
}
|
||||
|
@ -21,21 +21,166 @@
|
||||
|
||||
#define VBLANK_INTERRUPT (0x2A)
|
||||
|
||||
void LCD_SetBrightness(u8 brightness);
|
||||
u8 LCD_GetBrightness(void);
|
||||
enum
|
||||
{
|
||||
PDN_GPU_CNT_RST_REGS = 1u, // And more?
|
||||
PDN_GPU_CNT_RST_PSC = 1u<<1, // ?
|
||||
PDN_GPU_CNT_RST_GEOSHADER = 1u<<2, // ?
|
||||
PDN_GPU_CNT_RST_RASTERIZER = 1u<<3, // ?
|
||||
PDN_GPU_CNT_RST_PPF = 1u<<4,
|
||||
PDN_GPU_CNT_RST_PDC = 1u<<5, // ?
|
||||
PDN_GPU_CNT_RST_PDC2 = 1u<<6, // Maybe pixel pipeline or so?
|
||||
|
||||
void LCD_Deinitialize(void);
|
||||
|
||||
void GPU_PSCFill(u32 start, u32 end, u32 fv);
|
||||
|
||||
enum {
|
||||
PDC_RGBA8 = 0,
|
||||
PDC_RGB24 = 1,
|
||||
PDC_RGB565 = 2,
|
||||
PDC_RGB5A1 = 3,
|
||||
PDC_RGBA4 = 4,
|
||||
PDN_GPU_CNT_RST_ALL = (PDN_GPU_CNT_RST_PDC2<<1) - 1
|
||||
};
|
||||
|
||||
void GPU_SetFramebufferMode(u32 screen, u8 mode);
|
||||
void GPU_SetFramebuffers(const u32 *framebuffers);
|
||||
void GPU_Init(void);
|
||||
typedef enum
|
||||
{
|
||||
GFX_RGBA8 = 0, ///< RGBA8. (4 bytes)
|
||||
GFX_BGR8 = 1, ///< BGR8. (3 bytes)
|
||||
GFX_RGB565 = 2, ///< RGB565. (2 bytes)
|
||||
GFX_RGB5A1 = 3, ///< RGB5A1. (2 bytes)
|
||||
GFX_RGBA4 = 4 ///< RGBA4. (2 bytes)
|
||||
} GfxFbFmt;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GFX_EVENT_PSC0 = 0u,
|
||||
GFX_EVENT_PSC1 = 1u,
|
||||
GFX_EVENT_PDC0 = 2u,
|
||||
GFX_EVENT_PDC1 = 3u,
|
||||
GFX_EVENT_PPF = 4u,
|
||||
GFX_EVENT_P3D = 5u
|
||||
} GfxEvent;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GFX_BLIGHT_BOT = 1u<<2,
|
||||
GFX_BLIGHT_TOP = 1u<<4,
|
||||
GFX_BLIGHT_BOTH = GFX_BLIGHT_TOP | GFX_BLIGHT_BOT
|
||||
} GfxBlight;
|
||||
|
||||
#define REG_CFG11_GPUPROT *((vu16*)(0x10140140))
|
||||
#define REG_PDN_GPU_CNT *((vu32*)(0x10141200))
|
||||
#define PDN_GPU_CNT_CLK_E (1u<<16)
|
||||
#define PDN_VRAM_CNT_CLK_E (1u)
|
||||
|
||||
|
||||
|
||||
#define GX_REGS_BASE (0x10400000)
|
||||
#define REG_GX_GPU_CLK *((vu32*)(GX_REGS_BASE + 0x0004)) // ?
|
||||
|
||||
// PSC (memory fill) regs.
|
||||
#define REG_GX_PSC_FILL0_S_ADDR *((vu32*)(GX_REGS_BASE + 0x0010)) // Start address
|
||||
#define REG_GX_PSC_FILL0_E_ADDR *((vu32*)(GX_REGS_BASE + 0x0014)) // End address
|
||||
#define REG_GX_PSC_FILL0_VAL *((vu32*)(GX_REGS_BASE + 0x0018)) // Fill value
|
||||
#define REG_GX_PSC_FILL0_CNT *((vu32*)(GX_REGS_BASE + 0x001C))
|
||||
|
||||
#define REG_GX_PSC_FILL1_S_ADDR *((vu32*)(GX_REGS_BASE + 0x0020))
|
||||
#define REG_GX_PSC_FILL1_E_ADDR *((vu32*)(GX_REGS_BASE + 0x0024))
|
||||
#define REG_GX_PSC_FILL1_VAL *((vu32*)(GX_REGS_BASE + 0x0028))
|
||||
#define REG_GX_PSC_FILL1_CNT *((vu32*)(GX_REGS_BASE + 0x002C))
|
||||
|
||||
#define REG_GX_PSC_VRAM *((vu32*)(GX_REGS_BASE + 0x0030)) // gsp mudule only changes bit 8-11.
|
||||
#define REG_GX_PSC_STAT *((vu32*)(GX_REGS_BASE + 0x0034))
|
||||
|
||||
// PDC0/1 regs see lcd.h.
|
||||
|
||||
// PPF (transfer engine) regs.
|
||||
#define REG_GX_PPF_IN_ADDR *((vu32*)(GX_REGS_BASE + 0x0C00))
|
||||
#define REG_GX_PPF_OUT_ADDR *((vu32*)(GX_REGS_BASE + 0x0C04))
|
||||
#define REG_GX_PPF_DT_OUTDIM *((vu32*)(GX_REGS_BASE + 0x0C08)) // Display transfer output dimensions.
|
||||
#define REG_GX_PPF_DT_INDIM *((vu32*)(GX_REGS_BASE + 0x0C0C)) // Display transfer input dimensions.
|
||||
#define REG_GX_PPF_FlAGS *((vu32*)(GX_REGS_BASE + 0x0C10))
|
||||
#define REG_GX_PPF_UNK14 *((vu32*)(GX_REGS_BASE + 0x0C14)) // Transfer interval?
|
||||
#define REG_GX_PPF_CNT *((vu32*)(GX_REGS_BASE + 0x0C18))
|
||||
#define REG_GX_PPF_IRQ_POS *((vu32*)(GX_REGS_BASE + 0x0C1C)) // ?
|
||||
#define REG_GX_PPF_LEN *((vu32*)(GX_REGS_BASE + 0x0C20)) // Texture copy size in bytes.
|
||||
#define REG_GX_PPF_TC_INDIM *((vu32*)(GX_REGS_BASE + 0x0C24)) // Texture copy input width and gap in 16 byte units.
|
||||
#define REG_GX_PPF_TC_OUTDIM *((vu32*)(GX_REGS_BASE + 0x0C28)) // Texture copy output width and gap in 16 byte units.
|
||||
|
||||
// P3D (GPU internal) regs. See gpu_regs.h.
|
||||
#define REG_GX_P3D(reg) *((vu32*)(GX_REGS_BASE + 0x1000 + ((reg) * 4)))
|
||||
|
||||
// LCD/ABL regs.
|
||||
#define LCD_REGS_BASE (0x10202000)
|
||||
#define REG_LCD_PARALLAX_CNT *((vu32*)(LCD_REGS_BASE + 0x000)) // Controls PWM for the parallax barrier?
|
||||
#define REG_LCD_PARALLAX_PWM *((vu32*)(LCD_REGS_BASE + 0x004)) // Frequency/other PWM stuff maybe?
|
||||
#define REG_LCD_UNK00C *((vu32*)(LCD_REGS_BASE + 0x00C)) // Wtf is "FIX"?
|
||||
#define REG_LCD_RST *((vu32*)(LCD_REGS_BASE + 0x014)) // Reset active low.
|
||||
|
||||
#define REG_LCD_ABL0_CNT *((vu32*)(LCD_REGS_BASE + 0x200)) // Bit 0 enables ABL aka power saving mode.
|
||||
#define REG_LCD_ABL0_FILL *((vu32*)(LCD_REGS_BASE + 0x204))
|
||||
#define REG_LCD_ABL0_LIGHT *((vu32*)(LCD_REGS_BASE + 0x240))
|
||||
#define REG_LCD_ABL0_LIGHT_PWM *((vu32*)(LCD_REGS_BASE + 0x244))
|
||||
|
||||
#define REG_LCD_ABL1_CNT *((vu32*)(LCD_REGS_BASE + 0xA00)) // Bit 0 enables ABL aka power saving mode.
|
||||
#define REG_LCD_ABL1_FILL *((vu32*)(LCD_REGS_BASE + 0xA04))
|
||||
#define REG_LCD_ABL1_LIGHT *((vu32*)(LCD_REGS_BASE + 0xA40))
|
||||
#define REG_LCD_ABL1_LIGHT_PWM *((vu32*)(LCD_REGS_BASE + 0xA44))
|
||||
|
||||
|
||||
// Technically these regs belong in gx.h but they are used for LCD configuration so...
|
||||
// Pitfall warning: The 3DS LCDs are physically rotated 90° CCW.
|
||||
|
||||
// PDC0 (top screen display controller) regs.
|
||||
#define REG_LCD_PDC0_HTOTAL *((vu32*)(GX_REGS_BASE + 0x400))
|
||||
#define REG_LCD_PDC0_VTOTAL *((vu32*)(GX_REGS_BASE + 0x424))
|
||||
#define REG_LCD_PDC0_HPOS *((const vu32*)(GX_REGS_BASE + 0x450))
|
||||
#define REG_LCD_PDC0_VPOS *((const vu32*)(GX_REGS_BASE + 0x454))
|
||||
#define REG_LCD_PDC0_FB_A1 *((vu32*)(GX_REGS_BASE + 0x468))
|
||||
#define REG_LCD_PDC0_FB_A2 *((vu32*)(GX_REGS_BASE + 0x46C))
|
||||
#define REG_LCD_PDC0_FMT *((vu32*)(GX_REGS_BASE + 0x470))
|
||||
#define REG_LCD_PDC0_CNT *((vu32*)(GX_REGS_BASE + 0x474))
|
||||
#define REG_LCD_PDC0_SWAP *((vu32*)(GX_REGS_BASE + 0x478))
|
||||
#define REG_LCD_PDC0_STAT *((const vu32*)(GX_REGS_BASE + 0x47C))
|
||||
#define REG_LCD_PDC0_GTBL_IDX *((vu32*)(GX_REGS_BASE + 0x480)) // Gamma table index.
|
||||
#define REG_LCD_PDC0_GTBL_FIFO *((vu32*)(GX_REGS_BASE + 0x484)) // Gamma table FIFO.
|
||||
#define REG_LCD_PDC0_STRIDE *((vu32*)(GX_REGS_BASE + 0x490))
|
||||
#define REG_LCD_PDC0_FB_B1 *((vu32*)(GX_REGS_BASE + 0x494))
|
||||
#define REG_LCD_PDC0_FB_B2 *((vu32*)(GX_REGS_BASE + 0x498))
|
||||
|
||||
// PDC1 (bottom screen display controller) regs.
|
||||
#define REG_LCD_PDC1_HTOTAL *((vu32*)(GX_REGS_BASE + 0x500))
|
||||
#define REG_LCD_PDC1_VTOTAL *((vu32*)(GX_REGS_BASE + 0x524))
|
||||
#define REG_LCD_PDC1_HPOS *((const vu32*)(GX_REGS_BASE + 0x550))
|
||||
#define REG_LCD_PDC1_VPOS *((const vu32*)(GX_REGS_BASE + 0x554))
|
||||
#define REG_LCD_PDC1_FB_A1 *((vu32*)(GX_REGS_BASE + 0x568))
|
||||
#define REG_LCD_PDC1_FB_A2 *((vu32*)(GX_REGS_BASE + 0x56C))
|
||||
#define REG_LCD_PDC1_FMT *((vu32*)(GX_REGS_BASE + 0x570))
|
||||
#define REG_LCD_PDC1_CNT *((vu32*)(GX_REGS_BASE + 0x574))
|
||||
#define REG_LCD_PDC1_SWAP *((vu32*)(GX_REGS_BASE + 0x578))
|
||||
#define REG_LCD_PDC1_STAT *((const vu32*)(GX_REGS_BASE + 0x57C))
|
||||
#define REG_LCD_PDC1_GTBL_IDX *((vu32*)(GX_REGS_BASE + 0x580)) // Gamma table index.
|
||||
#define REG_LCD_PDC1_GTBL_FIFO *((vu32*)(GX_REGS_BASE + 0x584)) // Gamma table FIFO.
|
||||
#define REG_LCD_PDC1_STRIDE *((vu32*)(GX_REGS_BASE + 0x590))
|
||||
#define REG_LCD_PDC1_FB_B1 *((vu32*)(GX_REGS_BASE + 0x594))
|
||||
#define REG_LCD_PDC1_FB_B2 *((vu32*)(GX_REGS_BASE + 0x598))
|
||||
|
||||
|
||||
// REG_LCD_PDC_CNT
|
||||
#define PDC_CNT_E (1u)
|
||||
#define PDC_CNT_I_MASK_H (1u<<8) // Disables H(Blank?) IRQs.
|
||||
#define PDC_CNT_I_MASK_V (1u<<9) // Disables VBlank IRQs.
|
||||
#define PDC_CNT_I_MASK_ERR (1u<<10) // Disables error IRQs. What kind of errors?
|
||||
#define PDC_CNT_OUT_E (1u<<16) // Output enable?
|
||||
|
||||
// REG_LCD_PDC_SWAP
|
||||
// Masks
|
||||
#define PDC_SWAP_NEXT (1u) // Next framebuffer.
|
||||
#define PDC_SWAP_CUR (1u<<4) // Currently displaying framebuffer?
|
||||
// Bits
|
||||
#define PDC_SWAP_RST_FIFO (1u<<8) // Which FIFO?
|
||||
#define PDC_SWAP_I_H (1u<<16) // H(Blank?) IRQ bit.
|
||||
#define PDC_SWAP_I_V (1u<<17) // VBlank IRQ bit.
|
||||
#define PDC_SWAP_I_ERR (1u<<18) // Error IRQ bit?
|
||||
#define PDC_SWAP_I_ALL (PDC_SWAP_I_ERR | PDC_SWAP_I_V | PDC_SWAP_I_H)
|
||||
|
||||
|
||||
unsigned GFX_init(GfxFbFmt mode);
|
||||
void GFX_setForceBlack(bool top, bool bot);
|
||||
void GFX_powerOnBacklights(GfxBlight mask);
|
||||
void GFX_powerOffBacklights(GfxBlight mask);
|
||||
|
||||
u8 GFX_getBrightness(void);
|
||||
void GFX_setBrightness(u8 top, u8 bot);
|
||||
|
@ -31,6 +31,9 @@
|
||||
#define I2C_IRQ_ENABLE (1u<<6)
|
||||
#define I2C_ENABLE (1u<<7)
|
||||
|
||||
#define I2C_DEV_LCD0 5
|
||||
#define I2C_DEV_LCD1 6
|
||||
|
||||
#define I2C_GET_ACK(reg) ((bool)((reg)>>4 & 1u))
|
||||
|
||||
|
||||
@ -62,3 +65,13 @@ bool I2C_readRegBuf(int devId, u8 regAddr, u8 *out, u32 size);
|
||||
* @return Returns true on success and false on failure.
|
||||
*/
|
||||
bool I2C_writeRegBuf(int devId, u8 regAddr, const u8 *in, u32 size);
|
||||
|
||||
static inline u8 I2C_readReg(int devId, u8 regAddr) {
|
||||
u8 v;
|
||||
I2C_readRegBuf(devId, regAddr, &v, 1);
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline void I2C_writeReg(int devId, u8 regAddr, u8 v) {
|
||||
I2C_writeRegBuf(devId, regAddr, &v, 1);
|
||||
}
|
||||
|
@ -135,12 +135,6 @@ void MCU_ResetLED(void)
|
||||
MCU_SetNotificationLED(0, 0);
|
||||
}
|
||||
|
||||
void MCU_PushToLCD(bool enable)
|
||||
{
|
||||
MCU_WriteReg(REG_LCD_STATE, enable ? 0x2A : 0x01);
|
||||
TIMER_WaitTicks(CLK_MS_TO_TICKS(160));
|
||||
}
|
||||
|
||||
void MCU_HandleInterrupts(u32 __attribute__((unused)) irqn)
|
||||
{
|
||||
u32 ints;
|
||||
@ -171,13 +165,11 @@ void MCU_HandleInterrupts(u32 __attribute__((unused)) irqn)
|
||||
break;
|
||||
|
||||
case MCU_SHELL_OPEN:
|
||||
MCU_PushToLCD(true);
|
||||
MCU_UpdateShellState(true);
|
||||
MCU_ResetLED();
|
||||
break;
|
||||
|
||||
case MCU_SHELL_CLOSE:
|
||||
MCU_PushToLCD(false);
|
||||
MCU_UpdateShellState(false);
|
||||
break;
|
||||
|
||||
@ -195,7 +187,7 @@ void MCU_HandleInterrupts(u32 __attribute__((unused)) irqn)
|
||||
|
||||
void MCU_Init(void)
|
||||
{
|
||||
u32 clrpend, mask = 0xFFBF0800;
|
||||
u32 clrpend, mask = 0;
|
||||
|
||||
/* set register mask and clear any pending registers */
|
||||
MCU_WriteRegBuf(REG_INT_EN, (const u8*)&mask, sizeof(mask));
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include "arm/timer.h"
|
||||
#include "hw/i2c.h"
|
||||
|
||||
#define MCU_INTERRUPT (0x71)
|
||||
@ -31,8 +32,6 @@ u32 MCU_GetSpecialHID(void);
|
||||
void MCU_SetNotificationLED(u32 period_ms, u32 color);
|
||||
void MCU_ResetLED(void);
|
||||
|
||||
void MCU_PushToLCD(bool enable);
|
||||
|
||||
void MCU_HandleInterrupts(u32 irqn);
|
||||
|
||||
void MCU_Init(void);
|
||||
@ -58,3 +57,20 @@ static inline bool MCU_WriteRegBuf(u8 addr, const u8 *buf, u32 size)
|
||||
{
|
||||
return I2C_writeRegBuf(I2C_MCU_DEVICE, addr, buf, size);
|
||||
}
|
||||
|
||||
static inline u32 MCU_waitEvents(u32 mask) {
|
||||
u32 v;
|
||||
while(1) {
|
||||
TIMER_WaitMS(10);
|
||||
MCU_ReadRegBuf(0x10, (u8*)&v, 4);
|
||||
v &= mask;
|
||||
if (v)
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline void MCU_controlLCDPower(u8 bits)
|
||||
{
|
||||
MCU_WriteReg(0x22u, bits);
|
||||
}
|
||||
|
@ -52,7 +52,8 @@ void VBlank_Handler(u32 __attribute__((unused)) irqn)
|
||||
int cur_bright_lvl = (MCU_GetVolumeSlider() >> 2) % countof(brightness_lvls);
|
||||
if ((cur_bright_lvl != prev_bright_lvl) && auto_brightness) {
|
||||
prev_bright_lvl = cur_bright_lvl;
|
||||
LCD_SetBrightness(brightness_lvls[cur_bright_lvl]);
|
||||
u8 br = brightness_lvls[cur_bright_lvl];
|
||||
GFX_setBrightness(br, br);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -98,9 +99,8 @@ void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
|
||||
|
||||
case PXI_SET_VMODE:
|
||||
{
|
||||
int mode = args[0] ? PDC_RGB24 : PDC_RGB565;
|
||||
GPU_SetFramebufferMode(0, mode);
|
||||
GPU_SetFramebufferMode(1, mode);
|
||||
int mode = args[0] ? GFX_BGR8 : GFX_RGB565;
|
||||
GFX_init(mode);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
@ -147,10 +147,11 @@ void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
|
||||
|
||||
case PXI_BRIGHTNESS:
|
||||
{
|
||||
ret = LCD_GetBrightness();
|
||||
s32 newbrightness = (s32)args[0];
|
||||
ret = GFX_getBrightness();
|
||||
#ifndef FIXED_BRIGHTNESS
|
||||
if ((args[0] > 0) && (args[0] < 0x100)) {
|
||||
LCD_SetBrightness(args[0]);
|
||||
if ((newbrightness > 0) && (newbrightness < 0x100)) {
|
||||
GFX_setBrightness(newbrightness, newbrightness);
|
||||
auto_brightness = false;
|
||||
} else {
|
||||
prev_bright_lvl = -1;
|
||||
@ -184,6 +185,8 @@ void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
|
||||
PXI_Send(ret);
|
||||
}
|
||||
|
||||
extern u32 pdcerr;
|
||||
|
||||
void __attribute__((noreturn)) MainLoop(void)
|
||||
{
|
||||
#ifdef FIXED_BRIGHTNESS
|
||||
|
@ -108,16 +108,7 @@ void SYS_CoreZeroInit(void)
|
||||
SPI_Init();
|
||||
CODEC_Init();
|
||||
|
||||
GPU_Init();
|
||||
GPU_PSCFill(VRAM_START, VRAM_END, 0);
|
||||
GPU_SetFramebuffers((u32[]){VRAM_TOP_LA, VRAM_TOP_LB,
|
||||
VRAM_TOP_RA, VRAM_TOP_RB,
|
||||
VRAM_BOT_A, VRAM_BOT_B});
|
||||
|
||||
GPU_SetFramebufferMode(0, PDC_RGB24);
|
||||
GPU_SetFramebufferMode(1, PDC_RGB24);
|
||||
|
||||
MCU_PushToLCD(true);
|
||||
GFX_init(GFX_RGB565);
|
||||
}
|
||||
|
||||
void SYS_CoreInit(void)
|
||||
|
@ -19,9 +19,6 @@ void main(int argc, char** argv, int entrypoint)
|
||||
// ARM11 says it's ready
|
||||
PXI_Barrier(ARM11_READY_BARRIER);
|
||||
|
||||
// Set screens to RGB16 mode
|
||||
PXI_DoCMD(PXI_SET_VMODE, (u32[]){0}, 1);
|
||||
|
||||
// A pointer to the shared memory region is
|
||||
// stored in the thread ID register in the ARM9
|
||||
ARM_InitSHMEM();
|
||||
|
@ -123,13 +123,9 @@ BootFirm:
|
||||
@ Setup the framebuffer struct
|
||||
ldr r0, =FBPTR_LOC
|
||||
ldr r1, =VRAM_TOP_LA
|
||||
ldr r2, =VRAM_TOP_RA
|
||||
ldr r2, =VRAM_TOP_LA
|
||||
ldr r3, =VRAM_BOT_A
|
||||
stmia r0!, {r1,r2,r3}
|
||||
|
||||
ldr r1, =VRAM_TOP_LB
|
||||
ldr r2, =VRAM_TOP_RB
|
||||
ldr r3, =VRAM_BOT_B
|
||||
stmia r0!, {r1,r2,r3}
|
||||
|
||||
@ Copy the FIRM path somewhere safe
|
||||
|
@ -18,8 +18,8 @@
|
||||
#define VRAM0_EASTER_BIN "easter.bin"
|
||||
|
||||
|
||||
#define VRAM0_OFFSET 0x18000000
|
||||
#define VRAM0_LIMIT 0x00300000
|
||||
#define VRAM0_OFFSET 0x080C0000
|
||||
#define VRAM0_LIMIT 0x00040000
|
||||
|
||||
#define TARDATA ((void*) VRAM0_OFFSET)
|
||||
#define TARDATA_(off) ((void*) (u32) (VRAM0_OFFSET + (off)))
|
||||
|
@ -1609,14 +1609,13 @@ u32 BuildCiaFromNcsdFile(const char* path_ncsd, const char* path_cia) {
|
||||
|
||||
// insert NCSD content
|
||||
TmdContentChunk* chunk = cia->content_list;
|
||||
for (u32 i = 0, idx = 0; i < 3; i++) {
|
||||
for (u32 i = 0; i < 3; i++) {
|
||||
NcchPartition* partition = ncsd.partitions + i;
|
||||
u32 offset = partition->offset * NCSD_MEDIA_UNIT;
|
||||
u32 size = partition->size * NCSD_MEDIA_UNIT;
|
||||
if (!size) continue;
|
||||
memset(chunk, 0, sizeof(TmdContentChunk));
|
||||
chunk->id[3] = i;
|
||||
chunk->index[1] = idx++;
|
||||
chunk->id[3] = chunk->index[1] = i;
|
||||
if (InsertCiaContent(path_cia, path_ncsd, offset, size, chunk++, NULL, false, (i == 0), false) != 0) {
|
||||
free(cia);
|
||||
return 1;
|
||||
|
@ -61,11 +61,13 @@
|
||||
#define assert(x) \
|
||||
(!!(x) ? (void)0 : __builtin_trap())
|
||||
|
||||
static inline void waitClks(unsigned clk) {
|
||||
asm_v("1: subs %0, %0, #2\n\tbne 1b\n\t":"=r"(clk)::"memory","cc");
|
||||
}
|
||||
|
||||
#define STATIC_ASSERT(...) \
|
||||
_Static_assert((__VA_ARGS__), #__VA_ARGS__)
|
||||
|
||||
|
||||
// standard output path (support file paths are in support.h)
|
||||
#define OUTPUT_PATH "0:/gm9/out"
|
||||
|
||||
|
@ -4,10 +4,8 @@
|
||||
#define BOTTOM_VRAM (320*240*4)
|
||||
|
||||
#define VRAM_START (0x18300000)
|
||||
|
||||
#define VRAM_TOP_LA (VRAM_START)
|
||||
#define VRAM_TOP_LB (VRAM_TOP_LA + TOP_VRAM)
|
||||
#define VRAM_TOP_RA (VRAM_TOP_LB + TOP_VRAM)
|
||||
#define VRAM_TOP_RB (VRAM_TOP_RA + TOP_VRAM)
|
||||
#define VRAM_BOT_A (VRAM_TOP_RB + TOP_VRAM)
|
||||
#define VRAM_BOT_B (VRAM_BOT_A + BOTTOM_VRAM)
|
||||
#define VRAM_END (VRAM_BOT_B + BOTTOM_VRAM)
|
||||
#define VRAM_BOT_A (VRAM_TOP_LA + TOP_VRAM)
|
||||
|
||||
#define VRAM_END (VRAM_BOT_A + BOTTOM_VRAM)
|
||||
|
Loading…
x
Reference in New Issue
Block a user