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.
#include <arm11.h> // for PDC0_FRAMEBUFFER_SETUP_REG, PDC1_FRAMEBU...
#include <ctr9/ctr_cache.h> // for ctr_cache_clean_and_flush_all
#include <ctr9/i2c.h> // for i2cWriteRegister, I2C_DEV_MCU
+#include <ctr9/ctr_system.h> // for i2cWriteRegister, I2C_DEV_MCU
#include <malloc.h> // for memalign
#include <std/draw.h> // for framebuffers
#include <util.h>
void invokeArm11Function(void (*func)())
{
- installArm11Stub();
-
*arm11Entry = (uint32_t)func;
while(*arm11Entry);
- *arm11Entry = ARM11_STUB_ADDRESS;
}
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;
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)
// 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];
ctr_cache_clean_and_flush_all();
invokeArm11Function(ARM11);
- clearScreens();
-
// Turn on backlight
// i2cWriteRegister(I2C_DEV_MCU, 0x22, 1 << 1);
//Turn on backlight
if (PDN_MPCORE_CFG == 7)
is_n3ds = 1; // Enable n3ds specific options.
+ // Init FB structs
+ set_fb_struct();
+
std_init();
if (crmount())
load_config(); // Load configuration.
- // Check key down for autoboot
- set_fb_struct();
-
install_interrupts(); // Get some free debug info.
if (is_firmlaunch()) {
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);
}
} 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);
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
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
// 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
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;
}
}
}
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);
}
}
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++)
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]];
}
}
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]];
}
}
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;
}
}
#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.
*
#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,