diff --git a/include/arm11/menu/bootinfo.h b/include/arm11/menu/bootinfo.h
new file mode 100644
index 0000000..a44c195
--- /dev/null
+++ b/include/arm11/menu/bootinfo.h
@@ -0,0 +1,32 @@
+#pragma once
+
+/*
+ * This file is part of fastboot 3DS
+ * Copyright (C) 2017 derrek, profi200, d0k3
+ *
+ * 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 .
+ */
+
+#include "types.h"
+
+#define MOUNT_STATE_PATHS "sdmc:", "twln:", "twlp:", "nand:"
+
+
+typedef struct {
+ char model[24];
+ char bootEnv[24];
+ u8 mountState;
+} bootInfo;
+
+void getBootInfo(bootInfo* info);
diff --git a/source/arm11/main.c b/source/arm11/main.c
index e350de9..593a6a3 100644
--- a/source/arm11/main.c
+++ b/source/arm11/main.c
@@ -246,7 +246,11 @@
if(err_string) free(err_string);
// power off
- if(hidGetPowerButton(true)) power_off();
+ if(hidGetPowerButton(true))
+ {
+ storeBootslot(0);
+ power_off();
+ }
// firm launch
if(g_startFirmLaunch)
diff --git a/source/arm11/menu/bootinfo.c b/source/arm11/menu/bootinfo.c
new file mode 100644
index 0000000..d9284cb
--- /dev/null
+++ b/source/arm11/menu/bootinfo.c
@@ -0,0 +1,81 @@
+/*
+ * This file is part of fastboot 3DS
+ * Copyright (C) 2017 myria, derrek, profi200, d0k3
+ *
+ * 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 .
+ */
+
+#include
+#include
+#include
+#include "arm11/hardware/i2c.h"
+#include "arm11/menu/bootinfo.h"
+#include "arm11/bootenv.h"
+#include "arm11/fmt.h"
+#include "fsutils.h"
+
+
+// System models.
+enum SystemModel {
+ MODEL_OLD_3DS = 0,
+ MODEL_OLD_3DS_XL,
+ MODEL_NEW_3DS,
+ MODEL_OLD_2DS,
+ MODEL_NEW_3DS_XL,
+ MODEL_NEW_2DS_XL,
+ NUM_MODELS
+};
+
+// Table of system models.
+// https://www.3dbrew.org/wiki/Cfg:GetSystemModel#System_Model_Values
+static const struct {
+ char name[12];
+ char product_code[4];
+} s_modelNames[] = {
+ { "Old 3DS", "CTR" }, // 0
+ { "Old 3DS XL", "SPR" }, // 1
+ { "New 3DS", "KTR" }, // 2
+ { "Old 2DS", "FTR" }, // 3
+ { "New 3DS XL", "RED" }, // 4
+ { "New 2DS XL", "JAN" }, // 5
+};
+
+void getBootInfo(bootInfo* info)
+{
+ // System model.
+ static u8 int_model = 0xFF;
+ ee_snprintf(info->model, 24, "");
+
+ // Get MCU system information.
+ u8 mcu_sysinfo[0x13];
+ if ((int_model >= NUM_MODELS) && I2C_readRegBuf(I2C_DEV_MCU, 0x7F, mcu_sysinfo, sizeof(mcu_sysinfo)))
+ int_model = mcu_sysinfo[0x09]; // System model.
+ if (int_model < NUM_MODELS)
+ ee_snprintf(info->model, 24, "%s (%s)", s_modelNames[int_model].name, s_modelNames[int_model].product_code);
+
+ // Boot environment.
+ u32 bootEnv = getBootEnv();
+ strncpy(info->bootEnv,
+ (bootEnv == BOOTENV_COLD_BOOT) ? "Cold boot" :
+ (bootEnv == BOOTENV_NATIVE_FIRM) ? "NATIVE_FIRM reboot" :
+ (bootEnv == BOOTENV_TWL_FIRM) ? "TWL_FIRM reboot" :
+ (bootEnv == BOOTENV_AGB_FIRM) ? "AGB_FIRM reboot" : "",
+ 24);
+
+ // Mounted drives.
+ info->mountState = 0;
+ const char* mount_paths[] = { MOUNT_STATE_PATHS };
+ for (u32 i = 0; i < sizeof(mount_paths) / sizeof(const char*); i++)
+ info->mountState |= (fsEnsureMounted(mount_paths[i]) ? 1 : 0) << i;
+}
diff --git a/source/arm11/menu/menu.c b/source/arm11/menu/menu.c
index 43e459a..0f07968 100644
--- a/source/arm11/menu/menu.c
+++ b/source/arm11/menu/menu.c
@@ -21,6 +21,7 @@
#include
#include
#include "types.h"
+#include "arm11/menu/bootinfo.h"
#include "arm11/menu/menu.h"
#include "arm11/menu/menu_util.h"
#include "arm11/menu/menu_color.h"
@@ -101,6 +102,22 @@
consoleSetCursor(desc_con, (desc_con->consoleWidth - strlen(title)) >> 1, 1);
ee_printf(ESC_SCHEME_ACCENT0 "%s" ESC_RESET, title);
+ // get bootinfo
+ const char* mount_paths[] = { MOUNT_STATE_PATHS };
+ bootInfo bootinfo;
+ getBootInfo(&bootinfo);
+
+ // print bootinfo
+ consoleSetCursor(desc_con, 0, 4);
+ ee_printf(" Model: %s\n", bootinfo.model);
+ ee_printf(" %s\n\n", bootinfo.bootEnv);
+ for (u32 i = 0; i < sizeof(mount_paths) / sizeof(const char*); i++)
+ {
+ ee_printf(" %s %s\n", mount_paths[i], ((bootinfo.mountState >> i) & 0x1) ?
+ ESC_SCHEME_GOOD "mounted ok" ESC_RESET :
+ ESC_SCHEME_BAD "not mounted" ESC_RESET);
+ }
+
// get description, check if available
MenuEntry* entry = &(curr_menu->entries[index]);
char* name = entry->name;