diff --git a/include/arm11/main.h b/include/arm11/main.h
index 2541931..acf6986 100644
--- a/include/arm11/main.h
+++ b/include/arm11/main.h
@@ -20,5 +20,5 @@
-extern volatile bool g_poweroffAllowed;
+extern volatile bool g_continueBootloader;
extern volatile bool g_startFirmLaunch;
diff --git a/include/arm11/menu/menu_fb3ds.h b/include/arm11/menu/menu_fb3ds.h
index 0c3f22d..c9c6514 100644
--- a/include/arm11/menu/menu_fb3ds.h
+++ b/include/arm11/menu/menu_fb3ds.h
@@ -75,9 +75,9 @@
{
"Main Menu", 6, NULL, 0,
{
- { "Continue boot", DESC_CONTINUE, &DummyFunc, 0 },
+ { "Continue boot", DESC_CONTINUE, &menuContinueBoot, 0 },
{ "Boot menu...", DESC_BOOT_MENU, NULL, 1 },
- { "Boot from file...", DESC_BOOT_FILE, &DummyFunc, 2 },
+ { "Boot from file...", DESC_BOOT_FILE, &menuLaunchFirm, 0xFF },
{ "NAND tools...", DESC_NAND_TOOLS, NULL, 7 },
{ "Miscellaneous...", DESC_MISC, NULL, 8 },
{ "Debug...", LOREM, NULL, 9 }
@@ -86,10 +86,10 @@
{ // 1
"Boot Menu", 5, &menuPresetBootSlot, MENU_FLAG_SLOTS,
{
- { "Boot [slot 1]", DESC_BOOT_SLOT(1), &DummyFunc, 0x00 },
- { "Boot [slot 2]", DESC_BOOT_SLOT(2), &DummyFunc, 0x01 },
- { "Boot [slot 3]", DESC_BOOT_SLOT(3), &DummyFunc, 0x02 },
- { "Boot from FIRM1", DESC_BOOT_FIRM1, &DummyFunc, 0xFF },
+ { "Boot [slot 1]", DESC_BOOT_SLOT(1), &menuLaunchFirm, 0x00 },
+ { "Boot [slot 2]", DESC_BOOT_SLOT(2), &menuLaunchFirm, 0x01 },
+ { "Boot [slot 3]", DESC_BOOT_SLOT(3), &menuLaunchFirm, 0x02 },
+ { "Boot from FIRM1", DESC_BOOT_FIRM1, &menuLaunchFirm, 0xFE },
{ "Boot setup...", DESC_BOOT_SETUP, NULL, 2 }
}
@@ -117,17 +117,17 @@
{ // 7
"NAND Tools", 4, NULL, 0,
{
- { "Backup NAND", DESC_NAND_BACKUP, &DummyFunc, 3 },
- { "Restore NAND", DESC_NAND_RESTORE, &DummyFunc, 4 },
- { "Restore NAND (forced)", DESC_NAND_RESTORE_F, &DummyFunc, 4 },
- { "Flash firmware", DESC_FIRM_FLASH, &DummyFunc, 2 }
+ { "Backup NAND", DESC_NAND_BACKUP, &menuDummyFunc, 3 },
+ { "Restore NAND", DESC_NAND_RESTORE, &menuDummyFunc, 4 },
+ { "Restore NAND (forced)", DESC_NAND_RESTORE_F, &menuDummyFunc, 4 },
+ { "Flash firmware", DESC_FIRM_FLASH, &menuDummyFunc, 2 }
}
},
{ // 8
"Miscellaneous", 2, NULL, 0,
{
- { "Update fastboot3DS", DESC_UPDATE, &DummyFunc, 1 },
- { "Credits", DESC_CREDITS, &ShowCredits, 0 }
+ { "Update fastboot3DS", DESC_UPDATE, &menuDummyFunc, 1 },
+ { "Credits", DESC_CREDITS, &menuShowCredits, 0 }
}
},
{ // 9
diff --git a/include/arm11/menu/menu_func.h b/include/arm11/menu/menu_func.h
index 91442fd..a2e4005 100644
--- a/include/arm11/menu/menu_func.h
+++ b/include/arm11/menu/menu_func.h
@@ -22,9 +22,13 @@
u32 menuPresetBootMode(void);
u32 menuPresetBootSlot(void);
+
u32 menuSetBootMode(PrintConsole* con, u32 param);
u32 menuSetupBootSlot(PrintConsole* con, u32 param);
u32 menuSetupBootKeys(PrintConsole* con, u32 param);
-u32 DummyFunc(PrintConsole* con, u32 param);
+u32 menuLaunchFirm(PrintConsole* con, u32 param);
+u32 menuShowCredits(PrintConsole* con, u32 param);
+u32 menuContinueBoot(PrintConsole* con, u32 param);
+
+u32 menuDummyFunc(PrintConsole* con, u32 param);
u32 SetView(PrintConsole* con, u32 param);
-u32 ShowCredits(PrintConsole* con, u32 param);
diff --git a/source/arm11/main.c b/source/arm11/main.c
index 7624767..2d1cc6d 100644
--- a/source/arm11/main.c
+++ b/source/arm11/main.c
@@ -33,76 +33,94 @@
#include "arm11/config.h"
-volatile bool g_poweroffAllowed = true;
+volatile bool g_continueBootloader = true;
volatile bool g_startFirmLaunch = false;
int main(void)
{
+ // init hardware / filesystem / load config
hardwareInit();
-
- GFX_init();
-
- // init menu console
- PrintConsole menu_con;
- consoleInit(SCREEN_SUB, &menu_con, false);
-
- // init description console
- PrintConsole desc_con;
- consoleInit(SCREEN_TOP, &desc_con, false);
-
- // init filesystem
fsMountSdmc();
fsMountNandFilesystems();
-
- // load/create config file
loadConfigFile();
-
- // run menu
- menuProcess(&menu_con, &desc_con, menu_fb3ds);
- // take over any changes to the config
- writeConfigFile();
+ // check keys held at boot
+ hidScanInput();
+ u32 kHeld = hidKeysHeld();
+
+ // boot slot keycombo held?
+ if (kHeld & 0xfff)
+ {
+ for(u32 i = 0; (i < 3) && !g_startFirmLaunch; i++)
+ {
+ if(!configDataExist(KBootOption1 + i) ||
+ !configDataExist(KBootOption1Buttons + i))
+ continue;
+
+ u32 combo = *(u32*) configGetData(KBootOption1Buttons + i);
+ if((kHeld & 0xfff) == combo)
+ {
+ char* path = (char*) configGetData(KBootOption1 + i);
+ g_startFirmLaunch = (loadVerifyFirm(path, false) >= 0);
+ }
+ }
+ }
+
+ // get bootmode from config
+ u32 bootmode = BootModeNormal;
+ if(configDataExist(KBootMode))
+ bootmode = *(u32*) configGetData(KBootMode);
- // deinit filestesystem
+ // menu specific code
+ // HOME button detection may not work yet
+ // if(!g_startFirmLaunch && ((bootmode == BootModeNormal) || (kHeld & KEY_HOME)))
+ if(!g_startFirmLaunch)
+ {
+ // init screens
+ GFX_init();
+
+ // init menu console
+ PrintConsole menu_con;
+ consoleInit(SCREEN_SUB, &menu_con, false);
+
+ // init description console
+ PrintConsole desc_con;
+ consoleInit(SCREEN_TOP, &desc_con, false);
+
+ // run menu
+ g_continueBootloader = false;
+ menuProcess(&menu_con, &desc_con, menu_fb3ds);
+
+ // write config (if something changed)
+ if (configHasChanged()) writeConfigFile();
+
+ // deinit GFX
+ GFX_deinit();
+ }
+
+ // search for a bootable firmware (all slots)
+ if (g_continueBootloader && !g_startFirmLaunch)
+ {
+ for(u32 i = 0; (i < 3) && !g_startFirmLaunch; i++)
+ {
+ if(!configDataExist(KBootOption1 + i))
+ continue;
+
+ char* path = (char*) configGetData(KBootOption1 + i);
+ g_startFirmLaunch = (loadVerifyFirm(path, false) >= 0);
+ }
+ }
+
+ // deinit filesystem
fsUnmountAll();
+ // firm launch
+ if(g_startFirmLaunch) firmLaunch();
+
// power off
- if(g_poweroffAllowed) power_off();
-
- /*while(!g_startFirmLaunch)
- {
- waitForInterrupt();
-
- hidScanInput();
- const u32 kDown = hidKeysDown();
- const u32 kUp = hidKeysUp();
-
- if(hidGetPowerButton(true))
- {
- if(g_poweroffAllowed) power_off();
- PXI_trySendWord(PXI_RPL_POWER_PRESSED);
- }
-
- if(kDown & KEY_HOME) PXI_trySendWord(PXI_RPL_HOME_PRESSED);
- if(kDown & KEY_SHELL) i2cmcu_lcd_poweroff();
- if(kUp & KEY_SHELL)
- {
- i2cmcu_lcd_poweron();
- i2cmcu_lcd_backlight_poweron();
- }
-
-
- u8 hidstate = i2cmcu_readreg_hid_held();
-
- if(!(hidstate & MCU_HID_HOME_BUTTON_NOT_HELD))
- PXI_trySendWord(PXI_RPL_HOME_HELD);
- }
-
- GFX_deinit(); // TODO: Let ARM9 decide when to deinit gfx
-
- firm_launch();*/
-
+ power_off();
+
return 0;
}
diff --git a/source/arm11/menu/menu.c b/source/arm11/menu/menu.c
index 20ef30f..c7f50f1 100644
--- a/source/arm11/menu/menu.c
+++ b/source/arm11/menu/menu.c
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+
+
#include
#include
#include "types.h"
@@ -25,6 +27,7 @@
#include "arm11/config.h"
#include "arm11/console.h"
#include "arm11/fmt.h"
+#include "arm11/main.h"
#include "hardware/gfx.h"
@@ -157,7 +160,7 @@
u32 last_index = (u32) -1;
// main menu processing loop
- while (true) {
+ while (!g_startFirmLaunch && !g_continueBootloader) {
// update menu and description (on demand)
if ((index != last_index) || (curr_menu != last_menu)) {
menuDraw(curr_menu, menu_con, index);
@@ -171,7 +174,8 @@
}
GFX_waitForEvent(GFX_EVENT_PDC0, true); // VBlank
- if(hidGetPowerButton(true)) // handle power button
+ // handle power button
+ if(hidGetPowerButton(true))
break; // deinits & poweroff outside of this function
hidScanInput();
diff --git a/source/arm11/menu/menu_func.c b/source/arm11/menu/menu_func.c
index 3507650..db90912 100644
--- a/source/arm11/menu/menu_func.c
+++ b/source/arm11/menu/menu_func.c
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+
+
#include
#include
#include
@@ -26,9 +28,29 @@
#include "arm11/console.h"
#include "arm11/config.h"
#include "arm11/fmt.h"
-#include "arm11/power.h"
+#include "arm11/firm.h"
+#include "arm11/main.h"
-// we need a better solution for this later (!!!)
+
+
+void outputEndWait(void)
+{
+ u32 kDown = 0;
+
+ do
+ {
+ GFX_waitForEvent(GFX_EVENT_PDC0, true);
+
+ if(hidGetPowerButton(false)) // handle power button
+ break;
+
+ hidScanInput();
+ kDown = hidKeysDown();
+ if (kDown & (KEY_SHELL)) sleepmode();
+ }
+ while (!(kDown & (KEY_B|KEY_HOME)));
+}
+
void updateScreens(void)
{
GX_textureCopy((u64*)RENDERBUF_TOP, 0, (u64*)GFX_getFramebuffer(SCREEN_TOP),
@@ -67,7 +89,6 @@
(void) con;
u32 res = (configSetKeyData(KBootMode, ¶m)) ? 0 : 1;
- writeConfigFile();
return res;
}
@@ -80,9 +101,9 @@
// if bit4 of param is set, reset slot and return
if (param & 0x10)
{
- u32 res = (configSetKeyData(KBootOption1Buttons + slot, NULL) &&
- configSetKeyData(KBootOption1 + slot, NULL)) ? 0 : 1;
- return res;
+ configDeleteKey(KBootOption1Buttons + slot);
+ configDeleteKey(KBootOption1 + slot);
+ return 0;
}
if (configDataExist(KBootOption1 + slot))
@@ -90,10 +111,7 @@
u32 res = 0;
if (menuFileSelector(res_path, con, start, "*.firm"))
- {
res = (configSetKeyData(KBootOption1 + slot, res_path)) ? 0 : 1;
- writeConfigFile();
- }
return res;
}
@@ -181,49 +199,92 @@
// if we arrive here, we have a button combo
u32 res = (configSetKeyData(KBootOption1Buttons + param, &kHeld)) ? 0 : 1;
- writeConfigFile();
return res;
}
-u32 DummyFunc(PrintConsole* con, u32 param)
+u32 menuLaunchFirm(PrintConsole* con, u32 param)
{
+ char path_store[256];
+ char* path;
+
+ if (param < 3) // loading from bootslot
+ {
+ // clear console
+ consoleSelect(con);
+ consoleClear();
+
+ // check if bootslot exists
+ ee_printf("Checking bootslot...\n");
+ if (!configDataExist(KBootOption1 + param))
+ {
+ ee_printf("Bootslot does not exist!\n");
+ goto fail;
+ }
+ path = (char*) configGetData(KBootOption1 + param);
+ }
+ else if (param == 0xFE) // loading from FIRM1
+ {
+ path = "firm1:";
+ }
+ else if (param == 0xFF) // user decision
+ {
+ path = path_store;
+ if (!menuFileSelector(path, con, NULL, "*.firm"))
+ return 1;
+ }
+
+ // clear console
+ if (param >= 3)
+ {
+ consoleSelect(con);
+ consoleClear();
+ }
+
+ // try load and verify
+ ee_printf("\nLoading %s...\n", path);
+ s32 res = loadVerifyFirm(path, false);
+ if (res != 0)
+ {
+ ee_printf("Firm %s error code %li!\n", (res > -8) ? "load" : "verify", res);
+ goto fail;
+ }
+
+ ee_printf("\nFirm load success, launching firm..."); // <-- you will never see this
+ g_startFirmLaunch = true;
+
+ return 0;
+
+ fail:
+
+ ee_printf("\nFirm launcher failed.\n\nPress B or HOME to return.");
+ updateScreens();
+ outputEndWait();
+
+ return 1;
+}
+
+u32 menuContinueBoot(PrintConsole* con, u32 param)
+{
+ // all the relevant stuff handled outside
+ (void) con;
+ (void) param;
+ g_continueBootloader = true;
+ return 0;
+}
+
+u32 menuDummyFunc(PrintConsole* con, u32 param)
+{
+ (void) param;
+
// clear console
consoleSelect(con);
consoleClear();
// print something
- ee_printf("Hello! I'm a dummy function.\nparam was %lu\n\nPress B to quit.\n\n", param);
+ ee_printf("\nThis is not implemented yet.\nGo look elsewhere, nothing to see here.\n\nPress B or HOME to return.");
updateScreens();
-
- // wait for B button
- do
- {
- if(hidGetPowerButton(false)) // handle power button
- {
- ee_printf("POWER button pressed.\nPress A to confirm cancel & poweroff.\n");
- updateScreens();
-
- do
- {
- hidScanInput();
- }
- while (!(hidKeysDown() & (KEY_A|KEY_B)));
-
- if (hidKeysDown() & KEY_B)
- {
- ee_printf("POWER off canceled, continuing...\n\n");
- updateScreens();
- hidGetPowerButton(true);
- }
- else
- {
- return 1;
- }
- }
- hidScanInput();
- }
- while (!(hidKeysDown() & (KEY_B|KEY_HOME)));
+ outputEndWait();
return 0;
}
@@ -257,8 +318,9 @@
// wait for B / HOME button
do
{
+ GFX_waitForEvent(GFX_EVENT_PDC0, true);
if(hidGetPowerButton(false)) // handle power button
- return 1;
+ return 0;
hidScanInput();
}
@@ -267,7 +329,7 @@
return 0;
}
-u32 ShowCredits(PrintConsole* con, u32 param)
+u32 menuShowCredits(PrintConsole* con, u32 param)
{
(void) param;
@@ -295,18 +357,8 @@
ee_printf_line_center("... everyone who contributed to 3dbrew.org");
updateScreens();
- // wait for B button or HOME button
- u32 kDown = 0;
- do
- {
- if(hidGetPowerButton(false)) // handle power button
- return 0;
-
- hidScanInput();
- kDown = hidKeysDown();
- if (kDown & (KEY_SHELL)) sleepmode();
- }
- while (!(kDown & (KEY_B|KEY_HOME)));
+ // wait for user
+ outputEndWait();
return 0;
}