From 2b55060d43c9b7d23ef616a071f8180689697de8 Mon Sep 17 00:00:00 2001 From: Jon Feldman Date: Sat, 20 May 2017 03:34:47 -0400 Subject: [PATCH] Screeninit is broken I'm still unsure as to *why*, but I assume something I'm doing is probably causing an ARM11 exception. To be honest, part of the problem here is that I never should have gone with the whole mixing arm11 and arm9 code thing. For now, I've temporarily made the drawing code work in 24-bit mode and 32-bit mode via #ifdefs and nerfed screeninit from the code, instead adding the '-i' flag to firmtool. --- boot/arm11.c | 42 +++-------------------------- boot/corbenik.c | 10 +++---- boot/start.s | 7 ++--- boot/std/draw.c | 66 +++++++++++++++++++++++----------------------- include/arm11.h | 5 +++- include/std/draw.h | 14 +++++++++- 6 files changed, 63 insertions(+), 81 deletions(-) diff --git a/boot/arm11.c b/boot/arm11.c index 4e0e89e..333c1ff 100644 --- a/boot/arm11.c +++ b/boot/arm11.c @@ -36,6 +36,7 @@ #include // for PDC0_FRAMEBUFFER_SETUP_REG, PDC1_FRAMEBU... #include // for ctr_cache_clean_and_flush_all #include // for i2cWriteRegister, I2C_DEV_MCU +#include // for i2cWriteRegister, I2C_DEV_MCU #include // for memalign #include // for framebuffers #include @@ -47,11 +48,8 @@ static const uint32_t brightness[4] = {0x26, 0x39, 0x4C, 0x5F}; void invokeArm11Function(void (*func)()) { - installArm11Stub(); - *arm11Entry = (uint32_t)func; while(*arm11Entry); - *arm11Entry = ARM11_STUB_ADDRESS; } void deinitScreens(void) @@ -59,7 +57,7 @@ void deinitScreens(void) void __attribute__((naked)) ARM11(void) { //Disable interrupts - __asm(".word 0xF10C01C0"); + __asm(".word 0xF10C01C0"); // This is actually 'cpsid aif' but gcc doesn't like mixing arm9 and arm11 code. //Shutdown LCDs *(volatile uint32_t *)0x10202A44 = 0; @@ -95,36 +93,6 @@ void updateBrightness(uint32_t brightnessIndex) 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 set_fb_struct() { if (!framebuffers) { // Look ma, dynamically allocating the CakeHax struct! (joking) @@ -135,12 +103,12 @@ void set_fb_struct() { // Set not-actually cakebrah framebuffers. Meh. framebuffers->top_left = (uint8_t *)0x18300000; framebuffers->top_right = (uint8_t *)0x18300000; - framebuffers->bottom = (uint8_t *)0x1835dc00; + framebuffers->bottom = (uint8_t *)0x18300000 + (TOP_WIDTH * TOP_HEIGHT * SCREEN_DEPTH); } } void screen_mode(uint32_t mode, uint32_t bright_level) { - static uint32_t stride, init_top, init_bottom, bright; + static volatile uint32_t stride, init_top, init_bottom, bright; bright = brightness[bright_level]; @@ -255,8 +223,6 @@ void screen_mode(uint32_t mode, uint32_t bright_level) { ctr_cache_clean_and_flush_all(); invokeArm11Function(ARM11); - clearScreens(); - // Turn on backlight // i2cWriteRegister(I2C_DEV_MCU, 0x22, 1 << 1); //Turn on backlight diff --git a/boot/corbenik.c b/boot/corbenik.c index 5cd597d..9753aa4 100644 --- a/boot/corbenik.c +++ b/boot/corbenik.c @@ -51,6 +51,9 @@ main(int argc, char** argv) if (PDN_MPCORE_CFG == 7) is_n3ds = 1; // Enable n3ds specific options. + // Init FB structs + set_fb_struct(); + std_init(); if (crmount()) @@ -58,9 +61,6 @@ main(int argc, char** argv) load_config(); // Load configuration. - // Check key down for autoboot - set_fb_struct(); - install_interrupts(); // Get some free debug info. if (is_firmlaunch()) { @@ -94,7 +94,7 @@ main(int argc, char** argv) shut_up(); // This does exactly what it sounds like. if (have_bg && !si) { - screen_mode(RGBA8, get_opt_u32(OPTION_BRIGHTNESS)); // Use RGBA8 mode. +// screen_mode(RGBA8, get_opt_u32(OPTION_BRIGHTNESS)); // Use RGBA8 mode. si = 1; clear_disp(TOP_SCREEN); @@ -102,7 +102,7 @@ main(int argc, char** argv) } } else { if (!si) { - screen_mode(RGBA8, get_opt_u32(OPTION_BRIGHTNESS)); // Use RGBA8 mode. +// screen_mode(RGBA8, get_opt_u32(OPTION_BRIGHTNESS)); // Use RGBA8 mode. si = 1; clear_disp(TOP_SCREEN); diff --git a/boot/start.s b/boot/start.s index ea2997c..7ba0d85 100644 --- a/boot/start.s +++ b/boot/start.s @@ -80,8 +80,8 @@ init: ldr r3, =0x08000029 // 08000000 2M | arm9 mem ldr r4, =0x10000029 // 10000000 2M | io mem ldr r5, =0x20000037 // 20000000 256M | fcram - ldr r6, =0x1FF00027 // 1FF00000 1M - ldr r7, =0x1800002D // 18000000 8M + ldr r6, =0x1FF00027 // 1FF00000 1M | dsp & axiwrap + ldr r7, =0x1800002D // 18000000 8M | vram (+ 2MB) mcr p15, 0, r0, c6, c0, 0 mcr p15, 0, r1, c6, c1, 0 mcr p15, 0, r2, c6, c2, 0 @@ -90,6 +90,7 @@ init: mcr p15, 0, r5, c6, c5, 0 mcr p15, 0, r6, c6, c6, 0 mcr p15, 0, r7, c6, c7, 0 + mov r0, #0b10101001 // FIXME which sections does this do... stuff to? mcr p15, 0, r0, c2, c0, 0 // data cacheable mcr p15, 0, r0, c2, c0, 1 // instruction cacheable @@ -216,7 +217,7 @@ enable_mpu_and_caching: // Enable caches, MPU, and itcm mrc p15, 0, r0, c1, c0, 0 // read control register orr r0, r0, #(1<<18) // - itcm enable - orr r0, r0, #(1<<13) // - alt exception vector enable +// orr r0, r0, #(1<<13) // - alt exception vector enable orr r0, r0, #(1<<12) // - instruction cache enable orr r0, r0, #(1<<2) // - data cache enable orr r0, r0, #(1<<0) // - mpu enable diff --git a/boot/std/draw.c b/boot/std/draw.c index 595c817..10c7ad9 100644 --- a/boot/std/draw.c +++ b/boot/std/draw.c @@ -92,9 +92,9 @@ void rect(void* channel, unsigned int x, unsigned int y, unsigned int x2, unsign unsigned int yDisplacement = ((height - y_a - 1) * SCREEN_DEPTH); unsigned int pos = xDisplacement + yDisplacement; - screen[pos + 1] = colors[color & 0xF]; - screen[pos + 2] = colors[color & 0xF] >> 8; - screen[pos + 3] = colors[color & 0xF] >> 16; + screen[pos + CH_B] = colors[color & 0xF]; + screen[pos + CH_G] = colors[color & 0xF] >> 8; + screen[pos + CH_R] = colors[color & 0xF] >> 16; } } } @@ -126,9 +126,9 @@ void screenshot(void) { int yDisplacement = ((240 - y - 1) * SCREEN_DEPTH); int pos = xDisplacement + yDisplacement; - crwrite(& framebuffers->top_left[pos + 3], 1, 1, f); - crwrite(& framebuffers->top_left[pos + 2], 1, 1, f); - crwrite(& framebuffers->top_left[pos + 1], 1, 1, f); + crwrite(& framebuffers->top_left[pos + CH_B], 1, 1, f); + crwrite(& framebuffers->top_left[pos + CH_G], 1, 1, f); + crwrite(& framebuffers->top_left[pos + CH_R], 1, 1, f); } } @@ -143,9 +143,9 @@ void screenshot(void) { int yDisplacement = ((240 - y - 1) * SCREEN_DEPTH); int pos = xDisplacement + yDisplacement; - crwrite(& framebuffers->bottom[pos + 3], 1, 1, f); - crwrite(& framebuffers->bottom[pos + 2], 1, 1, f); - crwrite(& framebuffers->bottom[pos + 1], 1, 1, f); + crwrite(& framebuffers->bottom[pos + CH_B], 1, 1, f); + crwrite(& framebuffers->bottom[pos + CH_G], 1, 1, f); + crwrite(& framebuffers->bottom[pos + CH_R], 1, 1, f); } for (int i = 0; i < 40 * 3; i++) @@ -255,9 +255,9 @@ clear_disp(uint8_t *screen) if (!kill_output && get_opt_u32(OPTION_DIM_MODE)) { for(int i=0; i < TOP_SIZE; i += 4) { - screen[i + 1] = alphamap[screen[i + 1]]; - screen[i + 2] = alphamap[screen[i + 2]]; - screen[i + 3] = alphamap[screen[i + 3]]; + screen[i + CH_B] = alphamap[screen[i + 1]]; + screen[i + CH_G] = alphamap[screen[i + 2]]; + screen[i + CH_R] = alphamap[screen[i + 3]]; } } @@ -268,9 +268,9 @@ clear_disp(uint8_t *screen) if (!kill_output && get_opt_u32(OPTION_DIM_MODE)) { for(int i=0; i < BOTTOM_SIZE; i += 4) { - screen[i + 1] = alphamap[screen[i + 1]]; - screen[i + 2] = alphamap[screen[i + 2]]; - screen[i + 3] = alphamap[screen[i + 3]]; + screen[i + CH_B] = alphamap[screen[i + 1]]; + screen[i + CH_G] = alphamap[screen[i + 2]]; + screen[i + CH_R] = alphamap[screen[i + 3]]; } } @@ -331,34 +331,34 @@ draw_character(uint8_t *screen, const unsigned int character, unsigned int ch_x, if (char_dat & 0x80) { if (color_fg == 0) { if (!kill_output && get_opt_u32(OPTION_DIM_MODE)) { - screen[pos + 1] = alphamap[buffer_bg[pos + 1]]; - screen[pos + 2] = alphamap[buffer_bg[pos + 2]]; - screen[pos + 3] = alphamap[buffer_bg[pos + 3]]; + screen[pos + CH_B] = alphamap[buffer_bg[pos + 1]]; + screen[pos + CH_G] = alphamap[buffer_bg[pos + 2]]; + screen[pos + CH_R] = alphamap[buffer_bg[pos + 3]]; } else { - screen[pos + 1] = buffer_bg[pos + 1]; - screen[pos + 2] = buffer_bg[pos + 2]; - screen[pos + 3] = buffer_bg[pos + 3]; + screen[pos + CH_B] = buffer_bg[pos + 1]; + screen[pos + CH_G] = buffer_bg[pos + 2]; + screen[pos + CH_R] = buffer_bg[pos + 3]; } } else { - screen[pos + 1] = color_fg; - screen[pos + 2] = color_fg >> 8; - screen[pos + 3] = color_fg >> 16; + screen[pos + CH_B] = color_fg; + screen[pos + CH_G] = color_fg >> 8; + screen[pos + CH_R] = color_fg >> 16; } } else { if (color_bg == 0) { if (!kill_output && get_opt_u32(OPTION_DIM_MODE)) { - screen[pos + 1] = alphamap[buffer_bg[pos + 1]]; - screen[pos + 2] = alphamap[buffer_bg[pos + 2]]; - screen[pos + 3] = alphamap[buffer_bg[pos + 3]]; + screen[pos + CH_B] = alphamap[buffer_bg[pos + 1]]; + screen[pos + CH_G] = alphamap[buffer_bg[pos + 2]]; + screen[pos + CH_R] = alphamap[buffer_bg[pos + 3]]; } else { - screen[pos + 1] = buffer_bg[pos + 1]; - screen[pos + 2] = buffer_bg[pos + 2]; - screen[pos + 3] = buffer_bg[pos + 3]; + screen[pos + CH_B] = buffer_bg[pos + 1]; + screen[pos + CH_G] = buffer_bg[pos + 2]; + screen[pos + CH_R] = buffer_bg[pos + 3]; } } else { - screen[pos + 1] = color_bg; - screen[pos + 2] = color_bg >> 8; - screen[pos + 3] = color_bg >> 16; + screen[pos + CH_B] = color_bg; + screen[pos + CH_G] = color_bg >> 8; + screen[pos + CH_R] = color_bg >> 16; } } diff --git a/include/arm11.h b/include/arm11.h index 57e9c8f..ea1a903 100644 --- a/include/arm11.h +++ b/include/arm11.h @@ -41,7 +41,10 @@ #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)(); +#define WAIT_FOR_ARM9() \ + *arm11Entry = 0; \ + while(!*arm11Entry); \ + ((void (*)())*arm11Entry)(); /* Initializes the screen and sets the display mode. * diff --git a/include/std/draw.h b/include/std/draw.h index 7242380..5197619 100644 --- a/include/std/draw.h +++ b/include/std/draw.h @@ -13,11 +13,23 @@ #define BOTTOM_WIDTH 320 ///< Bottom screen width #define BOTTOM_HEIGHT 240 ///< Bottom screen height -#define SCREEN_DEPTH 4 ///< Pixel depth of the screen +#define SCREEN_DEPTH 3 ///< Pixel depth of the screen #define TOP_SIZE (TOP_WIDTH * TOP_HEIGHT * SCREEN_DEPTH) ///< Buffer size of top screen #define BOTTOM_SIZE (BOTTOM_WIDTH * BOTTOM_HEIGHT * SCREEN_DEPTH) ///< Buffer size of bottom screen +#if SCREEN_DEPTH == 4 + #define CH_B 1 + #define CH_G 2 + #define CH_R 3 +#elif SCREEN_DEPTH == 3 + #define CH_B 0 + #define CH_G 1 + #define CH_R 2 +#else + #error "This screen format is not supported." +#endif + enum screen { screen_top_left, -- 2.39.5