void initScreens(void) { static bool needToSetup = true; if(needToSetup) { memcpy((void *)ARM11_PARAMETERS_ADDRESS, fbs, sizeof(fbs)); invokeArm11Function(SETUP_FRAMEBUFFERS); if(!ARESCREENSINITIALIZED) { *(vu32 *)ARM11_PARAMETERS_ADDRESS = brightness[MULTICONFIG(BRIGHTNESS)]; invokeArm11Function(INIT_SCREENS); //Turn on backlight i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A); } else updateBrightness(MULTICONFIG(BRIGHTNESS)); clearScreens(true); needToSetup = false; } clearScreens(false); swapFramebuffers(false); }
void mcuReboot(void) { flushEntireDCache(); //Ensure that all memory transfers have completed and that the data cache has been flushed i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); while(1); }
void menu_main() { while (1) { char *options[] = {"Boot CFW", "Select Patches", "More options...", "Version info", "Power off"}; int result = draw_menu("CakesFW " CAKES_VERSION, 0, sizeof(options) / sizeof(char *), options); switch (result) { case 0: save_config(); boot_cfw(); break; case 1: menu_select_patches(); break; case 2: menu_more(); break; case 3: version_info(); break; case 4: i2cWriteRegister(I2C_DEV_MCU, 0x20, 1); while(1); // Won't break out of this one >:D } } }
void shutdown(u32 mode, const char *message){ if(mode){ pos_y = drawString(message, 10, pos_y + SPACING_VERT, COLOR_RED); drawString("Press any button to shutdown", 10, pos_y, COLOR_WHITE); waitInput(); } i2cWriteRegister(I2C_DEV_MCU, 0x20, 1); while(1); }
//--------------------------------------------------------------------------------- void i2cIRQHandler() { //--------------------------------------------------------------------------------- int cause = (i2cReadRegister(I2C_PM, I2CREGPM_PWRIF) & 0x3) | (i2cReadRegister(I2C_GPIO, 0x02)<<2); switch (cause & 3) { case 1: if (__powerbuttonCB) { __powerbuttonCB(); } else { i2cWriteRegister(I2C_PM, I2CREGPM_RESETFLAG, 1); i2cWriteRegister(I2C_PM, I2CREGPM_PWRCNT, 1); } break; case 2: writePowerManagement(PM_CONTROL_REG,PM_SYSTEM_PWR); break; } }
void mcuReboot(void) { if(!isFirmlaunch && PDN_GPU_CNT != 1) clearScreens(true, true, false); //Ensure that all memory transfers have completed and that the data cache has been flushed flushEntireDCache(); i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 1); while(true); }
void mcuPowerOff(void) { if(!isFirmlaunch && ARESCREENSINITIALIZED) clearScreens(false); //Ensure that all memory transfers have completed and that the data cache has been flushed flushEntireDCache(); i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 0); while(true); }
// @breif Main routine surely. int main(void) { FSInit(); CFW_getSystemVersion(); if (cfw_bootGUI==true) //If gui autoboot is enabled or L is held, show the ui //L held not working { DrawClearScreenAll(); //MENU while (true) { //DRAW GUI if (menu_idx == MENU_ITEMS - 1) { sprintf(str, "/3ds/PastaCFW/UI/%c/menu6.bin", cfw_theme); DrawBottomSplash(str); sprintf(str, "/3ds/PastaCFW/UI/%c/creditsTOP.bin", cfw_theme); DrawTopSplash(str); TOP_Current = 0; } else { sprintf(str, "/3ds/PastaCFW/UI/%c/menu0.bin", cfw_theme); str[23] = menu_idx + 48; DrawBottomSplash(str); //BOTTOM SCREEN if (TOP_Current == 0){ sprintf(str, "/3ds/PastaCFW/UI/%c/menuTOP.bin", cfw_theme); DrawTopSplash(str); //TOP SCREEN TOP_Current = 1; } } //MENU CONTROLS u32 pad_state = HidWaitForInput(); if ((pad_state & BUTTON_RIGHT || pad_state & BUTTON_DOWN) && menu_idx != MENU_ITEMS - 1) menu_idx++; //MOVE RIGHT/DOWN (It depends on the theme) else if ((pad_state & BUTTON_LEFT || pad_state & BUTTON_UP) && menu_idx != 0)menu_idx--; //MOVE LEFT/UP (It depends on the theme) else if (pad_state & BUTTON_A)//SELECT { if (menu_idx == 0){ CFW_Boot(); break; }//BOOT CFW else if (menu_idx == 1)break; //REBOOT else if (menu_idx == 2)CFW_NandDumper(); //NAND DUMPER else if (menu_idx == 4)CFW_ARM9Dumper(); //ARM9 RAM DUMPER else if (menu_idx == 5)CFW_Settings(); //SETTINGS } else if (pad_state & BUTTON_START && pad_state & BUTTON_SELECT) //POWER OFF { i2cWriteRegister(I2C_DEV_MCU, 0x20, (u8)(1 << 0)); //As seen on 3dbrew while (1); } } } else CFW_Boot(); //else directly boot the cfw if (firmlaunch == true && cfw_enablefirmlaunch) FirmLaunch(); // return control to FIRM ARM9 code (performs firmlaunch) return 0; }
void shutdown(u32 mode, const char *message) { if(mode) { posY = drawString(message, 10, posY + SPACING_Y, mode == 1 ? COLOR_RED : COLOR_GREEN); drawString("Press any button to shutdown", 10, posY, COLOR_WHITE); waitInput(); } i2cWriteRegister(I2C_DEV_MCU, 0x20, 1); while(1); }
static void bgWork() { TryScreenShot(); // Check whether HOME or POWER button has been pressed if (*(volatile uint8_t *)0x10147021 == 13) { fadeOut(); // Return to HOME menu i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); while (1); } }
void error(const char *message){ initScreens(); drawString("An error has occurred:", 10, 10, COLOR_RED); int posY = drawString(message, 10, 30, COLOR_WHITE); drawString("Press any button to shutdown", 10, posY + 2 * SPACING_Y, COLOR_WHITE); waitInput(); //Shutdown i2cWriteRegister(I2C_DEV_MCU, 0x20, 1); while(1); }
int main() { //gateway *(volatile uint32_t*)0x80FFFC0 = 0x18300000; // framebuffer 1 top left *(volatile uint32_t*)0x80FFFC4 = 0x18300000; // framebuffer 2 top left *(volatile uint32_t*)0x80FFFC8 = 0x18300000; // framebuffer 1 top right *(volatile uint32_t*)0x80FFFCC = 0x18300000; // framebuffer 2 top right *(volatile uint32_t*)0x80FFFD0 = 0x18346500; // framebuffer 1 bottom *(volatile uint32_t*)0x80FFFD4 = 0x18346500; // framebuffer 2 bottom *(volatile uint32_t*)0x80FFFD8 = 1; // framebuffer select top *(volatile uint32_t*)0x80FFFDC = 1; // framebuffer select bottom //cakehax *(u32*)0x23FFFE00 = 0x18300000; *(u32*)0x23FFFE04 = 0x18300000; *(u32*)0x23FFFE08 = 0x18346500; FATFS fs; FIL payload; u32 br; if(f_mount(&fs, "0:", 0) == FR_OK) { char* payloadloc; if(HID_PAD & 1) { // Load Decrypt9 payloadloc = "decrypt9.bin"; } else { // Load regular payload payloadloc = "arm9loaderhax.bin"; } if(f_open(&payload, payloadloc, FA_READ | FA_OPEN_EXISTING) == FR_OK) { f_read(&payload, PAYLOAD_ADDRESS, PAYLOAD_SIZE, &br); ownArm11(); screenInit(); ((void (*)())PAYLOAD_ADDRESS)(); } } i2cWriteRegister(I2C_DEV_MCU, 0x20, (u8)(1<<0)); return 0; }
void screen_init() { if (PDN_GPU_CNT == 1) { uint32_t *screenInitAddress = (uint32_t *)0x24FFFC00; FILE *f = fopen(PATH_SCREENINIT_CODE, "r"); fread(screenInitAddress, 1, fsize(f), f); // Read in the screeninit payload. fclose(f); // Write brightness level for the stub to pick up screenInitAddress[2] = 0x5F; *a11_entry = (uint32_t)screenInitAddress; while (*a11_entry) ; // Turn on backlight i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A); } }
void ctr_system_reset(void) { i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); while (true); }
void configureCFW(const char *configPath, const char *patchedFirms[]) { initScreens(); drawString(CONFIG_TITLE, 10, 10, COLOR_TITLE); drawString("Press A to select, START to save and reboot", 10, 30, COLOR_WHITE); const char *optionsText[] = { "Screen-init brightness: 4( ) 3( ) 2( ) 1( )", "( ) Updated SysNAND mode (A9LH-only)", "( ) Use pre-patched FIRMs", "( ) Force A9LH detection", "( ) Use 9.0 FIRM as default", "( ) Use second EmuNAND as default", "( ) Show current NAND in System Settings", "( ) Show GBA boot screen in patched AGB_FIRM", "( ) Enable splash screen with no screen-init", "( ) Load loader from SD" }; u32 optionsAmount = sizeof(optionsText) / sizeof(char *); struct option { int posY; u32 enabled; } options[optionsAmount]; //Parse the existing configuration options[0].enabled = CONFIG(10, 3); for(u32 i = optionsAmount; i; i--) options[i].enabled = CONFIG((i - 1), 1); //Pre-select the first configuration option u32 selectedOption = 1, oldSelectedOption = 0, optionChanged = 0; //Character to display a selected option char selected = 'x'; //Starting position options[0].posY = 52; //Display all the normal options in white, brightness will be displayed later for(u32 i = 1; i < optionsAmount; i++) { options[i].posY = drawString(optionsText[i], 10, options[i - 1].posY + SPACING_Y + (!(1 - i) * 7), COLOR_WHITE); if(options[i].enabled) drawCharacter(selected, 10 + SPACING_X, options[i].posY, COLOR_WHITE); } //Boring configuration menu while(1) { u32 pressed = 0; do { //The status of the selected option changed, black out the previously visible 'x' if needed if(optionChanged) { if(!selectedOption) drawCharacter(selected, 10 + (26 + 5 * (optionChanged - 1)) * SPACING_X, options[0].posY, COLOR_BLACK); else if(!options[selectedOption].enabled) drawCharacter(selected, 10 + SPACING_X, options[selectedOption].posY, COLOR_BLACK); optionChanged = 0; } //The selected option changed, draw the new one in red and the old one (with its 'x') in white else if(selectedOption != oldSelectedOption) { drawString(optionsText[oldSelectedOption], 10, options[oldSelectedOption].posY, COLOR_WHITE); drawString(optionsText[selectedOption], 10, options[selectedOption].posY, COLOR_RED); if(!oldSelectedOption) drawCharacter(selected, 10 + (26 + 5 * options[0].enabled) * SPACING_X, options[0].posY, COLOR_WHITE); else if(options[oldSelectedOption].enabled) drawCharacter(selected, 10 + SPACING_X, options[oldSelectedOption].posY, COLOR_WHITE); } //In any case, if the current option is enabled (or brightness is selected) we must display a red 'x' if(!selectedOption) drawCharacter(selected, 10 + (26 + 5 * options[0].enabled) * SPACING_X, options[0].posY, COLOR_RED); else if(options[selectedOption].enabled) drawCharacter(selected, 10 + SPACING_X, options[selectedOption].posY, COLOR_RED); pressed = waitInput(); } while(!(pressed & MENU_BUTTONS)); //Remember the previously selected option oldSelectedOption = selectedOption; switch(pressed) { case BUTTON_UP: selectedOption = !selectedOption ? optionsAmount - 1 : selectedOption - 1; break; case BUTTON_DOWN: selectedOption = selectedOption == (optionsAmount - 1) ? 1 : selectedOption + 1; break; case BUTTON_LEFT: selectedOption = 1; break; case BUTTON_RIGHT: selectedOption = optionsAmount - 1; break; case BUTTON_A: optionChanged = 1; if(selectedOption) options[selectedOption].enabled = !options[selectedOption].enabled; else { optionChanged += options[0].enabled; options[0].enabled = options[0].enabled == 3 ? 0 : options[0].enabled + 1; } break; } if(pressed == BUTTON_START) break; } //If the user has been using A9LH and the "Updated SysNAND" setting changed, delete the patched 9.0 FIRM if(CONFIG(16, 1) && (CONFIG(0, 1) != options[1].enabled)) fileDelete(patchedFirms[3]); //If the "Show GBA boot screen in patched AGB_FIRM" setting changed, delete the patched AGB_FIRM if(CONFIG(6, 1) != options[7].enabled) fileDelete(patchedFirms[5]); //Preserve the last-used boot options (last 12 bits) config &= 0xFFF000; //Parse and write the new configuration config |= options[0].enabled << 10; for(u32 i = optionsAmount; i; i--) config |= options[i].enabled << (i - 1); fileWrite(&config, configPath, 3); //Zero the last booted FIRM flag CFG_BOOTENV = 0; //Reboot i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); while(1); }
static void ShutDown(int arg){ i2cWriteRegister(I2C_DEV_MCU, 0x20, (arg) ? (uint8_t)(1<<0):(uint8_t)(1<<2)); while(1); }
void main(void) { if(f_mount(&fs, "0:", 0) == FR_OK) { FIL pathFile, payload; bool foundPayload = false; if(f_open(&pathFile, "luma/path.txt", FA_READ) == FR_OK) { u32 pathSize = f_size(&pathFile); if(pathSize > 5 && pathSize < 58) { char path[pathSize + 1]; unsigned int read; f_read(&pathFile, path, pathSize, &read); if(path[pathSize - 1] == 0xA) pathSize--; if(path[pathSize - 1] == 0xD) pathSize--; if(pathSize > 5 && pathSize < 56 && path[0] == '/' && memcmp(&path[pathSize - 4], ".bin", 4) == 0) { path[pathSize] = 0; foundPayload = f_open(&payload, path, FA_READ) == FR_OK; } } f_close(&pathFile); } if(!foundPayload) foundPayload = f_open(&payload, "arm9loaderhax.bin", FA_READ) == FR_OK; if(foundPayload) { u32 *loaderAddress = (u32 *)0x24FFFF00; void *payloadAddress = (void *)0x24F00000; u32 payloadSize = f_size(&payload); memcpy(loaderAddress, loader_bin, loader_bin_size); loaderAddress[1] = payloadSize; unsigned int read; f_read(&payload, payloadAddress, payloadSize, &read); f_close(&payload); if((u32)read == payloadSize) { flushDCacheRange(loaderAddress, loader_bin_size); flushICacheRange(loaderAddress, loader_bin_size); ((void (*)())loaderAddress)(); } } } //Ensure that all memory transfers have completed and that the data cache has been flushed flushEntireDCache(); i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 0); while(true); }
void turnOnBacklight(void) { i2cWriteRegister(3, 0x22, 0x2A); // 0x2A -> boot into firm with no backlight }
void configureCFW(const char *configPath, const char *firm90Path){ initScreens(); drawString(CONFIG_TITLE, 10, 10, COLOR_TITLE); drawString("Press A to select, START to save and reboot", 10, 30, COLOR_WHITE); const char *optionsText[] = { "( ) Updated SysNAND mode (A9LH-only)", "( ) Use pre-patched FIRMs", "( ) Force A9LH detection", "( ) Use 9.0 FIRM as default", "( ) Use second EmuNAND as default", "( ) Show current NAND in System Settings" }; u32 optionsAmount = sizeof(optionsText) / sizeof(char *); struct option options[optionsAmount]; //Read and parse the existing configuration u32 tempConfig = 0; fileRead(&tempConfig, configPath, 3); for(u32 i = 0; i < optionsAmount; i++) options[i].enabled = (tempConfig >> i) & 0x1; //Pre-select the first configuration option u32 selectedOption = 0; //Boring configuration menu while(1){ u16 pressed = 0; do{ for(u32 i = 0; i < optionsAmount; i++){ options[i].posY = drawString(optionsText[i], 10, !i ? 60 : options[i - 1].posY + SPACING_Y, selectedOption == i ? COLOR_RED : COLOR_WHITE); drawCharacter('x', 10 + SPACING_X, options[i].posY, options[i].enabled ? (selectedOption == i ? COLOR_RED : COLOR_WHITE) : COLOR_BLACK); } pressed = waitInput(); } while(!(pressed & MENU_BUTTONS)); switch(pressed){ case BUTTON_UP: selectedOption = !selectedOption ? optionsAmount - 1 : selectedOption - 1; break; case BUTTON_DOWN: selectedOption = selectedOption == optionsAmount - 1 ? 0 : selectedOption + 1; break; case BUTTON_LEFT: selectedOption = 0; break; case BUTTON_RIGHT: selectedOption = optionsAmount - 1; break; case BUTTON_A: options[selectedOption].enabled = !options[selectedOption].enabled; break; } if(pressed == BUTTON_START) break; } //If the user has been using A9LH and the "Updated SysNAND" setting changed, delete the patched 9.0 FIRM if(((tempConfig >> 16) & 0x1) && ((tempConfig & 0x1) != options[0].enabled)) fileDelete(firm90Path); //Preserve the last-used boot options (last 12 bits) tempConfig &= 0xFFF000; //Parse and write the selected options for(u32 i = 0; i < optionsAmount; i++) tempConfig |= options[i].enabled << i; fileWrite(&tempConfig, configPath, 3); //Zero the last booted FIRM flag CFG_BOOTENV = 0; //Reboot i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); while(1); }
void ctr_system_poweroff(void) { i2cWriteRegister(I2C_DEV_MCU, 0x20, 1); while (true); }
void PowerOff() { i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 0); while (true); }
void Reboot() { i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); while(true); }
void shutdown(void){ i2cWriteRegister(3, 0x20, 1); }