diff --git a/include/arm9/debug.h b/include/arm9/debug.h new file mode 100644 index 0000000..fbff661 --- /dev/null +++ b/include/arm9/debug.h @@ -0,0 +1,7 @@ +#pragma once + +#include "types.h" + +void hashCodeRoData(); +noreturn void panic(); +void dumpMem(u8 *mem, u32 size, char *filepath); diff --git a/include/arm9/spiflash.h b/include/arm9/spiflash.h index bb5e462..fe60e09 100644 --- a/include/arm9/spiflash.h +++ b/include/arm9/spiflash.h @@ -5,10 +5,6 @@ #define SPIFLASH_CMD_RDSR 0x05 #define SPIFLASH_CMD_READ 0x03 -void spi_busy_wait(); -void spi_put_byte(u8 data); -u8 spi_receive_byte(); -void spiflash_select(bool select); // true if spiflash is installed, false otherwise bool spiflash_get_status(); void spiflash_read(u32 offset, u32 size, u8 *buf); diff --git a/source/arm9/config.c b/source/arm9/config.c index 9a7d169..5f6226e 100644 --- a/source/arm9/config.c +++ b/source/arm9/config.c @@ -13,6 +13,7 @@ #include "arm9/interrupt.h" #include "util.h" #include "hid.h" +#include "arm9/debug.h" #include "arm9/config.h" #define MAX_FILE_SIZE 0x4000 - 1 @@ -130,7 +131,7 @@ static bool writeConfigFile() { const u32 fileSize = strlen(filebuf); - u32 bytesWritten; + unsigned int bytesWritten; if(fileSize > MAX_FILE_SIZE) panic(); @@ -331,7 +332,7 @@ } } -static bool isValidPath(char *path) +static bool isValidPath(const char *path) { char c; bool gotMountpoint = false; @@ -343,8 +344,7 @@ { if(gotMountpoint) return false; - else - gotMountpoint = true; + gotMountpoint = true; } // no dir-return @@ -404,21 +404,23 @@ if(!attr->data) { buf = (char *) malloc(len + 1); - if(!attr->data) + if(!buf) return false; + attr->data = buf; } else if(len != attr->textLength) { free(attr->data); buf = (char *) malloc(len + 1); - if(!attr->data) + if(!buf) return false; + attr->data = buf; } + else buf = attr->data; memcpy(buf, path, len); buf[len] = '\0'; - attr->data = buf; attr->textLength = len; writeAttributeText(attr, path, key); diff --git a/source/arm9/main.c b/source/arm9/main.c index b8391dc..cd0b45a 100644 --- a/source/arm9/main.c +++ b/source/arm9/main.c @@ -30,14 +30,11 @@ int main(void) { int mode; - bool firmLoaded = false; hardwareInit(); hashCodeRoData(); // TODO: remove after debugging - PXI_sendWord(PXI_CMD_FORBID_POWER_OFF); - // Initialize console for both screens using the two different PrintConsole we have defined consoleInit(SCREEN_TOP, &con_top); consoleSetWindow(&con_top, 1, 1, con_top.windowWidth - 2, con_top.windowHeight - 2); @@ -47,6 +44,8 @@ printf("\x1B[32mGood morning\nHello !\e[0m\n\n"); + PXI_sendWord(PXI_CMD_FORBID_POWER_OFF); + printf("Early filesystem init...\n"); /* Try to read the settings file ASAP. */ diff --git a/source/arm9/menu.c b/source/arm9/menu.c index 1bd8cca..936e41b 100644 --- a/source/arm9/menu.c +++ b/source/arm9/menu.c @@ -41,18 +41,10 @@ } }; -const menu_state_options menu_options = { - 1, - { - {"Change Boot Mode...", MENU_STATE_OPTIONS_MODE} - } -}; - // menu_state_type -> menu_state_options instance const menu_state_options *options_lookup[] = { &menu_main, // STATE_MAIN &menu_nand, // STATE_NAND_MENU - &menu_options // MENU_STATE_OPTIONS_MENU }; enum menu_state_type menu_state; @@ -84,7 +76,7 @@ printf(" Wifi flash status: %s\e[0m", nand_res[bootInfo.wififlash_status]); } -void rewindConsole() +static void rewindConsole() { // get ready to repaint consoleSelect(&con_top); @@ -129,7 +121,6 @@ { case MENU_STATE_MAIN: case MENU_STATE_NAND_MENU: - case MENU_STATE_OPTIONS_MENU: hidScanInput(); keys = hidKeysDown(); @@ -175,6 +166,11 @@ menuRestoreNand("sdmc:/nand.bin"); clearConsoles(); break; + + case MENU_STATE_OPTIONS_MENU: + menuOptions(); + clearConsoles(); + break; case MENU_STATE_FIRM_LAUNCH: if(!menuLaunchFirm(firmPath)) @@ -404,3 +400,8 @@ menu_event_state = MENU_EVENT_NONE; } + +void menuPrintPrompt(const char *text) +{ + printf(text); +} diff --git a/source/arm9/menu_filebrowse.c b/source/arm9/menu_filebrowse.c index 79d0d97..3709865 100644 --- a/source/arm9/menu_filebrowse.c +++ b/source/arm9/menu_filebrowse.c @@ -8,9 +8,11 @@ #include "arm9/main.h" #include "arm9/menu.h" #include "arm9/interrupt.h" +#include "arm9/dev.h" #include "util.h" #include "hid.h" + #define MAX_CACHED_ENTRIES 0x400 #define MAX_ENTRY_SIZE _MAX_LFN + 2 #define MAX_NEW_ENTRIES 0x20 @@ -195,6 +197,33 @@ else strncpy_s(curPath, "sdmc:", sizeof(curPath) - 1, sizeof(curPath)); + /* check if we have to wait for the user */ + if(!dev_sdcard->is_active()) + { + menuPrintPrompt("Waiting for SD card to be inserted...\nPress B to exit.\n"); + + do { + hidScanInput(); + keys = hidKeysDown(); + if(keys & KEY_B) + goto fail; + + switch(menuUpdateGlobalState()) + { + case MENU_EVENT_HOME_PRESSED: + case MENU_EVENT_POWER_PRESSED: + goto fail; + default: + break; + } + + menuActState(); + + } while(!dev_sdcard->is_active()); + + clearConsoles(); + } + res = f_opendir(&curDirectory, curPath); if (res != FR_OK) { diff --git a/source/arm9/menu_firmloader.c b/source/arm9/menu_firmloader.c index 983bcee..cfb4342 100644 --- a/source/arm9/menu_firmloader.c +++ b/source/arm9/menu_firmloader.c @@ -58,6 +58,7 @@ printf("\n\x1B[32mFirmware verification SUCCESS!\e[0m\n\n"); + /* printf("Attempting to run firmware, press B to exit...\n"); for(int i=0; i<0x800000; i++) @@ -68,6 +69,7 @@ if(keys & KEY_B) goto fail; } + */ menuSetReturnToState(MENU_STATE_EXIT); diff --git a/source/arm9/menu_options.c b/source/arm9/menu_options.c new file mode 100644 index 0000000..edba406 --- /dev/null +++ b/source/arm9/menu_options.c @@ -0,0 +1,239 @@ +#include +#include +#include +#include "types.h" +#include "mem_map.h" +#include "arm9/console.h" +#include "arm9/dev.h" +#include "fatfs/ff.h" +#include "pxi.h" +#include "hid.h" +#include "util.h" +#include "arm9/main.h" +#include "arm9/timer.h" +#include "arm9/menu.h" +#include "arm9/config.h" + + +#define MAX_SUBOPTIONS 3 + +static const char *optionStrings[] = { + "Change Boot Mode", + "Test 1234", + "hi profi", + "dummy 3", + "dummy 42424242424242424242", + "dummy 55", + "dummy 6", +}; + +static char optionSubStrings[MAX_SUBOPTIONS][0x20]; + +static unsigned int curOptionIndex; +static unsigned int curSubOptionIndex; +static unsigned int curHighlightedSubOptionIndex; +static bool curSubOptionHighlighted; +static unsigned int curSubOptionCount; +static bool subOptionsActive; +static const unsigned int OptionCount = arrayEntries(optionStrings); +static int consoleX, consoleY; + +void calcConsoleMetrics(void); +void rewindConsole(void); +void rewindConsoleX(void); +void handleBootMode(void); + +bool menuOptions(void) +{ + u32 keys; + + PXI_sendWord(PXI_CMD_ALLOW_POWER_OFF); + + clearConsoles(); + consoleSelect(&con_bottom); + + calcConsoleMetrics(); + + curOptionIndex = 0; + curSubOptionIndex = 0; + curHighlightedSubOptionIndex = 0; + curSubOptionCount = 0; + subOptionsActive = false; + curSubOptionHighlighted = false; + + for(;;) + { + + /* Draw screen */ + + rewindConsole(); + + for(unsigned int i=0; i longestLen) + longestLen = curLen; + } + + consoleX = (maxLen - longestLen) / 2; + consoleY = (con_bottom.windowHeight - arrayEntries(optionStrings) - MAX_SUBOPTIONS) / 2; +} + +void rewindConsole(void) +{ + consoleSetCursor(&con_bottom, consoleX, consoleY); +} + +void rewindConsoleX(void) +{ + unsigned int len = con_bottom.windowWidth - con_bottom.cursorX; + if(len) len--; + while(len--) printf(" "); + + consoleSetCursor(&con_bottom, consoleX, con_bottom.cursorY + 1); +} + +void handleBootMode(void) +{ + if(subOptionsActive) + { + u32 mode = (u32) curSubOptionIndex; + configSetKeyData(KBootMode, &mode); + curHighlightedSubOptionIndex = curSubOptionIndex; + curSubOptionHighlighted = true; + } + else + { + u32 *mode = (u32 *)configGetData(KBootMode); + if(mode) + { + curHighlightedSubOptionIndex = *mode; + curSubOptionHighlighted = true; + } + else curSubOptionHighlighted = false; + + strcpy(optionSubStrings[0], "Normal"); + strcpy(optionSubStrings[1], "Quick Boot"); + strcpy(optionSubStrings[2], "Quiet Boot"); + curSubOptionCount = 3; + } +} diff --git a/source/arm9/spiflash.c b/source/arm9/spiflash.c index 44af94c..9d473d7 100644 --- a/source/arm9/spiflash.c +++ b/source/arm9/spiflash.c @@ -4,18 +4,18 @@ -void spi_busy_wait() +static void spi_busy_wait() { while(REG_SPI_BUS2_CNT & 0x80); } -void spi_put_byte(u8 data) +static void spi_put_byte(u8 data) { REG_SPI_BUS2_DATA = data; spi_busy_wait(); } -u8 spi_receive_byte() +static u8 spi_receive_byte() { // clock out a dummy byte REG_SPI_BUS2_DATA = 0x00; @@ -24,7 +24,7 @@ } // select spiflash if select=true, deselect otherwise -void spiflash_select(bool select) +static void spiflash_select(bool select) { // select device 1, enable SPI bus REG_SPI_BUS2_CNT = 0x8100 | (select << 11);