From: chaoskagami Date: Sat, 6 Aug 2016 14:01:37 +0000 (-0400) Subject: Refactor screeninit - fixes all the sanity issues, although some early-startup debugg... X-Git-Tag: v0.3.0~66^2 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=8e0ebc1b35f04fdea09bf8de4f1f5acdb3ad07d0;p=corbenik%2Fcorbenik.git Refactor screeninit - fixes all the sanity issues, although some early-startup debugging is gone --- diff --git a/Makefile.am b/Makefile.am index 7b893a1..657c66d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,7 +21,6 @@ all-local: cp source/corbenik.bin out/arm9loaderhax.bin cp external/loader/loader.cxi out@libdir@/module/loader.cxi cp external/bits/*.bin out@libexecdir@/ - cp external/screeninit/build/screeninit.bin out@libexecdir@/ cp host/termfont.bin out@datarootdir@/ cp patch/*.vco out@sbindir@ cp contrib/*.vco out@bindir@ diff --git a/external/Makefile.am b/external/Makefile.am index a88f86e..52d2b6a 100644 --- a/external/Makefile.am +++ b/external/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = libctr9 loader bits screeninit +SUBDIRS = libctr9 loader bits install: diff --git a/external/screeninit/Makefile b/external/screeninit/Makefile deleted file mode 100755 index b986b31..0000000 --- a/external/screeninit/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2)) - -ifeq ($(strip $(DEVKITARM)),) -$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") -endif - -include $(DEVKITARM)/3ds_rules - -CC := arm-none-eabi-gcc -AS := arm-none-eabi-as -LD := arm-none-eabi-ld -OC := arm-none-eabi-objcopy - -name_si := screeninit - -dir_source := source -dir_build := build - -ASFLAGS := -mcpu=mpcore -mfloat-abi=hard -CFLAGS := -Wall -Wextra -MMD -MP -mthumb -mthumb-interwork $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math -LDFLAGS := -nostdlib - -objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ - $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ - $(call rwildcard, $(dir_source), *.s *.c))) - -.PHONY: all -all: $(dir_build)/$(name_si).bin - -.PHONY: clean -clean: - @rm -rf $(dir_build) - -$(dir_build)/$(name_si).bin: $(dir_build)/$(name_si).elf - $(OC) -S -O binary $< $@ - -$(dir_build)/$(name_si).elf: $(objects) - $(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^ - -$(dir_build)/%.o: $(dir_source)/%.c - @mkdir -p "$(@D)" - $(COMPILE.c) $(OUTPUT_OPTION) $< - -$(dir_build)/%.o: $(dir_source)/%.s - @mkdir -p "$(@D)" - $(COMPILE.s) $(OUTPUT_OPTION) $< -include $(call rwildcard, $(dir_build), *.d) - -.PHONY: install -install: diff --git a/external/screeninit/linker.ld b/external/screeninit/linker.ld deleted file mode 100755 index 9ae0eaa..0000000 --- a/external/screeninit/linker.ld +++ /dev/null @@ -1,12 +0,0 @@ -ENTRY(_start) -SECTIONS -{ - . = 0x24FFFC00; - .text.start : { *(.text.start) } - .text : { *(.text) } - .data : { *(.data) } - .bss : { *(.bss COMMON) } - .rodata : { *(.rodata) } - . = ALIGN(4); -} - diff --git a/external/screeninit/source/main.c b/external/screeninit/source/main.c deleted file mode 100755 index d4f3898..0000000 --- a/external/screeninit/source/main.c +++ /dev/null @@ -1,143 +0,0 @@ -#include "types.h" - -#define FB_FMT(col, plx, screen) ((col & 0b111) | ((plx & 1) << 5) | ((screen & 1) << 6) | 0b10000000001100000000) - -#define RGBA8 0 -#define BGR8 1 -#define RGB565_OES 2 -#define RGB5_A1_OES 3 -#define RGBA4_OES 4 - -#define INIT_FULL 0 -#define INIT_PARAMS 1 -#define INIT_DEINIT 2 - -void __attribute__((naked)) main(void) { - // FIXME - We could use some serious macros here... - - u32 do_init = *(vu32 *)0x24FFFC08; - u32 brightnessLevel = *(vu32 *)0x24FFFC0C; - u32 mode = *(vu32 *)0x24FFFC10; - - u32 yaw, init_top, init_bottom; - switch(mode) { - case RGBA8: - yaw = 240 * 4; - break; - case BGR8: - case RGB565_OES: - case RGB5_A1_OES: - case RGBA4_OES: - yaw = 240 * 3; - break; - } - - init_top = FB_FMT(mode, 0, 1); - init_bottom = FB_FMT(mode, 0, 0); - - vu32 *const arm11 = (u32 *)0x1FFFFFF8; - - if (do_init == INIT_FULL) { - *(vu32 *)0x10141200 = 0x1007F; - *(vu32 *)0x10202014 = 0x00000001; - *(vu32 *)0x1020200C &= 0xFFFEFFFE; - } - - *(vu32 *)0x10202240 = brightnessLevel; // Alteration; directly read brightness. - *(vu32 *)0x10202A40 = brightnessLevel; - - if (do_init == INIT_FULL) { - *(vu32 *)0x10202244 = 0x1023E; - *(vu32 *)0x10202A44 = 0x1023E; - } - - // Top screen - *(vu32 *)0x10400400 = 0x000001c2; - *(vu32 *)0x10400404 = 0x000000d1; - *(vu32 *)0x10400408 = 0x000001c1; - *(vu32 *)0x1040040c = 0x000001c1; - *(vu32 *)0x10400410 = 0x00000000; - *(vu32 *)0x10400414 = 0x000000cf; - *(vu32 *)0x10400418 = 0x000000d1; - *(vu32 *)0x1040041c = 0x01c501c1; - *(vu32 *)0x10400420 = 0x00010000; - *(vu32 *)0x10400424 = 0x0000019d; - *(vu32 *)0x10400428 = 0x00000002; - *(vu32 *)0x1040042c = 0x00000192; - *(vu32 *)0x10400430 = 0x00000192; - *(vu32 *)0x10400434 = 0x00000192; - *(vu32 *)0x10400438 = 0x00000001; - *(vu32 *)0x1040043c = 0x00000002; - *(vu32 *)0x10400440 = 0x01960192; - *(vu32 *)0x10400444 = 0x00000000; - *(vu32 *)0x10400448 = 0x00000000; - - *(vu32 *)0x1040045C = 0x00f00190; - *(vu32 *)0x10400460 = 0x01c100d1; - *(vu32 *)0x10400464 = 0x01920002; - *(vu32 *)0x10400468 = 0x18300000; - *(vu32 *)0x10400470 = init_top; // Format - *(vu32 *)0x10400474 = 0x00010501; - *(vu32 *)0x10400478 = 0; - *(vu32 *)0x10400490 = yaw; - *(vu32 *)0x1040049C = 0x00000000; - - // Disco register - for(u32 i = 0; i < 256; i++) - *(vu32 *)0x10400484 = 0x10101 * i; - - // Bottom screen - *(vu32 *)0x10400500 = 0x000001c2; - *(vu32 *)0x10400504 = 0x000000d1; - *(vu32 *)0x10400508 = 0x000001c1; - *(vu32 *)0x1040050c = 0x000001c1; - *(vu32 *)0x10400510 = 0x000000cd; - *(vu32 *)0x10400514 = 0x000000cf; - *(vu32 *)0x10400518 = 0x000000d1; - *(vu32 *)0x1040051c = 0x01c501c1; - *(vu32 *)0x10400520 = 0x00010000; - *(vu32 *)0x10400524 = 0x0000019d; - *(vu32 *)0x10400528 = 0x00000052; - *(vu32 *)0x1040052c = 0x00000192; - *(vu32 *)0x10400530 = 0x00000192; - *(vu32 *)0x10400534 = 0x0000004f; - *(vu32 *)0x10400538 = 0x00000050; - *(vu32 *)0x1040053c = 0x00000052; - *(vu32 *)0x10400540 = 0x01980194; - *(vu32 *)0x10400544 = 0x00000000; - *(vu32 *)0x10400548 = 0x00000011; - *(vu32 *)0x1040055C = 0x00f00140; - *(vu32 *)0x10400560 = 0x01c100d1; - *(vu32 *)0x10400564 = 0x01920052; - *(vu32 *)0x10400568 = 0x18300000 + (yaw * 400); - *(vu32 *)0x10400570 = init_bottom; // Format - *(vu32 *)0x10400574 = 0x00010501; - *(vu32 *)0x10400578 = 0; - *(vu32 *)0x10400590 = yaw; - *(vu32 *)0x1040059C = 0x00000000; - - // Disco register - for(u32 i = 0; i < 256; i++) - *(vu32 *)0x10400584 = 0x10101 * i; - - *(vu32 *)0x10400468 = 0x18300000; - *(vu32 *)0x1040046c = 0x18300000; - *(vu32 *)0x10400494 = 0x18300000; - *(vu32 *)0x10400498 = 0x18300000; - *(vu32 *)0x10400568 = 0x18300000 + (yaw * 400); - *(vu32 *)0x1040056c = 0x18300000 + (yaw * 400); - - //Set CakeBrah framebuffers - *((vu32 *)0x23FFFE00) = 0x18300000; - *((vu32 *)0x23FFFE04) = 0x18300000; - *((vu32 *)0x23FFFE08) = 0x18300000 + (yaw * 400); - - //Clear ARM11 entry offset - *arm11 = 0; - - //Wait for the entry to be set - while(!*arm11); - - //Jump to it - ((void (*)())*arm11)(); -} diff --git a/external/screeninit/source/start.s b/external/screeninit/source/start.s deleted file mode 100644 index 1ce301b..0000000 --- a/external/screeninit/source/start.s +++ /dev/null @@ -1,12 +0,0 @@ -.section .text.start -.align 4 -.global _start -_start: - // Disable interrupts - CPSID aif - - b main - -do_init_or_deinit: .int 0 -brightness: .int 0 -mode: .int 0 diff --git a/external/screeninit/source/types.h b/external/screeninit/source/types.h deleted file mode 100755 index f47ac07..0000000 --- a/external/screeninit/source/types.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -//Common data types -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef volatile u8 vu8; -typedef volatile u16 vu16; -typedef volatile u32 vu32; -typedef volatile u64 vu64; - -extern int do_init_or_deinit; -extern int brightness; -extern int mode; -extern int brightness; diff --git a/include/screeninit.h b/include/screeninit.h index c616844..0a27794 100644 --- a/include/screeninit.h +++ b/include/screeninit.h @@ -1,6 +1,49 @@ #ifndef __SCREENINIT_H #define __SCREENINIT_H + +#define PDN_GPU_CNT (*(volatile uint32_t*)0x10141200) + +#define LCD_REG(offset) (*((volatile uint32_t*)(0x10202000 + (offset)))) +#define LCD_TOP_CONF_REG(offset) (*((volatile uint32_t*)(0x10202200 + (offset)))) +#define LCD_BOT_CONF_REG(offset) (*((volatile uint32_t*)(0x10202A00 + (offset)))) +#define LCD_TOP_CONF_BRIGHTNESS LCD_TOP_CONF_REG(0x40) +#define LCD_BOT_CONF_BRIGHTNESS LCD_BOT_CONF_REG(0x40) + +#define PDC0_FRAMEBUFFER_SETUP_REG(offset) (*((volatile uint32_t*)(0x10400400 + (offset)))) +#define PDC1_FRAMEBUFFER_SETUP_REG(offset) (*((volatile uint32_t*)(0x10400500 + (offset)))) + +#define PDC0_FRAMEBUFFER_SETUP_DIMS PDC0_FRAMEBUFFER_SETUP_REG(0x5C) +#define PDC0_FRAMEBUFFER_SETUP_FBA_ADDR_1 PDC0_FRAMEBUFFER_SETUP_REG(0x68) +#define PDC0_FRAMEBUFFER_SETUP_FBA_ADDR_2 PDC0_FRAMEBUFFER_SETUP_REG(0x6C) +#define PDC0_FRAMEBUFFER_SETUP_FB_FORMAT PDC0_FRAMEBUFFER_SETUP_REG(0x70) +#define PDC0_FRAMEBUFFER_SETUP_FB_SELECT PDC0_FRAMEBUFFER_SETUP_REG(0x78) +#define PDC0_FRAMEBUFFER_SETUP_DISCO PDC0_FRAMEBUFFER_SETUP_REG(0x84) +#define PDC0_FRAMEBUFFER_SETUP_FB_STRIDE PDC0_FRAMEBUFFER_SETUP_REG(0x90) +#define PDC0_FRAMEBUFFER_SETUP_FBB_ADDR_1 PDC0_FRAMEBUFFER_SETUP_REG(0x94) +#define PDC0_FRAMEBUFFER_SETUP_FBB_ADDR_2 PDC0_FRAMEBUFFER_SETUP_REG(0x98) + +#define PDC1_FRAMEBUFFER_SETUP_DIMS PDC1_FRAMEBUFFER_SETUP_REG(0x5C) +#define PDC1_FRAMEBUFFER_SETUP_FBA_ADDR_1 PDC1_FRAMEBUFFER_SETUP_REG(0x68) +#define PDC1_FRAMEBUFFER_SETUP_FBA_ADDR_2 PDC1_FRAMEBUFFER_SETUP_REG(0x6C) +#define PDC1_FRAMEBUFFER_SETUP_FB_FORMAT PDC1_FRAMEBUFFER_SETUP_REG(0x70) +#define PDC1_FRAMEBUFFER_SETUP_FB_SELECT PDC1_FRAMEBUFFER_SETUP_REG(0x78) +#define PDC1_FRAMEBUFFER_SETUP_DISCO PDC1_FRAMEBUFFER_SETUP_REG(0x84) +#define PDC1_FRAMEBUFFER_SETUP_FB_STRIDE PDC1_FRAMEBUFFER_SETUP_REG(0x90) +#define PDC1_FRAMEBUFFER_SETUP_FBB_ADDR_1 PDC1_FRAMEBUFFER_SETUP_REG(0x94) +#define PDC1_FRAMEBUFFER_SETUP_FBB_ADDR_2 PDC1_FRAMEBUFFER_SETUP_REG(0x98) + +#define MAKE_FRAMEBUFFER_PIXFMT(col, plx, screen) ((col & 0b111) | ((plx & 1) << 5) | ((screen & 1) << 6) | 0b10000000001100000000) + +#define RGBA8 0 +#define BGR8 1 +#define RGB565_OES 2 +#define RGB5_A1_OES 3 +#define RGBA4_OES 4 + +#define ARM11_STUB_ADDRESS (0x25000000 - 0x30) //It's currently only 0x28 bytes large. We're putting 0x30 just to be sure here +#define WAIT_FOR_ARM9() *arm11Entry = 0; while(!*arm11Entry); ((void (*)())*arm11Entry)(); + // Inits the screen if needed. void screen_mode(uint32_t mode); diff --git a/include/std/draw.h b/include/std/draw.h index dbc88a6..98c91e2 100644 --- a/include/std/draw.h +++ b/include/std/draw.h @@ -25,7 +25,7 @@ enum screen screen_bottom }; -_UNUSED static struct framebuffers +_UNUSED static volatile struct framebuffers { uint8_t *top_left; uint8_t *top_right; diff --git a/source/main.c b/source/main.c index 9a728e1..4ca5b9b 100644 --- a/source/main.c +++ b/source/main.c @@ -25,19 +25,19 @@ main(int argc, char** argv) // Failed to mount SD. Bomb out. // TODO - What the hell does one even do in this situation? // Spin until the card is available to mount, maybe? - abort("Failed to mount SD card.\n"); + while(1); } if (argc >= 1 && argc < 2) { // Valid argc passed. - fprintf(stderr, "Chainloaded. Path: %s\n", argv[0]); +// fprintf(stderr, "Chainloaded. Path: %s\n", argv[0]); } set_font(PATH_TERMFONT); // Read the font before all else. load_config(); // Load configuration. - screen_mode(0); // Use RGBA8 mode. + screen_mode(RGBA8); // Use RGBA8 mode. clear_bg(); @@ -47,9 +47,9 @@ main(int argc, char** argv) clear_disp(TOP_SCREEN); clear_disp(BOTTOM_SCREEN); - ctr_screen_enable_backlight(CTR_SCREEN_BOTH); +// ctr_screen_enable_backlight(CTR_SCREEN_BOTH); - install_interrupts(); // Get some free debug info. +// install_interrupts(); // Get some free debug info. if (CFG_BOOTENV == 7) { fprintf(stderr, "Rebooted from AGB, disabling EmuNAND.\n"); diff --git a/source/option.c b/source/option.c index b54dbb5..7d2edf8 100644 --- a/source/option.c +++ b/source/option.c @@ -16,12 +16,10 @@ regenerate_config() config.options[OPTION_BRIGHTNESS] = 3; if (!(conf_handle = fopen(PATH_CONFIG, "w"))) - abort("Failed to open config for write?\n"); + while(1); fwrite(&config, 1, sizeof(config), conf_handle); fclose(conf_handle); - - fprintf(BOTTOM_SCREEN, "Config file written.\n"); } void @@ -58,7 +56,6 @@ update_config() int updated = 0; if (config.options[OPTION_ACCENT_COLOR] == 0) { - fprintf(stderr, "Config update: accent color\n"); config.options[OPTION_ACCENT_COLOR] = 2; updated = 1; } @@ -75,31 +72,17 @@ load_config() // Zero on success. if (!(conf_handle = fopen(PATH_CONFIG, "r"))) { - fprintf(BOTTOM_SCREEN, "Config file is missing:\n" - " %s\n" - "Regenerating with defaults.\n", - PATH_CONFIG); regenerate_config(); } else { fread(&config, 1, sizeof(config), conf_handle); fclose(conf_handle); if (memcmp(&(config.magic), CONFIG_MAGIC, 4)) { - fprintf(BOTTOM_SCREEN, "Config file at:\n" - " %s\n" - "has incorrect magic:\n" - " '%c%c%c%c'\n" - "Regenerating with defaults.\n", - PATH_CONFIG, config.magic[0], config.magic[1], config.magic[2], config.magic[3]); f_unlink(PATH_CONFIG); regenerate_config(); } if (config.config_ver < config_version) { - fprintf(BOTTOM_SCREEN, "Config file has outdated version:\n" - " %s\n" - "Regenerating with defaults.\n", - PATH_CONFIG); f_unlink(PATH_CONFIG); regenerate_config(); } @@ -107,9 +90,6 @@ load_config() list_patches_build(PATH_PATCHES, 0); - if (!config.options[OPTION_SILENCE]) - fprintf(BOTTOM_SCREEN, "Config file loaded.\n"); - update_config(); } @@ -121,7 +101,7 @@ save_config() f_unlink(PATH_CONFIG); if (!(conf_handle = fopen(PATH_CONFIG, "w"))) - abort("Failed to open config for write?\n"); + while(1); config.options[OPTION_RECONFIGURED] = 0; // This should not persist to disk. @@ -129,6 +109,4 @@ save_config() fclose(conf_handle); config.options[OPTION_RECONFIGURED] = 1; // Save caches on boot. - - fprintf(stderr, "Saved config successfully.\n"); } diff --git a/source/screeninit.c b/source/screeninit.c index 72dc48e..167c079 100644 --- a/source/screeninit.c +++ b/source/screeninit.c @@ -1,44 +1,254 @@ +// Copyright (C) 2016 Aurora Wright, TuxSH + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified +// reasonable legal notices or author attributions in that material or in the Appropriate Legal +// Notices displayed by works containing it. + +// ============================================ + +// Screen init code by dark_samus, bil1s, Normmatt, delebile and others. +// Screen deinit code by tiniVi. +// More readable screeninit by Gelex. + +// ============================================ + +// This is less a permanent solution and more a quickfix since I'd rather use libctr11 +// whenever Gelex finishes it. Don't rely on it staying here. + +// Also, you are correct in thinking this looks near nothing like Luma's code at this point. + #include #include #include +#include #include -#define PDN_GPU_CNT (*(volatile uint8_t *)0x10141200) +volatile uint32_t *const arm11Entry = (volatile uint32_t *)0x1FFFFFF8; +static const uint32_t brightness[4] = {0x26, 0x39, 0x4C, 0x5F}; + +void __attribute__((naked)) arm11Stub(void) +{ + //Disable interrupts + __asm(".word 0xF10C01C0"); -static volatile uint32_t *const a11_entry = (volatile uint32_t *)0x1FFFFFF8; + //Wait for the entry to be set + while(*arm11Entry == ARM11_STUB_ADDRESS); -void -screen_mode(uint32_t mode) + //Jump to it + ((void (*)())*arm11Entry)(); +} + +static void invokeArm11Function(void (*func)()) +{ + static int hasCopiedStub = false; + if(!hasCopiedStub) + { + memcpy((void *)ARM11_STUB_ADDRESS, arm11Stub, 0x30); + ctr_cache_clean_and_flush_all(); + hasCopiedStub = true; + } + + *arm11Entry = (uint32_t)func; + while(*arm11Entry); + *arm11Entry = ARM11_STUB_ADDRESS; +} + +void deinitScreens(void) { - uint32_t *screenInitAddress = (uint32_t *)0x24FFFC00; + void __attribute__((naked)) ARM11(void) + { + //Disable interrupts + __asm(".word 0xF10C01C0"); + + //Shutdown LCDs + *(volatile uint32_t *)0x10202A44 = 0; + *(volatile uint32_t *)0x10202244 = 0; + *(volatile uint32_t *)0x10202014 = 0; + + WAIT_FOR_ARM9(); + } + + if(PDN_GPU_CNT != 1) invokeArm11Function(ARM11); +} + +void updateBrightness(uint32_t brightnessIndex) +{ + static uint32_t brightnessLevel; + brightnessLevel = brightness[brightnessIndex]; + + void __attribute__((naked)) ARM11(void) + { + //Disable interrupts + __asm(".word 0xF10C01C0"); + + //Change brightness + *(volatile uint32_t *)0x10202240 = brightnessLevel; + *(volatile uint32_t *)0x10202A40 = brightnessLevel; + + WAIT_FOR_ARM9(); + } + + ctr_cache_clean_and_flush_all(); + invokeArm11Function(ARM11); +} + +void clearScreens(void) { + void __attribute__((naked)) ARM11(void) + { + //Disable interrupts + __asm(".word 0xF10C01C0"); + + //Setting up two simultaneous memory fills using the GPU + volatile uint32_t *REGs_PSC0 = (volatile uint32_t *)0x10400010; + + REGs_PSC0[0] = (uint32_t)framebuffers->top_left >> 3; //Start address + REGs_PSC0[1] = (uint32_t)(framebuffers->top_left + (400 * 240 * 4)) >> 3; //End address + REGs_PSC0[2] = 0; //Fill value + REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start + + volatile uint32_t *REGs_PSC1 = (volatile uint32_t *)0x10400020; + + REGs_PSC1[0] = (uint32_t)framebuffers->bottom >> 3; //Start address + REGs_PSC1[1] = (uint32_t)(framebuffers->bottom + (320 * 240 * 4)) >> 3; //End address + REGs_PSC1[2] = 0; //Fill value + REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start + + while(!((REGs_PSC0[3] & 2) && (REGs_PSC1[3] & 2))); + + WAIT_FOR_ARM9(); + } + + ctr_cache_clean_and_flush_all(); + invokeArm11Function(ARM11); +} + +void screen_mode(uint32_t mode) { + static uint32_t stride, init_top, init_bottom, bright; + + bright = brightness[config.options[OPTION_BRIGHTNESS]]; + + stride = 240 * 3; + if (mode == RGBA8) + stride = 240 * 4; + + init_top = MAKE_FRAMEBUFFER_PIXFMT(mode, 0, 1); + init_bottom = MAKE_FRAMEBUFFER_PIXFMT(mode, 0, 0); + + void __attribute__((naked)) ARM11(void) { + //Disable interrupts + __asm(".word 0xF10C01C0"); + + PDN_GPU_CNT = 0x1007F; //bit0: Enable GPU regs 0x10400000+, bit16 turn on LCD backlight? + LCD_REG(0x14) = 0x00000001; //UNKNOWN register, maybe LCD related? 0x10202000 + LCD_REG(0xC) &= 0xFFFEFFFE; //UNKNOWN register, maybe LCD related? + + LCD_TOP_CONF_BRIGHTNESS = bright; + LCD_BOT_CONF_BRIGHTNESS = bright; + LCD_TOP_CONF_REG(0x44) = 0x1023E; //unknown + LCD_BOT_CONF_REG(0x44) = 0x1023E; //unknown - FILE *f = fopen(PATH_SCREENINIT_CODE, "r"); - fread(screenInitAddress, 1, fsize(f), f); // Read in the screeninit payload. - fclose(f); + // Top screen + PDC0_FRAMEBUFFER_SETUP_REG(0x00) = 0x000001c2; //unknown + PDC0_FRAMEBUFFER_SETUP_REG(0x04) = 0x000000d1; //unknown + PDC0_FRAMEBUFFER_SETUP_REG(0x08) = 0x000001c1; + PDC0_FRAMEBUFFER_SETUP_REG(0x0c) = 0x000001c1; + PDC0_FRAMEBUFFER_SETUP_REG(0x10) = 0x00000000; + PDC0_FRAMEBUFFER_SETUP_REG(0x14) = 0x000000cf; + PDC0_FRAMEBUFFER_SETUP_REG(0x18) = 0x000000d1; + PDC0_FRAMEBUFFER_SETUP_REG(0x1c) = 0x01c501c1; + PDC0_FRAMEBUFFER_SETUP_REG(0x20) = 0x00010000; + PDC0_FRAMEBUFFER_SETUP_REG(0x24) = 0x0000019d; + PDC0_FRAMEBUFFER_SETUP_REG(0x28) = 0x00000002; + PDC0_FRAMEBUFFER_SETUP_REG(0x2c) = 0x00000192; + PDC0_FRAMEBUFFER_SETUP_REG(0x30) = 0x00000192; + PDC0_FRAMEBUFFER_SETUP_REG(0x34) = 0x00000192; + PDC0_FRAMEBUFFER_SETUP_REG(0x38) = 0x00000001; + PDC0_FRAMEBUFFER_SETUP_REG(0x3c) = 0x00000002; + PDC0_FRAMEBUFFER_SETUP_REG(0x40) = 0x01960192; + PDC0_FRAMEBUFFER_SETUP_REG(0x44) = 0x00000000; + PDC0_FRAMEBUFFER_SETUP_REG(0x48) = 0x00000000; + PDC0_FRAMEBUFFER_SETUP_DIMS = (240u << 16) | (400u); + PDC0_FRAMEBUFFER_SETUP_REG(0x60) = 0x01c100d1; + PDC0_FRAMEBUFFER_SETUP_REG(0x64) = 0x01920002; + PDC0_FRAMEBUFFER_SETUP_FBA_ADDR_1 = 0x18300000; + PDC0_FRAMEBUFFER_SETUP_FB_FORMAT = init_top; + PDC0_FRAMEBUFFER_SETUP_REG(0x74) = 0x00010501; + PDC0_FRAMEBUFFER_SETUP_FB_SELECT = 0; + PDC0_FRAMEBUFFER_SETUP_FB_STRIDE = stride; + PDC0_FRAMEBUFFER_SETUP_REG(0x9C) = 0x00000000; - // FIXME - At the moment, this seems mandatory to do full screeninit. + // Disco register + for(volatile uint32_t i = 0; i < 256; i++) + PDC0_FRAMEBUFFER_SETUP_DISCO = 0x10101 * i; - // I get very fucked up results from just changing the framebuffer offsets - // and display color mode. Until I figure out WHY a full screeninit has to - // be performed, I have to do a full screeninit. + // Bottom screen + PDC1_FRAMEBUFFER_SETUP_REG(0x00) = 0x000001c2; + PDC1_FRAMEBUFFER_SETUP_REG(0x04) = 0x000000d1; + PDC1_FRAMEBUFFER_SETUP_REG(0x08) = 0x000001c1; + PDC1_FRAMEBUFFER_SETUP_REG(0x0c) = 0x000001c1; + PDC1_FRAMEBUFFER_SETUP_REG(0x10) = 0x000000cd; + PDC1_FRAMEBUFFER_SETUP_REG(0x14) = 0x000000cf; + PDC1_FRAMEBUFFER_SETUP_REG(0x18) = 0x000000d1; + PDC1_FRAMEBUFFER_SETUP_REG(0x1c) = 0x01c501c1; + PDC1_FRAMEBUFFER_SETUP_REG(0x20) = 0x00010000; + PDC1_FRAMEBUFFER_SETUP_REG(0x24) = 0x0000019d; + PDC1_FRAMEBUFFER_SETUP_REG(0x28) = 0x00000052; + PDC1_FRAMEBUFFER_SETUP_REG(0x2c) = 0x00000192; + PDC1_FRAMEBUFFER_SETUP_REG(0x30) = 0x00000192; + PDC1_FRAMEBUFFER_SETUP_REG(0x34) = 0x0000004f; + PDC1_FRAMEBUFFER_SETUP_REG(0x38) = 0x00000050; + PDC1_FRAMEBUFFER_SETUP_REG(0x3c) = 0x00000052; + PDC1_FRAMEBUFFER_SETUP_REG(0x40) = 0x01980194; + PDC1_FRAMEBUFFER_SETUP_REG(0x44) = 0x00000000; + PDC1_FRAMEBUFFER_SETUP_REG(0x48) = 0x00000011; + PDC1_FRAMEBUFFER_SETUP_DIMS = (240u << 16) | 320u; + PDC1_FRAMEBUFFER_SETUP_REG(0x60) = 0x01c100d1; + PDC1_FRAMEBUFFER_SETUP_REG(0x64) = 0x01920052; + PDC1_FRAMEBUFFER_SETUP_FBA_ADDR_1 = 0x1835dc00; + PDC1_FRAMEBUFFER_SETUP_FB_FORMAT = init_bottom; + PDC1_FRAMEBUFFER_SETUP_REG(0x74) = 0x00010501; + PDC1_FRAMEBUFFER_SETUP_FB_SELECT = 0; + PDC1_FRAMEBUFFER_SETUP_FB_STRIDE = stride; + PDC1_FRAMEBUFFER_SETUP_REG(0x9C) = 0x00000000; - // And no, 3dbrew didn't help. Partial init seems to be a superset of what - // I was attempting. + // Disco register + for(volatile uint32_t i = 0; i < 256; i++) + PDC1_FRAMEBUFFER_SETUP_DISCO = 0x10101 * i; - screenInitAddress[2] = 1; // Do a partial init. + PDC0_FRAMEBUFFER_SETUP_FBA_ADDR_1 = 0x18300000; + PDC0_FRAMEBUFFER_SETUP_FBA_ADDR_2 = 0x18300000; + PDC0_FRAMEBUFFER_SETUP_FBB_ADDR_1 = 0x18300000; + PDC0_FRAMEBUFFER_SETUP_FBB_ADDR_2 = 0x18300000; - if (PDN_GPU_CNT == 1) - screenInitAddress[2] = 0; // Do a full init. + PDC1_FRAMEBUFFER_SETUP_FBA_ADDR_1 = 0x1835dc00; + PDC1_FRAMEBUFFER_SETUP_FBA_ADDR_2 = 0x1835dc00; - // FIXME - God awful syntactical hack. - screenInitAddress[3] = ("\x40\x8F\xC0\xFF")[config.options[OPTION_BRIGHTNESS]]; + //Set CakeBrah framebuffers + framebuffers->top_left = (uint8_t *)0x18300000; + framebuffers->top_right = (uint8_t *)0x18300000; + framebuffers->bottom = (uint8_t *)0x1835dc00; - screenInitAddress[4] = mode; // Mode + WAIT_FOR_ARM9(); + } - *a11_entry = (uint32_t)screenInitAddress; + ctr_cache_clean_and_flush_all(); + invokeArm11Function(ARM11); - while (*a11_entry); + clearScreens(); - // Turn on backlight - i2cWriteRegister(I2C_DEV_MCU, 0x22, 1 << 1); + //Turn on backlight + i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A); }