diff --git a/include/arm9/config.h b/include/arm9/config.h index dd4226a..df8fa95 100644 --- a/include/arm9/config.h +++ b/include/arm9/config.h @@ -19,7 +19,7 @@ */ -enum Keys { +/*enum Keys { KBootOption1 = 0, KBootOption2, KBootOption3, @@ -51,4 +51,4 @@ const char *configGetKeyText(int key); bool configSetKeyData(int key, const void *data); void configRestoreDefaults(); -bool configDevModeEnabled(); +bool configDevModeEnabled();*/ diff --git a/include/arm9/console.h b/include/arm9/console.h deleted file mode 100644 index d956ee7..0000000 --- a/include/arm9/console.h +++ /dev/null @@ -1,195 +0,0 @@ -#pragma once - -/* - * This code is part of ctrulib (https://github.com/smealum/ctrulib) - */ - -/** - * @file console.h - * @brief 3ds stdio support. - * - * Provides stdio integration for printing to the 3DS screen as well as debug print - * functionality provided by stderr. - * - * General usage is to initialize the console by: - * @code - * consoleDemoInit() - * @endcode - * or to customize the console usage by: - * @code - * consoleInit() - * @endcode - */ - -#include "types.h" -#include "hardware/gfx.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SCREEN_TOP 1 -#define SCREEN_LOW 0 - -#define CONSOLE_ESC(x) "\x1b[" #x -#define CONSOLE_RESET CONSOLE_ESC(0m) -#define CONSOLE_BLACK CONSOLE_ESC(30m) -#define CONSOLE_RED CONSOLE_ESC(31;1m) -#define CONSOLE_GREEN CONSOLE_ESC(32;1m) -#define CONSOLE_YELLOW CONSOLE_ESC(33;1m) -#define CONSOLE_BLUE CONSOLE_ESC(34;1m) -#define CONSOLE_MAGENTA CONSOLE_ESC(35;1m) -#define CONSOLE_CYAN CONSOLE_ESC(36;1m) -#define CONSOLE_WHITE CONSOLE_ESC(37;1m) - -/// A callback for printing a character. -typedef bool(*ConsolePrint)(void* con, int c); - -/// A font struct for the console. -typedef struct ConsoleFont -{ - const u8* gfx; ///< A pointer to the font graphics - u16 asciiOffset; ///< Offset to the first valid character in the font table - u16 numChars; ///< Number of characters in the font graphics -}ConsoleFont; - -/** - * @brief Console structure used to store the state of a console render context. - * - * Default values from consoleGetDefault(); - * @code - * PrintConsole defaultConsole = - * { - * //Font: - * { - * (u8*)default_font_bin, //font gfx - * 0, //first ascii character in the set - * 128, //number of characters in the font set - * }, - * 0,0, //cursorX cursorY - * 0,0, //prevcursorX prevcursorY - * 40, //console width - * 30, //console height - * 0, //window x - * 0, //window y - * 32, //window width - * 24, //window height - * 3, //tab size - * 0, //font character offset - * 0, //print callback - * false //console initialized - * }; - * @endcode - */ -typedef struct PrintConsole -{ - ConsoleFont font; ///< Font of the console - - u16 *frameBuffer; ///< Framebuffer address - - int cursorX; ///< Current X location of the cursor (as a tile offset by default) - int cursorY; ///< Current Y location of the cursor (as a tile offset by default) - - int prevCursorX; ///< Internal state - int prevCursorY; ///< Internal state - - int consoleWidth; ///< Width of the console hardware layer in characters - int consoleHeight; ///< Height of the console hardware layer in characters - - int windowX; ///< Window X location in characters (not implemented) - int windowY; ///< Window Y location in characters (not implemented) - int windowWidth; ///< Window width in characters (not implemented) - int windowHeight; ///< Window height in characters (not implemented) - - int tabSize; ///< Size of a tab - int fg; ///< Foreground color - int bg; ///< Background color - int flags; ///< Reverse/bright flags - - ConsolePrint PrintChar; ///< Callback for printing a character. Should return true if it has handled rendering the graphics (else the print engine will attempt to render via tiles). - - bool consoleInitialised; ///< True if the console is initialized -}PrintConsole; - -#define CONSOLE_COLOR_BOLD (1<<0) ///< Bold text -#define CONSOLE_COLOR_FAINT (1<<1) ///< Faint text -#define CONSOLE_ITALIC (1<<2) ///< Italic text -#define CONSOLE_UNDERLINE (1<<3) ///< Underlined text -#define CONSOLE_BLINK_SLOW (1<<4) ///< Slow blinking text -#define CONSOLE_BLINK_FAST (1<<5) ///< Fast blinking text -#define CONSOLE_COLOR_REVERSE (1<<6) ///< Reversed color text -#define CONSOLE_CONCEAL (1<<7) ///< Concealed text -#define CONSOLE_CROSSED_OUT (1<<8) ///< Crossed out text - -/// Console debug devices supported by libnds. -typedef enum { - debugDevice_NULL, ///< Swallows prints to stderr - debugDevice_3DMOO, ///< Directs stderr debug statements to 3dmoo - debugDevice_CONSOLE, ///< Directs stderr debug statements to 3DS console window -} debugDevice; - -/** - * @brief Loads the font into the console. - * @param console Pointer to the console to update, if NULL it will update the current console. - * @param font The font to load. - */ -void consoleSetFont(PrintConsole* console, ConsoleFont* font); - -/** - * @brief Sets the print window. - * @param console Console to set, if NULL it will set the current console window. - * @param x X location of the window. - * @param y Y location of the window. - * @param width Width of the window. - * @param height Height of the window. - */ -void consoleSetWindow(PrintConsole* console, int x, int y, int width, int height); - -/** - * @brief Gets a pointer to the console with the default values. - * This should only be used when using a single console or without changing the console that is returned, otherwise use consoleInit(). - * @return A pointer to the console with the default values. - */ -PrintConsole* consoleGetDefault(void); - -/** - * @brief Make the specified console the render target. - * @param console A pointer to the console struct (must have been initialized with consoleInit(PrintConsole* console)). - * @return A pointer to the previous console. - */ -PrintConsole *consoleSelect(PrintConsole* console); - -/** - * @brief Returns the currently used console. - * @return A pointer to the current console. - */ -PrintConsole *consoleGet(void); - -/** - * @brief Returns the currently used foreground color. - * @return The foreground color in RGB565. - */ -u16 consoleGetFgColor(void); - -/** - * @brief Initialise the console. - * @param screen The screen to use for the console. - * @param console A pointer to the console data to initialize (if it's NULL, the default console will be used). - * @return A pointer to the current console. - */ -PrintConsole* consoleInit(int screen, PrintConsole* console, bool clear); - -/// Clears the screan by using iprintf("\x1b[2J"); -void consoleClear(void); - -void consoleSetCursor(PrintConsole* console, int x, int y); - -void drawConsoleWindow(PrintConsole* console, int thickness, u8 colorIndex); - -u16 consoleGetRGB565Color(u8 colorIndex); - -ssize_t con_write(UNUSED struct _reent *r,UNUSED void *fd,const char *ptr, size_t len); - -#ifdef __cplusplus -} -#endif diff --git a/include/arm9/fmt.h b/include/arm9/fmt.h deleted file mode 100644 index bc34a6e..0000000 --- a/include/arm9/fmt.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -/* -* This file is part of Luma3DS -* Copyright (C) 2016-2017 Aurora Wright, TuxSH -* -* 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 . -* -* Additional Terms 7.b and 7.c of GPLv3 apply to this file: -* * Requiring preservation of specified reasonable legal notices or -* author attributions in that material or in the Appropriate Legal -* Notices displayed by works containing it. -* * Prohibiting misrepresentation of the origin of that material, -* or requiring that modified versions of such material be marked in -* reasonable ways as different from the original version. -*/ - -#include -#include "types.h" - - - -u32 ee_vsnprintf(char *const buf, u32 size, const char *const fmt, va_list arg); -u32 ee_vsprintf(char *const buf, const char *const fmt, va_list arg); -__attribute__ ((format (printf, 2, 3))) u32 ee_sprintf(char *const buf, const char *const fmt, ...); -__attribute__ ((format (printf, 3, 4))) u32 ee_snprintf(char *const buf, u32 size, const char *const fmt, ...); -__attribute__ ((format (printf, 1, 2))) u32 ee_printf(const char *const fmt, ...); -u32 ee_puts(const char *const str); diff --git a/include/arm9/gui/menu.h b/include/arm9/gui/menu.h deleted file mode 100644 index 275a3eb..0000000 --- a/include/arm9/gui/menu.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 "arm9/gui/ui.h" -#include "arm9/gui/menu_firmloader.h" -#include "arm9/gui/menu_nand.h" -#include "arm9/gui/menu_options.h" -#include "arm9/gui/menu_filebrowse.h" -#include "arm9/gui/menu_update.h" -#include "arm9/gui/menu_credits.h" - - -enum menu_state_type { - MENU_STATE_MAIN = 0, - MENU_STATE_NAND_MENU, - MENU_STATE_LOAD_FIRM, - MENU_STATE_OPTIONS_MENU, - MENU_STATE_OPTIONS_MODE, - MENU_STATE_FIRM_LAUNCH_SETTINGS, - MENU_STATE_NAND_BACKUP, - MENU_STATE_NAND_RESTORE, - MENU_STATE_NAND_FLASH_FIRM, - MENU_STATE_FIRM_LAUNCH, - MENU_STATE_BROWSER, - MENU_STATE_UPDATE, - MENU_STATE_CREDITS, - MENU_STATE_EXIT, - - STATE_PREVIOUS // pseudo state for menuSetReturnToState() -}; - -typedef struct { - const char *name; - const enum menu_state_type state; -} named_state; - -typedef struct { - const u8 count; // holds the number of available options - const named_state options[]; -} menu_state_options; - -enum menu_events { - MENU_EVENT_NONE = 0, - MENU_EVENT_HOME_PRESSED, - MENU_EVENT_POWER_PRESSED, - MENU_EVENT_SD_CARD_INSERTED, - MENU_EVENT_SD_CARD_REMOVED, - MENU_EVENT_STATE_CHANGE -}; - -extern enum menu_state_type menu_state; -extern enum menu_state_type menu_next_state; - -extern enum menu_state_type menu_previous_states[8]; -extern int menu_previous_states_count; - -extern int menu_event_state; - - - -// Enable or disable the pseudo VBlank in the menu. -void menuSetVBlank(bool enable); - -int enter_menu(int initial_state); - -// Use this to change to another sub-menu. -// Call menuUpdateGlobalState and menuActState afterwards. -bool menuSetReturnToState(int state); -// Use this to change back to a previous sub-menu. -// Call menuUpdateGlobalState and menuActState afterwards. -void menuSetEnterNextState(int state); -// This must be called once in each (sub-) menu iteration. -// Returns an event code. -int menuUpdateGlobalState(void); -// This must be called once in each (sub-) menu iteration, -// after menuUpdateGlobalState has been called. -void menuActState(void); -// Shows a windowed text, updates menu state. -void menuPrintPrompt(const char *text); -// Waits for any key being pressed, updates menu state. -void menuWaitForAnyPadkey(); - diff --git a/include/arm9/gui/menu_credits.h b/include/arm9/gui/menu_credits.h deleted file mode 100644 index 9d08f68..0000000 --- a/include/arm9/gui/menu_credits.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 . - */ - - - -void menuCredits(void); diff --git a/include/arm9/gui/menu_filebrowse.h b/include/arm9/gui/menu_filebrowse.h deleted file mode 100644 index 4c3e071..0000000 --- a/include/arm9/gui/menu_filebrowse.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 . - */ - - - -const char *browseForFile(const char *basePath); diff --git a/include/arm9/gui/menu_firmloader.h b/include/arm9/gui/menu_firmloader.h deleted file mode 100644 index 7bfca2c..0000000 --- a/include/arm9/gui/menu_firmloader.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 . - */ - - - -bool isFirmLoaded(void); -bool menuLaunchFirm(const char *filePath, bool quick); -bool tryLoadFirmwareFromSettings(bool fromMenu); -bool tryLoadFirmware(const char *filepath, bool skipHashCheck, bool printInfo); diff --git a/include/arm9/gui/menu_nand.h b/include/arm9/gui/menu_nand.h deleted file mode 100644 index 7133fdf..0000000 --- a/include/arm9/gui/menu_nand.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 . - */ - - - -bool menuDumpNand(const char *filePath); -bool menuRestoreNand(const char *filePath); -bool menuFlashFirmware(const char *filepath); diff --git a/include/arm9/gui/menu_options.h b/include/arm9/gui/menu_options.h deleted file mode 100644 index 3677f29..0000000 --- a/include/arm9/gui/menu_options.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 . - */ - - - -bool menuOptions(void); diff --git a/include/arm9/gui/menu_update.h b/include/arm9/gui/menu_update.h deleted file mode 100644 index dedae50..0000000 --- a/include/arm9/gui/menu_update.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 . - */ - - - -bool menuUpdateLoader(); diff --git a/include/arm9/gui/splash.h b/include/arm9/gui/splash.h deleted file mode 100644 index 339d385..0000000 --- a/include/arm9/gui/splash.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 FLAG_ROTATED (1u<<3) -#define FLAG_COMPRESSED (1u<<4) -#define FLAG_SWAPPED (1u<<5) - - -enum -{ - FORMAT_RGB565 = 0, - FORMAT_RGB8 = 1, - FORMAT_RGBA8 = 2, - FORMAT_INVALID = 7 -}; - -typedef struct -{ - u32 magic; - u16 width; - u16 height; - u32 flags; -} SplashHeader; - - - -void getSplashDimensions(const void *const data, u32 *const width, u32 *const height); -bool drawSplashscreen(const void *const data, s32 startX, s32 startY); diff --git a/include/arm9/gui/ui.h b/include/arm9/gui/ui.h deleted file mode 100644 index f21c1a9..0000000 --- a/include/arm9/gui/ui.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 "arm9/console.h" -#include "arm9/hardware/hid.h" - - -#define uiPrintInfo(format, ...) uiPrint(format, 0, false, ##__VA_ARGS__) -#define uiPrintWarning(format, ...) uiPrint(format, 33, false, ##__VA_ARGS__) -#define uiPrintError(format, ...) uiPrint(format, 31, false, ##__VA_ARGS__) - - -// PrintConsole for each screen -PrintConsole con_top, con_bottom; - - - -void uiInit(); -void uiDrawSplashScreen(); -void uiDrawConsoleWindow(); -void uiClearConsoles(); -void clearConsole(int which); -void uiSetVerboseMode(bool verb); -bool uiGetVerboseMode(); -bool uiDialogYesNo(int screen, const char *textYes, const char *textNo, const char *const format, ...); -void uiPrintIfVerbose(const char *const format, ...); -void uiPrint(const char *const format, unsigned int color, bool centered, ...); -void uiPrintCenteredInLine(unsigned int y, const char *const format, ...); -void uiPrintTextAt(unsigned int x, unsigned int y, const char *const format, ...); -u32 uiDialog(const char *const format, const char *const lastLine, u32 waitKeys, - int screen, unsigned int x, unsigned int y, bool centered, ...); -void uiPrintProgressBar(unsigned int x, unsigned int y, unsigned int w, - unsigned int h, unsigned int cur, unsigned int max); -void uiPrintDevModeRequirement(); -void uiPrintBootWarning(); -void uiPrintBootFailure(); -bool uiCheckHomePressed(u32 msTimeout); -void uiWaitForAnyPadkey(); diff --git a/include/arm9/main.h b/include/arm9/main.h deleted file mode 100644 index 152a899..0000000 --- a/include/arm9/main.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 "arm9/debug.h" -#include "fatfs/ff.h" -#include "arm9/gui/ui.h" - - -enum bootOptionResultTypes { - BO_NOT_ATTEMPTED = 0, - BO_NOT_FOUND, - BO_FAILED, - BO_SKIPPED -}; - -typedef struct { - char model[0x10]; - bool unitIsNew3DS; - char bootEnv[0x20]; - char mode[7]; - char fw_ver1[10]; - char fw_ver2[10]; - u32 numBootOptionsAttempted; - u32 bootOptionResults[3]; - bool wififlash_status; - u32 nand_status; // Bit 0: twln, bit 1: twlp, bit 2: nand - u32 sd_status; // 0: Not inserted, 1: FS init failed, 2: OK -} bootInfoStruct; - -bootInfoStruct bootInfo; - - - -void devs_close(); -u8 rng_get_byte(); -noreturn void power_off_safe(); -noreturn void reboot_safe(); diff --git a/include/hardware/pxi.h b/include/hardware/pxi.h index 08c48bb..5bc2df0 100644 --- a/include/hardware/pxi.h +++ b/include/hardware/pxi.h @@ -40,8 +40,8 @@ // Defines for PX_SYNC regs -#define PXI_DATA_RECEIVED(reg) (reg & 0xFF) -#define PXI_DATA_SENT(reg) (reg>>8 & 0xFF) +#define PXI_DATA_RECEIVED(reg) ((reg) & 0xFFu) +#define PXI_DATA_SENT(reg, sent) (((reg) & ~(0xFFu<<8)) | sent<<8) #define PXI_NOTIFY_11 (1u<<29) #define PXI_NOTIFY_9 (1u<<30) #define PXI_IRQ_ENABLE (1u<<31) @@ -57,24 +57,39 @@ #define PXI_EMPTY_FULL_ERROR (1u<<14) #define PXI_ENABLE_SEND_RECV_FIFO (1u<<15) -// Custom PXI Command/Reply Definitions -#define PXI_CMD_ENABLE_LCDS (0x4C434453) -#define PXI_CMD_SET_BRIGHTNESS (0x78D28107) -#define PXI_CMD_POWER_OFF (0x504F4646) -#define PXI_CMD_REBOOT (0x48326482) -#define PXI_CMD_ALLOW_POWER_OFF (0x504F4F4B) -#define PXI_CMD_FORBID_POWER_OFF (0x504F4E4F) -#define PXI_CMD_FIRM_LAUNCH (0x544F4F42) -#define PXI_RPL_FIRM_LAUNCH_READY (0x4F4B6666) -#define PXI_RPL_OK (0x4F4B4F4B) -#define PXI_RPL_HOME_PRESSED (0x484F4D45) -#define PXI_RPL_HOME_HELD (0x484F4D22) -#define PXI_RPL_POWER_PRESSED (0x504F5752) + +typedef enum +{ + PXI_CMD9_FMOUNT = 0, + PXI_CMD9_FUNMOUNT = 1, + PXI_CMD9_FOPEN = 2, + PXI_CMD9_FCLOSE = 3, + PXI_CMD9_FREAD = 4, + PXI_CMD9_FWRITE = 5, + PXI_CMD9_FOPEN_DIR = 6, + PXI_CMD9_FREAD_DIR = 7, + PXI_CMD9_FCLOSE_DIR = 8, + PXI_CMD9_FUNLINK = 9, + PXI_CMD9_FGETFREE = 10, + PXI_CMD9_READ_SECTORS = 11, + PXI_CMD9_WRITE_SECTORS = 12, + PXI_CMD9_MALLOC = 13, + PXI_CMD9_FREE = 14, + PXI_CMD9_LOAD_VERIFY_FIRM = 15, + PXI_CMD9_FIRM_LAUNCH = 16, + PXI_CMD9_PREPA_POWER = 17, + PXI_CMD9_PANIC = 18, + PXI_CMD9_EXCEPTION = 19 +} PxiCmd9; + +typedef enum +{ + PXI_CMD11_PRINT_MSG = 0, + PXI_CMD11_PANIC = 1, + PXI_CMD11_EXCEPTION = 2 +} PxiCmd11; + void PXI_init(void); -void PXI_sendWord(u32 val); -bool PXI_trySendWord(u32 val); -u32 PXI_recvWord(void); -u32 PXI_tryRecvWord(bool *success); -void PXI_sendBuf(const u32 *const buf, u32 size); +u32 PXI_sendCmd(u32 cmd, const u32 *const buf, u8 words); diff --git a/source/arm11/firm.c b/source/arm11/firm.c index 73f8d2f..916f9ec 100644 --- a/source/arm11/firm.c +++ b/source/arm11/firm.c @@ -24,7 +24,7 @@ -void NAKED firmLaunchStub(void) +/*void NAKED firmLaunchStub(void) { *((vu32*)A11_FALLBACK_ENTRY) = 0; @@ -49,15 +49,15 @@ } ((void (*)(void))entry)(); -} +}*/ noreturn void firm_launch(void) { // Relocate ARM11 stub - memcpy((void*)A11_STUB_ENTRY, (const void*)firmLaunchStub, A11_STUB_SIZE); + /*memcpy((void*)A11_STUB_ENTRY, (const void*)firmLaunchStub, A11_STUB_SIZE); deinitCpu(); - ((void (*)(void))A11_STUB_ENTRY)(); + ((void (*)(void))A11_STUB_ENTRY)();*/ while(1); } diff --git a/source/arm11/hardware/pxi.c b/source/arm11/hardware/pxi.c index 12e7d9e..c7a6ba4 100644 --- a/source/arm11/hardware/pxi.c +++ b/source/arm11/hardware/pxi.c @@ -19,9 +19,7 @@ #include "types.h" #include "hardware/pxi.h" #include "arm11/hardware/interrupt.h" -#include "hardware/gfx.h" -#include "arm11/main.h" -#include "arm11/power.h" +//#include "arm11/debug.h" @@ -32,7 +30,7 @@ REG_PXI_SYNC11 = PXI_IRQ_ENABLE; REG_PXI_CNT11 = PXI_FLUSH_SEND_FIFO | PXI_EMPTY_FULL_ERROR | PXI_ENABLE_SEND_RECV_FIFO; - while((REG_PXI_SYNC11 & 0xFFu) != 9u); + while(PXI_DATA_RECEIVED(REG_PXI_SYNC11) != 9u); REG_PXI_SYNC11 |= 11u<<8; IRQ_registerHandler(IRQ_PXI_SYNC, 13, 0, true, pxiIrqHandler); @@ -40,77 +38,42 @@ static void pxiIrqHandler(UNUSED u32 intSource) { - u32 cmdCode = PXI_recvWord(); + u32 result = 0; + const u32 cmdCode = REG_PXI_RECV11; - switch(cmdCode) + if((cmdCode>>16 & 0xFFu) != PXI_DATA_RECEIVED(REG_PXI_SYNC11)) { - case PXI_CMD_ENABLE_LCDS: - GFX_init(); - PXI_sendWord(PXI_RPL_OK); + //panic(); + } + + switch(cmdCode>>24) + { + case PXI_CMD11_PRINT_MSG: break; - case PXI_CMD_SET_BRIGHTNESS: - cmdCode = PXI_recvWord(); - GFX_setBrightness(cmdCode); + case PXI_CMD11_PANIC: break; - case PXI_CMD_ALLOW_POWER_OFF: - g_poweroffAllowed = true; - break; - case PXI_CMD_FORBID_POWER_OFF: - g_poweroffAllowed = false; - break; - case PXI_CMD_POWER_OFF: - power_off(); - break; - case PXI_CMD_REBOOT: - power_reboot(); - break; - case PXI_CMD_FIRM_LAUNCH: - g_startFirmLaunch = true; + case PXI_CMD11_EXCEPTION: break; default: ; - } -} - -void PXI_sendWord(u32 val) -{ - while(REG_PXI_CNT11 & PXI_SEND_FIFO_FULL); - REG_PXI_SEND11 = val; - REG_PXI_SYNC11 |= PXI_NOTIFY_9; -} - -bool PXI_trySendWord(u32 val) -{ - if(REG_PXI_CNT11 & PXI_SEND_FIFO_FULL) - return false; - REG_PXI_SEND11 = val; - REG_PXI_SYNC11 |= PXI_NOTIFY_9; - return true; -} - -u32 PXI_recvWord(void) -{ - while(REG_PXI_CNT11 & PXI_RECV_FIFO_EMPTY); - return REG_PXI_RECV11; -} - -u32 PXI_tryRecvWord(bool *success) -{ - if(REG_PXI_CNT11 & PXI_RECV_FIFO_EMPTY) - { - *success = false; - return 0; + //panic(); } - *success = true; - return REG_PXI_RECV11; + REG_PXI_SEND11 = result; } -void PXI_sendBuf(const u32 *const buf, u32 size) +u32 PXI_sendCmd(u32 cmd, const u32 *const buf, u8 words) { + if(!buf) words = 0; + while(REG_PXI_CNT11 & PXI_SEND_FIFO_FULL); - for(u32 i = 0; i < size / 4; i++) + REG_PXI_SEND11 = cmd | words<<16; + for(u32 i = 0; i < words; i++) { REG_PXI_SEND11 = buf[i]; } - REG_PXI_SYNC11 |= PXI_NOTIFY_9; + + REG_PXI_SYNC11 = PXI_DATA_SENT(REG_PXI_SYNC11, words) | PXI_NOTIFY_9; + + while(REG_PXI_CNT11 & PXI_RECV_FIFO_EMPTY); + return REG_PXI_RECV11; } diff --git a/source/arm9/config.c b/source/arm9/config.c index d530e21..ecfa5e4 100644 --- a/source/arm9/config.c +++ b/source/arm9/config.c @@ -18,22 +18,18 @@ /* This is a parser/writer for the fastbootcfg.txt file. It's not vulnerable, I swear. */ -#include +/*#include #include #include #include #include "types.h" -#include "arm9/fmt.h" #include "mem_map.h" #include "fatfs/ff.h" #include "arm9/fsutils.h" -#include "arm9/console.h" -#include "arm9/main.h" #include "arm9/hardware/interrupt.h" #include "util.h" #include "arm9/hardware/hid.h" #include "arm9/debug.h" -#include "arm9/gui/ui.h" #include "arm9/config.h" #define MAX_FILE_SIZE 0x4000 - 1 @@ -87,9 +83,9 @@ static FunctionsEntryType keyFunctions[] = { { parseBootOption, writeBootOption }, { parseBootOption, writeBootOption }, - { parseBootOption, writeBootOption }, + { parseBootOption, writeBootOption },*/ /* use the same functions for nand image option */ - { parseBootOption, writeBootOption }, + /*{ parseBootOption, writeBootOption }, { parseBootOption, writeBootOption }, { parseBootOption, writeBootOption }, { parseBootOptionPad, writeBootOptionPad }, @@ -103,10 +99,10 @@ static char *filebuf = NULL; -static bool configLoaded = false; +static bool configLoaded = false;*/ /* This loads the config file from SD card or eMMC and parses it */ -bool loadConfigFile() +/*bool loadConfigFile() { FILINFO fileStat; u32 fileSize; @@ -195,10 +191,10 @@ static void unloadConfigFile() { configLoaded = false; - AttributeEntryType *curAttr; + AttributeEntryType *curAttr;*/ /* Free all data */ - for(u32 i=0; i -#include -#include "types.h" -#include "arm9/fmt.h" -#include "hardware/gfx.h" -#include "util.h" -#include "arm9/console.h" - -#include "default_font_bin.h" - -//set up the palette for color printing -static u16 colorTable[] = { - RGB8_to_565( 0, 0, 0), // faint black - RGB8_to_565(255, 0, 0), // bright red - RGB8_to_565( 0,255, 0), // bright green - RGB8_to_565(255,255, 0), // bright yellow - RGB8_to_565( 0, 0,255), // bright blue - RGB8_to_565(255, 0,255), // bright magenta - RGB8_to_565( 0,255,255), // bright cyan - RGB8_to_565(255,255,255), // bright white - - RGB8_to_565(128,128,128), // bright black - RGB8_to_565(255, 0, 0), // bright red - RGB8_to_565( 0,255, 0), // bright green - RGB8_to_565(255,255, 0), // bright yellow - RGB8_to_565( 0, 0,255), // bright blue - RGB8_to_565(255, 0,255), // bright magenta - RGB8_to_565( 0,255,255), // bright cyan - RGB8_to_565(255,255,255), // bright white - - RGB8_to_565( 0, 0, 0), // faint black - RGB8_to_565( 64, 0, 0), // faint red - RGB8_to_565( 0, 64, 0), // faint green - RGB8_to_565( 64, 64, 0), // faint yellow - RGB8_to_565( 0, 0, 64), // faint blue - RGB8_to_565( 64, 0, 64), // faint magenta - RGB8_to_565( 0, 64, 64), // faint cyan - RGB8_to_565( 96, 96, 96), // faint white -}; - -PrintConsole defaultConsole = -{ - //Font: - { - default_font_bin, //font gfx - 0, //first ascii character in the set - 256 //number of characters in the font set - }, - (u16*)NULL, - 0,0, //cursorX cursorY - 0,0, //prevcursorX prevcursorY - 40, //console width - 30, //console height - 0, //window x - 0, //window y - 40, //window width - 30, //window height - 3, //tab size - 7, // foreground color - 0, // background color - 0, // flags - 0, //print callback - false //console initialized -}; - -PrintConsole currentCopy; - -PrintConsole* currentConsole = ¤tCopy; - -PrintConsole* consoleGetDefault(void){return &defaultConsole;} - -void consolePrintChar(int c); -void consoleDrawChar(int c); - -//--------------------------------------------------------------------------------- -static void consoleCls(char mode) { -//--------------------------------------------------------------------------------- - - int i = 0; - int colTemp,rowTemp; - - switch (mode) - { - case '[': - case '0': - { - colTemp = currentConsole->cursorX ; - rowTemp = currentConsole->cursorY ; - - while(i++ < ((currentConsole->windowHeight * currentConsole->windowWidth) - (rowTemp * currentConsole->consoleWidth + colTemp))) - consolePrintChar(' '); - - currentConsole->cursorX = colTemp; - currentConsole->cursorY = rowTemp; - break; - } - case '1': - { - colTemp = currentConsole->cursorX ; - rowTemp = currentConsole->cursorY ; - - currentConsole->cursorY = 0; - currentConsole->cursorX = 0; - - while (i++ < (rowTemp * currentConsole->windowWidth + colTemp)) - consolePrintChar(' '); - - currentConsole->cursorX = colTemp; - currentConsole->cursorY = rowTemp; - break; - } - case '2': - { - currentConsole->cursorY = 0; - currentConsole->cursorX = 0; - - while(i++ < currentConsole->windowHeight * currentConsole->windowWidth) - consolePrintChar(' '); - - currentConsole->cursorY = 0; - currentConsole->cursorX = 0; - break; - } - default: ; - } -} -//--------------------------------------------------------------------------------- -static void consoleClearLine(char mode) { -//--------------------------------------------------------------------------------- - - int i = 0; - int colTemp; - - switch (mode) - { - case '[': - case '0': - { - colTemp = currentConsole->cursorX ; - - while(i++ < (currentConsole->windowWidth - colTemp)) { - consolePrintChar(' '); - } - - currentConsole->cursorX = colTemp; - - break; - } - case '1': - { - colTemp = currentConsole->cursorX ; - - currentConsole->cursorX = 0; - - while(i++ < ((currentConsole->windowWidth - colTemp)-2)) { - consolePrintChar(' '); - } - - currentConsole->cursorX = colTemp; - - break; - } - case '2': - { - colTemp = currentConsole->cursorX ; - - currentConsole->cursorX = 0; - - while(i++ < currentConsole->windowWidth) { - consolePrintChar(' '); - } - - currentConsole->cursorX = colTemp; - - break; - } - default: ; - } -} - -//--------------------------------------------------------------------------------- -ssize_t con_write(UNUSED struct _reent *r,UNUSED void *fd,const char *ptr, size_t len) { -//--------------------------------------------------------------------------------- - - char chr; - - int i, count = 0; - const char *tmp = ptr; - - if(!tmp || len<=0) return -1; - - i = 0; - - while(i= '0' && chr <= '9') || chr == ';') - continue; - - switch (chr) { - //--------------------------------------- - // Cursor directional movement - //--------------------------------------- - case 'A': - consumed = 0; - assigned = fb_sscanf(escapeseq,"[%dA%n", ¶meter, &consumed); - if (assigned==0) parameter = 1; - if (consumed) - currentConsole->cursorY = (currentConsole->cursorY - parameter) < 0 ? 0 : currentConsole->cursorY - parameter; - escaping = false; - break; - case 'B': - consumed = 0; - assigned = fb_sscanf(escapeseq,"[%dB%n", ¶meter, &consumed); - if (assigned==0) parameter = 1; - if (consumed) - currentConsole->cursorY = (currentConsole->cursorY + parameter) > currentConsole->windowHeight - 1 ? currentConsole->windowHeight - 1 : currentConsole->cursorY + parameter; - escaping = false; - break; - case 'C': - consumed = 0; - assigned = fb_sscanf(escapeseq,"[%dC%n", ¶meter, &consumed); - if (assigned==0) parameter = 1; - if (consumed) - currentConsole->cursorX = (currentConsole->cursorX + parameter) > currentConsole->windowWidth - 1 ? currentConsole->windowWidth - 1 : currentConsole->cursorX + parameter; - escaping = false; - break; - case 'D': - consumed = 0; - assigned = fb_sscanf(escapeseq,"[%dD%n", ¶meter, &consumed); - if (assigned==0) parameter = 1; - if (consumed) - currentConsole->cursorX = (currentConsole->cursorX - parameter) < 0 ? 0 : currentConsole->cursorX - parameter; - escaping = false; - break; - //--------------------------------------- - // Cursor position movement - //--------------------------------------- - case 'H': - case 'f': - { - int x, y; - char c; - if(fb_sscanf(escapeseq,"[%d;%d%c", &y, &x, &c) == 3 && (c == 'f' || c == 'H')) { - currentConsole->cursorX = x; - currentConsole->cursorY = y; - escaping = false; - break; - } - - x = y = 1; - if(fb_sscanf(escapeseq,"[%d;%c", &y, &c) == 2 && (c == 'f' || c == 'H')) { - currentConsole->cursorX = x; - currentConsole->cursorY = y; - escaping = false; - break; - } - - x = y = 1; - if(fb_sscanf(escapeseq,"[;%d%c", &x, &c) == 2 && (c == 'f' || c == 'H')) { - currentConsole->cursorX = x; - currentConsole->cursorY = y; - escaping = false; - break; - } - - x = y = 1; - if(fb_sscanf(escapeseq,"[;%c", &c) == 1 && (c == 'f' || c == 'H')) { - currentConsole->cursorX = x; - currentConsole->cursorY = y; - escaping = false; - break; - } - - // invalid format - escaping = false; - break; - } - //--------------------------------------- - // Screen clear - //--------------------------------------- - case 'J': - if(escapelen <= 3) - consoleCls(escapeseq[escapelen-2]); - escaping = false; - break; - //--------------------------------------- - // Line clear - //--------------------------------------- - case 'K': - if(escapelen <= 3) - consoleClearLine(escapeseq[escapelen-2]); - escaping = false; - break; - //--------------------------------------- - // Save cursor position - //--------------------------------------- - case 's': - if(escapelen == 2) { - currentConsole->prevCursorX = currentConsole->cursorX ; - currentConsole->prevCursorY = currentConsole->cursorY ; - } - escaping = false; - break; - //--------------------------------------- - // Load cursor position - //--------------------------------------- - case 'u': - if(escapelen == 2) { - currentConsole->cursorX = currentConsole->prevCursorX ; - currentConsole->cursorY = currentConsole->prevCursorY ; - } - escaping = false; - break; - //--------------------------------------- - // Color scan codes - //--------------------------------------- - case 'm': - escapeseq++; - escapelen--; - - do { - parameter = 0; - if (escapelen == 1) { - consumed = 1; - } else if (memchr(escapeseq,';',escapelen)) { - fb_sscanf(escapeseq,"%d;%n", ¶meter, &consumed); - } else { - fb_sscanf(escapeseq,"%dm%n", ¶meter, &consumed); - } - - escapeseq += consumed; - escapelen -= consumed; - - switch(parameter) { - case 0: // reset - currentConsole->flags = 0; - currentConsole->bg = 0; - currentConsole->fg = 7; - break; - - case 1: // bold - currentConsole->flags &= ~CONSOLE_COLOR_FAINT; - currentConsole->flags |= CONSOLE_COLOR_BOLD; - break; - - case 2: // faint - currentConsole->flags &= ~CONSOLE_COLOR_BOLD; - currentConsole->flags |= CONSOLE_COLOR_FAINT; - break; - - case 3: // italic - currentConsole->flags |= CONSOLE_ITALIC; - break; - - case 4: // underline - currentConsole->flags |= CONSOLE_UNDERLINE; - break; - - case 5: // blink slow - currentConsole->flags &= ~CONSOLE_BLINK_FAST; - currentConsole->flags |= CONSOLE_BLINK_SLOW; - break; - - case 6: // blink fast - currentConsole->flags &= ~CONSOLE_BLINK_SLOW; - currentConsole->flags |= CONSOLE_BLINK_FAST; - break; - - case 7: // reverse video - currentConsole->flags |= CONSOLE_COLOR_REVERSE; - break; - - case 8: // conceal - currentConsole->flags |= CONSOLE_CONCEAL; - break; - - case 9: // crossed-out - currentConsole->flags |= CONSOLE_CROSSED_OUT; - break; - - case 21: // bold off - currentConsole->flags &= ~CONSOLE_COLOR_BOLD; - break; - - case 22: // normal color - currentConsole->flags &= ~CONSOLE_COLOR_BOLD; - currentConsole->flags &= ~CONSOLE_COLOR_FAINT; - break; - - case 23: // italic off - currentConsole->flags &= ~CONSOLE_ITALIC; - break; - - case 24: // underline off - currentConsole->flags &= ~CONSOLE_UNDERLINE; - break; - - case 25: // blink off - currentConsole->flags &= ~CONSOLE_BLINK_SLOW; - currentConsole->flags &= ~CONSOLE_BLINK_FAST; - break; - - case 27: // reverse off - currentConsole->flags &= ~CONSOLE_COLOR_REVERSE; - break; - - case 29: // crossed-out off - currentConsole->flags &= ~CONSOLE_CROSSED_OUT; - break; - - case 30 ... 37: // writing color - currentConsole->fg = parameter - 30; - break; - - case 39: // reset foreground color - currentConsole->fg = 7; - break; - - case 40 ... 47: // screen color - currentConsole->bg = parameter - 40; - break; - - case 49: // reset background color - currentConsole->fg = 0; - break; - default: ; - } - } while (escapelen > 0); - - escaping = false; - break; - - default: - // some sort of unsupported escape; just gloss over it - escaping = false; - break; - } - } while (escaping); - continue; - } - - consolePrintChar(chr); - } - - return count; -} - -//--------------------------------------------------------------------------------- -PrintConsole* consoleInit(int screen, PrintConsole* console, bool clear) { -//--------------------------------------------------------------------------------- - - if(console) { - currentConsole = console; - } else { - console = currentConsole; - } - - *currentConsole = defaultConsole; - - console->consoleInitialised = 1; - - if(screen==1) { - console->frameBuffer = (u16*)FRAMEBUF_TOP_A_1; - console->consoleWidth = 50; - console->windowWidth = 50; - } - else console->frameBuffer = (u16*)FRAMEBUF_SUB_A_1; - - - if(clear) consoleCls('2'); - - return currentConsole; - -} - -//--------------------------------------------------------------------------------- -PrintConsole *consoleSelect(PrintConsole* console){ -//--------------------------------------------------------------------------------- - PrintConsole *tmp = currentConsole; - currentConsole = console; - return tmp; -} - -//--------------------------------------------------------------------------------- -PrintConsole *consoleGet(void){ -//--------------------------------------------------------------------------------- - return currentConsole; -} - -//--------------------------------------------------------------------------------- -u16 consoleGetFgColor(void){ -//--------------------------------------------------------------------------------- - return colorTable[currentConsole->fg]; -} - -//--------------------------------------------------------------------------------- -void consoleSetFont(PrintConsole* console, ConsoleFont* font){ -//--------------------------------------------------------------------------------- - - if(!console) console = currentConsole; - - console->font = *font; - -} - -//--------------------------------------------------------------------------------- -static void newRow() { -//--------------------------------------------------------------------------------- - - - currentConsole->cursorY ++; - - - if(currentConsole->cursorY >= currentConsole->windowHeight) { - currentConsole->cursorY --; - u16 *dst = ¤tConsole->frameBuffer[(currentConsole->windowX * 8 * 240) + (239 - (currentConsole->windowY * 8))]; - u16 *src = dst - 8; - - int i,j; - - for (i=0; iwindowWidth*8; i++) { - u32 *from = (u32*)((int)src & ~3); - u32 *to = (u32*)((int)dst & ~3); - for (j=0;j<(((currentConsole->windowHeight-1)*8)/2);j++) *(to--) = *(from--); - dst += 240; - src += 240; - } - - consoleClearLine('2'); - } -} -//--------------------------------------------------------------------------------- -void consoleDrawChar(int c) { -//--------------------------------------------------------------------------------- - c -= currentConsole->font.asciiOffset; - if ( c < 0 || c > currentConsole->font.numChars ) return; - - const u8 *fontdata = currentConsole->font.gfx + (8 * c); - - int writingColor = currentConsole->fg; - int screenColor = currentConsole->bg; - - if (currentConsole->flags & CONSOLE_COLOR_BOLD) { - writingColor += 8; - } else if (currentConsole->flags & CONSOLE_COLOR_FAINT) { - writingColor += 16; - } - - if (currentConsole->flags & CONSOLE_COLOR_REVERSE) { - int tmp = writingColor; - writingColor = screenColor; - screenColor = tmp; - } - - u16 bg = colorTable[screenColor]; - u16 fg = colorTable[writingColor]; - - u8 b1 = *(fontdata++); - u8 b2 = *(fontdata++); - u8 b3 = *(fontdata++); - u8 b4 = *(fontdata++); - u8 b5 = *(fontdata++); - u8 b6 = *(fontdata++); - u8 b7 = *(fontdata++); - u8 b8 = *(fontdata++); - - if (currentConsole->flags & CONSOLE_UNDERLINE) b8 = 0xff; - - if (currentConsole->flags & CONSOLE_CROSSED_OUT) b4 = 0xff; - - u8 mask = 0x80; - - - int i; - - int x = (currentConsole->cursorX + currentConsole->windowX) * 8; - int y = ((currentConsole->cursorY + currentConsole->windowY) *8 ); - - u16 *screen = ¤tConsole->frameBuffer[(x * 240) + (239 - (y + 7))]; - - for (i=0;i<8;i++) { - if (b8 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; } - if (b7 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; } - if (b6 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; } - if (b5 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; } - if (b4 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; } - if (b3 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; } - if (b2 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; } - if (b1 & mask) { *(screen++) = fg; }else{ *(screen++) = bg; } - mask >>= 1; - screen += 240 - 8; - } - -} - -//--------------------------------------------------------------------------------- -void consolePrintChar(int c) { -//--------------------------------------------------------------------------------- - if (c==0) return; - - if(currentConsole->PrintChar) - if(currentConsole->PrintChar(currentConsole, c)) - return; - - if(currentConsole->cursorX >= currentConsole->windowWidth) { - currentConsole->cursorX = 0; - - newRow(); - } - - switch(c) { - /* - The only special characters we will handle are tab (\t), carriage return (\r), line feed (\n) - and backspace (\b). - Carriage return & line feed will function the same: go to next line and put cursor at the beginning. - For everything else, use VT sequences. - - Reason: VT sequences are more specific to the task of cursor placement. - The special escape sequences \b \f & \v are archaic and non-portable. - */ - case 8: - currentConsole->cursorX--; - - if(currentConsole->cursorX < 0) { - if(currentConsole->cursorY > 0) { - currentConsole->cursorX = currentConsole->windowX - 1; - currentConsole->cursorY--; - } else { - currentConsole->cursorX = 0; - } - } - - consoleDrawChar(' '); - break; - - case 9: - currentConsole->cursorX += currentConsole->tabSize - ((currentConsole->cursorX)%(currentConsole->tabSize)); - break; - case 10: - newRow(); - // falls through - case 13: - currentConsole->cursorX = 0; - break; - default: - consoleDrawChar(c); - ++currentConsole->cursorX ; - break; - } -} - -//--------------------------------------------------------------------------------- -void consoleClear(void) { -//--------------------------------------------------------------------------------- - ee_printf("\x1b[2J"); -} - -//--------------------------------------------------------------------------------- -void consoleSetWindow(PrintConsole* console, int x, int y, int width, int height){ -//--------------------------------------------------------------------------------- - - if(!console) console = currentConsole; - - console->windowWidth = width; - console->windowHeight = height; - console->windowX = x; - console->windowY = y; - - console->cursorX = 0; - console->cursorY = 0; - -} - -void drawConsoleWindow(PrintConsole* console, int thickness, u8 colorIndex) { - - if(colorIndex >= 16) return; - - if(!console) console = currentConsole; - - int startx = console->windowX * 8 - thickness; - int endx = (console->windowX + console->windowWidth) * 8 + thickness; - - int starty = (console->windowY - 1) * 8 - thickness; - int endy = console->windowHeight * 8 + thickness; - - u16 color = colorTable[colorIndex]; - - // upper line - for(int y = starty; y < starty + thickness; y++) - for(int x = startx; x < endx; x++) - { - u16 *screen = ¤tConsole->frameBuffer[(x * 240) + (239 - (y + 7))]; - *screen = color; - } - - // lower line - for(int y = endy; y > endy - thickness; y--) - for(int x = startx; x < endx; x++) - { - u16 *screen = ¤tConsole->frameBuffer[(x * 240) + (239 - (y + 7))]; - *screen = color; - } - - // left and right - for(int y = starty; y < endy; y++) - { - for(int i = 0; i < thickness; i++) - { - u16 *screen = ¤tConsole->frameBuffer[((startx + i) * 240) + (239 - (y + 7))]; - *screen = color; - screen = ¤tConsole->frameBuffer[((endx - thickness + i) * 240) + (239 - (y + 7))]; - *screen = color; - } - } -} - -void consoleSetCursor(PrintConsole* console, int x, int y) { - console->cursorX = x; - console->cursorY = y; -} - -u16 consoleGetRGB565Color(u8 colorIndex) { - if(colorIndex >= arrayEntries(colorTable)) - return 0; - return colorTable[colorIndex]; -} diff --git a/source/arm9/debug.c b/source/arm9/debug.c index 4138d4d..6634346 100644 --- a/source/arm9/debug.c +++ b/source/arm9/debug.c @@ -19,13 +19,10 @@ #include #include #include "types.h" -#include "arm9/fmt.h" #include "mem_map.h" #include "hardware/pxi.h" -#include "arm9/console.h" #include "fatfs/ff.h" #include "arm9/fsutils.h" -#include "arm9/main.h" #include "arm9/hardware/interrupt.h" static u32 debugHash = 0; @@ -51,14 +48,14 @@ { register u32 lr __asm__("lr"); - consoleInit(0, NULL, true); + //consoleInit(0, NULL, true); - ee_printf("\x1b[41m\x1b[0J\x1b[9C****PANIC!!!****\n\nlr = 0x%08" PRIX32 "\n", lr); + //ee_printf("\x1b[41m\x1b[0J\x1b[9C****PANIC!!!****\n\nlr = 0x%08" PRIX32 "\n", lr); fsUnmountAll(); - devs_close(); + //devs_close(); - PXI_sendWord(PXI_CMD_ALLOW_POWER_OFF); + //PXI_sendWord(PXI_CMD_ALLOW_POWER_OFF); while(1) waitForInterrupt(); } @@ -67,15 +64,15 @@ { register u32 lr __asm__("lr"); - consoleInit(0, NULL, true); + /*consoleInit(0, NULL, true); ee_printf("\x1b[41m\x1b[0J\x1b[9C****PANIC!!!****\n\nlr = 0x%08" PRIX32 "\n", lr); - ee_printf("\nERROR MESSAGE:\n%s\n", msg); - + ee_printf("\nERROR MESSAGE:\n%s\n", msg);*/ + fsUnmountAll(); - devs_close(); + //devs_close(); - PXI_sendWord(PXI_CMD_ALLOW_POWER_OFF); + //PXI_sendWord(PXI_CMD_ALLOW_POWER_OFF); while(1) waitForInterrupt(); } @@ -95,13 +92,13 @@ if(prevHash != debugHash) codeChanged = true; - consoleInit(0, NULL, true); + //consoleInit(0, NULL, true); if(excStack[16] & 0x20) instSize = 2; // Processor was in Thumb mode? if(type == 2) realPc = excStack[15] - (instSize * 2); // Data abort else realPc = excStack[15] - instSize; // Other - ee_printf("\x1b[41m\x1b[0J\x1b[9CGuru Meditation Error!\n\n%s:\n", typeStr[type]); + /*ee_printf("\x1b[41m\x1b[0J\x1b[9CGuru Meditation Error!\n\n%s:\n", typeStr[type]); ee_printf("CPSR: 0x%08" PRIX32 "\n" "r0 = 0x%08" PRIX32 " r8 = 0x%08" PRIX32 "\n" "r1 = 0x%08" PRIX32 " r9 = 0x%08" PRIX32 "\n" @@ -137,13 +134,13 @@ } } - if(codeChanged) ee_printf("Attention: RO section data changed!!"); + if(codeChanged) ee_printf("Attention: RO section data changed!!");*/ // avoid fs corruptions fsUnmountAll(); - devs_close(); + //devs_close(); - PXI_sendWord(PXI_CMD_ALLOW_POWER_OFF); + //PXI_sendWord(PXI_CMD_ALLOW_POWER_OFF); while(1) waitForInterrupt(); } diff --git a/source/arm9/dev.c b/source/arm9/dev.c index cf74d4f..379ea01 100644 --- a/source/arm9/dev.c +++ b/source/arm9/dev.c @@ -22,7 +22,6 @@ #include "types.h" #include "arm9/fb_assert.h" #include "mem_map.h" -#include "arm9/main.h" #include "arm9/ncsd.h" #include "arm9/hardware/sdmmc.h" #include "arm9/hardware/spiflash.h" @@ -298,9 +297,9 @@ } else if(i == 4) // CTR NAND partition { - if(bootInfo.unitIsNew3DS) + /*if(bootInfo.unitIsNew3DS) partitionSetKeyslot(index, 0x05); - else + else*/ partitionSetKeyslot(index, 0x04); partitionSetName(index, "nand"); diff --git a/source/arm9/fb_assert.c b/source/arm9/fb_assert.c index 9f2b764..5ef0520 100644 --- a/source/arm9/fb_assert.c +++ b/source/arm9/fb_assert.c @@ -17,14 +17,13 @@ */ #include "types.h" -#include "arm9/fmt.h" #include "arm9/hardware/interrupt.h" -noreturn void __fb_assert(const char *const str, u32 line) +noreturn void __fb_assert(UNUSED const char *const str, UNUSED u32 line) { - ee_printf("Assertion failed: %s:%" PRIu32, str, line); + //ee_printf("Assertion failed: %s:%" PRIu32, str, line); while(1) waitForInterrupt(); } diff --git a/source/arm9/firm.c b/source/arm9/firm.c deleted file mode 100644 index b86fa34..0000000 --- a/source/arm9/firm.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 "types.h" -// we need the arm11 mem map information -#define ARM11 -#include "mem_map.h" -#undef ARM11 -#include "arm9/firm.h" -#include "arm9/start.h" -#include "arm9/hardware/crypto.h" -#include "arm9/hardware/ndma.h" -#include "arm9/gui/ui.h" -#include "hardware/cache.h" -#include "util.h" -#include "hardware/pxi.h" - - - -/* We don't want the FIRM to do hacky stuff with our loader */ - -typedef struct -{ - u32 addr; - u32 size; -} firmProtectedArea; - -static const firmProtectedArea firmProtectedAreas[] = { - { // FIRM buffer - FIRM_LOAD_ADDR, FIRM_MAX_SIZE - }, - { // io regs - IO_MEM_BASE, VRAM_BASE - IO_MEM_BASE - }, - { // arm9 exception vector table - A9_VECTORS_START, A9_VECTORS_SIZE - }, - { // arm9 stack - A9_STACK_START, A9_STACK_END - A9_STACK_START - }, - { // Console unique data + ARM9 FIRM launch stub + argv data - ITCM_BASE + 0x3800, ITCM_SIZE - 0x3800 - }, - { // arm11 exception vector table - A11_VECTORS_START, A11_VECTORS_SIZE - }, - { // arm11 stack - A11_STACK_START, A11_STACK_END - A11_STACK_START - }, - { // arm11 relocated firm launch stub - A11_STUB_ENTRY, A11_STUB_SIZE - } -}; - -/* Calculates the actual firm partition size by using its header */ -bool firm_size(size_t *size) -{ - firm_header *firm_hdr = (firm_header*)FIRM_LOAD_ADDR; - u32 curLen = sizeof(firm_header); - u32 curOffset = 0; - *size = 0; - - /* scan sections in reverse order */ - for(int i=3; i>=0; i--) - { - firm_sectionheader *section = &firm_hdr->section[i]; - - if(section->size == 0) - continue; - - if(section->offset <= curOffset) - continue; - - curOffset = section->offset; - - if(section->size > FIRM_MAX_SIZE || curOffset >= FIRM_MAX_SIZE) - return false; - - if(curLen < curOffset + section->size) - curLen = curOffset + section->size; - - if(curLen > FIRM_MAX_SIZE) - return false; - } - - *size = curLen; - - return true; -} - -// NOTE: Do not call any functions here! -void NAKED firmLaunchStub(int argc, const char **argv) -{ - firm_header *firm_hdr = (firm_header*)FIRM_LOAD_ADDR; - void (*entry9)(int, const char**, u32) = (void (*)(int, const char**, u32))firm_hdr->entrypointarm9; - u32 entry11 = firm_hdr->entrypointarm11; - - - for(u32 i = 0; i < 4; i++) - { - firm_sectionheader *section = &firm_hdr->section[i]; - if(section->size == 0) - continue; - - // Use NDMA for everything but copy method 2 - if(section->copyMethod < 2) - { - REG_NDMA_SRC_ADDR(i) = FIRM_LOAD_ADDR + section->offset; - REG_NDMA_DST_ADDR(i) = section->address; - REG_NDMA_LOG_BLK_CNT(i) = section->size / 4; - REG_NDMA_INT_CNT(i) = NDMA_INT_SYS_FREQ; - REG_NDMA_CNT(i) = NDMA_ENABLE | NDMA_BURST_SIZE(128) | NDMA_STARTUP_IMMEDIATE | - NDMA_SRC_UPDATE_INC | NDMA_DST_UPDATE_INC; - } - else - { - u32 *dst = (u32*)section->address; - u32 *src = (u32*)(FIRM_LOAD_ADDR + section->offset); - - for(u32 n = 0; n < section->size / 4; n += 4) - { - dst[n + 0] = src[n + 0]; - dst[n + 1] = src[n + 1]; - dst[n + 2] = src[n + 2]; - dst[n + 3] = src[n + 3]; - } - } - } - - while(REG_NDMA0_CNT & NDMA_ENABLE || REG_NDMA1_CNT & NDMA_ENABLE || - REG_NDMA2_CNT & NDMA_ENABLE || REG_NDMA3_CNT & NDMA_ENABLE); - - // Tell ARM11 its entrypoint - REG_PXI_SYNC9 = 0; // Disable all IRQs - while(REG_PXI_CNT9 & PXI_SEND_FIFO_FULL); - REG_PXI_SEND9 = entry11; - - // Wait for ARM11... - while(1) - { - while(REG_PXI_CNT9 & PXI_RECV_FIFO_EMPTY); - if(REG_PXI_RECV9 == PXI_RPL_FIRM_LAUNCH_READY) - break; - } - REG_PXI_CNT9 = 0; // Disable PXI - - // go for it! - entry9(argc, argv, 0x2BEEFu); -} - -bool firm_verify(u32 fwSize, bool skipHashCheck, bool printInfo) -{ - firm_header *firm_hdr = (firm_header*)FIRM_LOAD_ADDR; - const char *const res[2] = {"\x1B[31mBAD", "\x1B[32mGOOD"}; - bool isValid; - bool retval = true; - u32 hash[8]; - - if(fwSize > FIRM_MAX_SIZE) - return false; - - if(fwSize <= sizeof(firm_header)) - return false; - - if(memcmp(&firm_hdr->magic, "FIRM", 4) != 0) - return false; - - if(firm_hdr->entrypointarm9 == 0) - { - if(printInfo) uiPrintError("Bad ARM9 entrypoint!\n"); - return false; - } - - if(printInfo) - { - uiPrintInfo("\nARM9 entry: 0x%" PRIX32 "\n", firm_hdr->entrypointarm9); - uiPrintInfo("ARM11 entry: 0x%" PRIX32 "\n\n", firm_hdr->entrypointarm11); - } - - for(u32 i=0; i<4; i++) - { - firm_sectionheader *section = &firm_hdr->section[i]; - - if(section->size == 0) - continue; - - if(printInfo) - uiPrintInfo("Section %" PRIu32 ":\n Offset: 0x%" PRIX32 "\n Addr: 0x%" PRIX32 "\n Size: 0x%" PRIX32 "\n", - i, section->offset, section->address, section->size); - - if(section->offset >= fwSize || section->offset < sizeof(firm_header)) - { - if(printInfo) - uiPrintError("Bad section offset!\n"); - return false; - } - - if((section->size >= fwSize) || (section->size + section->offset > fwSize)) - { - if(printInfo) - uiPrintError("Bad section size!\n"); - return false; - } - - // check for bad sections - const u32 numEntries = arrayEntries(firmProtectedAreas); - - for(u32 j=0; jaddress; - u32 end = start + section->size; - - isValid = true; - - if(start >= addr && start < addr + size) isValid = false; - - else if(end > addr && end <= addr + size) isValid = false; - - else if(start < addr && end > addr + size) isValid = false; - - if(!isValid) - { - if(printInfo) - uiPrintError("Unallowed section:\n0x%" PRIX32 " - 0x%" PRIX32 "\n", start, end); - retval = false; - break; - } - } - - if(!skipHashCheck) - { - sha((u32*)(FIRM_LOAD_ADDR + section->offset), section->size, hash, - SHA_INPUT_BIG | SHA_MODE_256, SHA_OUTPUT_BIG); - isValid = memcmp(hash, section->hash, 32) == 0; - - if(printInfo) - uiPrintInfo(" Hash: %s\x1B[0m\n", res[isValid]); - - retval &= isValid; - } - } - - return retval; -} - -noreturn void firm_launch(int argc, const char **argv) -{ - //ee_printf("Sending PXI_CMD_FIRM_LAUNCH\n"); - PXI_sendWord(PXI_CMD_FIRM_LAUNCH); - - //ee_printf("Waiting for ARM11...\n"); - while(PXI_recvWord() != PXI_RPL_OK); - - //ee_printf("Relocating FIRM launch stub...\n"); - memcpy((void*)A9_STUB_ENTRY, (const void*)firmLaunchStub, A9_STUB_SIZE); - - deinitCpu(); - - //ee_printf("Starting firm launch...\n"); - ((void (*)(int, const char**))A9_STUB_ENTRY)(argc, argv); - while(1); -} diff --git a/source/arm9/firmwriter.c b/source/arm9/firmwriter.c index e087be2..69ccb0e 100644 --- a/source/arm9/firmwriter.c +++ b/source/arm9/firmwriter.c @@ -26,8 +26,6 @@ #include "arm9/hardware/hid.h" #include "util.h" #include "arm9/firmwriter.h" -#include "arm9/main.h" -#include "arm9/gui/menu.h" #include "arm9/hardware/timer.h" diff --git a/source/arm9/fmt.c b/source/arm9/fmt.c deleted file mode 100644 index be6e110..0000000 --- a/source/arm9/fmt.c +++ /dev/null @@ -1,430 +0,0 @@ -/* -* This file is part of Luma3DS -* Copyright (C) 2016-2017 Aurora Wright, TuxSH -* -* 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 . -* -* Additional Terms 7.b and 7.c of GPLv3 apply to this file: -* * Requiring preservation of specified reasonable legal notices or -* author attributions in that material or in the Appropriate Legal -* Notices displayed by works containing it. -* * Prohibiting misrepresentation of the origin of that material, -* or requiring that modified versions of such material be marked in -* reasonable ways as different from the original version. -*/ - -/* File : barebones/ee_printf.c - This file contains an implementation of ee_printf that only requires a method to output a char to a UART without pulling in library code. - -This code is based on a file that contains the following: - Copyright (C) 2002 Michael Ringgaard. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3. Neither the name of the project nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - -*/ - -//TuxSH's changes: add support for 64-bit numbers, remove floating-point code - -#include -#include -#include "types.h" -#include "arm9/fmt.h" -#include "arm9/console.h" - -#define ZEROPAD (1<<0) //Pad with zero -#define SIGN (1<<1) //Unsigned/signed long -#define PLUS (1<<2) //Show plus -#define SPACE (1<<3) //Spacer -#define LEFT (1<<4) //Left justified -#define HEX_PREP (1<<5) //0x -#define UPPERCASE (1<<6) //'ABCDEF' - -#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9') - -u32 strnlen(const char *string, u32 maxlen) -{ - u32 size; - - for(size = 0; size < maxlen && *string; string++, size++); - - return size; -} - -static s32 skipAtoi(const char **s) -{ - s32 i = 0; - - while(IS_DIGIT(**s)) i = i * 10 + *((*s)++) - '0'; - - return i; -} - -static char *processNumber(char *str, const char *const strEnd, s64 num, bool isHex, s32 size, s32 precision, u32 type) -{ - char sign = 0; - - if(type & SIGN) - { - if(num < 0) - { - sign = '-'; - num = -num; - size--; - } - else if(type & PLUS) - { - sign = '+'; - size--; - } - else if(type & SPACE) - { - sign = ' '; - size--; - } - } - - static const char *lowerDigits = "0123456789abcdef", - *upperDigits = "0123456789ABCDEF"; - - s32 i = 0; - char tmp[20]; - const char *dig = (type & UPPERCASE) ? upperDigits : lowerDigits; - - if(num == 0) - { - if(precision != 0) tmp[i++] = '0'; - type &= ~HEX_PREP; - } - else - { - while(num != 0) - { - u64 base = isHex ? 16ULL : 10ULL; - tmp[i++] = dig[(u64)num % base]; - num = (s64)((u64)num / base); - } - } - - if(type & LEFT || precision != -1) type &= ~ZEROPAD; - if(type & HEX_PREP && isHex) size -= 2; - if(i > precision) precision = i; - size -= precision; - if(!(type & (ZEROPAD | LEFT))) - while(size-- > 0) - { - if(str >= strEnd) goto end; - *str++ = ' '; - } - if(sign) - { - if(str >= strEnd) goto end; - *str++ = sign; - } - - if(type & HEX_PREP && isHex) - { - if(str + 2 >= strEnd) goto end; - *str++ = '0'; - *str++ = 'x'; - } - - if(type & ZEROPAD) - while(size-- > 0) - { - if(str >= strEnd) goto end; - *str++ = '0'; - } - while(i < precision--) - { - if(str >= strEnd) goto end; - *str++ = '0'; - } - while(i-- > 0) - { - if(str >= strEnd) goto end; - *str++ = tmp[i]; - } - while(size-- > 0) - { - if(str >= strEnd) goto end; - *str++ = ' '; - } - -end: - return str; -} - -u32 ee_vsnprintf(char *buf, u32 size, const char *fmt, va_list args) -{ - if(size == 0) return 0; - const char *const strEnd = buf + size - 1; - - char *str; - for(str = buf; *fmt; fmt++) - { - if(*fmt != '%') - { - if(str >= strEnd) break; - *str++ = *fmt; - continue; - } - - //Process flags - u32 flags = 0; //Flags to number() - bool loop = true; - - while(loop) - { - switch(*++fmt) - { - case '-': flags |= LEFT; break; - case '+': flags |= PLUS; break; - case ' ': flags |= SPACE; break; - case '#': flags |= HEX_PREP; break; - case '0': flags |= ZEROPAD; break; - default: loop = false; break; - } - } - - //Get field width - s32 fieldWidth = -1; //Width of output field - if(IS_DIGIT(*fmt)) fieldWidth = skipAtoi(&fmt); - else if(*fmt == '*') - { - fmt++; - - fieldWidth = va_arg(args, s32); - - if(fieldWidth < 0) - { - fieldWidth = -fieldWidth; - flags |= LEFT; - } - } - - //Get the precision - s32 precision = -1; //Min. # of digits for integers; max number of chars for from string - if(*fmt == '.') - { - fmt++; - - if(IS_DIGIT(*fmt)) precision = skipAtoi(&fmt); - else if(*fmt == '*') - { - fmt++; - precision = va_arg(args, s32); - } - - if(precision < 0) precision = 0; - } - - //Get the conversion qualifier - u32 integerType = 0; - if(*fmt == 'l') - { - if(*++fmt == 'l') - { - fmt++; - integerType = 1; - } - - } - else if(*fmt == 'h') - { - if(*++fmt == 'h') - { - fmt++; - integerType = 3; - } - else integerType = 2; - } - - bool isHex; - - switch(*fmt) - { - case 'c': - if(!(flags & LEFT)) - while(--fieldWidth > 0) - { - if(str >= strEnd) goto end; - *str++ = ' '; - } - if(str >= strEnd) goto end; - *str++ = (u8)va_arg(args, s32); - while(--fieldWidth > 0) - { - if(str >= strEnd) goto end; - *str++ = ' '; - } - continue; - - case 's': - { - char *s = va_arg(args, char *); - if(!s) s = ""; - u32 len = (precision != -1) ? strnlen(s, precision) : strlen(s); - if(!(flags & LEFT)) - while((s32)len < fieldWidth--) - { - if(str >= strEnd) goto end; - *str++ = ' '; - } - for(u32 i = 0; i < len; i++) - { - if(str >= strEnd) goto end; - *str++ = *s++; - } - while((s32)len < fieldWidth--) - { - if(str >= strEnd) goto end; - *str++ = ' '; - } - continue; - } - - case 'p': - if(fieldWidth == -1) - { - fieldWidth = 8; - flags |= ZEROPAD; - } - str = processNumber(str, strEnd, va_arg(args, u32), true, fieldWidth, precision, flags); - continue; - - //Integer number formats - set up the flags and "break" - case 'X': - flags |= UPPERCASE; - //Falls through - case 'x': - isHex = true; - break; - - case 'd': - case 'i': - flags |= SIGN; - //Falls through - case 'u': - isHex = false; - break; - - default: - if(*fmt != '%') - { - if(str >= strEnd) goto end; - *str++ = '%'; - } - if(*fmt) - { - if(str >= strEnd) goto end; - *str++ = *fmt; - } - else fmt--; - continue; - } - - s64 num; - - if(flags & SIGN) - { - if(integerType == 1) num = va_arg(args, s64); - else num = va_arg(args, s32); - - if(integerType == 2) num = (s16)num; - else if(integerType == 3) num = (s8)num; - } - else - { - if(integerType == 1) num = va_arg(args, u64); - else num = va_arg(args, u32); - - if(integerType == 2) num = (u16)num; - else if(integerType == 3) num = (u8)num; - } - - str = processNumber(str, strEnd, num, isHex, fieldWidth, precision, flags); - } - -end: - *str = 0; - return str - buf; -} - -u32 ee_vsprintf(char *const buf, const char *const fmt, va_list arg) -{ - return ee_vsnprintf(buf, 0x1000, fmt, arg); -} - -__attribute__ ((format (printf, 2, 3))) u32 ee_sprintf(char *const buf, const char *const fmt, ...) -{ - va_list args; - va_start(args, fmt); - u32 res = ee_vsnprintf(buf, 0x1000, fmt, args); - va_end(args); - - return res; -} - -__attribute__ ((format (printf, 3, 4))) u32 ee_snprintf(char *const buf, u32 size, const char *const fmt, ...) -{ - va_list args; - va_start(args, fmt); - u32 res = ee_vsnprintf(buf, size, fmt, args); - va_end(args); - - return res; -} - -__attribute__ ((format (printf, 1, 2))) u32 ee_printf(const char *const fmt, ...) -{ - char buf[512]; - va_list args; - va_start(args, fmt); - u32 res = ee_vsnprintf(buf, 512, fmt, args); - va_end(args); - - con_write(NULL, NULL, buf, res); - - return res; -} - -u32 ee_puts(const char *const str) -{ - con_write(NULL, NULL, str, strnlen(str, 512)); - con_write(NULL, NULL, "\n", 1); - return 0; -} diff --git a/source/arm9/gui/menu.c b/source/arm9/gui/menu.c deleted file mode 100644 index 0012b70..0000000 --- a/source/arm9/gui/menu.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 "types.h" -#include "mem_map.h" -#include "util.h" -#include "hardware/pxi.h" -#include "arm9/console.h" -#include "arm9/dev.h" -#include "fatfs/ff.h" -#include "fatfs/diskio.h" -#include "arm9/fsutils.h" -#include "arm9/hardware/hid.h" -#include "arm9/main.h" -#include "arm9/gui/menu.h" -#include "arm9/gui/menu_firmloader.h" -#include "arm9/hardware/timer.h" -#include "arm9/hardware/interrupt.h" -#include "arm9/config.h" - - -const menu_state_options menu_main = { - 6, - { - {"Continue boot", MENU_STATE_FIRM_LAUNCH_SETTINGS}, - {"Launch Firmware...", MENU_STATE_BROWSER}, - {"NAND tools...", MENU_STATE_NAND_MENU}, - {"Options...", MENU_STATE_OPTIONS_MENU}, - {"Update", MENU_STATE_UPDATE}, - {"Credits", MENU_STATE_CREDITS}, - } -}; - -const menu_state_options menu_nand = { - 3, - { - {"Backup NAND", MENU_STATE_NAND_BACKUP}, - {"Restore NAND", MENU_STATE_NAND_RESTORE}, - {"Flash Firmware", MENU_STATE_NAND_FLASH_FIRM} - } -}; - -const menu_state_options menu_loadfw = { - 2, - { - {"Load from SD card", MENU_STATE_BROWSER}, - {"Load firm1", 0}, - } -}; - -// menu_state_type -> menu_state_options instance -const menu_state_options *options_lookup[] = { - &menu_main, // STATE_MAIN - &menu_nand, // STATE_NAND_MENU - &menu_loadfw, // MENU_STATE_LOAD_FIRM -}; - -enum menu_state_type menu_state; -enum menu_state_type menu_next_state; - -enum menu_state_type menu_previous_states[8]; -int menu_previous_states_count; - -int menu_event_state; -static bool waitForVBlank; - -static void menuRunOnce(int state); - -static void menu_main_draw_top() -{ - const char *const sd_res[3] = {"\x1B[33mNot inserted ", "\x1B[31mFS init failed", "\x1B[32mOK "}; - const char *const nand_res[2] = {"\x1B[31mInit failed: ", "\x1B[32mOK "}; - const char *const nand_drives[3] = {"twln ", "twlp ", "nand"}; - const char *const boot_res[4] = {"Not attempted", "Not found", "Failed", "Skipped"}; - - consoleSelect(&con_top); - - uiPrintCenteredInLine(1, "fastboot 3DS " VERS_STRING); - - uiPrintTextAt(1, 4, "Model: %s", bootInfo.model); - uiPrintTextAt(1, 5, "\x1B[33m%s\e[0m", bootInfo.bootEnv); - uiPrintTextAt(1, 6, "\x1B[32m(%s Mode)\x1B[0m", bootInfo.mode); - uiPrintTextAt(1, 8, "SD card status: %s\x1B[0m", sd_res[bootInfo.sd_status]); - uiPrintTextAt(1, 9, "NAND status: %s\x1B[0m", nand_res[bootInfo.nand_status == 7]); - if(bootInfo.nand_status != 7) - { - for(u32 i = 0; i < 3; i++) - { - if(!(bootInfo.nand_status>>i & 1u)) uiPrintError(nand_drives[i]); - } - } - uiPrintTextAt(1, 10, "Wifi flash status: %s\e[0m", nand_res[bootInfo.wififlash_status]); - - if(bootInfo.numBootOptionsAttempted != 0) - { - uiPrintTextAt(1, 15, "Firm launch statistics:"); - uiPrintTextAt(1, 16, "[Slot1]: %s", boot_res[bootInfo.bootOptionResults[0]]); - uiPrintTextAt(1, 17, "[Slot2]: %s", boot_res[bootInfo.bootOptionResults[1]]); - uiPrintTextAt(1, 18, "[Slot3]: %s", boot_res[bootInfo.bootOptionResults[2]]); - } -} - -void menuSetVBlank(bool enable) -{ - if(enable) - { - IRQ_registerHandler(IRQ_TIMER_0, NULL); - TIMER_start(TIMER_0, TIMER_PRESCALER_64, TIMER_FREQ_64(60.0f), true); - waitForVBlank = true; - } - else - { - waitForVBlank = false; - TIMER_stop(TIMER_0); - IRQ_unregisterHandler(IRQ_TIMER_0); - } -} - -int enter_menu(int initial_state) -{ - u32 keys; - int cursor_pos; - const char* path; - const char *firmPath = NULL; - - menu_event_state = MENU_EVENT_NONE; - - cursor_pos = 0; - - uiClearConsoles(); - uiDrawConsoleWindow(); - - menuSetVBlank(true); - - // caller requested to enter a submenu? - if(initial_state != MENU_STATE_MAIN) - { - menuRunOnce(initial_state); - goto exitAndLaunchFirm; - } - - menuSetEnterNextState(MENU_STATE_MAIN); - menuActState(); - - - // Menu main loop - for(;;) - { - const menu_state_options *cur_options = options_lookup[menu_state]; - - switch(menu_state) - { - case MENU_STATE_MAIN: - case MENU_STATE_NAND_MENU: - - hidScanInput(); - keys = hidKeysDown(); - - menu_main_draw_top(); - - // print all the options of the current state - consoleSelect(&con_bottom); - for(int i=0; i < cur_options->count; i++) - uiPrintTextAt(9, 4+i, "%s\e[0m %s\n", cursor_pos == i ? "\x1B[33m*" : " ", - cur_options->options[i].name); - - if(keys & KEY_DUP) - { - if(cursor_pos == 0) cursor_pos = cur_options->count - 1; // jump to the last option - else cursor_pos--; - } - else if(keys & KEY_DDOWN) - { - if(cursor_pos == cur_options->count - 1) cursor_pos = 0; // jump to the first option - else cursor_pos++; - } - else if(keys & KEY_A) // select option - { - menuSetEnterNextState(cur_options->options[cursor_pos].state); - cursor_pos = 0; - } - else if(keys & KEY_B) // go back - { - if(menuSetReturnToState(STATE_PREVIOUS)) - cursor_pos = 0; - } - break; - - case MENU_STATE_NAND_BACKUP: - menuSetVBlank(false); - menuDumpNand("sdmc:/nand.bin"); - uiClearConsoles(); - menuSetVBlank(true); - break; - - case MENU_STATE_NAND_RESTORE: - menuSetVBlank(false); - menuRestoreNand("sdmc:/nand.bin"); - uiClearConsoles(); - menuSetVBlank(true); - break; - - case MENU_STATE_NAND_FLASH_FIRM: - path = browseForFile("sdmc:"); - uiClearConsoles(); - if(!path) - break; - menuSetVBlank(false); - menuFlashFirmware(path); - uiClearConsoles(); - menuSetVBlank(true); - break; - - case MENU_STATE_OPTIONS_MENU: - menuOptions(); - uiClearConsoles(); - break; - - case MENU_STATE_FIRM_LAUNCH: - if(!menuLaunchFirm(firmPath, false)) - uiClearConsoles(); - break; - - case MENU_STATE_FIRM_LAUNCH_SETTINGS: - if(!tryLoadFirmwareFromSettings(true)) - uiClearConsoles(); - break; - - case MENU_STATE_BROWSER: - path = browseForFile("sdmc:"); - uiClearConsoles(); - firmPath = path; - if(!path) // no file selected - break; - menuSetEnterNextState(MENU_STATE_FIRM_LAUNCH); - break; - - case MENU_STATE_UPDATE: - menuSetVBlank(false); - menuUpdateLoader(); - uiClearConsoles(); - menuSetVBlank(true); - break; - - case MENU_STATE_CREDITS: - menuCredits(); - uiClearConsoles(); - break; - - case MENU_STATE_EXIT: - goto exitAndLaunchFirm; - break; - - /* this should never happen */ - default: uiPrintIfVerbose("OOPS!\n"); break; - } - - switch(menuUpdateGlobalState()) - { - case MENU_EVENT_HOME_PRESSED: - break; - case MENU_EVENT_STATE_CHANGE: - if(menu_next_state == MENU_STATE_EXIT) - goto exitAndLaunchFirm; - else - clearConsole(0); - break; - default: - break; - } - - menuActState(); - } - -exitAndLaunchFirm: - menuSetVBlank(false); - - return 0; -} - -static void menuRunOnce(int state) -{ - switch(state) - { - case MENU_STATE_FIRM_LAUNCH_SETTINGS: - if(!tryLoadFirmwareFromSettings(true)) - uiClearConsoles(); - break; - - default: - panic(); - } -} - -bool menuSetReturnToState(int state) -{ - int i; - - if(state == STATE_PREVIOUS) - { - if(menu_previous_states_count <= 1) - return false; - state = menu_previous_states[menu_previous_states_count - 1]; - menu_previous_states_count--; - } - else if(state == MENU_STATE_EXIT) - { - menu_previous_states_count = 0; - } - else - { - for(i=menu_previous_states_count; i>0; i--) - { - if(menu_previous_states[i] == state) - { - menu_previous_states_count = i; - } - } - } - - menu_next_state = state; - // emit event - menu_event_state = MENU_EVENT_STATE_CHANGE; - - return true; -} - -void menuSetEnterNextState(int state) -{ - if(menu_previous_states_count >= 8) - panic(); - - menu_previous_states[menu_previous_states_count] = menu_state; - menu_previous_states_count++; - - menu_next_state = state; - // emit event - menu_event_state = MENU_EVENT_STATE_CHANGE; -} - -int menuUpdateGlobalState(void) -{ - int retcode = MENU_EVENT_NONE; - - // Later if PXI interrupts are implemented we need an - // interrupt handler here which can tell the timer and - // PXI interrupts apart. - if(waitForVBlank) waitForInterrupt(); - - - /* Check PXI Response register */ - - bool successFlag; - u32 replyCode = PXI_tryRecvWord(&successFlag); - - while(successFlag) - { - switch(replyCode) - { - case PXI_RPL_HOME_PRESSED: - case PXI_RPL_HOME_HELD: - retcode = MENU_EVENT_HOME_PRESSED; - break; - case PXI_RPL_POWER_PRESSED: - retcode = MENU_EVENT_POWER_PRESSED; - break; - default: - panic(); - } - // maybe there's more..? - replyCode = PXI_tryRecvWord(&successFlag); - } - - - /* Check for HW changes */ - - bool sd_active = dev_sdcard->is_active(); - if(!bootInfo.sd_status && sd_active) - { - retcode = MENU_EVENT_SD_CARD_INSERTED; - } - else if(bootInfo.sd_status && !sd_active) - { - retcode = MENU_EVENT_SD_CARD_REMOVED; - } - - - // Submenu wants to call a new menu? - if(menu_state != menu_next_state) - retcode = MENU_EVENT_STATE_CHANGE; - - // did anything happen? - if(retcode != MENU_EVENT_NONE) - menu_event_state = retcode; - - return retcode; -} - -void menuActState(void) -{ - switch(menu_event_state) - { - case MENU_EVENT_NONE: - break; // nothing to do, boring. - case MENU_EVENT_POWER_PRESSED: - power_off_safe(); - break; - case MENU_EVENT_HOME_PRESSED: - menuSetReturnToState(MENU_STATE_MAIN); - break; - case MENU_EVENT_STATE_CHANGE: - menu_state = menu_next_state; - break; - case MENU_EVENT_SD_CARD_INSERTED: - fsUnmountNandFilesystems(); - if(fsMountSdmc()) bootInfo.sd_status = 2; - else bootInfo.sd_status = 1; - bootInfo.nand_status = fsRemountNandFilesystems(); - // also try to load saved settings - loadConfigFile(); - break; - case MENU_EVENT_SD_CARD_REMOVED: - bootInfo.sd_status = 0; - dev_sdcard->close(); - f_mount(NULL, "sdmc:", 1); - break; - default: - break; - } - - menu_event_state = MENU_EVENT_NONE; -} - -void menuPrintPrompt(const char *text) -{ - // TODO: use uiShowMessageWindow - uiPrintInfo(text); -} - -void menuWaitForAnyPadkey() -{ - int keys; - bool finished = false; - - do { - hidScanInput(); - keys = hidKeysDown(); - if(keys & HID_KEY_MASK_ALL) - finished = true; - - switch(menuUpdateGlobalState()) - { - case MENU_EVENT_HOME_PRESSED: - case MENU_EVENT_POWER_PRESSED: - finished = true; - default: - break; - } - - menuActState(); - - } while(!finished); -} diff --git a/source/arm9/gui/menu_credits.c b/source/arm9/gui/menu_credits.c deleted file mode 100644 index ed5be7d..0000000 --- a/source/arm9/gui/menu_credits.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 "types.h" -#include "mem_map.h" -#include "arm9/console.h" -#include "arm9/dev.h" -#include "fatfs/ff.h" -#include "hardware/pxi.h" -#include "arm9/hardware/hid.h" -#include "util.h" -#include "arm9/main.h" -#include "arm9/hardware/timer.h" -#include "arm9/gui/menu.h" -#include "arm9/gui/ui.h" - -void menuCredits(void) -{ - u32 keys; - unsigned i = 3; - - uiClearConsoles(); - - uiPrintCenteredInLine(1, "Credits"); - - uiPrintCenteredInLine(i++, "Main developers:"); - uiPrintCenteredInLine(i++, "derrek"); - uiPrintCenteredInLine(i++, "profi200"); - i++; - uiPrintCenteredInLine(i++, "Thanks to:"); - uiPrintCenteredInLine(i++, "yellows8"); - uiPrintCenteredInLine(i++, "plutoo"); - uiPrintCenteredInLine(i++, "smea"); - uiPrintCenteredInLine(i++, "Normmatt (for sdmmc code)"); - uiPrintCenteredInLine(i++, "WinterMute (for console code)"); - uiPrintCenteredInLine(i+=2, "... everyone who contributed to 3dbrew.org"); - - for(;;) - { - /* Handle HID */ - hidScanInput(); - keys = hidKeysDown(); - - if(keys & KEY_B) - { - goto done; - } - - switch(menuUpdateGlobalState()) - { - case MENU_EVENT_HOME_PRESSED: - case MENU_EVENT_POWER_PRESSED: - case MENU_EVENT_STATE_CHANGE: - goto done; - default: - break; - } - - menuActState(); - } - -done: - - menuActState(); - menuSetReturnToState(STATE_PREVIOUS); -} diff --git a/source/arm9/gui/menu_filebrowse.c b/source/arm9/gui/menu_filebrowse.c deleted file mode 100644 index e394c84..0000000 --- a/source/arm9/gui/menu_filebrowse.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 "types.h" -#include "arm9/fmt.h" -#include "mem_map.h" -#include "fatfs/ff.h" -#include "arm9/console.h" -#include "arm9/main.h" -#include "arm9/gui/menu.h" -#include "arm9/hardware/interrupt.h" -#include "arm9/dev.h" -#include "util.h" -#include "arm9/hardware/hid.h" - - -#define MAX_CACHED_ENTRIES 0x400 -#define MAX_ENTRY_SIZE FF_MAX_LFN + 2 -#define MAX_NEW_ENTRIES 0x20 -#define MAX_PATH_LENGTH 0x400 -#define MAX_PATH_DEPTH 0x20 - -typedef struct { - char name[MAX_ENTRY_SIZE]; - bool isDir; -} EntryType; - -static EntryType *dirEntries; // [MAX_ENTRY_SIZE][MAX_CACHED_ENTRIES]; -static DIR curDirectory; -static char curPath[MAX_PATH_LENGTH]; -static u32 curEntriesCount; - -// This stack is used to recover the original cursor position -// in the dir entries list when returning from a subdir. -static u32 indexStack[MAX_PATH_DEPTH]; -static u32 *indexStackPtr = indexStack; - -/* This scans the current directory for entries. - Only MAX_NEW_ENTRIES will be added at maximum. - This also updates the curEntriesCount. - Returns true if new entries were added. */ -static bool scanDirectory() -{ - FRESULT res; - static FILINFO fno; - unsigned i = 0; - - for(i=0; i bufSize - 1) - { - end = in + entryLen; - strcpy(&out[3], end - bufSize + 3); - memcpy(out, "...", 3); - } - else strcpy(out, in); - } - else - { - if(entryLen > bufSize - 1) - { - memcpy(out, in, bufSize - 4); - memcpy(&out[bufSize - 5], "...", 4); - } - else strcpy(out, in); - } -} - -static void updateCursor(int cursor_pos, int old_cursor_pos, int maxEntries) -{ - // clear old '*' char - consoleSetCursor(&con_bottom, 0, (old_cursor_pos % (maxEntries)) + 1); - uiPrintInfo(" "); - - consoleSetCursor(&con_bottom, 0, (cursor_pos % (maxEntries)) + 1); - uiPrintInfo("*"); -} - -static void updateScreen(int cursor_pos, bool dirChange) -{ - // we don't want ugly line breaks in our list - const int maxLen = con_bottom.windowWidth - 1; - const int maxEntries = con_bottom.windowHeight - 1; - - static int old_cursor_pos; - - consoleSelect(&con_bottom); - - if(!dirChange && (cursor_pos < maxEntries) && (old_cursor_pos < maxEntries)) - { - updateCursor(cursor_pos, old_cursor_pos, maxEntries); - old_cursor_pos = cursor_pos; - return; - } - - old_cursor_pos = cursor_pos; - - char entry [maxLen]; // should be safe - unsigned start, end; - - consoleClear(); - - // print the current path in the first line - formatEntry(entry, curPath, (u32) maxLen - 3, false); - uiPrintInfo("%s :", entry); - - if(cursor_pos < (int) maxEntries) - { - start = 0; - end = min(maxEntries, curEntriesCount); - } - else - { - start = cursor_pos - maxEntries + 1; - end = min(cursor_pos + 1, curEntriesCount); - } - - for(unsigned i = start; i < end; i++) - { - formatEntry(entry, dirEntries[i].name, (u32) maxLen - 2, true); - uiPrintInfo("\n%s %s", i == (unsigned) cursor_pos ? "*" : " ", entry); - } -} - -const char *browseForFile(const char *basePath) -{ - FRESULT res; - u32 keys; - u32 cursor_pos = 0; - bool fileSelected = false; - int returnState = STATE_PREVIOUS; - - curEntriesCount = 0; - indexStackPtr = indexStack; - - uiClearConsoles(); - - dirEntries = (EntryType *) malloc(MAX_CACHED_ENTRIES * sizeof(EntryType)); - if(!dirEntries) - { - menuSetReturnToState(STATE_PREVIOUS); - menuUpdateGlobalState(); - menuActState(); - return NULL; - } - - if(basePath) - strncpy_s(curPath, basePath, sizeof(curPath) - 1, sizeof(curPath)); - 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()); - - uiClearConsoles(); - } - - res = f_opendir(&curDirectory, curPath); - if (res != FR_OK) - { - menuPrintPrompt("Failed to enter directory.\n"); - menuWaitForAnyPadkey(); - free(dirEntries); - menuSetReturnToState(STATE_PREVIOUS); - menuUpdateGlobalState(); - menuActState(); - return NULL; - } - - // do an initial scan - scanDirectory(); - - updateScreen((int)cursor_pos, true); - - for(;;) - { - hidScanInput(); - keys = hidKeysDown()/* | hidKeysHeld()*/; - - if(curEntriesCount != 0) - { - if(keys & KEY_DUP || keys & KEY_DLEFT) - { - if(cursor_pos != 0) - { - cursor_pos -= keys & KEY_DLEFT ? min(cursor_pos, 8) : 1; - updateScreen((int)cursor_pos, false); - } - } - - else if(keys & KEY_DDOWN || keys & KEY_DRIGHT) - { - // we reached the end of our entries list? - u32 old_pos = cursor_pos; - cursor_pos += keys & KEY_DRIGHT ? 8 : 1; - if(cursor_pos >= curEntriesCount) - { - scanDirectory(); - // we got more entries? - if(curEntriesCount > cursor_pos) - cursor_pos = min(cursor_pos, curEntriesCount - 1); - else - cursor_pos = curEntriesCount - 1; - if(cursor_pos != old_pos) - updateScreen((int)cursor_pos, false); - } - else - { - updateScreen((int)cursor_pos, false); - } - } - - else if(keys & KEY_A) // select entry - { - if(dirEntries[cursor_pos].isDir) // it's a dir - { - if(descendPath(cursor_pos, dirEntries[cursor_pos].name)) - { - f_closedir(&curDirectory); - res = f_opendir(&curDirectory, curPath); - if (res != FR_OK) - ascendPath(); - else - { - // fetch new entries - curEntriesCount = 0; - scanDirectory(); - cursor_pos = 0; - updateScreen((int)cursor_pos, true); - } - } - } - else // we got our file! - { - if(strlen(dirEntries[cursor_pos].name) + strlen(curPath) + 2 > sizeof(curPath)) - goto fail; // TODO? Path too long. - strcat(curPath, "/"); - strcat(curPath, dirEntries[cursor_pos].name); - fileSelected = true; - menuSetReturnToState(STATE_PREVIOUS); - } - } - } - if(keys & KEY_B) // go back - { - if(indexStackPtr != indexStack) - { - cursor_pos = ascendPath(); - f_closedir(&curDirectory); - - res = f_opendir(&curDirectory, curPath); - if (res != FR_OK) - goto fail; - curEntriesCount = 0; - - do { - if(!scanDirectory()) - goto fail; - } while(curEntriesCount <= cursor_pos); - - updateScreen((int)cursor_pos, true); - } - else - menuSetReturnToState(STATE_PREVIOUS); - } - - switch(menuUpdateGlobalState()) - { - case MENU_EVENT_HOME_PRESSED: - returnState = MENU_STATE_MAIN; - goto fail; - case MENU_EVENT_POWER_PRESSED: - case MENU_EVENT_SD_CARD_REMOVED: - goto fail; - case MENU_EVENT_STATE_CHANGE: - if(!fileSelected) goto fail; - else goto done; - default: - break; - } - - menuActState(); - - } - -done: - - f_closedir(&curDirectory); - free(dirEntries); - - menuSetReturnToState(returnState); - menuActState(); - - - return curPath; - -fail: - - f_closedir(&curDirectory); - free(dirEntries); - - menuSetReturnToState(returnState); - menuActState(); - - return NULL; -} diff --git a/source/arm9/gui/menu_firmloader.c b/source/arm9/gui/menu_firmloader.c deleted file mode 100644 index 8dee59b..0000000 --- a/source/arm9/gui/menu_firmloader.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 "types.h" -#include "mem_map.h" -#include "arm9/console.h" -#include "arm9/dev.h" -#include "fatfs/ff.h" -#include "arm9/hardware/hid.h" -#include "util.h" -#include "hardware/pxi.h" -#include "arm9/main.h" -#include "arm9/hardware/timer.h" -#include "arm9/gui/menu.h" -#include "arm9/firm.h" -#include "arm9/config.h" -#include "arm9/partitions.h" -#include "arm9/fsutils.h" - -static int firmLoaded = 0; - -bool isFirmLoaded(void) -{ - return firmLoaded != 0; -} - -bool menuLaunchFirm(const char *filePath, bool quick) -{ - if(!filePath) - return false; - - firmLoaded = 0; - - uiClearConsoles(); - consoleSelect(&con_top); - - uiPrintCenteredInLine(1, "FIRM Loader"); - - menuUpdateGlobalState(); - - if(!tryLoadFirmware(filePath, false, true)) - { - if(!quick) - { - uiPrintError("Bad firmware.\n"); - uiPrintInfo("Press any key...\n"); - - menuWaitForAnyPadkey(); - } - goto fail; - } - - firmLoaded = 1; - - uiPrint("Firmware verification SUCCESS!", 32, true); - - menuSetReturnToState(MENU_STATE_EXIT); - - return true; - -fail: - - uiPrintCenteredInLine(25, "FIRM-Launch aborted."); - - TIMER_sleep(500); - - firmLoaded = 0; - - menuSetReturnToState(STATE_PREVIOUS); - - return false; -} - -// Does very basic checks whether the firmware actually exists. -static bool statFirmware(const char *filePath) -{ - FILINFO fileStat; - // u32 fileSize; - - fsEnsureMounted(filePath); - - if(strncmp(filePath, "sdmc:", 5) == 0) - { - if(f_stat(filePath, &fileStat) != FR_OK) - return false; - - /* - fileSize = fileStat.fsize; - - if(fileSize == 0 || fileSize > FIRM_MAX_SIZE) - return false; - */ - - return true; - } - else if(strncmp(filePath, "firm1:", 5) == 0) - return true; // this is always available - - // unknown mountpoint - return false; -} - -static bool checkForHIDAbort() -{ - // give it 10 ms to check whether home button was pressed - return uiCheckHomePressed(10); -} - -bool tryLoadFirmwareFromSettings(bool fromMenu) -{ - const char *path; - int keyBootOption, bootMode, keyPad; - int i; - u32 padValue, expectedPadValue; - - if(fromMenu) - uiClearConsoles(); - - consoleSelect(&con_top); - - firmLoaded = 0; - - bootInfo.numBootOptionsAttempted = 0; - bootInfo.bootOptionResults[0] = BO_NOT_ATTEMPTED; - bootInfo.bootOptionResults[1] = BO_NOT_ATTEMPTED; - bootInfo.bootOptionResults[2] = BO_NOT_ATTEMPTED; - - if(fromMenu) - uiPrintCenteredInLine(1, "Loading FIRM from settings\n"); - - // No Boot Option set up? - if(!configDataExist(KBootOption1) && - !configDataExist(KBootOption2) && - !configDataExist(KBootOption3)) - { - if(fromMenu) - { - menuPrintPrompt("No Boot-Option set up yet.\nGo to 'Options' to choose a file.\n"); - menuWaitForAnyPadkey(); - menuSetReturnToState(STATE_PREVIOUS); - } - return false; - } - - const u32 *temp = configGetData(KBootMode); - bootMode = temp? *temp : BootModeNormal; - - keyBootOption = KBootOption1; - keyPad = KBootOption1Buttons; - - for(i=0; i<3; i++, keyBootOption++, keyPad++) - { - if(checkForHIDAbort()) - return false; - - bootInfo.numBootOptionsAttempted ++; - - path = (const char *)configGetData(keyBootOption); - if(path) - { - if(fromMenu) - uiPrintInfo("Boot Option #%i:\n%s\n", i + 1, path); - - // check if fw still exists - if(!statFirmware(path)) - { - if(fromMenu) - uiPrintInfo("Couldn't find firmware...\n"); - bootInfo.bootOptionResults[i] = BO_NOT_FOUND; - goto try_next; - } - - // check pad value - const u32 *dataPtr; - dataPtr = (const u32 *)configGetData(keyPad); - if(dataPtr) - { - expectedPadValue = *dataPtr; - - if(expectedPadValue != 0) - { - hidScanInput(); - padValue = HID_KEY_MASK_ALL & hidKeysHeld(); - if(padValue != expectedPadValue) - { - if(fromMenu) - { - uiPrintInfo("Skipping, right buttons are not pressed.\n"); - uiPrintInfo("%" PRIX32 " %" PRIX32 "\n", padValue, expectedPadValue); - } - bootInfo.bootOptionResults[i] = BO_SKIPPED; - goto try_next; - } - } - } - - if(fromMenu) - { - if(menuLaunchFirm(path, false)) - break; - else - { - uiClearConsoles(); - consoleSelect(&con_top); - } - } - else - { - if(tryLoadFirmware(path, false, false)) - break; - else - { - if(bootMode != BootModeQuiet) - uiPrintBootWarning(); - } - } - - bootInfo.bootOptionResults[i] = BO_FAILED; - } - else - continue; - -try_next: - - if(fromMenu) - TIMER_sleep(300); - - // ... we failed, try next one - } - - if(i >= 3) - { - if(fromMenu) - menuSetReturnToState(STATE_PREVIOUS); - else if(bootMode != BootModeQuiet) - uiPrintBootFailure(); - return false; - } - - if(checkForHIDAbort()) - return false; - - firmLoaded = 1; - - if(fromMenu) - menuSetReturnToState(MENU_STATE_EXIT); - - return true; -} - -static u32 loadFirmSd(const char *filePath) -{ - FIL file; - u32 fileSize; - UINT bytesRead = 0; - FILINFO fileStat; - - if(f_stat(filePath, &fileStat) != FR_OK) - { - uiPrintInfo("Failed to get file status!\n"); - return 0; - } - - fileSize = fileStat.fsize; - - if(f_open(&file, filePath, FA_READ) != FR_OK) - { - uiPrintInfo("Failed to open '%s'!\n", filePath); - return 0; - } - - if(fileSize == 0 || fileSize > FIRM_MAX_SIZE) - { - f_close(&file); - return 0; - } - - if(f_read(&file, (u8*)FIRM_LOAD_ADDR, fileSize, &bytesRead) != FR_OK) - { - uiPrintInfo("Failed to read from file!\n"); - fileSize = 0; - } - - if(bytesRead != fileSize) - fileSize = 0; - - f_close(&file); - - return fileSize; -} - -static u32 loadFirmNandPartition(const char *filePath) -{ - char partName[11]; - void *firmBuf = (void *) FIRM_LOAD_ADDR; - size_t index; - size_t sector; - size_t firmSize; - - strncpy_s(partName, filePath, 11, 11); - - if(!partitionGetIndex(partName, &index)) - return 0; - - partitionGetSectorOffset(index, §or); - - /* get header to figure out the actual firm size */ - if(!dev_decnand->read_sector(sector, 1, firmBuf)) - return 0; - - if(!firm_size(&firmSize)) - return 0; - - /* read the rest */ - - if(!dev_decnand->read_sector(sector + 1, firmSize - 1, firmBuf + 0x200)) - return 0; - - return firmSize; -} - -bool tryLoadFirmware(const char *filepath, bool skipHashCheck, bool printInfo) -{ - u32 fw_size; - - if(!filepath) - return false; - - if(!statFirmware(filepath)) - return false; - - // ee_printf("Loading firmware:\n%s\n\n", filepath); - - /* SD card */ - if(strncmp(filepath, "sdmc:", 5) == 0) - fw_size = loadFirmSd(filepath); - /* NAND */ - else if(strncmp(filepath, "firm1:", 5) == 0) - fw_size = loadFirmNandPartition(filepath); - else - return false; // TODO: Support more devices - - if(fw_size == 0) - return false; - - if(!firm_verify(fw_size, skipHashCheck, printInfo)) return false; - - ((const char**)(ITCM_KERNEL_MIRROR + 0x7470))[0] = ((const char*)(ITCM_KERNEL_MIRROR + 0x7474)); - strncpy_s((void*)(ITCM_KERNEL_MIRROR + 0x7474), filepath, 256, 256); - - return true; -} diff --git a/source/arm9/gui/menu_nand.c b/source/arm9/gui/menu_nand.c deleted file mode 100644 index 9ec758d..0000000 --- a/source/arm9/gui/menu_nand.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 "types.h" -#include "mem_map.h" -#include "arm9/console.h" -#include "arm9/dev.h" -#include "fatfs/ff.h" -#include "arm9/hardware/hid.h" -#include "util.h" -#include "arm9/main.h" -#include "arm9/gui/menu.h" -#include "arm9/hardware/timer.h" -#include "arm9/partitions.h" -#include "arm9/firmwriter.h" -#include "arm9/nandimage.h" -#include "arm9/fsutils.h" - - -bool menuDumpNand(const char *filePath) -{ - const u32 sectorCount = dev_rawnand->get_sector_count(); - const u32 sectorBlkSize = 0x400; // 512 KB in sectors - FIL file; - FRESULT fres; - UINT bytesWritten; - u64 bytesFree; - - u8 *buf = (u8*)malloc(sectorBlkSize<<9); - if(!buf) - { // this should never happen. - uiPrintIfVerbose("Out of memory!"); - return false; - } - - uiClearConsoles(); - consoleSelect(&con_top); - - uiPrintCenteredInLine(1, "NAND Backup"); - - uiPrintTextAt(0, 3, "Checking free space on SD card...\n"); - - if(!fsGetFreeSpaceOnDrive("sdmc:", &bytesFree)) - uiPrintError("Failed to get free space!\n"); - - if(bytesFree < sectorCount<<9) - { - uiPrintError("Not enough space on the SD card!\n"); - goto fail; - } - - uiPrintTextAt(0, 4, "Creating image file...\n"); - - if((fres = f_open(&file, filePath, FA_CREATE_ALWAYS | FA_WRITE)) != FR_OK) - { - uiPrintError("Failed to create '%s'! Error: %X\n", filePath, fres); - goto fail; - } - - // Allocate space to make sure the nand image is a contiguous file - if((fres = f_expand(&file, sectorCount<<9, 0)) != FR_OK) - { - uiPrintError("Failed to expand file! Error: %X\n", fres); - f_sync(&file); - f_close(&file); - f_unlink(filePath); - goto fail; - } - - uiPrintTextAt(0, 4, "Unmounting NAND fs...\n"); - - fsUnmountNandFilesystems(); - - uiPrintTextAt(0, 5, "Dumping NAND...\n"); - uiPrintTextAt(0, 22, "Press B to cancel."); - - /* Main loop */ - - u32 curSector = 0; - u32 curSectorBlkSize; - while(curSector < sectorCount) - { - if(curSector + sectorBlkSize < sectorCount) curSectorBlkSize = sectorBlkSize; - else curSectorBlkSize = sectorCount - curSector; - - if(!dev_rawnand->read_sector(curSector, curSectorBlkSize, buf)) - { - uiPrintError("\nFailed to read sector 0x%"PRIx32"!\n", curSector); - f_sync(&file); - f_close(&file); - f_unlink(filePath); - goto fail; - } - if((f_write(&file, buf, curSectorBlkSize<<9, &bytesWritten) != FR_OK) || (bytesWritten != curSectorBlkSize<<9)) - { - uiPrintError("\nFailed to write to file!\n"); - f_sync(&file); - f_close(&file); - f_unlink(filePath); - goto fail; - } - - hidScanInput(); - if(hidKeysDown() & KEY_B) - { - uiPrintTextAt(0, 22, "... canceled. "); - f_sync(&file); - f_close(&file); - f_unlink(filePath); - goto fail; - } - - curSector += curSectorBlkSize; - - // print current progress information - uiPrintTextAt(1, 20, "\r%"PRId32"/%"PRId32" MB (Sector 0x%"PRIX32"/0x%"PRIX32")", curSector>>11, sectorCount>>11, - curSector, sectorCount); - - uiPrintProgressBar(10, 80, 380, 20, curSector, sectorCount); - - switch(menuUpdateGlobalState()) - { - case MENU_EVENT_HOME_PRESSED: - case MENU_EVENT_POWER_PRESSED: - f_sync(&file); - f_close(&file); - // falls through - case MENU_EVENT_SD_CARD_REMOVED: - menuActState(); - goto fail; - default: - break; - } - - menuActState(); - } - - f_sync(&file); - f_close(&file); - free(buf); - fsRemountNandFilesystems(); - - uiDialog("Finished!\nPress any key to return.", NULL, HID_KEY_MASK_ALL, 1, 0, 0, true); - - menuSetReturnToState(STATE_PREVIOUS); - - return true; - -fail: - free(buf); - fsRemountNandFilesystems(); - - uiPrintTextAt(0, 24, "Press any key to return."); - menuWaitForAnyPadkey(); - - menuSetReturnToState(STATE_PREVIOUS); - - return false; -} - -bool menuRestoreNand(const char *filePath) -{ - const u32 sectorBlkSize = 0x400; // 512 KB in sectors - FIL file; - UINT bytesRead; - - u8 *buf = (u8*)malloc(sectorBlkSize<<9); - if(!buf) - { // this should never happen. - uiPrintIfVerbose("Out of memory!"); - return false; - } - - uiClearConsoles(); - consoleSelect(&con_top); - - uiPrintCenteredInLine(1, "NAND Restore"); - - uiPrintTextAt(0, 3, "Checking backup file...\n"); - - FILINFO fileStat; - if(f_stat(filePath, &fileStat) != FR_OK) - { - uiPrintError("Failed to get file status!\n"); - goto fail; - } - if(fileStat.fsize > dev_rawnand->get_sector_count()<<9) - { - uiPrintError("NAND file is bigger than NAND!\n"); - goto fail; - } - if(fileStat.fsize < 0x200) - { - uiPrintError("NAND file is too small!\n"); - goto fail; - } - - if(f_open(&file, filePath, FA_READ) != FR_OK) - { - uiPrintError("Failed to open '%s'!\n", filePath); - f_close(&file); - goto fail; - } - - if(!isNandImageCompatible(&file)) - { - uiPrintError("NAND file is not compatible with this console!\n"); - f_close(&file); - goto fail; - } - - uiPrintTextAt(0, 4, "Unmounting NAND fs...\n"); - - fsUnmountNandFilesystems(); - - uiPrintTextAt(0, 5, "Restoring...\n"); - uiPrintTextAt(0, 22, "Press B to cancel."); - - /* Main loop */ - - const u32 sectorCount = fileStat.fsize>>9; - u32 curSector = 0; - u32 curSectorBlkSize; - while(curSector < sectorCount) - { - if(curSector + sectorBlkSize < sectorCount) curSectorBlkSize = sectorBlkSize; - else curSectorBlkSize = sectorCount - curSector; - - if(f_read(&file, buf, curSectorBlkSize<<9, &bytesRead) != FR_OK || bytesRead != curSectorBlkSize<<9) - { - uiPrintError("\nFailed to read from file!\n"); - f_close(&file); - goto fail; - } - if(!dev_rawnand->write_sector(curSector, curSectorBlkSize, buf)) - { - uiPrintError("\nFailed to write sector 0x%"PRIX32"!\n", curSector); - f_close(&file); - goto fail; - } - - hidScanInput(); - if(hidKeysDown() & KEY_B) - { - uiPrintTextAt(0, 22, "... canceled. "); - f_close(&file); - goto fail; - } - - curSector += curSectorBlkSize; - - uiPrintTextAt(1, 20, "\r%"PRId32"/%"PRId32" MB (Sector 0x%"PRIX32"/0x%"PRIX32")", curSector>>11, sectorCount>>11, - curSector, sectorCount); - - uiPrintProgressBar(10, 80, 380, 20, curSector, sectorCount); - - switch(menuUpdateGlobalState()) - { - case MENU_EVENT_HOME_PRESSED: - case MENU_EVENT_POWER_PRESSED: - f_close(&file); - // falls through - case MENU_EVENT_SD_CARD_REMOVED: - menuActState(); - goto fail; - default: - break; - } - - menuActState(); - } - - f_close(&file); - free(buf); - fsRemountNandFilesystems(); - - uiPrintTextAt(0, 24, "Finished! Press any key to return."); - menuWaitForAnyPadkey(); - - menuSetReturnToState(STATE_PREVIOUS); - - return true; - -fail: - free(buf); - fsRemountNandFilesystems(); - - uiPrintTextAt(0, 24, "Press any key to return."); - menuWaitForAnyPadkey(); - - menuSetReturnToState(STATE_PREVIOUS); - - return false; -} - -bool menuFlashFirmware(const char *filepath) -{ - const char *partName = "firm1"; // TODO let the user decide - FILINFO fileStat; - size_t fwSize; - size_t index; - size_t sector; - size_t numSectors; - - uiClearConsoles(); - consoleSelect(&con_top); - - uiPrintCenteredInLine(1, "Flash firmware"); - - uiPrintTextAt(0, 3, "Verifying file...\n"); - - if(f_stat(filepath, &fileStat) != FR_OK) - { - uiPrintError("Could not retrieve file status!\n"); - goto fail; - } - - if(!tryLoadFirmware(filepath, false, false) || !firm_size(&fwSize)) - { - uiPrintError("Firmware is invalid or corrupted!\n"); - goto fail; - } - - if(!partitionGetIndex(partName, &index)) - { - uiPrintError("Could not find partition %s!", partName); - goto fail; - } - - partitionGetSectorOffset(index, §or); - - if(!uiDialogYesNo(1, "Proceed", "Cancel", "Flash firmware to %s?", partName)) - { - goto fail; - } - - uiPrintTextAt(0, 4, "Writing...\n"); - - if(!firmwriterInit(sector, fwSize / 0x200, false)) - { - uiPrintError("Failed to start flashing process!"); - goto fail; - } - - for(size_t i=0; i. - */ - -#include -#include -#include -#include "types.h" -#include "mem_map.h" -#include "arm9/console.h" -#include "arm9/dev.h" -#include "fatfs/ff.h" -#include "hardware/pxi.h" -#include "arm9/hardware/hid.h" -#include "util.h" -#include "arm9/main.h" -#include "arm9/hardware/timer.h" -#include "arm9/gui/menu.h" -#include "arm9/nandimage.h" -#include "arm9/config.h" - - -#define MAX_SUBOPTIONS 3 - -static const char *optionStrings[] = { - "Change Boot Mode", - "Setup Boot Option", - // "Setup NAND Image" -- currently unuseed -}; - -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); -void handleBootOption(void); -void handleNandImage(void); - -bool menuOptions(void) -{ - u32 keys; - - uiClearConsoles(); - 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); - consoleSelect(&con_bottom); -} - -void rewindConsoleX(void) -{ - unsigned int len = con_bottom.windowWidth - con_bottom.cursorX; - while(len--) uiPrintInfo(" "); - - 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 - { - const u32 *mode = (const 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; - } -} - -void handleBootOption(void) -{ - if(subOptionsActive) - { - int key = KBootOption1 + (int) curSubOptionIndex; - - // const char *curPath = (const char *) configGetData(key); - - menuSetEnterNextState(MENU_STATE_BROWSER); - menuUpdateGlobalState(); - menuActState(); - const char *path = browseForFile("sdmc:"); - uiClearConsoles(); - - if(path) - configSetKeyData(key, path); - } - else - { - strcpy(optionSubStrings[0], "[Slot 1]"); - strcpy(optionSubStrings[1], "[Slot 2]"); - strcpy(optionSubStrings[2], "[Slot 3]"); - curSubOptionCount = 3; - } -} - -void handleNandImage(void) -{ - if(subOptionsActive) - { - int ret; - int key = KBootOption1NandImage + (int) curSubOptionIndex; - - // const char *curPath = (const char *) configGetData(key); - - menuSetEnterNextState(MENU_STATE_BROWSER); - menuUpdateGlobalState(); - menuActState(); - const char *path = browseForFile("sdmc:"); - uiClearConsoles(); - - if(path) - { - if((ret = validateNandImage(path)) != 0) - { - switch(ret) - { - case NANDIMG_ERROR_BADPATH: - menuPrintPrompt("Unsupported device or filepath!\n"); - break; - case NANDIMG_ERROR_NEXISTS: - menuPrintPrompt("NAND Image file corrupted!\n"); - break; - case NANDIMG_ERROR_NCONTS: - menuPrintPrompt("NAND Image file is not continuous!\n"); - break; - default: - break; - } - } - else configSetKeyData(key, path); - } - } - else - { - strcpy(optionSubStrings[0], "[Slot 1] Image"); - strcpy(optionSubStrings[1], "[Slot 2] Image"); - strcpy(optionSubStrings[2], "[Slot 3] Image"); - curSubOptionCount = 3; - } -} diff --git a/source/arm9/gui/menu_update.c b/source/arm9/gui/menu_update.c deleted file mode 100644 index 02d6a58..0000000 --- a/source/arm9/gui/menu_update.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 "types.h" -#include "mem_map.h" -#include "arm9/console.h" -#include "arm9/dev.h" -#include "arm9/partitions.h" -#include "fatfs/ff.h" -#include "arm9/hardware/hid.h" -#include "util.h" -#include "arm9/firmwriter.h" -#include "arm9/main.h" -#include "arm9/gui/menu.h" -#include "arm9/hardware/timer.h" -#include "arm9/hardware/crypto.h" -#include "fastboot3DS_pubkey_bin.h" - -#define MIN_UPDATE_SIZE 0x1000 - -static const char *updateFilePath = "sdmc:/fastboot3DS.firm"; -static const char *installPath = "firm0"; - -bool menuUpdateLoader() -{ - u32 *updateBuffer = (u32 *) FIRM_LOAD_ADDR; - FILINFO fileStat; - size_t fwSize; - size_t index; - size_t sector; - - uiClearConsoles(); - consoleSelect(&con_top); - - uiPrintCenteredInLine(1, "fastboot Updater"); - - uiPrintTextAt(0, 3, "Checking update file...\n"); - - if(f_stat(updateFilePath, &fileStat) != FR_OK) - { - uiPrintError("Could not find fastboot3ds.bin!\n"); - goto fail; - } - - // update file is just a firmware - if(!tryLoadFirmware(updateFilePath, false, false)) - { - uiPrintError("Update file is corrupted!\n"); - goto fail; - } - -#ifdef NDEBUG - // Verify signature - if(!RSA_setKey2048(3, fastboot3DS_pubkey_bin, 0x01000100) || - !RSA_verify2048(updateBuffer + 0x40, updateBuffer, 0x100)) - { - uiPrintError("Update file signature verification failed!\n"); - goto fail; - } -#endif - - if(!firm_size(&fwSize) || fwSize < MIN_UPDATE_SIZE || fwSize % 0x200) - { - // this would be really odd. - uiPrintError("Invalid update file!\n"); - goto fail; - } - - // verify fastboot magic - if(memcmp((void*)updateBuffer+0x200, "FASTBOOT 3DS ", 0x10) != 0) - { - uiPrintError("Not an update file!\n"); - goto fail; - } - - /* check version */ - u32 updateVersion = *(u32 *)((void*)updateBuffer + 0x210); - - if(updateVersion < ((u32)VERS_MAJOR<<16 | VERS_MINOR)) - { - uiPrintError("Update version is below current version!\n"); - goto fail; - } - - if(updateVersion == ((u32)VERS_MAJOR<<16 | VERS_MINOR)) - { - uiPrintWarning("You are on this version already.\n"); - goto fail; - } - - if(!uiDialogYesNo(1, "Update", "Cancel", "Update to v%" PRIu16 ".%" PRIu16, - updateVersion>>16, updateVersion & 0xFFFFu)) - { - goto fail; - } - - /* NOTE: We assume sighax is installed on firm0 */ - - if(!partitionGetIndex(installPath, &index)) - { - uiPrintError("Could not find partition %s!", installPath); - goto fail; - } - - partitionGetSectorOffset(index, §or); - // ee_printf("writing to offset 0x%x aka 0x%x\n", sector, sector<<9); - - uiPrintTextAt(0, 9, "Updating...\n"); - - if(!firmwriterInit(sector, fwSize / 0x200, true)) - { - uiPrintError("Failed to start update process!"); - goto fail; - } - - size_t numSectors; - - for(size_t i=1; i. - */ - -#include -#include -#include -#include "types.h" -#include "arm9/gui/splash.h" -#include "arm9/fmt.h" -#include "hardware/gfx.h" - - - -void lz11Decompress(const void *in, void *out, u32 size); - -void getSplashDimensions(const void *const data, u32 *const width, u32 *const height) -{ - const SplashHeader *const header = (const SplashHeader *const)data; - - if(width) *width = header->width; - if(height) *height = header->height; -} - -static bool validateSplashHeader(const SplashHeader *const header) -{ - if(memcmp(&header->magic, "SPLA", 4)) return false; - - const u32 width = header->width, height = header->height; - if(width == 0 || width > SCREEN_WIDTH_TOP || height == 0 || height > SCREEN_HEIGHT_TOP) - return false; - - const u32 flags = header->flags; - if((flags & FORMAT_INVALID) != FORMAT_RGB565) return false; - if(!(flags & FLAG_ROTATED) || flags & FLAG_SWAPPED) return false; - - return true; -} - -bool drawSplashscreen(const void *const data, s32 startX, s32 startY) -{ - const SplashHeader *const header = (const SplashHeader *const)data; - if(!validateSplashHeader(header)) return false; - - const u32 width = header->width, height = header->height; - const u32 flags = header->flags; - const bool isCompressed = flags & FLAG_COMPRESSED; - - u16 *imgData; - if(isCompressed) - { - imgData = (u16*)malloc(width * height * 2); - if(!imgData) return false; - lz11Decompress(data + sizeof(SplashHeader), imgData, width * height * 2); - } - else imgData = (u16*)(data + sizeof(SplashHeader)); - - u32 xx, yy; - if(startX < 0 || (u32)startX > SCREEN_WIDTH_TOP - width) xx = (SCREEN_WIDTH_TOP - width) / 2; - else xx = (u32)startX; - if(startY < 0 || (u32)startY > SCREEN_HEIGHT_TOP - height) yy = (SCREEN_HEIGHT_TOP - height) / 2; - else yy = (u32)startY; - - u16 *fb = (u16*)FRAMEBUF_TOP_A_1; - for(u32 x = 0; x < width; x++) - { - for(u32 y = 0; y < height; y++) - { - fb[(x + xx) * SCREEN_HEIGHT_TOP + y + yy] = imgData[x * height + y]; - } - } - - if(isCompressed) free(imgData); - - return true; -} diff --git a/source/arm9/gui/ui.c b/source/arm9/gui/ui.c deleted file mode 100644 index b38006f..0000000 --- a/source/arm9/gui/ui.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * 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 -#include "types.h" -#include "arm9/fmt.h" -#include "util.h" -#include "arm9/hardware/hid.h" -#include "hardware/pxi.h" -#include "arm9/hardware/timer.h" -#include "arm9/main.h" -#include "arm9/gui/ui.h" -#include "arm9/console.h" -#include "arm9/gui/splash.h" -#include "banner_spla.h" -#include "bootwarning_spla.h" -#include "bootfail_spla.h" - - -static u8 randomColor; -static bool verbose = false; - -static const void *bannerData = banner_spla; -static const void *bootWarningData = bootwarning_spla; -static const void *bootFailureData = bootfail_spla; - - - -static void consoleMainInit() -{ - /* Initialize console for both screens using the two different PrintConsole we have defined */ - consoleInit(SCREEN_TOP, &con_top, true); - consoleSetWindow(&con_top, 1, 1, con_top.windowWidth - 2, con_top.windowHeight - 2); - - // randomize color - randomColor = (rng_get_byte() % 6) + 1; - - consoleInit(SCREEN_LOW, &con_bottom, true); - - consoleSelect(&con_top); -} - -void uiDrawSplashScreen() -{ - drawSplashscreen(bannerData, -1, -1); - TIMER_sleep(600); -} - -void uiInit() -{ - consoleMainInit(); -} - -void uiDrawConsoleWindow() -{ - drawConsoleWindow(&con_top, 2, randomColor); -} - -static void clearConsoles() -{ - consoleSelect(&con_bottom); - consoleClear(); - consoleSelect(&con_top); - consoleClear(); -} - -void uiClearConsoles() -{ - clearConsoles(); -} - -void clearConsole(int which) -{ - if(which) - consoleSelect(&con_top); - else - consoleSelect(&con_bottom); - - consoleClear(); -} - -void uiSetVerboseMode(bool verb) -{ - verbose = verb; -} - -bool uiGetVerboseMode() -{ - return verbose; -} - -/* TODO: Should look similar to uiShowMessageWindow */ -bool uiDialogYesNo(int screen, const char *textYes, const char *textNo, const char *const format, ...) -{ - char tmp[256]; - char lastline[256]; - u32 keys; - - va_list args; - va_start(args, format); - ee_vsnprintf(tmp, 256, format, args); - va_end(args); - - ee_snprintf(lastline, 256, "(A): %s (B): %s", textYes, textNo); - - /* Print dialog */ - keys = uiDialog(tmp, lastline, KEY_A | KEY_B, screen, 0, 0, true); - - /* Evaluate user input */ - if(keys == KEY_A) - return true; - - // KEY_B - return false; -} - -void uiPrintIfVerbose(const char *const format, ...) -{ - if(verbose) - { - char tmp[256]; - - va_list args; - va_start(args, format); - ee_vsnprintf(tmp, 256, format, args); - va_end(args); - - ee_printf(tmp); - } -} - -/* Prints a given text at the current position */ -void uiPrint(const char *const format, unsigned int color, bool centered, ...) -{ - const unsigned int width = (unsigned int)consoleGet()->consoleWidth; - char tmp[256]; - - va_list args; - va_start(args, centered); - ee_vsnprintf(tmp, 556, format, args); - va_end(args); - - if(centered) - { - // Warning. The string must be <= the console width here! - size_t len = strlen(tmp); - ee_printf("\x1B[%um%*s%s\x1B[0m", color, (width - len) / 2, "", tmp); - } - else - { - ee_printf("\x1B[%um%s\x1B[0m", color, tmp); - } -} - -void uiPrintCenteredInLine(unsigned int y, const char *const format, ...) -{ - const unsigned int width = (unsigned int)consoleGet()->consoleWidth; - char tmp[width + 1]; - - va_list args; - va_start(args, format); - ee_vsnprintf(tmp, width + 1, format, args); - va_end(args); - - size_t len = strlen(tmp); - ee_printf("\x1b[%u;%uH", y, 0); - ee_printf("%*s%s\n", (width - len) / 2, "", tmp); -} - -/* Prints a given text at a certain position in the current window */ -void uiPrintTextAt(unsigned int x, unsigned int y, const char *const format, ...) -{ - char tmp[256]; - - va_list args; - va_start(args, format); - ee_vsnprintf(tmp, 256, format, args); - va_end(args); - - ee_printf("\x1b[%u;%uH%s", y, x, tmp); -} - -/* Prints a given text surrounded by a graphical window */ -/* centered in the middle of the screen. */ -/* Waits for the user to press any button, after that the */ -/* original framebuffer gets restored */ -u32 uiDialog(const char *const format, const char *const lastLine, u32 waitKeys, - int screen, unsigned int x, unsigned int y, bool centered, ...) -{ - char tmp[256]; - - va_list args; - va_start(args, centered); - ee_vsnprintf(tmp, 256, format, args); - va_end(args); - - char *ptr = tmp; - unsigned int lines = lastLine ? 5 : 3, longestLine = 2, curLen = 2; - while(*ptr) - { - switch(*ptr) - { - case '\n': - lines++; - curLen = 2; - break; - default: - curLen++; - } - if(curLen > longestLine) longestLine = curLen; - - ptr++; - } - - if(lastLine) - { - unsigned int lastLineLen = strlen(lastLine) + 2; - if(lastLineLen > longestLine) longestLine = lastLineLen; - } - - PrintConsole *prevCon = consoleGet(); - PrintConsole windowCon; - consoleInit(screen, &windowCon, false); - - if(centered) - { - x = (windowCon.windowWidth / 2) - (longestLine / 2); - y = (windowCon.windowHeight / 2) - (lines / 2); - } - consoleSetWindow(&windowCon, x, 30 - y - lines, longestLine, lines); - - u8 *fbBackup = (u8*)malloc(screen ? SCREEN_SIZE_TOP : SCREEN_SIZE_SUB); - u32 keys = 0; - if(fbBackup) - { - u16 *fb = consoleGet()->frameBuffer; - - // TODO: Optimize to only backup what will be overwritten. I'm lazy. - memcpy(fbBackup, fb, screen ? SCREEN_SIZE_TOP : SCREEN_SIZE_SUB); - - ee_printf("\x1B[37m\x1B[40m\x1B[2J\n"); - - const char *linePtr = tmp; - while(1) - { - unsigned int length = 0; - while(linePtr[length] != '\n' && linePtr[length] != '\0') length++; - ee_printf(" %.*s\n", length, linePtr); - if(*(linePtr + length) == '\0') break; - linePtr += length + 1; - } - - if(lastLine) - ee_printf("\x1b[%u;%uH%s", lines - 2, (longestLine - strlen(lastLine)) / 2, lastLine); - - const u16 color = consoleGetRGB565Color(randomColor); - for(u32 xx = x * 8 + 1; xx < x * 8 + (longestLine * 8) - 1; xx++) - { - fb[xx * SCREEN_HEIGHT_SUB + (y * 8)] = color; - fb[xx * SCREEN_HEIGHT_SUB + (y * 8) + (lines * 8) - 1] = color; - } - for(u32 xx = x * 8 + 3; xx < x * 8 + (longestLine * 8) - 3; xx++) - { - fb[xx * SCREEN_HEIGHT_SUB + (y * 8) + 2] = color; - fb[xx * SCREEN_HEIGHT_SUB + (y * 8) + (lines * 8) - 3] = color; - } - for(u32 yy = y * 8; yy < y * 8 + (lines * 8); yy++) - { - fb[x * 8 * SCREEN_HEIGHT_SUB + yy] = color; - fb[(x * 8 + (longestLine * 8) - 1) * SCREEN_HEIGHT_SUB + yy] = color; - } - for(u32 yy = y * 8 + 2; yy < y * 8 + (lines * 8) - 2; yy++) - { - fb[(x * 8 + 2) * SCREEN_HEIGHT_SUB + yy] = color; - fb[(x * 8 + (longestLine * 8) - 3) * SCREEN_HEIGHT_SUB + yy] = color; - } - - if(waitKeys) - { - do - { - hidScanInput(); - } while(!(keys = hidKeysDown() & waitKeys)); - } - - memcpy(fb, fbBackup, screen ? SCREEN_SIZE_TOP : SCREEN_SIZE_SUB); - } - free(fbBackup); // free() checks for NULL - - consoleSelect(prevCon); - - return keys; -} - -void uiPrintDevModeRequirement() -{ - // This should use uiShowMessageWindow some day... - uiPrintError("This feature is blocked!"); - uiPrintError("You must enable Developer Mode to use it."); - - do { - hidScanInput(); - u32 keys = hidKeysDown() & HID_KEY_MASK_ALL; - if(keys == KEY_A) - break; - } while(1); -} - -void uiPrintProgressBar(unsigned int x, unsigned int y, unsigned int w, - unsigned int h, unsigned int cur, unsigned int max) -{ - u16 *fb = consoleGet()->frameBuffer; - const u16 color = consoleGetFgColor(); - - - for(u32 xx = x + 1; xx < x + w - 1; xx++) - { - fb[xx * SCREEN_HEIGHT_TOP + y] = color; - fb[xx * SCREEN_HEIGHT_TOP + y + h - 1] = color; - } - - for(u32 yy = y; yy < y + h; yy++) - { - fb[x * SCREEN_HEIGHT_TOP + yy] = color; - fb[(x + w - 1) * SCREEN_HEIGHT_TOP + yy] = color; - } - - for(u32 xx = x + 2; xx < (u32)(((float)(x + w - 2) / max) * cur); xx++) - { - for(u32 yy = y + 2; yy < y + h - 2; yy++) - { - fb[xx * SCREEN_HEIGHT_TOP + yy] = color; - } - } -} - -void uiPrintBootWarning() -{ - drawSplashscreen(bootWarningData, -1, 10); - TIMER_sleep(400); -} - -void uiPrintBootFailure() -{ - drawSplashscreen(bootFailureData, -1, 10); - TIMER_sleep(400); -} - -bool uiCheckHomePressed(u32 msTimeout) -{ - u32 curMs; - bool successFlag; - - /* Check PXI Response register */ - u32 replyCode = PXI_tryRecvWord(&successFlag); - - curMs = 0; - - do { - - while(successFlag) - { - if(replyCode == PXI_RPL_HOME_PRESSED || - replyCode == PXI_RPL_HOME_HELD) - { - return true; - } - // maybe there's more..? - replyCode = PXI_tryRecvWord(&successFlag); - } - - TIMER_sleep(1); - curMs++; - - } while(curMs < msTimeout); - - /* timed out ... */ - - return false; -} diff --git a/source/arm9/hardware/pxi.c b/source/arm9/hardware/pxi.c index b20d501..1ceaf03 100644 --- a/source/arm9/hardware/pxi.c +++ b/source/arm9/hardware/pxi.c @@ -19,60 +19,95 @@ #include "types.h" #include "hardware/pxi.h" #include "arm9/hardware/interrupt.h" +#include "arm9/debug.h" +static void pxiIrqHandler(UNUSED u32 id); + void PXI_init(void) { REG_PXI_SYNC9 = PXI_IRQ_ENABLE; REG_PXI_CNT9 = PXI_FLUSH_SEND_FIFO | PXI_EMPTY_FULL_ERROR | PXI_ENABLE_SEND_RECV_FIFO; REG_PXI_SYNC9 |= 9u<<8; - while((REG_PXI_SYNC9 & 0xFFu) != 11u); + while(PXI_DATA_RECEIVED(REG_PXI_SYNC9) != 11u); - IRQ_registerHandler(IRQ_PXI_SYNC, NULL); + IRQ_registerHandler(IRQ_PXI_SYNC, pxiIrqHandler); } -void PXI_sendWord(u32 val) +static void pxiIrqHandler(UNUSED u32 id) { - while(REG_PXI_CNT9 & PXI_SEND_FIFO_FULL); - REG_PXI_SEND9 = val; - REG_PXI_SYNC9 |= PXI_NOTIFY_11; -} + u32 result = 0; + const u32 cmdCode = REG_PXI_RECV9; -bool PXI_trySendWord(u32 val) -{ - if(REG_PXI_CNT9 & PXI_SEND_FIFO_FULL) - return false; - REG_PXI_SEND9 = val; - REG_PXI_SYNC9 |= PXI_NOTIFY_11; - return true; -} - -u32 PXI_recvWord(void) -{ - while(REG_PXI_CNT9 & PXI_RECV_FIFO_EMPTY); - return REG_PXI_RECV9; -} - -u32 PXI_tryRecvWord(bool *success) -{ - if(REG_PXI_CNT9 & PXI_RECV_FIFO_EMPTY) + if((cmdCode>>16 & 0xFFu) != PXI_DATA_RECEIVED(REG_PXI_SYNC9)) { - *success = false; - return 0; + panic(); } - *success = true; - return REG_PXI_RECV9; + switch(cmdCode>>24) + { + case PXI_CMD9_FMOUNT: + break; + case PXI_CMD9_FUNMOUNT: + break; + case PXI_CMD9_FOPEN: + break; + case PXI_CMD9_FCLOSE: + break; + case PXI_CMD9_FREAD: + break; + case PXI_CMD9_FWRITE: + break; + case PXI_CMD9_FOPEN_DIR: + break; + case PXI_CMD9_FREAD_DIR: + break; + case PXI_CMD9_FCLOSE_DIR: + break; + case PXI_CMD9_FUNLINK: + break; + case PXI_CMD9_FGETFREE: + break; + case PXI_CMD9_READ_SECTORS: + break; + case PXI_CMD9_WRITE_SECTORS: + break; + case PXI_CMD9_MALLOC: + break; + case PXI_CMD9_FREE: + break; + case PXI_CMD9_LOAD_VERIFY_FIRM: + break; + case PXI_CMD9_FIRM_LAUNCH: + break; + case PXI_CMD9_PREPA_POWER: + break; + case PXI_CMD9_PANIC: + break; + case PXI_CMD9_EXCEPTION: + break; + default: + panic(); + } + + REG_PXI_SEND9 = result; } -void PXI_sendBuf(const u32 *const buf, u32 size) +u32 PXI_sendCmd(u32 cmd, const u32 *const buf, u8 words) { + if(!buf) words = 0; + while(REG_PXI_CNT9 & PXI_SEND_FIFO_FULL); - for(u32 i = 0; i < size / 4; i++) + REG_PXI_SEND9 = cmd | words<<16; + for(u32 i = 0; i < words; i++) { REG_PXI_SEND9 = buf[i]; } - REG_PXI_SYNC9 |= PXI_NOTIFY_11; + + REG_PXI_SYNC9 = PXI_DATA_SENT(REG_PXI_SYNC9, words) | PXI_NOTIFY_11; + + while(REG_PXI_CNT9 & PXI_RECV_FIFO_EMPTY); + return REG_PXI_RECV9; } diff --git a/source/arm9/main.c b/source/arm9/main.c index a2de425..0f39578 100644 --- a/source/arm9/main.c +++ b/source/arm9/main.c @@ -20,12 +20,12 @@ #include #include #include "types.h" -#include "arm9/fmt.h" #include "mem_map.h" #include "util.h" #include "hardware/pxi.h" #include "arm9/hardware/hid.h" #include "arm9/hardware/hardware.h" +#include "arm9/debug.h" #include "arm9/hardware/interrupt.h" #include "fatfs/ff.h" #include "arm9/dev.h" @@ -33,19 +33,10 @@ #include "arm9/firm.h" #include "arm9/config.h" #include "arm9/hardware/timer.h" -#include "arm9/gui/menu.h" -#include "arm9/main.h" #include "arm9/start.h" #include "hardware/cache.h" -static void initWifiFlash(void); -static u32 mount_fs(void); -static void screen_init(); -static void unit_detect(); -static void boot_env_detect(); -static void fw_detect(); -static bool loadSettings(int *mode); -static void checkSetVerboseMode(); + int main(void) { @@ -63,7 +54,7 @@ uiPrintIfVerbose("\x1B[32mGood morning\nHello !\e[0m\n\n");*/ - PXI_sendWord(PXI_CMD_ALLOW_POWER_OFF); + //PXI_sendWord(PXI_CMD_ALLOW_POWER_OFF); /*uiPrintIfVerbose("Detecting unit...\n"); @@ -142,185 +133,3 @@ return 0; } - -void devs_close() -{ - dev_sdcard->close(); - dev_decnand->close(); - dev_rawnand->close(); - dev_flash->close(); -} - -static void initWifiFlash(void) -{ - const char *const res_str[2] = {"\x1B[31m Failed!", "\x1B[32m OK!"}; - - uiPrintIfVerbose(" Initializing Wifi flash..."); - bool flashRes = dev_flash->init(); - uiPrintIfVerbose("%s\x1B[0m\n", res_str[flashRes]); - bootInfo.wififlash_status = flashRes; -} - -static u32 mount_fs(void) -{ - FRESULT tmp; - u32 res = 0; - const char *const res_str[2] = {"\x1B[31m Failed!", "\x1B[32m OK!"}; - - - uiPrintIfVerbose(" Mounting SD card FAT FS..."); - tmp = f_mount(&sd_fs, "sdmc:", 1); - bootInfo.sd_status = (tmp ? 0 : 2u); - uiPrintIfVerbose("%s %d\x1B[0m\n", res_str[tmp == FR_OK], tmp); - res |= (tmp ? 0 : 1u); - - - uiPrintIfVerbose(" Mounting twln FS..."); - tmp = f_mount(&nand_twlnfs, "twln:", 1); - uiPrintIfVerbose("%s %d\x1B[0m\n", res_str[tmp == FR_OK], tmp); - res |= (tmp ? 0 : 1u<<1); - - uiPrintIfVerbose(" Mounting twlp FS..."); - tmp = f_mount(&nand_twlpfs, "twlp:", 1); - uiPrintIfVerbose("%s %d\x1B[0m\n", res_str[tmp == FR_OK], tmp); - res |= (tmp ? 0 : 1u<<2); - - uiPrintIfVerbose(" Mounting CTR NAND FS..."); - tmp = f_mount(&nand_fs, "nand:", 1); - uiPrintIfVerbose("%s %d\x1B[0m\n", res_str[tmp == FR_OK], tmp); - res |= (tmp ? 0 : 1u<<3); - - bootInfo.nand_status = res>>1; - - - if(res != 0xFu && uiGetVerboseMode()) - { - screen_init(); - TIMER_sleep(2000); - } - - return res; -} - -static void screen_init() -{ - static bool screenInitDone; - if(!screenInitDone) - { - screenInitDone = true; - PXI_sendWord(PXI_CMD_ENABLE_LCDS); - while(PXI_recvWord() != PXI_RPL_OK); - } -} - -static void unit_detect() -{ - bootInfo.unitIsNew3DS = REG_PDN_MPCORE_CFG & 2; - - ee_sprintf(bootInfo.model, "%s 3DS", bootInfo.unitIsNew3DS ? "New" : "Original"); - - uiPrintIfVerbose("%s detected!\n", bootInfo.model); -} - -static void boot_env_detect() -{ - static const char *boot_environment [4] = { "Cold boot", // 0 - "Booted from Native FIRM", // 1 - "Booted from ", // 2, etc - "Booted from Legacy FIRM" // 3 - }; - - u32 boot_env = CFG_BOOTENV; - if(boot_env > 3) boot_env = 2; - - ee_sprintf(bootInfo.mode, "%s", CFG_UNITINFO != 0 ? "Dev" : "Retail"); - - strcpy(bootInfo.bootEnv, boot_environment[boot_env]); -} - -static void fw_detect() -{ - u8 *nand_sector = (u8*)malloc(0x200); - - if(!bootInfo.nand_status) - uiPrintIfVerbose("\x1B[31mFailed!\e[0m\n"); - else - { - dev_decnand->read_sector(0x0B130000 >> 9, 1, nand_sector); - // TODO: lookup... - strcpy(bootInfo.fw_ver1, "Unknown"); - strcpy(bootInfo.fw_ver2, "Unknown"); - } - - free(nand_sector); -} - -static bool loadSettings(int *mode) -{ - const char *res_str[2] = {"\x1B[31mFailed!", "\x1B[32mOK!"}; - - bool success = loadConfigFile(); - uiPrintIfVerbose("%s\e[0m\n", res_str[success]); - - if(success) - { - const int *mode_ptr = (const int *)configGetData(KBootMode); - if(mode_ptr != NULL) - *mode = *mode_ptr; - else *mode = BootModeNormal; - return true; - } - - *mode = BootModeNormal; - - return false; -} - -static void checkSetVerboseMode() -{ - u32 keys; - - hidScanInput(); - keys = hidKeysDown() & HID_KEY_MASK_ALL; - if(keys == HID_VERBOSE_MODE_BUTTONS) - uiSetVerboseMode(true); -} - -u8 rng_get_byte() -{ - u32 tmp = REG_PRNG[0]; - return (u8)tmp; -} - -noreturn void power_off_safe() -{ - uiClearConsoles(); - uiPrintIfVerbose("Attempting to turn off...\n"); - - fsUnmountAll(); - devs_close(); - - flushDCache(); - __asm__ __volatile__("msr cpsr_c, #0xDF" : :); // System mode, interrupts disabled - - // tell the arm11 we're done - PXI_sendWord(PXI_CMD_POWER_OFF); - - while(1) waitForInterrupt(); -} - -noreturn void reboot_safe() -{ - uiClearConsoles(); - uiPrintIfVerbose("Attempting to reboot...\n"); - - fsUnmountAll(); - devs_close(); - - flushDCache(); - __asm__ __volatile__("msr cpsr_c, #0xDF" : :); // System mode, interrupts disabled - - PXI_sendWord(PXI_CMD_REBOOT); - - while(1) waitForInterrupt(); -}