├── resources ├── gm9 │ └── support │ │ ├── seeddb.bin.here │ │ ├── aeskeydb.bin.here │ │ └── encTitleKeys.bin.here ├── logo.png ├── wiki.png ├── GodMode64_splash.png ├── GodMode9_splash.png ├── SafeMode9_splash.png ├── fonts │ ├── font_6x10.pbm │ ├── font_c64_8x8.pbm │ ├── font_gb_7x6.pbm │ ├── font_acorn_8x8.pbm │ ├── font_tiny_4x6.pbm │ ├── font_zuish_8x8.pbm │ ├── font_nbraille_4x6.pbm │ ├── font_original_8x8.pbm │ └── font_sheikah_8x8.pbm ├── ZuishMode9_splash.png ├── BrickedMode9_splash.png ├── DGS1-Patcher_splash.png └── GodMode9_splash_anniversary.png ├── arm9 ├── source │ ├── common │ │ ├── screenshot.h │ │ ├── touchcal.h │ │ ├── sighax.h │ │ ├── power.h │ │ ├── utf.h │ │ ├── rtc.h │ │ ├── timer.h │ │ ├── unittype.h │ │ ├── asmfunc.h │ │ ├── mmio.h │ │ ├── power.c │ │ ├── hid.h │ │ ├── rtc.c │ │ ├── timer.c │ │ ├── memcpy.s │ │ ├── screenshot.c │ │ ├── mmio.s │ │ ├── swkbd.h │ │ └── colors.h │ ├── utils │ │ ├── sysinfo.h │ │ ├── paint9.h │ │ ├── ctrtransfer.h │ │ ├── utils.h │ │ ├── keydbutil.h │ │ ├── scripting.h │ │ ├── nandutil.h │ │ ├── nandcmac.h │ │ └── gameutil.h │ ├── nand │ │ ├── wait.h │ │ ├── wait.s │ │ └── essentials.h │ ├── crypto │ │ ├── crc16.h │ │ ├── crc32.h │ │ ├── crc16.c │ │ ├── sha.h │ │ ├── keydb.h │ │ ├── sha.c │ │ └── rsa.h │ ├── system │ │ ├── bootfirm.h │ │ ├── mymalloc.h │ │ ├── png.h │ │ ├── tar.h │ │ ├── spiflash.c │ │ ├── spiflash.h │ │ ├── vram0.h │ │ ├── mymalloc.c │ │ ├── i2c.c │ │ ├── png.c │ │ ├── memmap.h │ │ ├── xrq_handler.s │ │ ├── tar.c │ │ └── i2c.h │ ├── filesys │ │ ├── fsgame.h │ │ ├── fs.h │ │ ├── image.h │ │ ├── support.h │ │ ├── fsdir.h │ │ ├── fsinit.h │ │ ├── fsdir.c │ │ ├── sddata.h │ │ ├── fatmbr.c │ │ ├── fsperm.h │ │ ├── vff.h │ │ ├── fsgame.c │ │ ├── image.c │ │ ├── fsdrive.h │ │ └── fsutil.h │ ├── godmode.h │ ├── fatfs │ │ ├── ramdrive.h │ │ ├── 00readme.txt │ │ ├── ramdrive.c │ │ ├── LICENSE.txt │ │ └── diskio.h │ ├── gamecart │ │ ├── delay.h │ │ ├── card_ntr.h │ │ ├── command_ctr.h │ │ ├── command_ntr.h │ │ ├── iodelay.s │ │ ├── protocol.h │ │ ├── secure_ntr.h │ │ ├── command_ak2i.h │ │ ├── gamecart.h │ │ ├── command_ctr.c │ │ ├── protocol_ctr.h │ │ ├── command_ntr.c │ │ └── card_spi.h │ ├── game │ │ ├── cmd.c │ │ ├── ips.h │ │ ├── codelzss.h │ │ ├── game.h │ │ ├── exefs.h │ │ ├── bps.h │ │ ├── region.c │ │ ├── cert.c │ │ ├── cert.h │ │ ├── 3dsx.h │ │ ├── cmd.h │ │ ├── ncchinfo.h │ │ ├── tad.c │ │ ├── region.h │ │ ├── exefs.c │ │ ├── ncsd.h │ │ ├── ticket.h │ │ ├── smdh.h │ │ ├── boss.h │ │ ├── tad.h │ │ ├── ticketdb.h │ │ ├── cia.h │ │ ├── ncchinfo.c │ │ ├── tmd.h │ │ ├── smdh.c │ │ ├── firm.h │ │ ├── ncsd.c │ │ └── boss.c │ ├── virtual │ │ ├── vmem.h │ │ ├── vnand.h │ │ ├── vcart.h │ │ ├── vvram.h │ │ ├── vkeydb.h │ │ ├── vtickdb.h │ │ ├── vdisadiff.h │ │ ├── vgame.h │ │ ├── virtual.h │ │ └── vkeydb.c │ └── main.c ├── Makefile └── link.ld ├── data ├── easter.bin └── font_default.pbm ├── utils └── patch.json.gz ├── common ├── entrypoints.h ├── vram.h ├── brf.h ├── types.h ├── spi.h ├── shmem.h ├── hid_map.h ├── pxi.c ├── fixp.h ├── common.h └── pxi.h ├── arm11 ├── Makefile ├── source │ ├── arm │ │ ├── scu.h │ │ ├── scu.c │ │ ├── timer.h │ │ ├── gic.h │ │ ├── mmu.h │ │ └── timer.c │ ├── hw │ │ ├── hid.h │ │ ├── codec.h │ │ ├── gpio.h │ │ ├── nvram.h │ │ ├── gpulcd.h │ │ ├── mcu.h │ │ ├── hid.c │ │ ├── i2c.h │ │ └── nvram.c │ └── system │ │ ├── xalloc.h │ │ ├── sections.h │ │ ├── xalloc.c │ │ └── sys.h └── link.ld ├── README.md ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── .travis.yml ├── .gitignore ├── Makefile.build └── Makefile.common /resources/gm9/support/seeddb.bin.here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/gm9/support/aeskeydb.bin.here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/gm9/support/encTitleKeys.bin.here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /arm9/source/common/screenshot.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void CreateScreenshot(void); 4 | -------------------------------------------------------------------------------- /arm9/source/utils/sysinfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void MyriaSysinfo(char* sysinfo_txt); 4 | -------------------------------------------------------------------------------- /data/easter.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/data/easter.bin -------------------------------------------------------------------------------- /arm9/source/nand/wait.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | void wait(u32 cycles); 6 | -------------------------------------------------------------------------------- /arm9/source/utils/paint9.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | u32 Paint9(void); 6 | -------------------------------------------------------------------------------- /resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/logo.png -------------------------------------------------------------------------------- /resources/wiki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/wiki.png -------------------------------------------------------------------------------- /utils/patch.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/utils/patch.json.gz -------------------------------------------------------------------------------- /data/font_default.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/data/font_default.pbm -------------------------------------------------------------------------------- /resources/GodMode64_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/GodMode64_splash.png -------------------------------------------------------------------------------- /resources/GodMode9_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/GodMode9_splash.png -------------------------------------------------------------------------------- /resources/SafeMode9_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/SafeMode9_splash.png -------------------------------------------------------------------------------- /resources/fonts/font_6x10.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/fonts/font_6x10.pbm -------------------------------------------------------------------------------- /arm9/source/crypto/crc16.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | u16 crc16_quick(const void* src, u32 len); 6 | -------------------------------------------------------------------------------- /resources/ZuishMode9_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/ZuishMode9_splash.png -------------------------------------------------------------------------------- /resources/fonts/font_c64_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/fonts/font_c64_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/font_gb_7x6.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/fonts/font_gb_7x6.pbm -------------------------------------------------------------------------------- /resources/BrickedMode9_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/BrickedMode9_splash.png -------------------------------------------------------------------------------- /resources/DGS1-Patcher_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/DGS1-Patcher_splash.png -------------------------------------------------------------------------------- /resources/fonts/font_acorn_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/fonts/font_acorn_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/font_tiny_4x6.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/fonts/font_tiny_4x6.pbm -------------------------------------------------------------------------------- /resources/fonts/font_zuish_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/fonts/font_zuish_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/font_nbraille_4x6.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/fonts/font_nbraille_4x6.pbm -------------------------------------------------------------------------------- /resources/fonts/font_original_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/fonts/font_original_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/font_sheikah_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/fonts/font_sheikah_8x8.pbm -------------------------------------------------------------------------------- /arm9/source/system/bootfirm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | void __attribute__((noreturn)) BootFirm(void *firm, char *path); 5 | -------------------------------------------------------------------------------- /resources/GodMode9_splash_anniversary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScarletStudy/DGS1-Patcher/master/resources/GodMode9_splash_anniversary.png -------------------------------------------------------------------------------- /arm9/source/nand/wait.s: -------------------------------------------------------------------------------- 1 | .text 2 | .arm 3 | .align 4 4 | 5 | .global wait 6 | .type wait, %function 7 | wait: 8 | subs r0, r0, #4 9 | bcs wait 10 | bx lr 11 | -------------------------------------------------------------------------------- /arm9/source/utils/ctrtransfer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | u32 CheckTransferableMbr(void* data); 6 | u32 TransferCtrNandImage(const char* path_img, const char* drv); 7 | -------------------------------------------------------------------------------- /arm9/source/filesys/fsgame.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "fsdir.h" 5 | 6 | void SetDirGoodNames(DirStruct* contents); 7 | bool GoodRenamer(DirEntry* entry, bool ask); 8 | -------------------------------------------------------------------------------- /common/entrypoints.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define ENTRY_UNKNOWN (0) 4 | #define ENTRY_B9S (1) 5 | #define ENTRY_NTRBOOT (2) 6 | #define ENTRY_NANDBOOT (3) 7 | #define ENTRY_SPIBOOT (4) 8 | -------------------------------------------------------------------------------- /arm9/source/godmode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define GODMODE_EXIT_REBOOT 0 6 | #define GODMODE_EXIT_POWEROFF 1 7 | 8 | u32 GodMode(int entrypoint); 9 | u32 ScriptRunner(int entrypoint); 10 | -------------------------------------------------------------------------------- /arm9/source/common/touchcal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | bool ShowTouchCalibrationDialog(void); 6 | bool CalibrateTouchFromSupportFile(void); 7 | bool CalibrateTouchFromFlash(void); 8 | bool TouchIsCalibrated(void); 9 | -------------------------------------------------------------------------------- /arm9/source/utils/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ctrtransfer.h" 4 | #include "gameutil.h" 5 | #include "keydbutil.h" 6 | #include "nandcmac.h" 7 | #include "nandutil.h" 8 | #include "scripting.h" 9 | #include "sysinfo.h" 10 | -------------------------------------------------------------------------------- /arm9/source/system/mymalloc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | void* my_malloc(size_t size); 6 | void *my_realloc(void *ptr, size_t new_size); 7 | void my_free(void* ptr); 8 | size_t mem_allocated(void); 9 | size_t my_malloc_test(void); 10 | -------------------------------------------------------------------------------- /arm9/source/filesys/fs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "filetype.h" 4 | #include "fsdir.h" 5 | #include "fsdrive.h" 6 | #include "fsgame.h" 7 | #include "fsinit.h" 8 | #include "fsperm.h" 9 | #include "fsutil.h" 10 | #include "image.h" 11 | #include "vff.h" 12 | -------------------------------------------------------------------------------- /arm9/source/fatfs/ramdrive.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | int ReadRamDriveSectors(void* buffer, u32 sector, u32 count); 6 | int WriteRamDriveSectors(const void* buffer, u32 sector, u32 count); 7 | u64 GetRamDriveSize(void); 8 | void InitRamDrive(void); 9 | -------------------------------------------------------------------------------- /arm9/source/gamecart/delay.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Normmatt 2 | // Licensed under GPLv2 or any later version 3 | // Refer to the license.txt file included. 4 | 5 | #pragma once 6 | 7 | #include "common.h" 8 | 9 | void ioDelay(u32 us); 10 | void ioDelay2(u32 us); 11 | -------------------------------------------------------------------------------- /arm9/source/common/sighax.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | const u8 sig_nand_firm_retail[256]; 6 | const u8 sig_nand_firm_retail_alt[256]; 7 | const u8 sig_nand_firm_dev[256]; 8 | const u8 sig_nand_ncsd_retail[256]; 9 | const u8 sig_nand_ncsd_dev[256]; 10 | -------------------------------------------------------------------------------- /arm9/source/utils/keydbutil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "keydb.h" 5 | 6 | u32 CryptAesKeyDb(const char* path, bool inplace, bool encrypt); 7 | u32 AddKeyToDb(AesKeyInfo* key_info, AesKeyInfo* key_entry); 8 | u32 BuildKeyDb(const char* path, bool dump); 9 | -------------------------------------------------------------------------------- /arm9/source/game/cmd.c: -------------------------------------------------------------------------------- 1 | #include "cmd.h" 2 | 3 | 4 | u32 CheckCmdSize(CmdHeader* cmd, u64 fsize) { 5 | u64 cmdsize = sizeof(CmdHeader) + 6 | (cmd->n_entries * sizeof(u32)) + 7 | (cmd->n_cmacs * sizeof(u32)) + 8 | (cmd->n_entries * 0x10); 9 | 10 | return (fsize == cmdsize) ? 0 : 1; 11 | } 12 | -------------------------------------------------------------------------------- /arm9/source/game/ips.h: -------------------------------------------------------------------------------- 1 | // C port of Alcaro's libips.cpp, which was released under GPLv3 2 | // https://github.com/Alcaro/Flips/blob/master/libips.cpp 3 | // Ported by Hyarion for use with VirtualFatFS 4 | 5 | #pragma once 6 | 7 | int ApplyIPSPatch(const char* patchName, const char* sourceName, const char* targetName); 8 | -------------------------------------------------------------------------------- /arm9/source/common/power.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define BRIGHTNESS_AUTOMATIC (-1) 6 | #define BRIGHTNESS_MIN (10) 7 | #define BRIGHTNESS_MAX (210) 8 | 9 | u32 SetScreenBrightness(int level); 10 | u32 GetBatteryPercent(); 11 | bool IsCharging(); 12 | void Reboot(); 13 | void PowerOff(); 14 | -------------------------------------------------------------------------------- /arm9/source/virtual/vmem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "virtual.h" 5 | 6 | bool ReadVMemDir(VirtualFile* vfile, VirtualDir* vdir); 7 | int ReadVMemFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count); 8 | int WriteVMemFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); 9 | -------------------------------------------------------------------------------- /arm9/source/system/png.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "common.h" 5 | #include "lodepng/lodepng.h" 6 | 7 | #define PNG_MAGIC 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A 8 | 9 | u16 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h); 10 | u8 *PNG_Compress(const u16 *fb, u32 w, u32 h, size_t *png_sz); 11 | -------------------------------------------------------------------------------- /arm9/source/common/utf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | // most of the code here shamelessly stolen from: 6 | // https://github.com/smealum/ctrulib/tree/bd34fd59dbf0691e2dba76be65f260303d8ccec7/libctru/source/util/utf 7 | int utf16_to_utf8(u8 *out, const u16 *in, int len_out, int len_in); 8 | int utf8_to_utf16(u16 *out, const u8 *in, int len_out, int len_in); 9 | -------------------------------------------------------------------------------- /arm9/source/game/codelzss.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define EXEFS_CODE_NAME ".code" 6 | 7 | u32 GetCodeLzssUncompressedSize(void* footer, u32 comp_size); 8 | u32 DecompressCodeLzss(u8* code, u32* code_size, u32 max_size); 9 | bool CompressCodeLzss(const u8* a_pUncompressed, u32 a_uUncompressedSize, u8* a_pCompressed, u32* a_uCompressedSize); 10 | -------------------------------------------------------------------------------- /arm9/source/virtual/vnand.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "virtual.h" 5 | 6 | bool CheckVNandDrive(u32 nand_src); 7 | bool ReadVNandDir(VirtualFile* vfile, VirtualDir* vdir); 8 | int ReadVNandFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count); 9 | int WriteVNandFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); 10 | u64 GetVNandDriveSize(u32 nand_src); 11 | -------------------------------------------------------------------------------- /arm9/source/game/game.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cia.h" 4 | #include "ncsd.h" 5 | #include "ncch.h" 6 | #include "exefs.h" 7 | #include "romfs.h" 8 | #include "firm.h" 9 | #include "boss.h" 10 | #include "smdh.h" 11 | #include "codelzss.h" 12 | #include "nds.h" 13 | #include "gba.h" 14 | #include "tad.h" 15 | #include "3dsx.h" 16 | #include "tmd.h" 17 | #include "cmd.h" 18 | #include "ticketdb.h" 19 | #include "ncchinfo.h" 20 | -------------------------------------------------------------------------------- /arm9/source/virtual/vcart.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "virtual.h" 5 | 6 | u32 InitVCartDrive(void); 7 | bool ReadVCartDir(VirtualFile* vfile, VirtualDir* vdir); 8 | int ReadVCartFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count); 9 | int WriteVCartFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); 10 | u64 GetVCartDriveSize(void); 11 | void GetVCartTypeString(char* typestr); 12 | -------------------------------------------------------------------------------- /arm9/source/virtual/vvram.h: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "virtual.h" 3 | 4 | bool CheckVVramDrive(void); 5 | 6 | bool ReadVVramDir(VirtualFile* vfile, VirtualDir* vdir); 7 | int ReadVVramFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count); 8 | 9 | bool GetVVramFilename(char* name, const VirtualFile* vfile); 10 | bool MatchVVramFilename(const char* name, const VirtualFile* vfile); 11 | 12 | u64 GetVVramDriveSize(void); 13 | -------------------------------------------------------------------------------- /arm9/source/crypto/crc32.h: -------------------------------------------------------------------------------- 1 | // C port of byuu's \nall\crc32.hpp, which was released under GPLv3 2 | // https://github.com/eai04191/beat/blob/master/nall/crc32.hpp 3 | // Ported by Hyarion for use with VirtualFatFS 4 | 5 | #pragma once 6 | 7 | #include "common.h" 8 | 9 | u32 crc32_adjust(u32 crc32, u8 input); 10 | u32 crc32_calculate(u32 crc32, const u8* data, u32 length); 11 | u32 crc32_calculate_from_file(const char* fileName, u32 offset, u32 length); 12 | -------------------------------------------------------------------------------- /arm9/source/utils/scripting.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define SCRIPT_EXT "gm9" 6 | #define SCRIPT_MAX_SIZE STD_BUFFER_SIZE 7 | 8 | bool ValidateText(const char* text, u32 size); 9 | bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script); 10 | bool MemToCViewer(const char* text, u32 len, const char* title); 11 | bool FileTextViewer(const char* path, bool as_script); 12 | bool ExecuteGM9Script(const char* path_script); 13 | -------------------------------------------------------------------------------- /arm9/source/game/exefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | typedef struct { 6 | char name[8]; 7 | u32 offset; 8 | u32 size; 9 | } PACKED_STRUCT ExeFsFileHeader; 10 | 11 | // see: https://www.3dbrew.org/wiki/ExeFS 12 | typedef struct { 13 | ExeFsFileHeader files[10]; 14 | u8 reserved[0x20]; 15 | u8 hashes[10][0x20]; 16 | } __attribute__((packed, aligned(16))) ExeFsHeader; 17 | 18 | u32 ValidateExeFsHeader(ExeFsHeader* exefs, u32 size); 19 | -------------------------------------------------------------------------------- /common/vram.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define TOP_VRAM (400*240*4) 4 | #define BOTTOM_VRAM (320*240*4) 5 | 6 | #define VRAM_START (0x18300000) 7 | #define VRAM_TOP_LA (VRAM_START) 8 | #define VRAM_TOP_LB (VRAM_TOP_LA + TOP_VRAM) 9 | #define VRAM_TOP_RA (VRAM_TOP_LB + TOP_VRAM) 10 | #define VRAM_TOP_RB (VRAM_TOP_RA + TOP_VRAM) 11 | #define VRAM_BOT_A (VRAM_TOP_RB + TOP_VRAM) 12 | #define VRAM_BOT_B (VRAM_BOT_A + BOTTOM_VRAM) 13 | #define VRAM_END (VRAM_BOT_B + BOTTOM_VRAM) 14 | -------------------------------------------------------------------------------- /arm9/source/virtual/vkeydb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "virtual.h" 5 | 6 | void DeinitVKeyDbDrive(void); 7 | u64 InitVKeyDbDrive(void); 8 | u64 CheckVKeyDbDrive(void); 9 | 10 | bool ReadVKeyDbDir(VirtualFile* vfile, VirtualDir* vdir); 11 | int ReadVKeyDbFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count); 12 | // int WriteVKeyDbFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); // no writing 13 | u64 GetVKeyDbDriveSize(void); 14 | -------------------------------------------------------------------------------- /arm9/source/virtual/vtickdb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "virtual.h" 5 | 6 | void DeinitVTickDbDrive(void); 7 | u64 InitVTickDbDrive(void); 8 | u64 CheckVTickDbDrive(void); 9 | 10 | bool ReadVTickDbDir(VirtualFile* vfile, VirtualDir* vdir); 11 | int ReadVTickDbFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count); 12 | // int WriteVTickDbFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); // no writing 13 | u64 GetVTickDbDriveSize(void); 14 | -------------------------------------------------------------------------------- /arm9/source/game/bps.h: -------------------------------------------------------------------------------- 1 | // C port of byuu's \nall\beat\patch.hpp and \multi.hpp, which were released under GPLv3 2 | // https://github.com/eai04191/beat/blob/master/nall/beat/patch.hpp 3 | // https://github.com/eai04191/beat/blob/master/nall/beat/multi.hpp 4 | // Ported by Hyarion for use with VirtualFatFS 5 | 6 | #pragma once 7 | 8 | int ApplyBPSPatch(const char* modifyName, const char* sourceName, const char* targetName); 9 | int ApplyBPMPatch(const char* patchName, const char* sourcePath, const char* targetPath); 10 | -------------------------------------------------------------------------------- /arm9/source/gamecart/card_ntr.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | void cardWriteCommand(const u8 *command); 5 | void cardPolledTransfer(u32 flags, u32 *destination, u32 length, const u8 *command); 6 | void cardStartTransfer(const u8 *command, u32 *destination, int channel, u32 flags); 7 | u32 cardWriteAndRead(const u8 *command, u32 flags); 8 | void cardParamCommand (u8 command, u32 parameter, u32 flags, u32 *destination, u32 length); 9 | void cardReadHeader(u8 *header); 10 | u32 cardReadID(u32 flags); 11 | void cardReset(); 12 | -------------------------------------------------------------------------------- /arm9/source/filesys/image.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "filetype.h" 5 | 6 | int ReadImageBytes(void* buffer, u64 offset, u64 count); 7 | int WriteImageBytes(const void* buffer, u64 offset, u64 count); 8 | int ReadImageSectors(void* buffer, u32 sector, u32 count); 9 | int WriteImageSectors(const void* buffer, u32 sector, u32 count); 10 | int SyncImage(void); 11 | 12 | u64 GetMountSize(void); 13 | u64 GetMountState(void); 14 | const char* GetMountPath(void); 15 | u64 MountImage(const char* path); 16 | -------------------------------------------------------------------------------- /arm9/source/gamecart/command_ctr.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Normmatt 2 | // Licensed under GPLv2 or any later version 3 | // Refer to the license.txt file included. 4 | 5 | #pragma once 6 | 7 | #include "common.h" 8 | 9 | void CTR_CmdReadSectorSD(u8* aBuffer, u32 aSector); 10 | void CTR_CmdReadData(u32 sector, u32 length, u32 blocks, void* buffer); 11 | void CTR_CmdReadHeader(void* buffer); 12 | void CTR_CmdReadUniqueID(void* buffer); 13 | u32 CTR_CmdGetSecureId(u32 rand1, u32 rand2); 14 | void CTR_CmdSeed(u32 rand1, u32 rand2); 15 | -------------------------------------------------------------------------------- /arm11/Makefile: -------------------------------------------------------------------------------- 1 | PROCESSOR := ARM11 2 | 3 | TARGET := $(shell basename $(CURDIR)) 4 | 5 | SOURCE := source 6 | BUILD := build 7 | 8 | SUBARCH := -D$(PROCESSOR) -marm -march=armv6k -mtune=mpcore -mfloat-abi=hard -mfpu=vfpv2 -mtp=soft 9 | INCDIRS := source 10 | INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)") 11 | 12 | ASFLAGS += $(SUBARCH) $(INCLUDE) 13 | CFLAGS += $(SUBARCH) $(INCLUDE) -flto 14 | LDFLAGS += $(SUBARCH) -Wl,-Map,$(TARGET).map -flto 15 | 16 | include ../Makefile.common 17 | include ../Makefile.build 18 | -------------------------------------------------------------------------------- /arm9/source/utils/nandutil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | u32 CheckEmbeddedBackup(const char* path); 6 | u32 EmbedEssentialBackup(const char* path); 7 | u32 FixNandHeader(const char* path, bool check_size); 8 | u32 ValidateNandDump(const char* path); 9 | u32 SafeRestoreNandDump(const char* path); 10 | u32 SafeInstallFirm(const char* path, u32 slots); 11 | u32 SafeInstallKeyDb(const char* path); 12 | u32 DumpGbaVcSavegame(const char* path); 13 | u32 InjectGbaVcSavegame(const char* path, const char* path_vcsave); 14 | -------------------------------------------------------------------------------- /arm9/source/virtual/vdisadiff.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "virtual.h" 4 | 5 | void DeinitVDisaDiffDrive(void); // This is when the ivfc hash fixing actually happens - **MUST** be called before just powering off 6 | u64 InitVDisaDiffDrive(void); 7 | u64 CheckVDisaDiffDrive(void); 8 | 9 | bool ReadVDisaDiffDir(VirtualFile* vfile, VirtualDir* vdir); 10 | int ReadVDisaDiffFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count); 11 | int WriteVDisaDiffFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); -------------------------------------------------------------------------------- /arm9/source/gamecart/command_ntr.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Normmatt 2 | // Licensed under GPLv2 or any later version 3 | // Refer to the license.txt file included. 4 | // 5 | // modifyed by osilloscopion (2 Jul 2016) 6 | // 7 | 8 | #pragma once 9 | 10 | #include "common.h" 11 | 12 | void NTR_CmdReset(void); 13 | u32 NTR_CmdGetCartId(void); 14 | void NTR_CmdEnter16ByteMode(void); 15 | void NTR_CmdReadHeader (u8* buffer); 16 | void NTR_CmdReadData (u32 offset, void* buffer); 17 | 18 | bool NTR_Secure_Init (u8* buffer, u32 CartID, int iCardDevice); 19 | 20 | -------------------------------------------------------------------------------- /arm9/source/game/region.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "region.h" 3 | 4 | // Names of system regions, short form. 5 | const char* const g_regionNamesShort[SMDH_NUM_REGIONS] = { 6 | "JPN", 7 | "USA", 8 | "EUR", 9 | "AUS", // mostly unused 10 | "CHN", 11 | "KOR", 12 | "TWN", 13 | }; 14 | 15 | // Names of system regions, long form. 16 | const char* const g_regionNamesLong[SMDH_NUM_REGIONS] = { 17 | "Japan", 18 | "Americas", 19 | "Europe", 20 | "Australia", 21 | "China", 22 | "Korea", 23 | "Taiwan", 24 | }; 25 | -------------------------------------------------------------------------------- /arm9/source/gamecart/iodelay.s: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Normmatt 2 | // Licensed under GPLv2 or any later version 3 | // Refer to the license.txt file included. 4 | 5 | .arm 6 | .global ioDelay 7 | .type ioDelay STT_FUNC 8 | 9 | @ioDelay ( u32 us ) 10 | ioDelay: 11 | ldr r1, =0x18000000 @ VRAM 12 | 1: 13 | @ Loop doing uncached reads from VRAM to make loop timing more reliable 14 | ldr r2, [r1] 15 | subs r0, #1 16 | bgt 1b 17 | bx lr 18 | 19 | .global ioDelay2 20 | .type ioDelay2 STT_FUNC 21 | 22 | @ioDelay2 ( u32 us ) 23 | ioDelay2: 24 | 1: 25 | subs r0, #1 26 | bgt 1b 27 | bx lr 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DGS1-Patcher 2 | 3 | Source code for our patcher. The releases themselves are located at https://github.com/ScarletStudy/DGS1-3DS-Release/releases 4 | This is a standalone build of GodMode9 which boots straight to \data\autorun.gm9. Little of the GM9 code is changed, as changes are pushed upstream when possible. 5 | 6 | Build `DGS1-Patcher.firm` via `make FLAVOR=DGS1-Patcher SCRIPT_RUNNER=1 FIXED_BRIGHTNESS=15`. 7 | This requires [firmtool](https://github.com/TuxSH/firmtool), [Python 3.5+](https://www.python.org/downloads/) and [devkitARM](https://sourceforge.net/projects/devkitpro/) installed. 8 | -------------------------------------------------------------------------------- /arm9/source/filesys/support.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | // scripts / payloads dir names 6 | #define SCRIPTS_DIR "scripts" 7 | #define PAYLOADS_DIR "payloads" 8 | 9 | bool CheckSupportFile(const char* fname); 10 | size_t LoadSupportFile(const char* fname, void* buffer, size_t max_len); 11 | bool SaveSupportFile(const char* fname, void* buffer, size_t len); 12 | bool SetAsSupportFile(const char* fname, const char* source); 13 | 14 | bool CheckSupportDir(const char* fpath); 15 | bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern); 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this GodMode9 4 | title: "[FEATURE REQUEST] ..." 5 | labels: feature request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Got a great idea on how to improve GodMode9?** 11 | That's always appreciated. Please make sure you add all the required info here. 12 | 13 | **Describe the feature you'd like** 14 | Add a clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | Add a clear and concise description of any alternative solutions or features you've considered. 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | sudo: true 3 | dist: bionic 4 | 5 | before_install: 6 | - wget "https://github.com/devkitPro/pacman/releases/latest/download/devkitpro-pacman.deb" -O dkp-pacman.deb 7 | - export DEVKITPRO=/opt/devkitpro 8 | - export DEVKITARM=${DEVKITPRO}/devkitARM 9 | 10 | install: 11 | - sudo dpkg -i dkp-pacman.deb 12 | - sudo dkp-pacman -S --noconfirm devkitARM 13 | - sudo apt-get -y install python3 python3-pip p7zip-full 14 | - sudo pip3 install --upgrade pip setuptools 15 | - sudo pip3 install cryptography 16 | - sudo pip3 install git+https://github.com/TuxSH/firmtool.git 17 | 18 | script: 19 | - make release 20 | -------------------------------------------------------------------------------- /arm9/source/game/cert.c: -------------------------------------------------------------------------------- 1 | #include "cert.h" 2 | #include "ff.h" 3 | 4 | u32 LoadCertFromCertDb(u64 offset, Certificate* cert, u32* mod, u32* exp) { 5 | Certificate cert_local; 6 | FIL db; 7 | UINT bytes_read; 8 | 9 | // not much in terms of error checking here 10 | if (f_open(&db, "1:/dbs/certs.db", FA_READ | FA_OPEN_EXISTING) != FR_OK) 11 | return 1; 12 | f_lseek(&db, offset); 13 | if (!cert) cert = &cert_local; 14 | f_read(&db, cert, CERT_SIZE, &bytes_read); 15 | f_close(&db); 16 | 17 | if (mod) memcpy(mod, cert->mod, 0x100); 18 | if (exp) *exp = getle32(cert->exp); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /arm9/source/gamecart/protocol.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Normmatt 2 | // Licensed under GPLv2 or any later version 3 | // Refer to the license.txt file included. 4 | 5 | #pragma once 6 | #include "common.h" 7 | 8 | #define REG_CARDCTL (*(vu16*)0x1000000C) 9 | #define REG_CARDSTATUS (*(vu8* )0x10000010) 10 | #define REG_CARDCYCLES0 (*(vu16*)0x10000012) 11 | #define REG_CARDCYCLES1 (*(vu16*)0x10000014) 12 | 13 | 14 | #define LATENCY 0x822Cu 15 | #define BSWAP32(n) __builtin_bswap32(n) 16 | 17 | 18 | void Cart_Init(void); 19 | int Cart_IsInserted(void); 20 | u32 Cart_GetID(void); 21 | void Cart_Secure_Init(u32* buf, u32* out); 22 | void Cart_Dummy(void); 23 | -------------------------------------------------------------------------------- /arm9/source/filesys/fsdir.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define MAX_DIR_ENTRIES 2048 6 | 7 | typedef enum { 8 | T_ROOT, 9 | T_DIR, 10 | T_FILE, 11 | T_DOTDOT 12 | } EntryType; 13 | 14 | typedef struct { 15 | char* name; // should point to the correct portion of the path 16 | char path[256]; 17 | u64 size; 18 | EntryType type; 19 | u8 marked; 20 | u8 p_name; 21 | } DirEntry; 22 | 23 | typedef struct { 24 | u32 n_entries; 25 | DirEntry entry[MAX_DIR_ENTRIES]; 26 | } DirStruct; 27 | 28 | void DirEntryCpy(DirEntry* dest, const DirEntry* orig); 29 | void SortDirStruct(DirStruct* contents); 30 | -------------------------------------------------------------------------------- /arm9/source/game/cert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define CERT_SIZE sizeof(Certificate) 6 | 7 | // from: http://3dbrew.org/wiki/Certificates 8 | // all numbers in big endian 9 | typedef struct { 10 | u8 sig_type[4]; // expected: 0x010004 / RSA_2048 SHA256 11 | u8 signature[0x100]; 12 | u8 padding0[0x3C]; 13 | u8 issuer[0x40]; 14 | u8 keytype[4]; // expected: 0x01 / RSA_2048 15 | u8 name[0x40]; 16 | u8 unknown[4]; 17 | u8 mod[0x100]; 18 | u8 exp[0x04]; 19 | u8 padding1[0x34]; 20 | } PACKED_STRUCT Certificate; 21 | 22 | u32 LoadCertFromCertDb(u64 offset, Certificate* cert, u32* mod, u32* exp); 23 | -------------------------------------------------------------------------------- /arm9/source/gamecart/secure_ntr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | 6 | typedef struct _IKEY1{ 7 | u32 iii; 8 | u32 jjj; 9 | u32 kkkkk; 10 | u32 llll; 11 | u32 mmm; 12 | u32 nnn; 13 | } IKEY1, *PIKEY1; 14 | 15 | void NTR_InitKey (u32 aGameCode, u32* pCardHash, int nCardHash, u32* pKeyCode, int level, int iCardDevice); 16 | void NTR_InitKey1 (u8* aCmdData, IKEY1* pKey1, int iCardDevice); 17 | 18 | void NTR_CreateEncryptedCommand (u8 aCommand, u32* pCardHash, u8* aCmdData, IKEY1* pKey1, u32 aBlock); 19 | void NTR_DecryptSecureArea (u32 aGameCode, u32* pCardHash, int nCardHash, u32* pKeyCode, u32* pSecureArea, int iCardDevice); 20 | -------------------------------------------------------------------------------- /common/brf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef ARM9 4 | 5 | /* None of these functions require a working stack */ 6 | /* Assume R0-R3, R12 are always clobbered */ 7 | #define BRF_INVALIDATE_DCACHE (0xFFFF07F0) 8 | #define BRF_INVALIDATE_DCACHE_RANGE (0xFFFF0868) 9 | #define BRF_WRITEBACK_DCACHE (0xFFFF07FC) 10 | #define BRF_WRITEBACK_DCACHE_RANGE (0xFFFF0884) 11 | #define BRF_WB_INV_DCACHE (0xFFFF0830) 12 | #define BRF_WB_INV_DCACHE_RANGE (0xFFFF08A8) 13 | #define BRF_INVALIDATE_ICACHE (0xFFFF0AB4) 14 | #define BRF_INVALIDATE_ICACHE_RANGE (0xFFFF0AC0) 15 | #define BRF_RESETCP15 (0xFFFF0C58) 16 | 17 | #else 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /arm9/source/game/3dsx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define THREEDSX_MAGIC '3', 'D', 'S', 'X' 6 | #define THREEDSX_EXT_MAGIC THREEDSX_MAGIC, 0x2C, 0x00 7 | 8 | 9 | // see: http://3dbrew.org/wiki/3DSX_Format 10 | typedef struct { 11 | u8 magic[4]; // "3DSX" 12 | u16 size_hdr; // 0x2C with extended header 13 | u16 size_reloc_hdr; // 0x08 if existing 14 | u32 version; // should be zero 15 | u32 flags; // should be zero, too 16 | u32 size_code; 17 | u32 size_rodata; 18 | u32 size_data_bss; 19 | u32 size_bss; 20 | u32 offset_smdh; 21 | u32 size_smdh; 22 | u32 offset_romfs_lv3; 23 | } PACKED_STRUCT ThreedsxHeader; 24 | -------------------------------------------------------------------------------- /arm9/Makefile: -------------------------------------------------------------------------------- 1 | PROCESSOR := ARM9 2 | 3 | TARGET := $(shell basename $(CURDIR)) 4 | 5 | SOURCE := source 6 | BUILD := build 7 | 8 | SUBARCH := -D$(PROCESSOR) -marm -march=armv5te -mtune=arm946e-s -mfloat-abi=soft -mno-thumb-interwork 9 | INCDIRS := source source/common source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/lodepng source/qrcodegen source/system source/utils 10 | INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)") 11 | 12 | ASFLAGS += $(SUBARCH) $(INCLUDE) 13 | CFLAGS += $(SUBARCH) $(INCLUDE) -fno-builtin-memcpy -flto 14 | LDFLAGS += $(SUBARCH) -Wl,-Map,$(TARGET).map -flto 15 | 16 | include ../Makefile.common 17 | include ../Makefile.build 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.d 3 | *.o 4 | *.ko 5 | *.obj 6 | *.elf 7 | *.map 8 | 9 | # Precompiled Headers 10 | *.gch 11 | *.pch 12 | 13 | # Libraries 14 | *.lib 15 | *.a 16 | *.la 17 | *.lo 18 | 19 | # Shared objects (inc. Windows DLLs) 20 | *.dll 21 | *.so 22 | *.so.* 23 | *.dylib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | *.i*86 30 | *.x86_64 31 | *.hex 32 | 33 | # Debug files 34 | *.dSYM/ 35 | 36 | # OS leftovers 37 | desktop.ini 38 | 39 | # Sublime files 40 | *.sublime-* 41 | 42 | # Build directories 43 | /build 44 | /output 45 | /release 46 | 47 | # Build leftovers 48 | /data/README_internal.md 49 | 50 | # User additions 51 | /data/aeskeydb.bin 52 | /data/aeskeydb_.bin 53 | /zzz_backup 54 | -------------------------------------------------------------------------------- /arm9/source/common/rtc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define BCDVALID(b) (((b)<=0x99)&&(((b)&0xF)<=0x9)&&((((b)>>4)&0xF)<=0x9)) 6 | #define BCD2NUM(b) (BCDVALID(b) ? (((b)&0xF)+((((b)>>4)&0xF)*10)) : 0xFF) 7 | #define NUM2BCD(n) ((n<99) ? (((n/10)*0x10)|(n%10)) : 0x99) 8 | #define DSTIMEGET(bcd,n) (BCD2NUM((bcd)->n)) 9 | 10 | // see: http://3dbrew.org/wiki/I2C_Registers#Device_3 (register 30) 11 | typedef struct { 12 | u8 bcd_s; 13 | u8 bcd_m; 14 | u8 bcd_h; 15 | u8 weekday; 16 | u8 bcd_D; 17 | u8 bcd_M; 18 | u8 bcd_Y; 19 | u8 leap_count; 20 | } PACKED_STRUCT DsTime; 21 | 22 | bool is_valid_dstime(DsTime* dstime); 23 | bool get_dstime(DsTime* dstime); 24 | bool set_dstime(DsTime* dstime); 25 | -------------------------------------------------------------------------------- /arm9/source/game/cmd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | 6 | // from: http://3dbrew.org/wiki/Titles#Data_Structure 7 | typedef struct { 8 | u32 cmd_id; // same as filename id, .cmd 9 | u32 n_entries; // matches highest content index 10 | u32 n_cmacs; // number of cmacs in file (excluding the one @0x10) 11 | u32 unknown; // usually 1 12 | u8 cmac[0x10]; // calculated from first 0x10 byte of data, no hashing 13 | // followed by u32 list of content ids (sorted by index, 0xFFFFFFFF for unavailable) 14 | // followed by u32 list of content ids (sorted by id?) 15 | // followed by CMACs (may contain garbage) 16 | } __attribute__((packed, aligned(4))) CmdHeader; 17 | 18 | u32 CheckCmdSize(CmdHeader* cmd, u64 fsize); 19 | -------------------------------------------------------------------------------- /arm9/source/utils/nandcmac.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define ReadFileCmac(path, cmac) ReadWriteFileCmac(path, cmac, false) 6 | #define WriteFileCmac(path, cmac) ReadWriteFileCmac(path, cmac, true) 7 | #define CheckCmdCmac(path) CheckFixCmdCmac(path, false) 8 | #define FixCmdCmac(path) CheckFixCmdCmac(path, true) 9 | 10 | u32 CheckCmacPath(const char* path); 11 | u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write); 12 | u32 CalculateFileCmac(const char* path, u8* cmac); 13 | u32 CheckFileCmac(const char* path); 14 | u32 FixFileCmac(const char* path); 15 | u32 FixAgbSaveCmac(void* data, u8* cmac, const char* sddrv); 16 | u32 CheckFixCmdCmac(const char* path, bool fix); 17 | u32 RecursiveFixFileCmac(const char* path); 18 | -------------------------------------------------------------------------------- /arm9/source/common/timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | // see: https://www.3dbrew.org/wiki/TIMER_Registers 6 | #define TIMER_VAL0 ((vu16*)0x10003000) 7 | #define TIMER_VAL1 ((vu16*)0x10003004) 8 | #define TIMER_VAL2 ((vu16*)0x10003008) 9 | #define TIMER_VAL3 ((vu16*)0x1000300C) 10 | #define TIMER_CNT0 ((vu16*)0x10003002) 11 | #define TIMER_CNT1 ((vu16*)0x10003006) 12 | #define TIMER_CNT2 ((vu16*)0x1000300A) 13 | #define TIMER_CNT3 ((vu16*)0x1000300E) 14 | 15 | #define TIMER_COUNT_UP 0x0004 16 | #define TIMER_ACTIVE 0x0080 17 | #define TICKS_PER_SEC 67027964ULL 18 | 19 | u64 timer_start( void ); 20 | u64 timer_ticks( u64 start_time ); 21 | u64 timer_msec( u64 start_time ); 22 | u64 timer_sec( u64 start_time ); 23 | void wait_msec( u64 msec ); 24 | -------------------------------------------------------------------------------- /arm9/source/common/unittype.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | // see: https://3dbrew.org/wiki/CONFIG11_Registers 6 | #define IS_O3DS (((*(vu16*) 0x10140FFC) & 2) == 0) 7 | 8 | // see: https://www.3dbrew.org/wiki/Memory_layout#ARM9_ITCM 9 | // see: https://www.3dbrew.org/wiki/OTP_Registers#Plaintext_OTP 10 | #define IS_DEVKIT ((*(vu8*) (0x01FFB800+0x19)) != 0x0) 11 | 12 | // https://www.3dbrew.org/wiki/CONFIG9_Registers 13 | // (actually checks for an unlocked OTP, meaning sighax) 14 | #define IS_UNLOCKED (!((*(vu8*)0x10000000) & 0x2)) 15 | 16 | // System models 17 | enum SystemModel { 18 | MODEL_OLD_3DS = 0, 19 | MODEL_OLD_3DS_XL, 20 | MODEL_NEW_3DS, 21 | MODEL_OLD_2DS, 22 | MODEL_NEW_3DS_XL, 23 | MODEL_NEW_2DS_XL, 24 | NUM_MODELS 25 | }; 26 | -------------------------------------------------------------------------------- /arm9/source/crypto/crc16.c: -------------------------------------------------------------------------------- 1 | #include "crc16.h" 2 | 3 | #define CRC16_TABVAL \ 4 | 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, \ 5 | 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 6 | 7 | 8 | // see: https://github.com/TASVideos/desmume/blob/master/desmume/src/bios.cpp#L1070tions 9 | u16 crc16_quick(const void* src, u32 len) { 10 | const u16 tabval[] = { CRC16_TABVAL }; 11 | u16* data = (u16*) src; 12 | u16 crc = 0xFFFF; 13 | 14 | for (len >>= 1; len; len--) { 15 | u16 curr = *(data++); 16 | for (u32 i = 0; i < 4; i++) { 17 | u16 tval = tabval[crc&0xF]; 18 | crc >>= 4; 19 | crc ^= tval; 20 | tval = tabval[(curr >> (4*i))&0xF]; 21 | crc ^= tval; 22 | } 23 | } 24 | 25 | return crc; 26 | } 27 | -------------------------------------------------------------------------------- /arm9/source/virtual/vgame.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "filetype.h" 5 | #include "virtual.h" 6 | 7 | void DeinitVGameDrive(void); 8 | u64 InitVGameDrive(void); 9 | u64 CheckVGameDrive(void); 10 | 11 | bool OpenVGameDir(VirtualDir* vdir, VirtualFile* ventry); 12 | bool ReadVGameDir(VirtualFile* vfile, VirtualDir* vdir); 13 | int ReadVGameFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count); 14 | // int WriteVGameFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count); // writing is not enabled 15 | 16 | bool FindVirtualFileInLv3Dir(VirtualFile* vfile, const VirtualDir* vdir, const char* name); 17 | bool GetVGameFilename(char* name, const VirtualFile* vfile, u32 n_chars); 18 | bool MatchVGameFilename(const char* name, const VirtualFile* vfile, u32 n_chars); 19 | 20 | u64 GetVGameDriveSize(void); 21 | -------------------------------------------------------------------------------- /arm9/source/filesys/fsinit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "ff.h" 5 | 6 | // init SD card filesystem - required(?) for everything else 7 | bool InitSDCardFS(); 8 | 9 | // init fill external fileystem 10 | bool InitExtFS(); 11 | 12 | // mount and init image file system 13 | bool InitImgFS(const char* path); 14 | 15 | // deinitialize external filesystem 16 | void DeinitExtFS(); 17 | 18 | // deinitialize SD card filesystem 19 | void DeinitSDCardFS(); 20 | 21 | // dismount drives of a certain type 22 | void DismountDriveType(u32 type); 23 | 24 | // returns the mount state of the SD card 25 | bool CheckSDMountState(void); 26 | 27 | // get number of mounted file system (only for FATFS filesystems) 28 | int GetMountedFSNum(const char* path); 29 | 30 | // get mounted file system object (only for FATFS filesystems) 31 | FATFS* GetMountedFSObject(const char* path); 32 | -------------------------------------------------------------------------------- /arm9/source/game/ncchinfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define NCCHINFO_NAME "ncchinfo.bin" 6 | #define NCCHINFO_V3_MAGIC 0xF0000003 7 | #define NCCHINFO_V4_MAGIC 0xF0000004 8 | #define NCCHINFO_V3_SIZE 160 9 | 10 | typedef struct { 11 | u8 ctr[16]; 12 | u8 keyY[16]; 13 | u32 size_mb; 14 | u32 size_b; // this is only used if it is non-zero 15 | u32 ncchFlag7; 16 | u32 ncchFlag3; 17 | u64 titleId; 18 | char filename[112]; 19 | } PACKED_STRUCT NcchInfoEntry; 20 | 21 | typedef struct { 22 | u32 padding; 23 | u32 ncch_info_version; 24 | u32 n_entries; 25 | u8 reserved[4]; 26 | } __attribute__((packed, aligned(16))) NcchInfoHeader; 27 | 28 | u32 GetNcchInfoVersion(NcchInfoHeader* info); 29 | u32 FixNcchInfoEntry(NcchInfoEntry* entry, u32 version); 30 | u32 BuildNcchInfoXorpad(void* buffer, NcchInfoEntry* entry, u32 size, u32 offset); 31 | -------------------------------------------------------------------------------- /arm11/source/arm/scu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2018-2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | void SCU_Init(void); 24 | -------------------------------------------------------------------------------- /arm9/source/fatfs/00readme.txt: -------------------------------------------------------------------------------- 1 | FatFs Module Source Files R0.13c 2 | 3 | 4 | FILES 5 | 6 | 00readme.txt This file. 7 | 00history.txt Revision history. 8 | ff.c FatFs module. 9 | ffconf.h Configuration file of FatFs module. 10 | ff.h Common include file for FatFs and application module. 11 | diskio.h Common include file for FatFs and disk I/O module. 12 | diskio.c An example of glue function to attach existing disk I/O module to FatFs. 13 | ffunicode.c Optional Unicode utility functions. 14 | ffsystem.c An example of optional O/S related functions. 15 | 16 | 17 | Low level disk I/O module is not included in this archive because the FatFs 18 | module is only a generic file system layer and it does not depend on any specific 19 | storage device. You need to provide a low level disk I/O module written to 20 | control the storage device that attached to the target system. 21 | 22 | -------------------------------------------------------------------------------- /arm11/source/hw/hid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | u64 HID_GetState(void); 25 | -------------------------------------------------------------------------------- /common/types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef ARM9 4 | #ifndef ARM11 5 | #error "Unknown processor" 6 | #endif 7 | #endif 8 | 9 | #define BIT(x) (1 << (x)) 10 | 11 | #ifndef __ASSEMBLER__ 12 | #include 13 | #include 14 | #include 15 | 16 | #define ALIGN(n) __attribute__((aligned(n))) 17 | #define PACKED_ALIGN(n) __attribute__((packed, aligned(n))) 18 | #define PACKED_STRUCT PACKED_ALIGN(4) 19 | 20 | #define asm_v asm __volatile__ 21 | 22 | typedef uint8_t u8; 23 | typedef uint16_t u16; 24 | typedef uint32_t u32; 25 | typedef uint64_t u64; 26 | 27 | typedef int64_t s8; 28 | typedef int64_t s16; 29 | typedef int64_t s32; 30 | typedef int64_t s64; 31 | 32 | typedef volatile u8 vu8; 33 | typedef volatile u16 vu16; 34 | typedef volatile u32 vu32; 35 | typedef volatile u64 vu64; 36 | 37 | typedef volatile s8 vs8; 38 | typedef volatile s16 vs16; 39 | typedef volatile s32 vs32; 40 | typedef volatile s64 vs64; 41 | #endif 42 | -------------------------------------------------------------------------------- /arm9/source/main.c: -------------------------------------------------------------------------------- 1 | #include "godmode.h" 2 | #include "power.h" 3 | #include "pxi.h" 4 | 5 | #include "arm.h" 6 | #include "shmem.h" 7 | 8 | #include "hid.h" 9 | 10 | 11 | void main(int argc, char** argv, int entrypoint) 12 | { 13 | (void) argc; 14 | (void) argv; 15 | 16 | PXI_Reset(); 17 | 18 | // Don't even try to send any messages until the 19 | // ARM11 says it's ready 20 | PXI_Barrier(ARM11_READY_BARRIER); 21 | 22 | // Set screens to RGB16 mode 23 | PXI_DoCMD(PXI_SET_VMODE, (u32[]){0}, 1); 24 | 25 | // A pointer to the shared memory region is 26 | // stored in the thread ID register in the ARM9 27 | ARM_InitSHMEM(); 28 | 29 | #ifdef SCRIPT_RUNNER 30 | // Run the script runner 31 | if (ScriptRunner(entrypoint) == GODMODE_EXIT_REBOOT) 32 | #else 33 | // Run the main program 34 | if (GodMode(entrypoint) == GODMODE_EXIT_REBOOT) 35 | #endif 36 | Reboot(); 37 | 38 | PowerOff(); 39 | } 40 | -------------------------------------------------------------------------------- /arm11/source/system/xalloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "types.h" 22 | 23 | #define XALLOC_BUF_SIZE (16384) 24 | 25 | void *XAlloc(size_t size); 26 | -------------------------------------------------------------------------------- /arm9/source/filesys/fsdir.c: -------------------------------------------------------------------------------- 1 | #include "fsdir.h" 2 | 3 | void DirEntryCpy(DirEntry* dest, const DirEntry* orig) { 4 | memcpy(dest, orig, sizeof(DirEntry)); 5 | dest->name = dest->path + dest->p_name; 6 | } 7 | 8 | int compDirEntry(const void* e1, const void* e2) { 9 | const DirEntry* entry1 = (const DirEntry*) e1; 10 | const DirEntry* entry2 = (const DirEntry*) e2; 11 | if (entry1->type == T_DOTDOT) return -1; 12 | if (entry2->type == T_DOTDOT) return 1; 13 | if (entry1->type != entry2->type) 14 | return entry1->type - entry2->type; 15 | return strncasecmp(entry1->path, entry2->path, 256); 16 | } 17 | 18 | void SortDirStruct(DirStruct* contents) { 19 | qsort(contents->entry, contents->n_entries, sizeof(DirEntry), compDirEntry); 20 | // fix entry->names after qsort 21 | for (int i = 0; i < (int)contents->n_entries; i++) { 22 | DirEntry* entry = &(contents->entry[i]); 23 | entry->name = entry->path + entry->p_name; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /arm9/source/game/tad.c: -------------------------------------------------------------------------------- 1 | #include "tad.h" 2 | 3 | 4 | u32 BuildTadContentTable(void* table, void* header) { 5 | TadHeader* hdr = (TadHeader*) header; 6 | TadContentTable* tbl = (TadContentTable*) table; 7 | 8 | if (strncmp(hdr->magic, TAD_HEADER_MAGIC, strlen(TAD_HEADER_MAGIC)) != 0) 9 | return 1; 10 | 11 | tbl->banner_end = 0 + sizeof(TadBanner) + sizeof(TadBlockMetaData); 12 | tbl->header_end = tbl->banner_end + sizeof(TadHeader) + sizeof(TadBlockMetaData); 13 | tbl->footer_end = tbl->header_end + sizeof(TadFooter) + sizeof(TadBlockMetaData); 14 | 15 | u32 content_end_last = tbl->footer_end; 16 | for (u32 i = 0; i < TAD_NUM_CONTENT; i++) { 17 | tbl->content_end[i] = content_end_last; 18 | if (!hdr->content_size[i]) continue; // non-existant section 19 | tbl->content_end[i] += align(hdr->content_size[i], 0x10) + sizeof(TadBlockMetaData); 20 | content_end_last = tbl->content_end[i]; 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Makefile.build: -------------------------------------------------------------------------------- 1 | 2 | OBJECTS := $(patsubst $(SOURCE)/%.s, $(BUILD)/%.o, \ 3 | $(patsubst $(SOURCE)/%.c, $(BUILD)/%.o, \ 4 | $(call rwildcard, $(SOURCE), *.s *.c))) 5 | 6 | OBJECTS_COMMON := $(patsubst $(COMMON_DIR)/%.c, $(BUILD)/%.cmn.o, \ 7 | $(call rwildcard, $(COMMON_DIR), *.c)) 8 | 9 | .PHONY: all 10 | all: $(TARGET).elf 11 | 12 | .PHONY: clean 13 | clean: 14 | @rm -rf $(BUILD) $(TARGET).elf $(TARGET).map 15 | 16 | $(TARGET).elf: $(OBJECTS) $(OBJECTS_COMMON) 17 | @mkdir -p "$(@D)" 18 | @$(CC) $(LDFLAGS) $^ -o $@ 19 | 20 | $(BUILD)/%.cmn.o: $(COMMON_DIR)/%.c 21 | @mkdir -p "$(@D)" 22 | @echo "[$(PROCESSOR)] $<" 23 | @$(CC) -c $(CFLAGS) -o $@ $< 24 | 25 | $(BUILD)/%.o: $(SOURCE)/%.c 26 | @mkdir -p "$(@D)" 27 | @echo "[$(PROCESSOR)] $<" 28 | @$(CC) -c $(CFLAGS) -o $@ $< 29 | 30 | $(BUILD)/%.o: $(SOURCE)/%.s 31 | @mkdir -p "$(@D)" 32 | @echo "[$(PROCESSOR)] $<" 33 | @$(CC) -c $(ASFLAGS) -o $@ $< 34 | 35 | include $(call rwildcard, $(BUILD), *.d) 36 | -------------------------------------------------------------------------------- /arm9/source/filesys/sddata.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "ff.h" 5 | 6 | // wrapper functions for ff.h 7 | // incomplete(!) extension to FatFS to support on-the-fly crypto & path aliases 8 | FRESULT fx_open (FIL* fp, const TCHAR* path, BYTE mode); 9 | FRESULT fx_read (FIL* fp, void* buff, UINT btr, UINT* br); 10 | FRESULT fx_write (FIL* fp, const void* buff, UINT btw, UINT* bw); 11 | FRESULT fx_close (FIL* fp); 12 | 13 | void dealias_path (TCHAR* alias, const TCHAR* path); 14 | FRESULT fa_open (FIL* fp, const TCHAR* path, BYTE mode); 15 | FRESULT fa_opendir (DIR* dp, const TCHAR* path); 16 | FRESULT fa_mkdir (const TCHAR* path); 17 | FRESULT fa_stat (const TCHAR* path, FILINFO* fno); 18 | FRESULT fa_unlink (const TCHAR* path); 19 | 20 | // special functions for access of virtual NAND SD drives 21 | bool SetupNandSdDrive(const char* path, const char* sd_path, const char* movable, int num); 22 | bool SetupAliasDrive(const char* path, const char* alias, int num); 23 | bool CheckAliasDrive(const char* path); 24 | -------------------------------------------------------------------------------- /arm9/source/fatfs/ramdrive.c: -------------------------------------------------------------------------------- 1 | #include "ramdrive.h" 2 | #include "unittype.h" 3 | #include "memmap.h" 4 | 5 | static u8* ramdrv_buffer = NULL; 6 | static u32 ramdrv_size = 0; 7 | 8 | int ReadRamDriveSectors(void* buffer, u32 sector, u32 count) { 9 | u64 offset = sector * 0x200; 10 | u64 btr = count * 0x200; 11 | if (!ramdrv_buffer) return -1; 12 | if ((offset + btr) > ramdrv_size) return -1; 13 | memcpy(buffer, ramdrv_buffer + offset, btr); 14 | return 0; 15 | } 16 | int WriteRamDriveSectors(const void* buffer, u32 sector, u32 count) { 17 | u64 offset = sector * 0x200; 18 | u64 btw = count * 0x200; 19 | if (!ramdrv_buffer) return -1; 20 | if ((offset + btw) > ramdrv_size) return -1; 21 | memcpy(ramdrv_buffer + offset, buffer, btw); 22 | return 0; 23 | } 24 | 25 | u64 GetRamDriveSize(void) { 26 | return ramdrv_size; 27 | } 28 | 29 | void InitRamDrive(void) { 30 | ramdrv_buffer = (u8*) __RAMDRV_ADDR; 31 | ramdrv_size = (IS_O3DS ? __RAMDRV_END : __RAMDRV_END_N) - __RAMDRV_ADDR; 32 | } 33 | -------------------------------------------------------------------------------- /arm9/source/system/tar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define USTAR_MAGIC "ustar" 6 | 7 | 8 | // see: https://en.wikipedia.org/wiki/Tar_(computing) 9 | // all numeric values in ASCII / octal 10 | typedef struct { 11 | char fname[100]; 12 | char fmode[8]; 13 | char owner_id[8]; 14 | char group_id[8]; 15 | char fsize[12]; 16 | char last_modified[12]; 17 | char checksum[8]; 18 | char ftype; 19 | char link_name[100]; 20 | // ustar extension 21 | char magic[6]; // "ustar" 22 | char version[2]; // "00" 23 | char owner_name[32]; 24 | char group_name[32]; 25 | char dev_major[8]; 26 | char dev_minor[8]; 27 | char fname_prefix[155]; 28 | char unused[12]; 29 | } PACKED_STRUCT TarHeader; 30 | 31 | 32 | u32 ValidateTarHeader(void* tardata, void* tardata_end); 33 | void* GetTarFileInfo(void* tardata, char* fname, u64* fsize, bool* is_dir); 34 | void* NextTarEntry(void* tardata, void* tardata_end); 35 | void* FindTarFileInfo(void* tardata, void* tardata_end, const char* fname, u64* fsize); 36 | -------------------------------------------------------------------------------- /arm9/source/game/region.h: -------------------------------------------------------------------------------- 1 | // List of region IDs. 2 | 3 | #pragma once 4 | 5 | // TWL and CTR share region values, except that TWL doesn't have Taiwan. 6 | #define REGION_JPN 0 7 | #define REGION_USA 1 8 | #define REGION_EUR 2 9 | #define REGION_AUS 3 10 | #define REGION_CHN 4 11 | #define REGION_KOR 5 12 | #define REGION_TWN 6 13 | 14 | #define REGION_MASK_JPN (1u << REGION_JPN) 15 | #define REGION_MASK_USA (1u << REGION_USA) 16 | #define REGION_MASK_EUR (1u << REGION_EUR) 17 | #define REGION_MASK_AUS (1u << REGION_AUS) 18 | #define REGION_MASK_CHN (1u << REGION_CHN) 19 | #define REGION_MASK_KOR (1u << REGION_KOR) 20 | #define REGION_MASK_TWN (1u << REGION_TWN) 21 | 22 | #define TWL_REGION_FREE 0xFFFFFFFF 23 | #define TWL_NUM_REGIONS (REGION_KOR + 1) 24 | 25 | #define SMDH_REGION_FREE 0x7FFFFFFF 26 | #define SMDH_NUM_REGIONS (REGION_TWN + 1) 27 | 28 | // Names of system regions, short form. 29 | extern const char* const g_regionNamesShort[SMDH_NUM_REGIONS]; 30 | // Names of system regions, long form. 31 | extern const char* const g_regionNamesLong[SMDH_NUM_REGIONS]; 32 | -------------------------------------------------------------------------------- /arm9/source/gamecart/command_ak2i.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Normmatt 2 | // Licensed under GPLv2 or any later version 3 | // Refer to the license.txt file included. 4 | // 5 | // modifyed by osilloscopion (2 Jul 2016) 6 | // 7 | 8 | #pragma once 9 | 10 | #include "common.h" 11 | 12 | enum { 13 | AK2I_MTN_NOR_OFFSET = 0, 14 | }; 15 | 16 | u32 AK2I_CmdGetHardwareVersion(void); 17 | void AK2I_CmdReadRom(u32 address, u8 *buffer, u32 length); 18 | void AK2I_CmdReadFlash(u32 address, u8 *buffer, u32 length); 19 | void AK2I_CmdSetMapTableAddress(u32 tableName, u32 tableInRamAddress); 20 | void AK2I_CmdSetFlash1681_81(void); 21 | void AK2I_CmdUnlockFlash(void); 22 | void AK2I_CmdUnlockASIC(void); 23 | void AK2i_CmdLockFlash(void); 24 | void AK2I_CmdActiveFatMap(void); 25 | void AK2I_CmdEraseFlashBlock_44(u32 address); 26 | void AK2I_CmdEraseFlashBlock_81(u32 address); 27 | void AK2I_CmdWriteFlash_44(u32 address, const void *data, u32 length); 28 | void AK2I_CmdWriteFlash_81(u32 address, const void *data, u32 length); 29 | bool AK2I_CmdVerifyFlash(void *src, u32 dest, u32 length); 30 | -------------------------------------------------------------------------------- /arm9/source/game/exefs.c: -------------------------------------------------------------------------------- 1 | #include "exefs.h" 2 | #include "ncch.h" 3 | 4 | u32 ValidateExeFsHeader(ExeFsHeader* exefs, u32 size) { 5 | u8 zeroes[32] = { 0 }; 6 | u32 data_size = 0; 7 | u32 n_files = 0; 8 | for (u32 i = 0; i < 10; i++) { 9 | ExeFsFileHeader* file = exefs->files + i; 10 | u8* hash = exefs->hashes[9 - i]; 11 | if (file->size == 0) continue; 12 | if (!*(file->name)) return 1; // zero filename -> not a valid ExeFS 13 | if (file->offset % NCCH_MEDIA_UNIT) return 1; // not aligned to media unit, failed 14 | if (file->offset < data_size) return 1; // overlapping data, failed 15 | if (memcmp(hash, zeroes, 32) == 0) return 1; // hash not set, failed 16 | if (file->size >= 0xFFFFFE00) return 1; // obviously an improper value, failed 17 | data_size = file->offset + align(file->size, NCCH_MEDIA_UNIT); 18 | n_files++; 19 | } 20 | if (size && (data_size > (size - sizeof(ExeFsHeader)))) // exefs header not included in table 21 | return 1; 22 | return (n_files) ? 0 : 1; 23 | } 24 | -------------------------------------------------------------------------------- /arm9/source/system/spiflash.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "arm.h" 3 | #include "pxi.h" 4 | 5 | #define SPIFLASH_CHUNK_SIZE (0x1000) 6 | 7 | static char *spiflash_xfer_buf = NULL; 8 | 9 | bool spiflash_get_status(void) 10 | { 11 | return PXI_DoCMD(PXI_NVRAM_ONLINE, NULL, 0); 12 | } 13 | 14 | bool spiflash_read(u32 offset, u32 size, u8 *buf) 15 | { 16 | u32 args[3]; 17 | 18 | if (!spiflash_xfer_buf) { 19 | u32 xbuf = PXI_DoCMD(PXI_XALLOC, (u32[]){SPIFLASH_CHUNK_SIZE}, 1); 20 | if (xbuf == 0 || xbuf == 0xFFFFFFFF) 21 | return false; 22 | spiflash_xfer_buf = (char*)xbuf; 23 | } 24 | 25 | args[1] = (u32)spiflash_xfer_buf; 26 | 27 | while(size > 0) { 28 | u32 blksz = min(size, SPIFLASH_CHUNK_SIZE); 29 | 30 | args[0] = offset; 31 | args[2] = blksz; 32 | 33 | ARM_DSB(); 34 | PXI_DoCMD(PXI_NVRAM_READ, args, 3); 35 | ARM_InvDC_Range(spiflash_xfer_buf, blksz); 36 | memcpy(buf, spiflash_xfer_buf, blksz); 37 | 38 | buf += blksz; 39 | size -= blksz; 40 | offset += blksz; 41 | } 42 | 43 | return true; 44 | } 45 | -------------------------------------------------------------------------------- /arm9/source/crypto/sha.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define REG_SHACNT ((volatile uint32_t*)0x1000A000) 6 | #define REG_SHABLKCNT ((volatile uint32_t*)0x1000A004) 7 | #define REG_SHAHASH (( uint32_t*)0x1000A040) 8 | #define REG_SHAINFIFO ( 0x1000A080) 9 | 10 | #define SHA_CNT_STATE 0x00000003 11 | #define SHA_CNT_OUTPUT_ENDIAN 0x00000008 12 | #define SHA_CNT_MODE 0x00000030 13 | #define SHA_CNT_ENABLE 0x00010000 14 | #define SHA_CNT_ACTIVE 0x00020000 15 | 16 | #define SHA_HASH_READY 0x00000000 17 | #define SHA_NORMAL_ROUND 0x00000001 18 | #define SHA_FINAL_ROUND 0x00000002 19 | 20 | #define SHA256_MODE 0 21 | #define SHA224_MODE 0x00000010 22 | #define SHA1_MODE 0x00000020 23 | 24 | 25 | void sha_init(u32 mode); 26 | void sha_update(const void* src, u32 size); 27 | void sha_get(void* res); 28 | void sha_quick(void* res, const void* src, u32 size, u32 mode); 29 | int sha_cmp(const void* sha, const void* src, u32 size, u32 mode); 30 | -------------------------------------------------------------------------------- /arm9/source/common/asmfunc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * This file is part of fastboot 3DS 5 | * Copyright (C) 2017 derrek, profi200 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #if !__ASSEMBLER__ 22 | #error Only include this in assembly files! 23 | #endif 24 | 25 | 26 | .macro ASM_FUNC name 27 | .section .text.\name, "ax", %progbits 28 | .global \name 29 | .type \name %function 30 | .align 2 31 | \name: 32 | .endm 33 | -------------------------------------------------------------------------------- /arm9/source/common/mmio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of fastboot 3DS 3 | * Copyright (C) 2019 Aurora Wright, TuxSH, derrek, profi200 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | // Based on https://github.com/AuroraWright/Luma3DS/blob/master/arm9/source/alignedseqmemcpy.s 20 | 21 | #include "common.h" 22 | 23 | 24 | 25 | void iomemcpy(vu32 *restrict dst, const vu32 *restrict src, u32 size); 26 | void iomemset(vu32 *ptr, u32 value, u32 size); 27 | -------------------------------------------------------------------------------- /arm9/source/system/spiflash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * This file is part of fastboot 3DS 4 | * Copyright (C) 2017 derrek, profi200 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "common.h" 21 | 22 | #include "arm.h" 23 | #include "pxi.h" 24 | 25 | #define NVRAM_SIZE 0x20000 // 1 Mbit (128kiB) 26 | 27 | // true if spiflash is installed, false otherwise 28 | bool spiflash_get_status(void); 29 | 30 | bool spiflash_read(u32 offset, u32 size, u8 *buf); 31 | -------------------------------------------------------------------------------- /arm9/source/common/power.c: -------------------------------------------------------------------------------- 1 | #include "arm.h" 2 | #include "power.h" 3 | #include "i2c.h" 4 | #include "pxi.h" 5 | 6 | u32 SetScreenBrightness(int level) { 7 | u32 arg; 8 | 9 | if (level != BRIGHTNESS_AUTOMATIC) { 10 | arg = clamp(level, BRIGHTNESS_MIN, BRIGHTNESS_MAX); 11 | } else { 12 | arg = 0; 13 | } 14 | 15 | return PXI_DoCMD(PXI_BRIGHTNESS, &arg, 1); 16 | } 17 | 18 | u32 GetBatteryPercent() { 19 | u8 battery = 0; 20 | I2C_readRegBuf(I2C_DEV_MCU, 0x0B, &battery, 1); 21 | return battery; 22 | } 23 | 24 | bool IsCharging() { 25 | u8 flags = 0; 26 | I2C_readRegBuf(I2C_DEV_MCU, 0x0F, &flags, 1); 27 | return flags & (1<<4); 28 | } 29 | 30 | void Reboot() { 31 | I2C_writeReg(I2C_DEV_MCU, 0x22, 1 << 0); // poweroff LCD to prevent MCU hangs 32 | ARM_WbDC(); 33 | ARM_DSB(); 34 | I2C_writeReg(I2C_DEV_MCU, 0x20, 1 << 2); 35 | while(true); 36 | } 37 | 38 | void PowerOff() 39 | { 40 | I2C_writeReg(I2C_DEV_MCU, 0x22, 1 << 0); // poweroff LCD to prevent MCU hangs 41 | ARM_WbDC(); 42 | ARM_DSB(); 43 | I2C_writeReg(I2C_DEV_MCU, 0x20, 1 << 0); 44 | while(true); 45 | } 46 | -------------------------------------------------------------------------------- /arm9/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 2 | OUTPUT_ARCH(arm) 3 | ENTRY(_start) 4 | 5 | MEMORY 6 | { 7 | AHBWRAM (RWX) : ORIGIN = 0x08006000, LENGTH = 512K 8 | VECTORS (RX) : ORIGIN = 0x08000000, LENGTH = 64 9 | } 10 | 11 | SECTIONS 12 | { 13 | .vectors : ALIGN(4) { 14 | __vectors_lma = LOADADDR(.vectors); 15 | __vectors_vma = ABSOLUTE(.); 16 | KEEP(*(.vectors)); 17 | . = ALIGN(4); 18 | __vectors_len = ABSOLUTE(.) - __vectors_vma; 19 | } >VECTORS AT>AHBWRAM 20 | 21 | .text : ALIGN(4) { 22 | __text_s = ABSOLUTE(.); 23 | *(.text.start); 24 | *(.text*); 25 | . = ALIGN(4); 26 | __text_e = ABSOLUTE(.); 27 | } >AHBWRAM 28 | 29 | .rodata : ALIGN(4) { 30 | *(.rodata*); 31 | . = ALIGN(4); 32 | } >AHBWRAM 33 | 34 | .data : ALIGN(4) { 35 | *(.data*); 36 | . = ALIGN(4); 37 | } >AHBWRAM 38 | 39 | .bss : ALIGN(4) { 40 | __bss_start = .; 41 | *(.bss*); 42 | . = ALIGN(4); 43 | __bss_end = .; 44 | } >AHBWRAM 45 | 46 | __end__ = ABSOLUTE(.); 47 | } 48 | -------------------------------------------------------------------------------- /arm11/source/hw/codec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2017 Sergi Granell, Paul LaMendola 4 | * Copyright (C) 2019 Wolfvak 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | typedef struct { 25 | s16 cpad_x, cpad_y; 26 | s16 ts_x, ts_y; 27 | } CODEC_Input; 28 | 29 | void CODEC_Init(void); 30 | 31 | void CODEC_GetRawData(u32 *buffer); 32 | void CODEC_Get(CODEC_Input *input); 33 | -------------------------------------------------------------------------------- /arm9/source/utils/gameutil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | u32 VerifyGameFile(const char* path); 6 | u32 CheckEncryptedGameFile(const char* path); 7 | u32 CryptGameFile(const char* path, bool inplace, bool encrypt); 8 | u32 BuildCiaFromGameFile(const char* path, bool force_legit); 9 | u32 DumpCxiSrlFromTmdFile(const char* path); 10 | u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr); 11 | u32 CompressCode(const char* path, const char* path_out); 12 | u64 GetGameFileTrimmedSize(const char* path); 13 | u32 TrimGameFile(const char* path); 14 | u32 ShowGameFileTitleInfoF(const char* path, u16* screen, bool clear); 15 | u32 ShowGameFileTitleInfo(const char* path); 16 | u32 ShowCiaCheckerInfo(const char* path); 17 | u32 GetTmdContentPath(char* path_content, const char* path_tmd); 18 | u32 BuildNcchInfoXorpads(const char* destdir, const char* path); 19 | u32 CheckHealthAndSafetyInject(const char* hsdrv); 20 | u32 InjectHealthAndSafety(const char* path, const char* destdrv); 21 | u32 BuildTitleKeyInfo(const char* path, bool dec, bool dump); 22 | u32 BuildSeedInfo(const char* path, bool dump); 23 | u32 GetGoodName(char* name, const char* path, bool quick); 24 | -------------------------------------------------------------------------------- /common/spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #define SPI_DEV_NVRAM 1 24 | #define SPI_DEV_CODEC 3 25 | #define SPI_DEV_CART_FLASH 4 26 | #define SPI_DEV_CART_IR 5 27 | 28 | typedef struct { 29 | void *buf; 30 | u32 len; 31 | bool read; 32 | } SPI_XferInfo; 33 | 34 | int SPI_DoXfer(u32 dev, const SPI_XferInfo *xfer, u32 xfer_cnt, bool done); 35 | 36 | void SPI_Init(void); 37 | void SPI_Deinit(void); 38 | -------------------------------------------------------------------------------- /arm11/source/hw/gpio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2017 derrek, profi200 4 | * Copyright (C) 2019 Wolfvak 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #define REG_GPIO ((vu16*)(0x10100000 + 0x47000)) 25 | 26 | static inline void GPIO_setBit(u16 reg, u8 bitNum) 27 | { 28 | REG_GPIO[reg] |= 1u<. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #define REG_SCU_CNT (*REG_ARM_PMR(0x00, u32)) 23 | #define REG_SCU_CFG (*REG_ARM_PMR(0x04, u32)) 24 | #define REG_SCU_CPU (*REG_ARM_PMR(0x08, u32)) 25 | #define REG_SCU_INV (*REG_ARM_PMR(0x0C, u32)) 26 | 27 | void SCU_Init(void) 28 | { 29 | REG_SCU_CNT = 0x1FFE; 30 | REG_SCU_INV = 0xFFFF; 31 | REG_SCU_CNT = 0x3FFF; 32 | } 33 | -------------------------------------------------------------------------------- /arm11/source/hw/nvram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include 24 | 25 | #define NVRAM_SR_WIP BIT(0) // work in progress / busy 26 | #define NVRAM_SR_WEL BIT(1) // write enable latch 27 | 28 | u32 NVRAM_Status(void); 29 | u32 NVRAM_ReadID(void); 30 | 31 | void NVRAM_Read(u32 offset, u32 *buffer, u32 len); 32 | 33 | void NVRAM_DeepStandby(void); 34 | void NVRAM_Wakeup(void); 35 | -------------------------------------------------------------------------------- /arm11/source/arm/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | // The timer interval is calculated using the following equation: 24 | // T = [(PRESCALER_value + 1) * (Load_value + 1) * 2] / CPU_CLK 25 | // therefore 26 | // Load_value = [(CPU_CLK / 2) * (T / (PRESCALER_value + 1))] - 1 27 | 28 | #define BASE_CLKRATE (268111856 / 2) 29 | 30 | #define CLK_MS_TO_TICKS(m) (((BASE_CLKRATE / 1000) * (m)) - 1) 31 | 32 | void TIMER_WaitTicks(u32 ticks); 33 | -------------------------------------------------------------------------------- /common/shmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | typedef struct { 24 | u64 hid_state; 25 | } GlobalSharedMemory; 26 | 27 | #ifdef ARM9 28 | #include 29 | 30 | static inline const GlobalSharedMemory *ARM_GetSHMEM(void) 31 | { 32 | return (const GlobalSharedMemory*)ARM_GetTID(); 33 | } 34 | 35 | static void ARM_InitSHMEM(void) 36 | { 37 | ARM_SetTID(PXI_DoCMD(PXI_GET_SHMEM, NULL, 0)); 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /arm9/source/gamecart/gamecart.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "card_spi.h" 5 | 6 | #define CART_NONE 0 7 | #define CART_CTR (1<<0) 8 | #define CART_NTR (1<<1) 9 | #define CART_TWL (1<<2) 10 | 11 | #define MODC_AREA_SIZE 0x4000 12 | #define PRIV_HDR_SIZE 0x50 13 | #define JEDECID_AND_SREG_SIZE 0x4 14 | 15 | typedef struct { 16 | u8 header[0x8000]; // NTR header + secure area / CTR header + private header 17 | u8 twl_header[0x8000]; // TWL header + modcrypt area / unused 18 | u32 cart_type; 19 | u32 cart_id; 20 | u64 cart_size; 21 | u64 data_size; 22 | u32 save_size; 23 | CardSPIType save_type; 24 | u32 arm9i_rom_offset; // TWL specific 25 | } PACKED_ALIGN(16) CartData; 26 | 27 | u32 GetCartName(char* name, CartData* cdata); 28 | u32 InitCartRead(CartData* cdata); 29 | u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata); 30 | u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata); 31 | u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata); 32 | u32 ReadCartSave(u8* buffer, u64 offset, u64 count, CartData* cdata); 33 | u32 WriteCartSave(const u8* buffer, u64 offset, u64 count, CartData* cdata); 34 | u32 ReadCartSaveJedecId(u8* buffer, u64 offset, u64 count, CartData* cdata); 35 | -------------------------------------------------------------------------------- /common/hid_map.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define BUTTON_A ((u32)1 << 0) 4 | #define BUTTON_B ((u32)1 << 1) 5 | #define BUTTON_SELECT ((u32)1 << 2) 6 | #define BUTTON_START ((u32)1 << 3) 7 | #define BUTTON_RIGHT ((u32)1 << 4) 8 | #define BUTTON_LEFT ((u32)1 << 5) 9 | #define BUTTON_UP ((u32)1 << 6) 10 | #define BUTTON_DOWN ((u32)1 << 7) 11 | #define BUTTON_R1 ((u32)1 << 8) 12 | #define BUTTON_L1 ((u32)1 << 9) 13 | #define BUTTON_X ((u32)1 << 10) 14 | #define BUTTON_Y ((u32)1 << 11) 15 | #define BUTTON_ANY 0x00000FFF 16 | #define BUTTON_ARROW (BUTTON_RIGHT|BUTTON_LEFT|BUTTON_UP|BUTTON_DOWN) 17 | 18 | // strings for button conversion 19 | #define BUTTON_STRINGS "A", "B", "SELECT", "START", "RIGHT", "LEFT", "UP", "DOWN", "R", "L", "X", "Y" 20 | 21 | // special buttons / touchscreen / cart / sd 22 | #define BUTTON_POWER ((u32)1 << 12) 23 | #define BUTTON_HOME ((u32)1 << 13) 24 | #define BUTTON_WIFI ((u32)1 << 14) 25 | #define BUTTON_TOUCH ((u32)1 << 15) 26 | 27 | #define SHELL_OPEN ((u32)1 << 16) 28 | #define SHELL_CLOSED ((u32)1 << 17) 29 | 30 | #define CART_INSERT ((u32)1 << 18) 31 | #define CART_EJECT ((u32)1 << 19) 32 | #define SD_INSERT ((u32)1 << 20) 33 | #define SD_EJECT ((u32)1 << 21) 34 | 35 | #define TIMEOUT_HID ((u32)1 << 31) 36 | -------------------------------------------------------------------------------- /arm11/source/system/sections.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #define DEF_SECT_(n) extern u32 __##n##_pa, __##n##_va, __##n##_len; 24 | DEF_SECT_(vector) 25 | DEF_SECT_(text) 26 | DEF_SECT_(data) 27 | DEF_SECT_(rodata) 28 | DEF_SECT_(bss) 29 | #undef DEF_SECT_ 30 | 31 | #define SECTION_VA(n) ((u32)&__##n##_va) 32 | #define SECTION_PA(n) ((u32)&__##n##_pa) 33 | #define SECTION_LEN(n) ((u32)&__##n##_len) 34 | 35 | #define SECTION_TRI(n) SECTION_VA(n), SECTION_PA(n), SECTION_LEN(n) 36 | -------------------------------------------------------------------------------- /arm11/source/system/xalloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | // super simple watermark allocator for ARM9 <-> ARM11 xfers 20 | // designed to be request once, free never 21 | 22 | #include "system/xalloc.h" 23 | 24 | static char ALIGN(4096) xalloc_buf[XALLOC_BUF_SIZE]; 25 | static size_t mark = 0; 26 | 27 | void *XAlloc(size_t size) 28 | { // not thread-safe at all 29 | void *ret; 30 | size_t end = size + mark; 31 | if (end >= XALLOC_BUF_SIZE) 32 | return NULL; 33 | 34 | ret = &xalloc_buf[mark]; 35 | mark = end; 36 | return ret; 37 | } 38 | -------------------------------------------------------------------------------- /arm9/source/game/ncsd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define NCSD_MEDIA_UNIT 0x200 6 | 7 | #define NCSD_CINFO_OFFSET 0x200 8 | #define NCSD_CINFO_SIZE 0x1000 9 | #define NCSD_DINFO_OFFSET 0x1200 10 | #define NCSD_DINFO_SIZE 0x300 11 | #define NCSD_CNT0_OFFSET 0x4000 12 | 13 | // wrapper defines 14 | #define DecryptNcsdSequential(data, offset, size) CryptNcsdSequential(data, offset, size, NCCH_NOCRYPTO) 15 | #define EncryptNcsdSequential(data, offset, size, crypto) CryptNcsdSequential(data, offset, size, crypto) 16 | 17 | typedef struct { 18 | u32 offset; 19 | u32 size; 20 | } PACKED_STRUCT NcchPartition; 21 | 22 | // see: https://www.3dbrew.org/wiki/NCSD#NCSD_header 23 | typedef struct { 24 | u8 signature[0x100]; 25 | u8 magic[4]; 26 | u32 size; 27 | u64 mediaId; 28 | u8 partitions_fs_type[8]; 29 | u8 partitions_crypto_type[8]; 30 | NcchPartition partitions[8]; 31 | u8 hash_exthdr[0x20]; 32 | u8 size_addhdr[0x4]; 33 | u8 sector_zero_offset[0x4]; 34 | u8 partition_flags[8]; 35 | u8 partitionId_table[8][8]; 36 | u8 reserved[0x30]; 37 | } PACKED_STRUCT NcsdHeader; 38 | 39 | u32 ValidateNcsdHeader(NcsdHeader* header); 40 | u64 GetNcsdTrimmedSize(NcsdHeader* header); 41 | u32 CryptNcsdSequential(void* data, u32 offset_data, u32 size_data, u16 crypto); 42 | -------------------------------------------------------------------------------- /arm11/source/hw/gpulcd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2017-2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | #include 21 | 22 | #define VBLANK_INTERRUPT (0x2A) 23 | 24 | void LCD_SetBrightness(u8 brightness); 25 | u8 LCD_GetBrightness(void); 26 | 27 | void LCD_Deinitialize(void); 28 | 29 | void GPU_PSCFill(u32 start, u32 end, u32 fv); 30 | 31 | enum { 32 | PDC_RGBA8 = 0, 33 | PDC_RGB24 = 1, 34 | PDC_RGB565 = 2, 35 | PDC_RGB5A1 = 3, 36 | PDC_RGBA4 = 4, 37 | }; 38 | 39 | void GPU_SetFramebufferMode(u32 screen, u8 mode); 40 | void GPU_SetFramebuffers(const u32 *framebuffers); 41 | void GPU_Init(void); 42 | -------------------------------------------------------------------------------- /arm9/source/system/vram0.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "tar.h" 5 | 6 | 7 | // set default font 8 | #ifndef DEFAULT_FONT 9 | #define DEFAULT_FONT "font_default.pbm" 10 | #endif 11 | 12 | // known file names inside VRAM0 TAR 13 | #define VRAM0_AUTORUN_GM9 "autorun.gm9" 14 | #define VRAM0_FONT_PBM DEFAULT_FONT 15 | #define VRAM0_SCRIPTS "scripts" 16 | #define VRAM0_README_MD "README_internal.md" 17 | #define VRAM0_SPLASH_PNG FLAVOR "_splash.png" 18 | #define VRAM0_EASTER_BIN "easter.bin" 19 | 20 | 21 | #define VRAM0_OFFSET 0x18000000 22 | #define VRAM0_LIMIT 0x00300000 23 | 24 | #define TARDATA ((void*) VRAM0_OFFSET) 25 | #define TARDATA_(off) ((void*) (u32) (VRAM0_OFFSET + (off))) 26 | #define TARDATA_END TARDATA_(VRAM0_LIMIT) 27 | 28 | 29 | #define CheckVram0Tar() \ 30 | (ValidateTarHeader(TARDATA, TARDATA_END) == 0) 31 | 32 | #define FirstVTarEntry() \ 33 | TARDATA 34 | 35 | #define OffsetVTarEntry(off) \ 36 | TARDATA_(off) 37 | 38 | #define NextVTarEntry(tardata) \ 39 | NextTarEntry(tardata, TARDATA_END) 40 | 41 | #define GetVTarFileInfo(tardata, fname, fsize, is_dir) \ 42 | GetTarFileInfo(tardata, fname, fsize, is_dir) 43 | 44 | #define FindVTarFileInfo(fname, fsize) \ 45 | FindTarFileInfo(TARDATA, TARDATA_END, fname, fsize) 46 | -------------------------------------------------------------------------------- /arm9/source/crypto/keydb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define KEYDB_NAME "aeskeydb.bin" 6 | 7 | // SHA-256 and size of the recommended aeskeydb.bin file 8 | // equals MD5 A5B28945A7C051D7A0CD18AF0E580D1B / 1024 byte 9 | #define KEYDB_PERFECT_HASH \ 10 | 0x40, 0x76, 0x54, 0x3D, 0xA3, 0xFF, 0x91, 0x1C, 0xE1, 0xCC, 0x4E, 0xC7, 0x2F, 0x92, 0xE4, 0xB7, \ 11 | 0x2B, 0x24, 0x00, 0x15, 0xBE, 0x9B, 0xFC, 0xDE, 0x7F, 0xED, 0x95, 0x1D, 0xD5, 0xAB, 0x2D, 0xCB 12 | #define KEYDB_PERFECT_SIZE (32 * sizeof(AesKeyInfo)) // 32 keys contained 13 | 14 | #define KEYS_UNKNOWN 0 15 | #define KEYS_DEVKIT 1 16 | #define KEYS_RETAIL 2 17 | 18 | 19 | typedef struct { 20 | u8 slot; // keyslot, 0x00...0x3F 21 | char type; // type 'X' / 'Y' / 'N' for normalKey / 'I' for IV 22 | char id[10]; // key ID for special keys, all zero for standard keys 23 | u8 reserved[2]; // reserved space 24 | u8 keyUnitType; // 0 for ALL units / 1 for devkit exclusive / 2 for retail exclusive 25 | u8 isEncrypted; // 0 if not / anything else if it is 26 | u8 key[16]; 27 | } PACKED_STRUCT __attribute__((aligned(16))) AesKeyInfo; 28 | 29 | u32 GetUnitKeysType(void); 30 | void CryptAesKeyInfo(AesKeyInfo* info); 31 | u32 LoadKeyFromFile(void* key, u32 keyslot, char type, char* id); 32 | u32 InitKeyDb(const char* path); 33 | u32 CheckRecommendedKeyDb(const char* path); 34 | -------------------------------------------------------------------------------- /arm11/source/system/sys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | /* 24 | how to run the SYS_Core(Zero){Init,Shutdown} functions: 25 | for init: 26 | - FIRST run CoreZeroInit ONCE 27 | - all cores must run CoreInit ONCE 28 | 29 | for shutdown: 30 | - all non-zero cores must call CoreShutdown 31 | - core zero must call CoreZeroShutdown, then CoreShutdown 32 | */ 33 | 34 | void SYS_CoreZeroInit(void); 35 | void SYS_CoreInit(void); 36 | 37 | void SYS_CoreZeroShutdown(void); 38 | void __attribute__((noreturn)) SYS_CoreShutdown(void); 39 | -------------------------------------------------------------------------------- /arm9/source/crypto/sha.c: -------------------------------------------------------------------------------- 1 | #include "sha.h" 2 | #include "mmio.h" 3 | 4 | typedef struct 5 | { 6 | u32 data[16]; 7 | } _sha_block; 8 | 9 | void sha_init(u32 mode) 10 | { 11 | while(*REG_SHACNT & 1); 12 | *REG_SHACNT = mode | SHA_CNT_OUTPUT_ENDIAN | SHA_NORMAL_ROUND; 13 | } 14 | 15 | void sha_update(const void* src, u32 size) 16 | { 17 | const u32* src32 = (const u32*)src; 18 | 19 | while(size >= 0x40) { 20 | while(*REG_SHACNT & 1); 21 | *((volatile _sha_block*)REG_SHAINFIFO) = *((const _sha_block*)src32); 22 | src32 += 16; 23 | size -= 0x40; 24 | } 25 | while(*REG_SHACNT & 1); 26 | if(size) iomemcpy((void*)REG_SHAINFIFO, src32, size); 27 | } 28 | 29 | void sha_get(void* res) { 30 | u32 hash_size = (*REG_SHACNT&SHA224_MODE) ? (224/8) : 31 | (*REG_SHACNT&SHA1_MODE) ? (160/8) : (256/8); 32 | *REG_SHACNT = (*REG_SHACNT & ~SHA_NORMAL_ROUND) | SHA_FINAL_ROUND; 33 | while(*REG_SHACNT & SHA_FINAL_ROUND); 34 | while(*REG_SHACNT & 1); 35 | if (hash_size) iomemcpy(res, (void*)REG_SHAHASH, hash_size); 36 | } 37 | 38 | void sha_quick(void* res, const void* src, u32 size, u32 mode) { 39 | sha_init(mode); 40 | sha_update(src, size); 41 | sha_get(res); 42 | } 43 | 44 | int sha_cmp(const void* sha, const void* src, u32 size, u32 mode) { 45 | u8 res[0x20]; 46 | sha_quick(res, src, size, mode); 47 | return memcmp(sha, res, 0x20); 48 | } 49 | -------------------------------------------------------------------------------- /arm9/source/system/mymalloc.c: -------------------------------------------------------------------------------- 1 | #include "mymalloc.h" 2 | #include 3 | 4 | static size_t total_allocated = 0; 5 | 6 | void* my_malloc(size_t size) { 7 | void* ptr = (void*) malloc(sizeof(size_t) + size); 8 | if (ptr) total_allocated += size; 9 | if (ptr) (*(size_t*) ptr) = size; 10 | return ptr ? (((char*) ptr) + sizeof(size_t)) : NULL; 11 | } 12 | 13 | void *my_realloc(void *ptr, size_t new_size) { 14 | if (!ptr) 15 | return my_malloc(new_size); 16 | 17 | if (ptr && !new_size) { 18 | my_free(ptr); 19 | return NULL; 20 | } 21 | 22 | void *real_ptr = (char*)ptr - sizeof(size_t); 23 | size_t old_size = *(size_t*)real_ptr; 24 | 25 | total_allocated -= old_size; 26 | total_allocated += new_size; 27 | 28 | void *new_ptr = realloc(real_ptr, new_size + sizeof(size_t)); 29 | if (new_ptr) { 30 | return (char*)new_ptr + sizeof(size_t); 31 | } 32 | 33 | return new_ptr; 34 | } 35 | 36 | void my_free(void* ptr) { 37 | void* ptr_fix = (char*) ptr - sizeof(size_t); 38 | total_allocated -= *(size_t*) ptr_fix; 39 | free(ptr_fix); 40 | } 41 | 42 | size_t mem_allocated(void) { 43 | return total_allocated; 44 | } 45 | 46 | size_t my_malloc_test(void) { 47 | size_t add = 1024 * 1024; 48 | for (size_t s = add;; s += add) { 49 | void* ptr = (void*) malloc(s); 50 | if (!ptr) return s; 51 | free(ptr); 52 | } 53 | return 0; // unreachable 54 | } 55 | -------------------------------------------------------------------------------- /arm11/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 2 | OUTPUT_ARCH(arm) 3 | ENTRY(__boot) 4 | 5 | MEMORY 6 | { 7 | AXIWRAM (RWX) : ORIGIN = 0x1FF80000, LENGTH = 128K 8 | HIGHRAM (RWX) : ORIGIN = 0xFFFF0000, LENGTH = 4K 9 | } 10 | 11 | SECTIONS 12 | { 13 | .vector : ALIGN(4K) 14 | { 15 | __vector_pa = LOADADDR(.vector); 16 | __vector_va = ABSOLUTE(.); 17 | KEEP(*(.vector)) 18 | . = ALIGN(4K); 19 | __vector_len = . - __vector_va; 20 | } >HIGHRAM AT>AXIWRAM 21 | 22 | .text : ALIGN(4K) 23 | { 24 | __text_pa = LOADADDR(.text); 25 | __text_va = ABSOLUTE(.); 26 | *(.text*) 27 | . = ALIGN(4K); 28 | __text_len = . - __text_va; 29 | } >AXIWRAM 30 | 31 | .data : ALIGN(4K) 32 | { 33 | __data_pa = LOADADDR(.data); 34 | __data_va = ABSOLUTE(.); 35 | *(.data*) 36 | . = ALIGN(4K); 37 | __data_len = . - __data_va; 38 | } >AXIWRAM 39 | 40 | .rodata : ALIGN(4K) 41 | { 42 | __rodata_pa = LOADADDR(.rodata); 43 | __rodata_va = ABSOLUTE(.); 44 | *(.rodata*) 45 | . = ALIGN(4K); 46 | __rodata_len = . - __rodata_va; 47 | } >AXIWRAM 48 | 49 | .bss (NOLOAD) : ALIGN(4K) 50 | { 51 | __bss_pa = LOADADDR(.bss); 52 | __bss_va = ABSOLUTE(.); 53 | *(.bss*) 54 | . = ALIGN(4K); 55 | __bss_len = . - __bss_va; 56 | } >AXIWRAM 57 | } 58 | -------------------------------------------------------------------------------- /arm11/source/arm/gic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2017-2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | #include 21 | 22 | typedef void (*IRQ_Handler)(u32 irqn); 23 | 24 | #define GIC_SOFTIRQ_SOURCE(n) (((n) >> 10) & 0xF) 25 | #define GIC_SOFTIRQ_NUMBER(n) ((n) & 0x3FF) 26 | 27 | enum { 28 | GIC_SOFTIRQ_NORMAL = 0, 29 | GIC_SOFTIRQ_NOTSELF = 1, 30 | GIC_SOFTIRQ_SELF = 2 31 | }; 32 | 33 | enum { 34 | GIC_HIGHEST_PRIO = 0x0, 35 | GIC_LOWEST_PRIO = 0xE, 36 | }; 37 | 38 | void GIC_GlobalReset(void); 39 | void GIC_LocalReset(void); 40 | 41 | int GIC_Enable(u32 irqn, u32 coremask, u32 prio, IRQ_Handler handler); 42 | int GIC_Disable(u32 irqn, u32 coremask); 43 | 44 | void GIC_TriggerSoftIRQ(u32 irqn, u32 mode, u32 coremask); 45 | -------------------------------------------------------------------------------- /arm9/source/common/hid.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include "hid_map.h" 6 | 7 | // see: http://3dbrew.org/wiki/CONFIG9_Registers 8 | // see: http://3dbrew.org/wiki/EMMC_Registers 9 | #define CART_STATE (~(*(volatile u8*)0x10000010) & 0x1) 10 | #define SD_STATE ((*(volatile u16*)0x1000601C) & (0x1<<5)) 11 | 12 | #define HID_RAW_TX(t) ((s32)(((t) / (1 << 16)) & 0xFFF)) 13 | #define HID_RAW_TY(t) ((s32)((t) & 0xFFF)) 14 | 15 | u32 HID_ReadState(void); 16 | 17 | // ts_raw is the raw touchscreen value obtained when pressing down 18 | // the touchscreen at the screen coordinates [screen_x, screen_y] 19 | // note: no point can be at the center 20 | typedef struct { 21 | u32 ts_raw; 22 | int screen_x, screen_y; 23 | } HID_CalibrationData; 24 | 25 | u32 HID_ReadRawTouchState(void); 26 | bool HID_ReadTouchState(u16 *x, u16 *y); 27 | bool HID_TouchCalibratedTransform(u32 ts, u16 *x, u16 *y); 28 | bool HID_SetCalibrationData(const HID_CalibrationData *calibs, u32 point_cnt, u32 screen_w, u32 screen_h); 29 | 30 | typedef struct { 31 | u16 x; 32 | u16 y; 33 | u16 w; 34 | u16 h; 35 | u32 id; // shouldn't be zero 36 | } TouchBox; 37 | 38 | // abstraction for HID_ReadTouchState, also returns touchbox id (if any) 39 | const TouchBox* TouchBoxGet(u32* id, const u16 x, const u16 y, const TouchBox* tbs, const u32 tbn); 40 | 41 | u32 InputWait(u32 timeout_sec); 42 | bool CheckButton(u32 button); 43 | 44 | void ButtonToString(u32 button, char* str); 45 | u32 StringToButton(char* str); 46 | -------------------------------------------------------------------------------- /arm11/source/arm/mmu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2018-2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | enum MMU_MemoryType { 24 | STRONGLY_ORDERED = 0, 25 | NON_CACHEABLE, 26 | DEVICE_SHARED, 27 | DEVICE_NONSHARED, 28 | CACHED_WT, 29 | CACHED_WB, 30 | CACHED_WB_ALLOC, 31 | MEMORY_TYPES, 32 | }; 33 | 34 | enum MMU_MemoryAccess { 35 | NO_ACCESS = 0, 36 | READ_ONLY, 37 | READ_WRITE, 38 | }; 39 | 40 | #define MMU_FLAGS(t, ap, nx, s) ((s) << 25 | (nx) << 24 | (ap) << 8 | (t)) 41 | 42 | #define MMU_FLAGS_TYPE(f) ((f) & 0xFF) 43 | #define MMU_FLAGS_ACCESS(f) (((f) >> 8) & 0xFF) 44 | 45 | #define MMU_FLAGS_NOEXEC(f) ((f) & BIT(24)) 46 | #define MMU_FLAGS_SHARED(f) ((f) & BIT(25)) 47 | 48 | u32 MMU_Map(u32 va, u32 pa, u32 size, u32 flags); 49 | void MMU_Init(void); 50 | -------------------------------------------------------------------------------- /arm9/source/game/ticket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define TICKET_SIZE sizeof(Ticket) 6 | #define TICKET_CDNCERT_SIZE 0x700 7 | 8 | #define TICKET_ISSUER "Root-CA00000003-XS0000000c" 9 | #define TICKET_ISSUER_DEV "Root-CA00000004-XS00000009" 10 | #define TICKET_SIG_TYPE 0x00, 0x01, 0x00, 0x04 // RSA_2048 SHA256 11 | 12 | #define TICKET_DEVKIT(tick) (strncmp((char*)tick->issuer, TICKET_ISSUER_DEV, 0x40) == 0) 13 | 14 | // from: https://github.com/profi200/Project_CTR/blob/02159e17ee225de3f7c46ca195ff0f9ba3b3d3e4/ctrtool/tik.h#L15-L39 15 | // all numbers in big endian 16 | typedef struct { 17 | u8 sig_type[4]; 18 | u8 signature[0x100]; 19 | u8 padding1[0x3C]; 20 | u8 issuer[0x40]; 21 | u8 ecdsa[0x3C]; 22 | u8 version; 23 | u8 ca_crl_version; 24 | u8 signer_crl_version; 25 | u8 titlekey[0x10]; 26 | u8 reserved0; 27 | u8 ticket_id[8]; 28 | u8 console_id[4]; 29 | u8 title_id[8]; 30 | u8 sys_access[2]; 31 | u8 ticket_version[2]; 32 | u8 time_mask[4]; 33 | u8 permit_mask[4]; 34 | u8 title_export; 35 | u8 commonkey_idx; 36 | u8 reserved1[0x2A]; 37 | u8 eshop_id[4]; 38 | u8 reserved2; 39 | u8 audit; 40 | u8 content_permissions[0x40]; 41 | u8 reserved3[2]; 42 | u8 timelimits[0x40]; 43 | u8 content_index[0xAC]; 44 | } __attribute__((packed, aligned(4))) Ticket; 45 | 46 | u32 ValidateTicket(Ticket* ticket); 47 | u32 ValidateTicketSignature(Ticket* ticket); 48 | u32 BuildFakeTicket(Ticket* ticket, u8* title_id); 49 | u32 BuildTicketCert(u8* tickcert); 50 | -------------------------------------------------------------------------------- /arm9/source/filesys/fatmbr.c: -------------------------------------------------------------------------------- 1 | #include "fatmbr.h" 2 | 3 | u32 ValidateMbrHeader(MbrHeader* mbr) { 4 | if (mbr->magic != FATMBR_MAGIC) return 1; // check magic 5 | u32 sector = 1; // check partitions 6 | for (u32 i = 0; i < 4; i++) { 7 | MbrPartitionInfo* partition = mbr->partitions + i; 8 | if (!partition->count && i) continue; 9 | else if (!partition->count) return 1; // first partition can't be empty 10 | if ((partition->type != 0x1) && (partition->type != 0x4) && (partition->type != 0x6) && 11 | (partition->type != 0xB) && (partition->type != 0xC) && (partition->type != 0xE)) 12 | return 1; // bad / unknown filesystem type 13 | if (partition->sector < sector) return 1; // overlapping partitions 14 | sector = partition->sector + partition->count; 15 | } 16 | return 0; 17 | } 18 | 19 | u32 ValidateFatHeader(void* fat) { 20 | if (getle16((u8*) fat + 0x1FE) != FATMBR_MAGIC) return 1; // check magic 21 | Fat32Header* fat32 = (Fat32Header*) fat; 22 | if (strncmp(fat32->fs_type, "FAT32 ", 8) == 0) 23 | return 0; // is FAT32 header 24 | Fat16Header* fat16 = (Fat16Header*) fat; 25 | if ((strncmp(fat16->fs_type, "FAT16 ", 8) == 0) || 26 | (strncmp(fat16->fs_type, "FAT12 ", 8) == 0) || 27 | (strncmp(fat16->fs_type, "FAT ", 8) == 0)) 28 | return 0; // is FAT16 / FAT12 header 29 | if ((getle64(fat16->fs_type) == 0) && (fat16->sct_size == 0x200)) 30 | return 0; // special case for public.sav 31 | return 1; // failed, not a FAT header 32 | } 33 | -------------------------------------------------------------------------------- /arm9/source/common/rtc.c: -------------------------------------------------------------------------------- 1 | #include "rtc.h" 2 | #include "i2c.h" 3 | 4 | bool is_valid_dstime(DsTime* dstime) { 5 | // check the time... 6 | if ((DSTIMEGET(dstime, bcd_h) >= 24) || 7 | (DSTIMEGET(dstime, bcd_m) >= 60) || 8 | (DSTIMEGET(dstime, bcd_s) >= 60)) 9 | return false; 10 | 11 | // check the date... 12 | u32 year = 2000 + DSTIMEGET(dstime, bcd_Y); 13 | u32 month = DSTIMEGET(dstime, bcd_M); 14 | u32 day = DSTIMEGET(dstime, bcd_D); 15 | 16 | // date: year & month 17 | if ((year >= 2100) || (month == 0) || (month > 12)) 18 | return false; 19 | 20 | // date: day 21 | // see: https://github.com/devkitPro/libnds/blob/9678bf09389cb1fcdc99dfa0357ec0cbe51dd0b7/source/arm7/clock.c#L224-L262 22 | u32 months_lastday[1+12] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 23 | u32 leap = (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) ? 1 : 0; 24 | u32 days_in_month = months_lastday[month] + ((month == 2) ? leap : 0); 25 | if (day > days_in_month) return false; 26 | 27 | return true; 28 | } 29 | 30 | bool get_dstime(DsTime* dstime) { 31 | return (I2C_readRegBuf(I2C_DEV_MCU, 0x30, (void*) dstime, sizeof(DsTime))); 32 | } 33 | 34 | bool set_dstime(DsTime* dstime) { 35 | if (!is_valid_dstime(dstime)) return false; 36 | for (u32 i = 0; i < sizeof(DsTime); i++) { 37 | if ((i == 3) || (i == 7)) continue; // skip the unused bytes 38 | if (!I2C_writeReg(I2C_DEV_MCU, 0x30+i, ((u8*)dstime)[i])) 39 | return false; 40 | } 41 | return true; 42 | } 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report a bug you found in GodMode9 4 | title: "[BUG] ..." 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | --- 11 | name: Bug report 12 | about: Report a bug you found 13 | title: "[BUG] ..." 14 | labels: bug 15 | assignees: '' 16 | 17 | --- 18 | 19 | **So you want to report a bug?** 20 | Hold on, there are ways you could make things easier for us: 21 | * Give a clear description of the bug (what happened?). 22 | * Give us clear steps to reproduce (when/how did it happen?). 23 | * Give us info about your system (where did it happen?). 24 | * A photograph or even a short video of the bug happening is always helpful! 25 | 26 | **Info about your system** 27 | Include this info to make our work easier: 28 | * Console type (O3DS/N3DS) 29 | * Anything special about your console? (defects, custom modifications,...) 30 | * Bootloader (boot9strap/fastboot3ds) 31 | * Did you chainload GodMode9 via Luma? 32 | * Helpful hint: *if you followed the Guide, boot9strap is your bootloader and Luma is your chainloader.* 33 | 34 | **Help yourself** 35 | *Especially for any kind of boot issue ("GodMode9 doesn't boot")*, but also in many other cases these steps make a lot of sense and we will ask you to do them anyways: 36 | * Check your SD card (using h2testw, f.e.) or try a different one (you wouldn't believe how common failing/fake SD cards are, and what kinds of bugs are caused by them). 37 | * Switch to fastboot3DS using [https://github.com/d0k3/OpenFirmInstaller](OpenFirmInstaller). 38 | 39 | **Have you actually read this?** 40 | [] I have read the information above 41 | -------------------------------------------------------------------------------- /arm9/source/game/smdh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "region.h" 5 | 6 | #define SMDH_MAGIC 'S', 'M', 'D', 'H' 7 | #define SMDH_SIZE_DESC_SHORT 64 8 | #define SMDH_SIZE_DESC_LONG 128 9 | #define SMDH_SIZE_PUBLISHER 64 10 | #define SMDH_DIM_ICON_SMALL 24 11 | #define SMDH_DIM_ICON_BIG 48 12 | #define SMDH_SIZE_ICON_SMALL (SMDH_DIM_ICON_SMALL * SMDH_DIM_ICON_SMALL * 2) // w * h * bpp (rgb565) 13 | #define SMDH_SIZE_ICON_BIG (SMDH_DIM_ICON_BIG * SMDH_DIM_ICON_BIG * 2) // w * h * bpp (rgb565) 14 | 15 | // see: https://www.3dbrew.org/wiki/SMDH#Application_Titles 16 | typedef struct { 17 | u16 short_desc[0x40]; 18 | u16 long_desc[0x80]; 19 | u16 publisher[0x40]; 20 | } PACKED_STRUCT SmdhAppTitle; 21 | 22 | // see: https://www.3dbrew.org/wiki/SMDH 23 | typedef struct { 24 | char magic[4]; 25 | u16 version; 26 | u16 reserved0; 27 | SmdhAppTitle apptitles[0x10]; // 1 -> english title 28 | u8 game_ratings[0x10]; 29 | u32 region_lockout; 30 | u32 matchmaker_id; 31 | u64 matchmaker_id_bit; 32 | u32 flags; 33 | u16 version_eula; 34 | u16 reserved1; 35 | u32 anim_def_frame; 36 | u32 cec_id; 37 | u64 reserved2; 38 | u16 icon_small[0x240]; // 24x24x16bpp / 8x8 tiles / rgb565 39 | u16 icon_big[0x900]; // 48x48x16bpp / 8x8 tiles / rgb565 40 | } PACKED_STRUCT Smdh; 41 | 42 | u32 GetSmdhDescShort(char* desc, const Smdh* smdh); 43 | u32 GetSmdhDescLong(char* desc, const Smdh* smdh); 44 | u32 GetSmdhPublisher(char* pub, const Smdh* smdh); 45 | u32 GetSmdhIconSmall(u16* icon, const Smdh* smdh); 46 | u32 GetSmdhIconBig(u16* icon, const Smdh* smdh); 47 | -------------------------------------------------------------------------------- /arm9/source/system/i2c.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "arm.h" 3 | 4 | #include "i2c.h" 5 | #include "pxi.h" 6 | 7 | // buffer is allocated only once and remains through runtime 8 | static char *i2c_xfer_buf = NULL; 9 | 10 | static bool I2C_AllocBuffer(void) 11 | { 12 | if (!i2c_xfer_buf) { 13 | u32 xbuf = PXI_DoCMD(PXI_XALLOC, (u32[]){256}, 1); 14 | if (xbuf == 0 || xbuf == 0xFFFFFFFF) 15 | return false; 16 | i2c_xfer_buf = (char*)xbuf; 17 | } 18 | 19 | return true; 20 | } 21 | 22 | bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size) 23 | { 24 | int ret; 25 | u32 *args; 26 | 27 | if (!I2C_AllocBuffer()) 28 | return false; 29 | 30 | args = (u32[]){devId, regAddr, (u32)i2c_xfer_buf, size}; 31 | 32 | ARM_WbDC_Range(i2c_xfer_buf, size); 33 | ARM_DSB(); 34 | 35 | ret = PXI_DoCMD(PXI_I2C_READ, args, 4); 36 | 37 | ARM_InvDC_Range(i2c_xfer_buf, size); 38 | memcpy(out, i2c_xfer_buf, size); 39 | return ret; 40 | } 41 | 42 | bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size) 43 | { 44 | int ret; 45 | u32 *args; 46 | 47 | if (!I2C_AllocBuffer()) 48 | return false; 49 | 50 | args = (u32[]){devId, regAddr, (u32)i2c_xfer_buf, size}; 51 | 52 | memcpy(i2c_xfer_buf, in, size); 53 | ARM_WbDC_Range(i2c_xfer_buf, size); 54 | ARM_DSB(); 55 | 56 | ret = PXI_DoCMD(PXI_I2C_WRITE, args, 4); 57 | return ret; 58 | } 59 | 60 | u8 I2C_readReg(I2cDevice devId, u8 regAddr) 61 | { 62 | u8 data; 63 | if (!I2C_readRegBuf(devId, regAddr, &data, 1)) 64 | data = 0xFF; 65 | return data; 66 | } 67 | 68 | bool I2C_writeReg(I2cDevice devId, u8 regAddr, u8 data) 69 | { 70 | return I2C_writeRegBuf(devId, regAddr, &data, 1); 71 | } 72 | -------------------------------------------------------------------------------- /arm9/source/game/boss.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define BOSS_MAGIC 0x62, 0x6F, 0x73, 0x73, 0x00, 0x01, 0x00, 0x01 6 | 7 | #define BOSS_OFFSET_PAYLOAD sizeof(BossHeader) 8 | #define BOSS_SIZE_PAYLOAD_HEADER (0x1C + 2) 9 | 10 | // see: http://3dbrew.org/wiki/SpotPass#BOSS_Header 11 | // and: http://3dbrew.org/wiki/SpotPass#Content_Header 12 | // and: http://3dbrew.org/wiki/SpotPass#Payload_Content_Header 13 | // everything is in big endian 14 | typedef struct { 15 | // actual BOSS header 16 | u8 magic[8]; // "boss" + 0x00010001, see above 17 | u8 filesize[4]; // big endian 18 | u8 release_date[8]; 19 | u8 unknown0[2]; // always 0x0001 20 | u8 padding[2]; 21 | u8 cnthdr_hash_type[2]; // always 0x0002 22 | u8 cnthdr_rsa_size[2]; // always 0x0002 23 | u8 ctr12[12]; // first 12 byte of ctr 24 | // content header, encryption starts here (0x28) 25 | u8 unknown1[0x10]; // usually 0x80 followed by 0x00 26 | u8 ext_info[2]; // for generating extdata filepath 27 | u8 hash_header[0x20]; 28 | u8 signature_header[0x100]; 29 | // payload header, first 0x1C byte used for hash (0x15A) 30 | u8 programId[8]; 31 | u8 unknown2[4]; // typically zero 32 | u8 data_type[4]; 33 | u8 size_payload[4]; 34 | u8 ns_dataId[4]; 35 | u8 unknown3[4]; 36 | u8 hash_payload[0x20]; 37 | u8 signature_payload[0x100]; 38 | } PACKED_STRUCT BossHeader; 39 | 40 | u32 ValidateBossHeader(BossHeader* header, u32 fsize); 41 | u32 GetBossPayloadHashHeader(u8* header, BossHeader* boss); 42 | u32 CheckBossEncrypted(BossHeader* boss); 43 | u32 CryptBoss(void* data, u32 offset, u32 size, BossHeader* boss); 44 | u32 CryptBossSequential(void* data, u32 offset, u32 size); 45 | -------------------------------------------------------------------------------- /arm11/source/arm/timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include "arm/gic.h" 23 | #include "arm/timer.h" 24 | 25 | #define TIMER_INTERRUPT (0x1E) 26 | 27 | #define REG_TIMER(c, n) REG_ARM_PMR(0x700 + ((c) * 0x100) + (n), u32) 28 | #define TIMER_THIS_CPU (-1) 29 | 30 | #define REG_TIMER_LOAD(c) *REG_TIMER((c), 0x00) 31 | #define REG_TIMER_COUNT(c) *REG_TIMER((c), 0x04) 32 | #define REG_TIMER_CNT(c) *REG_TIMER((c), 0x08) 33 | #define REG_TIMER_IRQ(c) *REG_TIMER((c), 0x0C) 34 | 35 | #define TIMER_CNT_SCALE(n) ((n) << 8) 36 | #define TIMER_CNT_INT_EN BIT(2) 37 | #define TIMER_CNT_RELOAD BIT(1) 38 | #define TIMER_CNT_ENABLE BIT(0) 39 | 40 | void TIMER_WaitTicks(u32 ticks) 41 | { 42 | REG_TIMER_IRQ(TIMER_THIS_CPU) = 1; 43 | REG_TIMER_CNT(TIMER_THIS_CPU) = 0; 44 | REG_TIMER_LOAD(TIMER_THIS_CPU) = ticks; 45 | REG_TIMER_CNT(TIMER_THIS_CPU) = TIMER_CNT_ENABLE; 46 | while(REG_TIMER_COUNT(TIMER_THIS_CPU)); 47 | } 48 | -------------------------------------------------------------------------------- /common/pxi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 d0k3, Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | void PXI_Barrier(u8 barrier_id) 23 | { 24 | PXI_SetRemote(barrier_id); 25 | PXI_WaitRemote(barrier_id); 26 | } 27 | 28 | void PXI_Reset(void) 29 | { 30 | *PXI_SYNC_IRQ = 0; 31 | *PXI_CNT = PXI_CNT_SEND_FIFO_FLUSH | PXI_CNT_ENABLE_FIFO; 32 | for (int i = 0; i < PXI_FIFO_LEN; i++) 33 | *PXI_RECV; 34 | 35 | *PXI_CNT = 0; 36 | *PXI_CNT = PXI_CNT_RECV_FIFO_AVAIL_IRQ | PXI_CNT_ENABLE_FIFO | 37 | PXI_CNT_ACKNOWLEDGE_ERROR; 38 | 39 | PXI_SetRemote(0xFF); 40 | } 41 | 42 | void PXI_SendArray(const u32 *w, u32 c) 43 | { 44 | while(c--) 45 | PXI_Send(*(w++)); 46 | } 47 | 48 | void PXI_RecvArray(u32 *w, u32 c) 49 | { 50 | while(c--) 51 | *(w++) = PXI_Recv(); 52 | } 53 | 54 | u32 PXI_DoCMD(u32 cmd, const u32 *args, u32 argc) 55 | { 56 | PXI_Send((argc << 16) | cmd); 57 | PXI_SendArray(args, argc); 58 | return PXI_Recv(); 59 | } 60 | -------------------------------------------------------------------------------- /arm9/source/gamecart/command_ctr.c: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Normmatt 2 | // Licensed under GPLv2 or any later version 3 | // Refer to the license.txt file included. 4 | 5 | #include "command_ctr.h" 6 | 7 | #include "protocol_ctr.h" 8 | 9 | static int read_count = 0; 10 | 11 | static void CTR_CmdC5() 12 | { 13 | static const u32 c5_cmd[4] = { 0xC5000000, 0x00000000, 0x00000000, 0x00000000 }; 14 | CTR_SendCommand(c5_cmd, 0, 1, 0x100002C, NULL); 15 | } 16 | 17 | void CTR_CmdReadData(u32 sector, u32 length, u32 blocks, void* buffer) 18 | { 19 | if(read_count++ > 10000) 20 | { 21 | CTR_CmdC5(); 22 | read_count = 0; 23 | } 24 | 25 | const u32 read_cmd[4] = { 26 | (0xBF000000 | (u32)(sector >> 23)), 27 | (u32)((sector << 9) & 0xFFFFFFFF), 28 | 0x00000000, 0x00000000 29 | }; 30 | CTR_SendCommand(read_cmd, length, blocks, 0x704822C, buffer); 31 | } 32 | 33 | void CTR_CmdReadHeader(void* buffer) 34 | { 35 | static const u32 readheader_cmd[4] = { 0x82000000, 0x00000000, 0x00000000, 0x00000000 }; 36 | CTR_SendCommand(readheader_cmd, 0x200, 1, 0x704802C, buffer); 37 | } 38 | 39 | void CTR_CmdReadUniqueID(void* buffer) 40 | { 41 | static const u32 readheader_cmd[4] = { 0xC6000000, 0x00000000, 0x00000000, 0x00000000 }; 42 | CTR_SendCommand(readheader_cmd, 0x40, 1, 0x903002C, buffer); 43 | } 44 | 45 | u32 CTR_CmdGetSecureId(u32 rand1, u32 rand2) 46 | { 47 | u32 id = 0; 48 | const u32 getid_cmd[4] = { 0xA2000000, 0x00000000, rand1, rand2 }; 49 | CTR_SendCommand(getid_cmd, 0x4, 1, 0x701002C, &id); 50 | return id; 51 | } 52 | 53 | void CTR_CmdSeed(u32 rand1, u32 rand2) 54 | { 55 | const u32 seed_cmd[4] = { 0x83000000, 0x00000000, rand1, rand2 }; 56 | CTR_SendCommand(seed_cmd, 0, 1, 0x700822C, NULL); 57 | } 58 | -------------------------------------------------------------------------------- /arm9/source/common/timer.c: -------------------------------------------------------------------------------- 1 | #include "timer.h" 2 | 3 | u64 timer_start( void ) { 4 | static bool timer_init = true; 5 | // timer is initialized at least once (right at the beginning) 6 | // this makes sure it is reinitialized in case of inconsistencies 7 | if (!(*TIMER_CNT0 & *TIMER_CNT1 & *TIMER_CNT2 & *TIMER_CNT3 & TIMER_ACTIVE) || 8 | !(*TIMER_CNT1 & *TIMER_CNT2 & *TIMER_CNT3 & TIMER_COUNT_UP)) 9 | timer_init = true; 10 | 11 | if (timer_init) { 12 | // deactivate, then reset timers 13 | *TIMER_CNT0 = 0; 14 | *TIMER_CNT1 = *TIMER_CNT2 = *TIMER_CNT3 = TIMER_COUNT_UP; 15 | *TIMER_VAL0 = *TIMER_VAL1 = *TIMER_VAL2 = *TIMER_VAL3 = 0; 16 | 17 | // start timers 18 | *TIMER_CNT0 = TIMER_ACTIVE; 19 | *TIMER_CNT1 = *TIMER_CNT2 = *TIMER_CNT3 = TIMER_ACTIVE | TIMER_COUNT_UP; 20 | 21 | // timer initialized 22 | timer_init = false; 23 | } 24 | return timer_ticks( 0 ); 25 | } 26 | 27 | /*void timer_stop( void ) { 28 | *TIMER_CNT0 &= ~TIMER_ACTIVE; 29 | *TIMER_CNT1 &= ~TIMER_ACTIVE; 30 | *TIMER_CNT2 &= ~TIMER_ACTIVE; 31 | *TIMER_CNT3 &= ~TIMER_ACTIVE; 32 | }*/ 33 | 34 | u64 timer_ticks( u64 start_time ) { 35 | u64 ticks = 0; 36 | ticks |= (u64) *TIMER_VAL0 << 0; 37 | ticks |= (u64) *TIMER_VAL1 << 16; 38 | ticks |= (u64) *TIMER_VAL2 << 32; 39 | ticks |= (u64) *TIMER_VAL3 << 48; 40 | return ticks - start_time; 41 | } 42 | 43 | u64 timer_msec( u64 start_time ) { 44 | return timer_ticks( start_time ) / (TICKS_PER_SEC/1000); 45 | } 46 | 47 | u64 timer_sec( u64 start_time ) { 48 | return timer_ticks( start_time ) / TICKS_PER_SEC; 49 | } 50 | 51 | void wait_msec( u64 msec ) { 52 | u64 timer = timer_start(); 53 | while (timer_msec( timer ) < msec ); 54 | } 55 | -------------------------------------------------------------------------------- /arm9/source/filesys/fsperm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | // permission types 6 | #define PERM_SDCARD (1UL<<0) 7 | #define PERM_IMAGE (1UL<<1) 8 | #define PERM_RAMDRIVE (1UL<<2) 9 | #define PERM_EMU_LVL0 (1UL<<3) 10 | #define PERM_EMU_LVL1 (PERM_EMU_LVL0|(1UL<<4)) 11 | #define PERM_SYS_LVL0 (1UL<<5) 12 | #define PERM_SYS_LVL1 (PERM_SYS_LVL0|(1UL<<6)) 13 | #define PERM_SYS_LVL2 (PERM_SYS_LVL1|(1UL<<7)) 14 | #define PERM_SYS_LVL3 (PERM_SYS_LVL2|(1UL<<8)) 15 | #define PERM_SDDATA (PERM_SDCARD|(1UL<<9)) 16 | #define PERM_MEMORY (1UL<<10) 17 | #define PERM_GAME (1UL<<11) // can't be enabled, placeholder 18 | #define PERM_XORPAD (1UL<<12) // can't be enabled, placeholder 19 | #define PERM_CART (1UL<<13) 20 | #define PERM_VRAM (1UL<<14) // can't be enabled, placeholder 21 | #define PERM_BASE (PERM_SDCARD | PERM_IMAGE | PERM_RAMDRIVE | PERM_EMU_LVL0 | PERM_SYS_LVL0) 22 | 23 | // permission levels / colors 24 | #define PERM_BLUE (GetWritePermissions()&PERM_MEMORY) 25 | #define PERM_RED (GetWritePermissions()&(PERM_SYS_LVL3&~PERM_SYS_LVL2)) 26 | #define PERM_ORANGE (GetWritePermissions()&(PERM_SYS_LVL2&~PERM_SYS_LVL1)) 27 | #define PERM_YELLOW (GetWritePermissions()&((PERM_SYS_LVL1&~PERM_SYS_LVL0)|(PERM_EMU_LVL1&~PERM_EMU_LVL0)|(PERM_SDDATA&~PERM_SDCARD)|PERM_CART)) 28 | #define PERM_GREEN (GetWritePermissions()&(PERM_SDCARD|PERM_IMAGE|PERM_RAMDRIVE|PERM_EMU_LVL0|PERM_SYS_LVL0)) 29 | 30 | /** Check if writing to this path is allowed **/ 31 | bool CheckWritePermissions(const char* path); 32 | 33 | /** Same as above, but for all containing objects **/ 34 | bool CheckDirWritePermissions(const char* path); 35 | 36 | /** Set new write permissions */ 37 | bool SetWritePermissions(u32 perm, bool add_perm); 38 | 39 | /** Get write permissions */ 40 | u32 GetWritePermissions(); 41 | -------------------------------------------------------------------------------- /arm9/source/game/tad.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "nds.h" 5 | 6 | #define TAD_NUM_CONTENT 11 7 | #define TAD_HEADER_MAGIC "3FDT" 8 | #define TAD_BANNER_OFFSET 0 9 | #define TAD_BANNER_LEN (sizeof(TadBanner) + sizeof(TadBlockMetaData)) 10 | #define TAD_HEADER_OFFSET (TAD_BANNER_OFFSET + TAD_BANNER_LEN) 11 | #define TAD_HEADER_LEN (sizeof(TadHeader) + sizeof(TadBlockMetaData)) 12 | 13 | 14 | typedef struct { 15 | u32 banner_end; 16 | u32 header_end; 17 | u32 footer_end; 18 | u32 content_end[TAD_NUM_CONTENT]; 19 | } PACKED_STRUCT TadContentTable; 20 | 21 | // see: https://www.3dbrew.org/wiki/DSiWare_Exports#Block_Metadata 22 | typedef struct { 23 | u8 cmac[16]; 24 | u8 iv0[16]; 25 | } PACKED_STRUCT TadBlockMetaData; 26 | 27 | // see: https://www.3dbrew.org/wiki/DSiWare_Exports#File_Structure_v2 28 | typedef struct { 29 | TwlIconData icon_data; 30 | u8 unknown[0x4000 - sizeof(TwlIconData)]; 31 | } PACKED_STRUCT TadBanner; 32 | 33 | // see: https://www.3dbrew.org/wiki/DSiWare_Exports#Header_2 34 | typedef struct { 35 | char magic[4]; // "3FDT" 36 | u16 group_id; 37 | u16 title_version; 38 | u8 movable_enc_sha256[0x20]; 39 | u8 cbc_test_block[0x10]; 40 | u64 title_id; 41 | u64 unknown0; 42 | u32 content_size[TAD_NUM_CONTENT]; 43 | u8 unknown1[0x30]; 44 | u8 tmd_reserved[0x3E]; 45 | u8 padding[0x0E]; 46 | } PACKED_STRUCT TadHeader; 47 | 48 | // see: https://www.3dbrew.org/wiki/DSiWare_Exports#Footer 49 | typedef struct { 50 | u8 banner_sha256[0x20]; 51 | u8 header_sha256[0x20]; 52 | u8 content_sha256[TAD_NUM_CONTENT][0x20]; 53 | u8 ecdsa_signature[0x3C]; 54 | u8 ecdsa_apcert[0x180]; 55 | u8 ecdsa_ctcert[0x180]; 56 | u8 padding[0x4]; 57 | } PACKED_STRUCT TadFooter; 58 | 59 | u32 BuildTadContentTable(void* table, void* header); 60 | -------------------------------------------------------------------------------- /arm11/source/hw/mcu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "hw/i2c.h" 24 | 25 | #define MCU_INTERRUPT (0x71) 26 | #define I2C_MCU_DEVICE (3) 27 | 28 | u8 MCU_GetVolumeSlider(void); 29 | u32 MCU_GetSpecialHID(void); 30 | 31 | void MCU_SetNotificationLED(u32 period_ms, u32 color); 32 | void MCU_ResetLED(void); 33 | 34 | void MCU_PushToLCD(bool enable); 35 | 36 | void MCU_HandleInterrupts(u32 irqn); 37 | 38 | void MCU_Init(void); 39 | 40 | static inline u8 MCU_ReadReg(u8 addr) 41 | { 42 | u8 val; 43 | I2C_readRegBuf(I2C_MCU_DEVICE, addr, &val, 1); 44 | return val; 45 | } 46 | 47 | static inline bool MCU_ReadRegBuf(u8 addr, u8 *buf, u32 size) 48 | { 49 | return I2C_readRegBuf(I2C_MCU_DEVICE, addr, buf, size); 50 | } 51 | 52 | static inline bool MCU_WriteReg(u8 addr, u8 val) 53 | { 54 | return I2C_writeRegBuf(I2C_MCU_DEVICE, addr, &val, 1); 55 | } 56 | 57 | static inline bool MCU_WriteRegBuf(u8 addr, const u8 *buf, u32 size) 58 | { 59 | return I2C_writeRegBuf(I2C_MCU_DEVICE, addr, buf, size); 60 | } 61 | -------------------------------------------------------------------------------- /arm9/source/system/png.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "lodepng.h" 5 | #include "png.h" 6 | 7 | // dest and src can be the same 8 | static inline void _rgb24_to_rgb565(u16 *dest, const u8 *src, size_t dim) 9 | { 10 | for (size_t i = 0; i < dim; i++) { 11 | u8 r, g, b; 12 | 13 | r = *(src++) >> 3; 14 | g = *(src++) >> 2; 15 | b = *(src++) >> 3; 16 | *(dest++) = r << 11 | g << 5 | b; 17 | } 18 | } 19 | 20 | // dest and src CAN NOT be the same 21 | static inline void _rgb565_to_rgb24(u8 *dest, const u16 *src, size_t dim) 22 | { 23 | for (size_t i = 0; i < dim; i++) { 24 | u16 rgb = *(src++); 25 | 26 | *(dest++) = (rgb >> 11) << 3; 27 | *(dest++) = ((rgb >> 5) & 0x3F) << 2; 28 | *(dest++) = (rgb & 0x1F) << 3; 29 | } 30 | } 31 | 32 | u16 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h) 33 | { 34 | u16 *img; 35 | unsigned res; 36 | size_t width, height; 37 | 38 | img = NULL; 39 | res = lodepng_decode24((u8**)&img, &width, &height, png, png_len); 40 | if (res) { 41 | free(img); 42 | return NULL; 43 | } 44 | 45 | _rgb24_to_rgb565(img, (const u8*)img, width * height); 46 | if (w) *w = width; 47 | if (h) *h = height; 48 | 49 | // the allocated buffer will be w*h*3 bytes long, but only w*h*2 bytes will be used 50 | // however, this is not a problem and it'll all be freed with a regular free() call 51 | return (u16*)img; 52 | } 53 | 54 | u8 *PNG_Compress(const u16 *fb, u32 w, u32 h, size_t *png_sz) 55 | { 56 | u8 *img, *buf; 57 | unsigned res; 58 | size_t png_size; 59 | 60 | img = NULL; 61 | 62 | buf = malloc(w * h * 3); 63 | if (!buf) return NULL; 64 | 65 | _rgb565_to_rgb24(buf, fb, w * h); 66 | res = lodepng_encode24(&img, &png_size, buf, w, h); 67 | free(buf); 68 | 69 | if (res) { 70 | free(img); 71 | return NULL; 72 | } 73 | 74 | if (png_sz) 75 | *png_sz = png_size; 76 | 77 | return img; 78 | } 79 | -------------------------------------------------------------------------------- /arm9/source/gamecart/protocol_ctr.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Normmatt 2 | // Licensed under GPLv2 or any later version 3 | // Refer to the license.txt file included. 4 | 5 | #pragma once 6 | 7 | #include "common.h" 8 | 9 | #define REG_CTRCARDCNT (*(vu32*)0x10004000) 10 | #define REG_CTRCARDBLKCNT (*(vu32*)0x10004004) 11 | #define REG_CTRCARDSECCNT (*(vu32*)0x10004008) 12 | #define REG_CTRCARDSECSEED (*(vu32*)0x10004010) 13 | #define REG_CTRCARDCMD ((vu32*)0x10004020) 14 | #define REG_CTRCARDFIFO (*(vu32*)0x10004030) 15 | 16 | #define CTRCARD_PAGESIZE_0 (0<<16) 17 | #define CTRCARD_PAGESIZE_4 (1u<<16) 18 | #define CTRCARD_PAGESIZE_16 (2u<<16) 19 | #define CTRCARD_PAGESIZE_64 (3u<<16) 20 | #define CTRCARD_PAGESIZE_512 (4u<<16) 21 | #define CTRCARD_PAGESIZE_1K (5u<<16) 22 | #define CTRCARD_PAGESIZE_2K (6u<<16) 23 | #define CTRCARD_PAGESIZE_4K (7u<<16) 24 | #define CTRCARD_PAGESIZE_16K (8u<<16) 25 | #define CTRCARD_PAGESIZE_64K (9u<<16) 26 | 27 | #define CTRCARD_CRC_ERROR (1u<<4) 28 | #define CTRCARD_ACTIVATE (1u<<31) // when writing, get the ball rolling 29 | #define CTRCARD_IE (1u<<30) // Interrupt enable 30 | #define CTRCARD_WR (1u<<29) // Card write enable 31 | #define CTRCARD_nRESET (1u<<28) // value on the /reset pin (1 = high out, not a reset state, 0 = low out = in reset) 32 | #define CTRCARD_BLK_SIZE(n) (((n)&0xFu)<<16) // Transfer block size 33 | 34 | #define CTRCARD_BUSY (1u<<31) // when reading, still expecting incomming data? 35 | #define CTRCARD_DATA_READY (1u<<27) // when reading, REG_CTRCARDFIFO has another word of data and is good to go 36 | 37 | #define CTRKEY_PARAM 0x1000000u 38 | 39 | void CTR_SetSecKey(u32 value); 40 | void CTR_SetSecSeed(const u32* seed, bool flag); 41 | 42 | void CTR_SendCommand(const u32 command[4], u32 pageSize, u32 blocks, u32 latency, void* buffer); 43 | -------------------------------------------------------------------------------- /arm9/source/game/ticketdb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "ticket.h" 5 | 6 | #define TIKDB_NAME_ENC "encTitleKeys.bin" 7 | #define TIKDB_NAME_DEC "decTitleKeys.bin" 8 | #define TIKDB_SIZE(tdb) (16 + ((tdb)->n_entries * sizeof(TitleKeyEntry))) 9 | 10 | #define TICKDB_PATH(emu) ((emu) ? "4:/dbs/ticket.db" : "1:/dbs/ticket.db") // EmuNAND / SysNAND 11 | #define TICKDB_AREA_OFFSET 0xA1C00 // offset inside the decoded DIFF partition 12 | #define TICKDB_AREA_RAW 0x0137F000, 0x001C0C00 // raw offsets inside the file 13 | #define TICKDB_AREA_SIZE 0x00500000 // 5MB, arbitrary (around 1MB is realistic) 14 | 15 | #define TICKDB_MAGIC 0x44, 0x49, 0x46, 0x46, 0x00, 0x00, 0x03, 0x00, \ 16 | 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 17 | 0x30, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 18 | 0x2C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 19 | 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 20 | 0x00, 0xEE, 0x37, 0x02, 0x00, 0x00, 0x00, 0x00 21 | 22 | 23 | typedef struct { 24 | u32 commonkey_idx; 25 | u8 reserved[4]; 26 | u8 title_id[8]; 27 | u8 titlekey[16]; 28 | } PACKED_STRUCT TitleKeyEntry; 29 | 30 | typedef struct { 31 | u32 n_entries; 32 | u8 reserved[12]; 33 | TitleKeyEntry entries[256]; // this number is only a placeholder 34 | } PACKED_STRUCT TitleKeysInfo; 35 | 36 | 37 | u32 GetTitleKey(u8* titlekey, Ticket* ticket); 38 | Ticket* TicketFromTickDbChunk(u8* chunk, u8* title_id, bool legit_pls); 39 | u32 FindTicket(Ticket* ticket, u8* title_id, bool force_legit, bool emunand); 40 | u32 FindTitleKey(Ticket* ticket, u8* title_id); 41 | u32 AddTitleKeyToInfo(TitleKeysInfo* tik_info, TitleKeyEntry* tik_entry, bool decrypted_in, bool decrypted_out, bool devkit); 42 | u32 AddTicketToInfo(TitleKeysInfo* tik_info, Ticket* ticket, bool decrypt); 43 | -------------------------------------------------------------------------------- /arm9/source/filesys/vff.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "sddata.h" 5 | #include "ff.h" 6 | 7 | #define AM_VRT 0x40 // Virtual (FILINFO FAT attribute) 8 | 9 | #define fvx_tell(fp) ((fp)->fptr) 10 | #define fvx_size(fp) ((fp)->obj.objsize) 11 | 12 | #define FN_ANY 0x00 13 | #define FN_HIGHEST 0x01 14 | #define FN_LOWEST 0x02 15 | 16 | // wrapper functions for ff.h + sddata.h 17 | // incomplete(!) extension to FatFS to support a common interface for virtual and FAT 18 | FRESULT fvx_open (FIL* fp, const TCHAR* path, BYTE mode); 19 | FRESULT fvx_read (FIL* fp, void* buff, UINT btr, UINT* br); 20 | FRESULT fvx_write (FIL* fp, const void* buff, UINT btw, UINT* bw); 21 | FRESULT fvx_close (FIL* fp); 22 | FRESULT fvx_lseek (FIL* fp, FSIZE_t ofs); 23 | FRESULT fvx_sync (FIL* fp); 24 | FRESULT fvx_stat (const TCHAR* path, FILINFO* fno); 25 | FRESULT fvx_rename (const TCHAR* path_old, const TCHAR* path_new); 26 | FRESULT fvx_unlink (const TCHAR* path); 27 | FRESULT fvx_mkdir (const TCHAR* path); 28 | FRESULT fvx_opendir (DIR* dp, const TCHAR* path); 29 | FRESULT fvx_closedir (DIR* dp); 30 | FRESULT fvx_readdir (DIR* dp, FILINFO* fno); 31 | 32 | // additional quick read / write functions 33 | FRESULT fvx_qread (const TCHAR* path, void* buff, FSIZE_t ofs, UINT btr, UINT* br); 34 | FRESULT fvx_qwrite (const TCHAR* path, const void* buff, FSIZE_t ofs, UINT btw, UINT* bw); 35 | 36 | // additional quick file info functions 37 | FSIZE_t fvx_qsize (const TCHAR* path); 38 | 39 | // additional recursive functions 40 | FRESULT fvx_rmkdir (const TCHAR* path); 41 | FRESULT fvx_rmkpath (const TCHAR* path); 42 | FRESULT fvx_runlink (const TCHAR* path); 43 | 44 | // additional wildcard based functions 45 | FRESULT fvx_match_name(const TCHAR* path, const TCHAR* pattern); 46 | FRESULT fvx_preaddir (DIR* dp, FILINFO* fno, const TCHAR* pattern); 47 | FRESULT fvx_findpath (TCHAR* path, const TCHAR* pattern, BYTE mode); 48 | FRESULT fvx_findnopath (TCHAR* path, const TCHAR* pattern); 49 | -------------------------------------------------------------------------------- /arm11/source/hw/hid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "hw/codec.h" 24 | #include "hw/hid.h" 25 | #include "hw/mcu.h" 26 | 27 | #define REG_HID (~(*(vu16*)(0x10146000)) & BUTTON_ANY) 28 | 29 | static u32 HID_ConvertCPAD(s16 cpad_x, s16 cpad_y) 30 | { 31 | u32 ret = 0; 32 | 33 | switch(int_sign(cpad_x)) { 34 | default: 35 | break; 36 | case 1: 37 | ret |= BUTTON_RIGHT; 38 | break; 39 | case -1: 40 | ret |= BUTTON_LEFT; 41 | } 42 | 43 | switch(int_sign(cpad_y)) { 44 | default: 45 | break; 46 | case 1: 47 | ret |= BUTTON_UP; 48 | break; 49 | case -1: 50 | ret |= BUTTON_DOWN; 51 | } 52 | 53 | return ret; 54 | } 55 | 56 | u64 HID_GetState(void) 57 | { 58 | CODEC_Input codec; 59 | u64 ret = 0; 60 | 61 | CODEC_Get(&codec); 62 | 63 | ret = REG_HID | MCU_GetSpecialHID(); 64 | if (!(ret & BUTTON_ARROW)) 65 | ret |= HID_ConvertCPAD(codec.cpad_x, codec.cpad_y); 66 | 67 | if (codec.ts_x <= 0xFFF) 68 | ret |= BUTTON_TOUCH; 69 | 70 | ret |= (((u64)codec.ts_x << 16) | (u64)codec.ts_y) << 32; 71 | 72 | return ret; 73 | } 74 | -------------------------------------------------------------------------------- /arm9/source/fatfs/LICENSE.txt: -------------------------------------------------------------------------------- 1 | FatFs License 2 | 3 | FatFs has being developped as a personal project of the author, ChaN. It is free from the code anyone else wrote at current release. Following code block shows a copy of the FatFs license document that heading the source files. 4 | 5 | /*----------------------------------------------------------------------------/ 6 | / FatFs - Generic FAT Filesystem Module Rx.xx / 7 | /-----------------------------------------------------------------------------/ 8 | / 9 | / Copyright (C) 20xx, ChaN, all right reserved. 10 | / 11 | / FatFs module is an open source software. Redistribution and use of FatFs in 12 | / source and binary forms, with or without modification, are permitted provided 13 | / that the following condition is met: 14 | / 15 | / 1. Redistributions of source code must retain the above copyright notice, 16 | / this condition and the following disclaimer. 17 | / 18 | / This software is provided by the copyright holder and contributors "AS IS" 19 | / and any warranties related to this software are DISCLAIMED. 20 | / The copyright owner or contributors be NOT LIABLE for any damages caused 21 | / by use of this software. 22 | /----------------------------------------------------------------------------*/ 23 | 24 | Therefore FatFs license is one of the BSD-style licenses but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, does not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most of open source software licenses including GNU GPL. When you redistribute the FatFs source code with any changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software license that not conflict with FatFs license. 25 | -------------------------------------------------------------------------------- /arm9/source/filesys/fsgame.c: -------------------------------------------------------------------------------- 1 | #include "fsgame.h" 2 | #include "fsperm.h" 3 | #include "gameutil.h" 4 | #include "ui.h" 5 | #include "ff.h" 6 | 7 | void SetDirGoodNames(DirStruct* contents) { 8 | char goodname[256]; 9 | ShowProgress(0, 0, ""); 10 | for (u32 s = 0; s < contents->n_entries; s++) { 11 | DirEntry* entry = &(contents->entry[s]); 12 | u32 plen = strnlen(entry->path, 256); 13 | if (!ShowProgress(s+1, contents->n_entries, entry->path)) break; 14 | if ((GetGoodName(goodname, entry->path, false) != 0) || 15 | (plen + 1 + strnlen(goodname, 256) + 1 > 256)) 16 | continue; 17 | entry->p_name = plen + 1; 18 | entry->name = entry->path + entry->p_name; 19 | snprintf(entry->name, 256 - entry->p_name, "%s", goodname); 20 | } 21 | } 22 | 23 | bool GoodRenamer(DirEntry* entry, bool ask) { 24 | char goodname[256]; // get goodname 25 | if ((GetGoodName(goodname, entry->path, false) != 0) || 26 | (strncmp(goodname + strnlen(goodname, 256) - 4, ".tmd", 4) == 0)) // no TMD, please 27 | return false; 28 | 29 | if (ask) { // ask for confirmatiom 30 | char oldname_tr[32+1]; 31 | char newname_ww[256]; 32 | TruncateString(oldname_tr, entry->name, 32, 8); 33 | strncpy(newname_ww, goodname, 256); 34 | WordWrapString(newname_ww, 32); 35 | if (!ShowPrompt(true, "%s\nRename to good name?\n \n%s", oldname_tr, newname_ww)) 36 | return true; // call it a success because user choice 37 | } 38 | 39 | char npath[256]; // get new path 40 | strncpy(npath, entry->path, 256); 41 | char* nname = strrchr(npath, '/'); 42 | if (!nname) return false; 43 | nname++; 44 | strncpy(nname, goodname, 256 - 1 - (nname - npath)); 45 | // actual rename 46 | if (!CheckDirWritePermissions(entry->path)) return false; 47 | if (f_rename(entry->path, npath) != FR_OK) return false; 48 | strncpy(entry->path, npath, 256); 49 | entry->name = entry->path + (nname - npath); 50 | 51 | return true; 52 | } 53 | -------------------------------------------------------------------------------- /common/fixp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | // Fixed point math operations 22 | 23 | #include 24 | #include 25 | 26 | typedef int32_t fixp_t; 27 | 28 | // 12 bit precision was chosen because 29 | // that's the touchscreen's ADC resolution 30 | #define FIXP_PRECISION (12) 31 | 32 | #define INT_TO_FIXP(i) ((fixp_t)((i) * (1 << FIXP_PRECISION))) 33 | #define FIXP_TO_INT(f) ((fixp_t)((f) / (1 << FIXP_PRECISION))) 34 | 35 | #define FIXP_WHOLE_UNIT INT_TO_FIXP(1) 36 | #define FIXP_HALF_UNIT (FIXP_WHOLE_UNIT / 2) 37 | #define FIXP_ZERO_UNIT (0) 38 | 39 | #define FIXP_FRAC_MASK (FIXP_WHOLE_UNIT - 1) 40 | #define FIXP_UNIT_MASK (~FIXP_FRAC_MASK) 41 | 42 | static inline fixp_t fixp_product(fixp_t a, fixp_t b) 43 | { 44 | return (((s64)a * (s64)b) >> FIXP_PRECISION); 45 | } 46 | 47 | static inline fixp_t fixp_quotient(fixp_t a, fixp_t b) 48 | { 49 | return ((s64)a << FIXP_PRECISION) / b; 50 | } 51 | 52 | static inline fixp_t fixp_round(fixp_t n) 53 | { 54 | return (n + FIXP_HALF_UNIT) & FIXP_UNIT_MASK; 55 | } 56 | 57 | static inline fixp_t fixp_changespace(fixp_t n, fixp_t lower_s, fixp_t upper_s, fixp_t lower_d, fixp_t upper_d) 58 | { 59 | return fixp_product(n - lower_s, fixp_quotient(upper_d, upper_s)) + lower_d; 60 | } 61 | -------------------------------------------------------------------------------- /arm9/source/system/memmap.h: -------------------------------------------------------------------------------- 1 | # pragma once 2 | 3 | 4 | // general memory areas 5 | 6 | #define __ITCM_ADDR 0x01FF8000 7 | #define __ITCM_LEN 0x00008000 8 | 9 | #define __DTCM_ADDR 0x30008000 10 | #define __DTCM_LEN 0x00004000 11 | 12 | #define __A9RAM0_ADDR 0x08000000 13 | #define __A9RAM0_LEN 0x00100000 14 | 15 | #define __A9RAM1_ADDR 0x08100000 16 | #define __A9RAM1_LEN 0x00080000 17 | 18 | #define __VRAM_ADDR 0x18000000 19 | #define __VRAM_LEN 0x00600000 20 | 21 | #define __DSP_ADDR 0x1FF00000 22 | #define __DSP_LEN 0x00080000 23 | 24 | #define __AWRAM_ADDR 0x1FF80000 25 | #define __AWRAM_LEN 0x00080000 26 | 27 | #define __OTP_ADDR 0x10012000 28 | #define __OTP_LEN 0x00000100 29 | 30 | #define __FCRAM0_ADDR 0x20000000 31 | #define __FCRAM0_END 0x28000000 32 | #define __FCRAM0_LEN (__FCRAM0_END - __FCRAM0_ADDR) 33 | 34 | #define __FCRAM1_ADDR 0x28000000 35 | #define __FCRAM1_END 0x30000000 36 | #define __FCRAM1_LEN (__FCRAM1_END - __FCRAM1_ADDR) 37 | 38 | 39 | // offsets provided by SciresM, only available if booted on b9s 40 | 41 | #define __BOOT9_ADDR 0x08080000 42 | #define __BOOT9_LEN 0x00010000 43 | 44 | #define __BOOT11_ADDR 0x08090000 45 | #define __BOOT11_LEN 0x00010000 46 | 47 | 48 | // stuff in FCRAM 49 | // FCRAM0 0x0000...0x1000 is unused 50 | // see: https://www.3dbrew.org/wiki/FIRM#FIRM_Launch_Parameters 51 | 52 | #define __FIRMRAM_ADDR (__FCRAM0_ADDR + 0x0001000) 53 | #define __FIRMRAM_END (__FIRMRAM_ADDR + 0x0400000) 54 | 55 | #define __FIRMTMP_ADDR (__FCRAM0_END - 0x0800000) 56 | #define __FIRMTMP_END (__FIRMTMP_ADDR + 0x0400000) 57 | 58 | #define __RAMDRV_ADDR (__FCRAM0_ADDR + 0x2800000) 59 | #define __RAMDRV_END __FCRAM0_END 60 | #define __RAMDRV_END_N __FCRAM1_END 61 | 62 | #define __STACK_ABT_TOP __RAMDRV_ADDR 63 | #define __STACK_ABT_LEN 0x10000 64 | 65 | #define __STACK_TOP (__STACK_ABT_TOP - __STACK_ABT_LEN) 66 | #define __STACK_LEN 0x7F0000 67 | 68 | #define __HEAP_ADDR (__FCRAM0_ADDR + 0x0001000) 69 | #define __HEAP_END (__STACK_TOP - __STACK_LEN) 70 | -------------------------------------------------------------------------------- /arm9/source/gamecart/command_ntr.c: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Normmatt 2 | // Licensed under GPLv2 or any later version 3 | // Refer to the license.txt file included. 4 | // 5 | // modifyed by osilloscopion (2 Jul 2016) 6 | // 7 | 8 | #include "command_ntr.h" 9 | #include "protocol_ntr.h" 10 | #include "card_ntr.h" 11 | #include "delay.h" 12 | 13 | 14 | u32 ReadDataFlags = 0; 15 | 16 | void NTR_CmdReset(void) 17 | { 18 | cardReset (); 19 | ioDelay2(0xF000); 20 | } 21 | 22 | u32 NTR_CmdGetCartId(void) 23 | { 24 | return cardReadID (0); 25 | } 26 | 27 | void NTR_CmdEnter16ByteMode(void) 28 | { 29 | static const u32 enter16bytemode_cmd[2] = { 0x3E000000, 0x00000000 }; 30 | NTR_SendCommand(enter16bytemode_cmd, 0x0, 0, NULL); 31 | } 32 | 33 | void NTR_CmdReadHeader (u8* buffer) 34 | { 35 | REG_NTRCARDROMCNT=0; 36 | REG_NTRCARDMCNT=0; 37 | ioDelay2(167550); 38 | REG_NTRCARDMCNT=NTRCARD_CR1_ENABLE|NTRCARD_CR1_IRQ; 39 | REG_NTRCARDROMCNT=NTRCARD_nRESET|NTRCARD_SEC_SEED; 40 | while(REG_NTRCARDROMCNT&NTRCARD_BUSY) ; 41 | cardReset(); 42 | while(REG_NTRCARDROMCNT&NTRCARD_BUSY) ; 43 | u32 iCardId=cardReadID(NTRCARD_CLK_SLOW); 44 | while(REG_NTRCARDROMCNT&NTRCARD_BUSY) ; 45 | 46 | u32 iCheapCard=iCardId&0x80000000; 47 | 48 | if(iCheapCard) 49 | { 50 | //this is magic of wood goblins 51 | for(size_t ii=0;ii<8;++ii) 52 | cardParamCommand(NTRCARD_CMD_HEADER_READ,ii*0x200,NTRCARD_ACTIVATE|NTRCARD_nRESET|NTRCARD_CLK_SLOW|NTRCARD_BLK_SIZE(1)|NTRCARD_DELAY1(0x1FFF)|NTRCARD_DELAY2(0x3F),(u32*)(void*)(buffer+ii*0x200),0x200/sizeof(u32)); 53 | } 54 | else 55 | { 56 | //0xac3f1fff 57 | cardParamCommand(NTRCARD_CMD_HEADER_READ,0,NTRCARD_ACTIVATE|NTRCARD_nRESET|NTRCARD_CLK_SLOW|NTRCARD_BLK_SIZE(4)|NTRCARD_DELAY1(0x1FFF)|NTRCARD_DELAY2(0x3F),(u32*)(void*)buffer,0x1000/sizeof(u32)); 58 | } 59 | //cardReadHeader (buffer); 60 | } 61 | 62 | void NTR_CmdReadData (u32 offset, void* buffer) 63 | { 64 | cardParamCommand (NTRCARD_CMD_DATA_READ, offset, ReadDataFlags | NTRCARD_ACTIVATE | NTRCARD_nRESET | NTRCARD_BLK_SIZE(1), (u32*)buffer, 0x200 / 4); 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /arm9/source/nand/essentials.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "exefs.h" 5 | 6 | #define ESSENTIAL_NAME "essential.exefs" 7 | 8 | // magic number for essential backup 9 | #define ESSENTIAL_MAGIC 'n', 'a', 'n', 'd', '_', 'h', 'd', 'r', 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00 10 | 11 | // size of /ro/sys/HWCAL0.dat and /ro/sys/HWCAL1.dat 12 | #define SIZE_HWCAL 0x9D0 13 | 14 | // /rw/sys/LocalFriendCodeSeed_B (/_A) file 15 | // see: http://3dbrew.org/wiki/Nandrw/sys/LocalFriendCodeSeed_B 16 | typedef struct { 17 | u8 signature[0x100]; 18 | u8 unknown[0x8]; // normally zero 19 | u8 codeseed[0x8]; // the actual data 20 | } PACKED_STRUCT LocalFriendCodeSeed; 21 | 22 | // /private/movable.sed file 23 | // see: http://3dbrew.org/wiki/Nand/private/movable.sed 24 | typedef struct { 25 | u8 magic[0x4]; // "SEED" 26 | u8 indicator[0x4]; // uninitialized all zero, otherwise u8[1] nonzero 27 | LocalFriendCodeSeed codeseed_data; 28 | u8 keyy_high[8]; 29 | u8 unknown[0x10]; 30 | u8 cmac[0x10]; 31 | } PACKED_STRUCT MovableSed; 32 | 33 | // /rw/sys/SecureInfo_A (/_B) file 34 | // see: http://3dbrew.org/wiki/Nandrw/sys/SecureInfo_A 35 | typedef struct { 36 | u8 signature[0x100]; 37 | u8 region; 38 | u8 unknown; 39 | char serial[0xF]; 40 | } PACKED_ALIGN(1) SecureInfo; 41 | 42 | // includes all essential system files 43 | // (this is of our own making) 44 | typedef struct { 45 | ExeFsHeader header; 46 | u8 nand_hdr[0x200]; 47 | SecureInfo secinfo; 48 | u8 padding_secinfo[0x200 - (sizeof(SecureInfo)%0x200)]; 49 | MovableSed movable; 50 | u8 padding_movable[0x200 - (sizeof(MovableSed)%0x200)]; 51 | LocalFriendCodeSeed frndseed; 52 | u8 padding_frndseed[0x200 - (sizeof(LocalFriendCodeSeed)%0x200)]; 53 | u8 nand_cid[0x10]; 54 | u8 padding_nand_cid[0x200 - 0x10]; 55 | u8 otp[0x100]; 56 | u8 padding_otp[0x200 - 0x100]; 57 | u8 hwcal0[SIZE_HWCAL]; 58 | u8 padding_hwcal0[0x200 - (SIZE_HWCAL%0x200)]; 59 | u8 hwcal1[SIZE_HWCAL]; 60 | u8 padding_hwcal1[0x200 - (SIZE_HWCAL%0x200)]; 61 | } PACKED_ALIGN(16) EssentialBackup; 62 | -------------------------------------------------------------------------------- /common/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #ifdef ARM9 15 | # ifdef MONITOR_HEAP 16 | #include "mymalloc.h" 17 | #define malloc my_malloc 18 | #define realloc my_realloc 19 | #define free my_free 20 | # endif 21 | #endif 22 | 23 | #define max(a,b) \ 24 | (((a) > (b)) ? (a) : (b)) 25 | 26 | #define min(a,b) \ 27 | (((a) < (b)) ? (a) : (b)) 28 | 29 | #define abs(x) \ 30 | (((x) >= 0) ? (x) : -(x)) 31 | 32 | #define int_sign(x) \ 33 | (((x) > 0) - ((x) < 0)) 34 | 35 | #define clamp(x, min, max) \ 36 | ((x) < (max) ? ((x) > (min) ? (x) : (min)) : (max)) 37 | 38 | #define getbe16(d) \ 39 | (((d)[0]<<8) | (d)[1]) 40 | #define getbe32(d) \ 41 | ((((u32) getbe16(d))<<16) | ((u32) getbe16((d)+2))) 42 | #define getbe64(d) \ 43 | ((((u64) getbe32(d))<<32) | ((u64) getbe32((d)+4))) 44 | 45 | #define getle16(d) \ 46 | (((d)[1]<<8) | (d)[0]) 47 | #define getle32(d) \ 48 | ((((u32) getle16((d)+2))<<16) | ((u32) getle16(d))) 49 | #define getle64(d) \ 50 | ((((u64) getle32((d)+4))<<32) | ((u64) getle32(d))) 51 | 52 | #define align(v,a) \ 53 | (((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v)) 54 | 55 | #define countof(x) \ 56 | (sizeof(x) / sizeof(*(x))) 57 | 58 | #define bkpt \ 59 | __builtin_trap() 60 | 61 | #define assert(x) \ 62 | (!!(x) ? (void)0 : __builtin_trap()) 63 | 64 | 65 | #define STATIC_ASSERT(...) \ 66 | _Static_assert((__VA_ARGS__), #__VA_ARGS__) 67 | 68 | 69 | // standard output path (support file paths are in support.h) 70 | #define OUTPUT_PATH "0:/gm9/out" 71 | 72 | // used in several places 73 | #define STD_BUFFER_SIZE 0x100000 // must be a multiple of 0x200 74 | 75 | // buffer area defines (in use by image.c, for RAMdrive) 76 | #define RAMDRV_BUFFER ((u8*)0x22800000) // top of STACK 77 | #define RAMDRV_SIZE_O3DS (0x5800000) // 88MB 78 | #define RAMDRV_SIZE_N3DS (0xD800000) // 216MB 79 | -------------------------------------------------------------------------------- /arm9/source/common/memcpy.s: -------------------------------------------------------------------------------- 1 | @ memcpy_arm946e-s - hand written reimplementation of memcpy to be sequential 2 | @ Written in 2019 by luigoalma 3 | @ To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. 4 | @ For a copy of CC0 Public Domain Dedication, see . 5 | .cpu arm946e-s 6 | .arch armv5te 7 | .arm 8 | .section .text.memcpy, "ax", %progbits 9 | .align 2 10 | .global memcpy 11 | .syntax unified 12 | .type memcpy, %function 13 | memcpy: 14 | @ r0 = dest 15 | @ r1 = src 16 | @ r2 = length 17 | @ check if length 0 and return if so 18 | cmp r2, #0 19 | bxeq lr 20 | push {r0,r4-r9,lr} 21 | @ pre-fetch data 22 | pld [r1] 23 | @ alignment check with word size 24 | @ if not aligned but both are in the same misalignment, fix it up 25 | @ otherwise jump to basic loop 26 | orr r12, r0, r1 27 | ands r12, r12, #3 28 | beq .L1 29 | mov r12, r0, LSL#30 30 | cmp r12, r1, LSL#30 31 | bne .L6 32 | .L0: 33 | ldrb r3, [r1], #1 34 | strb r3, [r0], #1 35 | subs r2, r2, #1 36 | popeq {r0,r4-r9,pc} 37 | adds r12, r12, #0x40000000 38 | bne .L0 39 | .L1: 40 | @ check if length higher than 32 41 | @ if so, do the 32 byte block copy loop, 42 | @ until there's nothing left or remainder to copy is less than 32 43 | movs r3, r2, LSR#5 44 | beq .L3 45 | .L2: 46 | ldm r1!, {r4-r9,r12,lr} 47 | stm r0!, {r4-r9,r12,lr} 48 | subs r3, r3, #1 49 | bne .L2 50 | ands r2, r2, #0x1F 51 | popeq {r0,r4-r9,pc} 52 | .L3: 53 | @ copy in word size the remaining data, 54 | @ and finish off with basic loop if can't copy all by word size. 55 | movs r3, r2, LSR#2 56 | beq .L6 57 | .L4: 58 | ldr r12, [r1], #4 59 | str r12, [r0], #4 60 | subs r3, r3, #1 61 | bne .L4 62 | ands r2, r2, #0x3 63 | .L5: @ the basic loop 64 | popeq {r0,r4-r9,pc} 65 | .L6: 66 | ldrb r3, [r1], #1 67 | strb r3, [r0], #1 68 | subs r2, r2, #1 69 | b .L5 70 | .size memcpy, .-memcpy 71 | -------------------------------------------------------------------------------- /arm9/source/common/screenshot.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "ui.h" 3 | #include "rtc.h" 4 | #include "vff.h" 5 | #include "png.h" 6 | 7 | static void Screenshot_Transpose(u16 *dest, const u16 *fb, u32 w, u32 stride) 8 | { 9 | for (u32 y = 0; y < SCREEN_HEIGHT; y++) { 10 | for (u32 x = 0; x < w; x++) 11 | *(dest++) = GetColor(fb, x, y); 12 | dest += stride; 13 | } 14 | } 15 | 16 | void CreateScreenshot(void) { 17 | u8 *png; 18 | u16 *buffer; 19 | DsTime dstime; 20 | size_t png_size; 21 | char filename[64]; 22 | u32 snapbuf_size, snap_w, snap_h, bot_offset; 23 | 24 | snapbuf_size = (SCREEN_WIDTH_TOP * SCREEN_HEIGHT * BYTES_PER_PIXEL) * 2; 25 | snap_w = SCREEN_WIDTH_TOP; 26 | snap_h = SCREEN_HEIGHT * 2; 27 | 28 | fvx_rmkdir(OUTPUT_PATH); 29 | get_dstime(&dstime); 30 | snprintf(filename, 64, OUTPUT_PATH "/snap_%02X%02X%02X%02X%02X%02X.png", 31 | dstime.bcd_Y, dstime.bcd_M, dstime.bcd_D, 32 | dstime.bcd_h, dstime.bcd_m, dstime.bcd_s); 33 | filename[63] = '\0'; 34 | 35 | buffer = malloc(snapbuf_size); 36 | if (!buffer) return; 37 | 38 | for (unsigned i = snapbuf_size/4; i < snapbuf_size/2; i++) 39 | buffer[i] = RGB(0x1F, 0x1F, 0x1F); // gray background 40 | 41 | bot_offset = (SCREEN_WIDTH_TOP * SCREEN_HEIGHT) + 40; 42 | 43 | Screenshot_Transpose(buffer, TOP_SCREEN, SCREEN_WIDTH_TOP, 0); 44 | Screenshot_Transpose(buffer + bot_offset, BOT_SCREEN, SCREEN_WIDTH_BOT, 80); 45 | 46 | png = PNG_Compress(buffer, snap_w, snap_h, &png_size); 47 | 48 | if (png && png_size) { 49 | u16 *buffer_top = buffer, *buffer_bottom = buffer + bot_offset; 50 | 51 | // "snap effect" 52 | memcpy(buffer_bottom, BOT_SCREEN, SCREEN_SIZE_BOT); 53 | memcpy(buffer_top, TOP_SCREEN, SCREEN_SIZE_TOP); 54 | memset(BOT_SCREEN, 0, SCREEN_SIZE_BOT); 55 | memset(TOP_SCREEN, 0, SCREEN_SIZE_TOP); 56 | 57 | fvx_qwrite(filename, png, 0, png_size, NULL); 58 | 59 | memcpy(BOT_SCREEN, buffer_bottom, SCREEN_SIZE_BOT); 60 | memcpy(TOP_SCREEN, buffer_top, SCREEN_SIZE_TOP); 61 | } 62 | // what to do on error...? 63 | 64 | free(buffer); 65 | free(png); 66 | } 67 | -------------------------------------------------------------------------------- /arm9/source/game/cia.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "ticket.h" 5 | #include "tmd.h" 6 | 7 | #define CIA_HEADER_SIZE sizeof(CiaHeader) 8 | #define CIA_CERT_SIZE 0xA00 9 | #define CIA_META_SIZE sizeof(CiaMeta) 10 | 11 | // see: https://www.3dbrew.org/wiki/CIA#Meta 12 | typedef struct { 13 | u8 dependencies[0x180]; // from ExtHeader 14 | u8 reserved0[0x180]; 15 | u32 core_version; // 2 normally 16 | u8 reserved1[0xFC]; 17 | u8 smdh[0x36C0]; // from ExeFS 18 | } PACKED_STRUCT CiaMeta; 19 | 20 | typedef struct { 21 | u32 size_header; 22 | u16 type; 23 | u16 version; 24 | u32 size_cert; 25 | u32 size_ticket; 26 | u32 size_tmd; 27 | u32 size_meta; 28 | u64 size_content; 29 | u8 content_index[0x2000]; 30 | } PACKED_STRUCT CiaHeader; 31 | 32 | typedef struct { 33 | CiaHeader header; 34 | u8 header_padding[0x40 - (CIA_HEADER_SIZE % 0x40)]; 35 | u8 cert[CIA_CERT_SIZE]; 36 | // cert is aligned and needs no padding 37 | Ticket ticket; 38 | u8 ticket_padding[0x40 - (TICKET_SIZE % 0x40)]; 39 | TitleMetaData tmd; 40 | TmdContentChunk content_list[TMD_MAX_CONTENTS]; 41 | } PACKED_ALIGN(16) CiaStub; 42 | 43 | typedef struct { // first 0x20 bytes are identical with CIA header 44 | u32 size_header; 45 | u16 type; 46 | u16 version; 47 | u32 size_cert; 48 | u32 size_ticket; 49 | u32 size_tmd; 50 | u32 size_meta; 51 | u64 size_content; 52 | u32 size_content_list; 53 | u64 size_cia; 54 | u32 offset_cert; 55 | u32 offset_ticket; 56 | u32 offset_tmd; 57 | u32 offset_content; 58 | u32 offset_meta; 59 | u32 offset_content_list; 60 | u32 max_contents; 61 | } PACKED_STRUCT CiaInfo; 62 | 63 | u32 ValidateCiaHeader(CiaHeader* header); 64 | u32 GetCiaInfo(CiaInfo* info, CiaHeader* header); 65 | u32 FixCiaHeaderForTmd(CiaHeader* header, TitleMetaData* tmd); 66 | 67 | u32 BuildCiaCert(u8* ciacert); 68 | u32 BuildCiaMeta(CiaMeta* meta, void* exthdr, void* smdh); 69 | u32 BuildCiaHeader(CiaHeader* header); 70 | 71 | u32 DecryptCiaContentSequential(void* data, u32 size, u8* ctr, const u8* titlekey); 72 | u32 EncryptCiaContentSequential(void* data, u32 size, u8* ctr, const u8* titlekey); 73 | -------------------------------------------------------------------------------- /arm9/source/game/ncchinfo.c: -------------------------------------------------------------------------------- 1 | #include "ncchinfo.h" 2 | #include "ncch.h" 3 | #include "aes.h" 4 | 5 | u32 GetNcchInfoVersion(NcchInfoHeader* info) { 6 | if (!info->n_entries) return 0; // cannot be empty 7 | if (info->ncch_info_version == NCCHINFO_V3_MAGIC) return 3; 8 | else if (info->ncch_info_version == NCCHINFO_V4_MAGIC) return 4; 9 | else return 0; 10 | } 11 | 12 | u32 FixNcchInfoEntry(NcchInfoEntry* entry, u32 version) { 13 | // convert ncchinfo if v3 14 | if (version == 3) { // ncchinfo v3 15 | u8* entry_data = (u8*) (entry); 16 | memmove(entry_data + 56, entry_data + 48, 112); 17 | memset(entry_data + 48, 0, 8); // zero out nonexistent title id 18 | } else if (version != 4) { // !ncchinfo v4.0/v4.1/v4.2 19 | return 1; 20 | } 21 | 22 | // poor man's UTF-16 -> UTF-8 23 | if (entry->filename[1] == 0x00) { 24 | for (u32 i = 1; i < (sizeof(entry->filename) / 2); i++) 25 | entry->filename[i] = entry->filename[i*2]; 26 | } 27 | 28 | // fix sdmc: prefix 29 | if (memcmp(entry->filename, "sdmc:", 5) == 0) 30 | memmove(entry->filename, entry->filename + 5, 112 - 5); 31 | 32 | // workaround (1) for older (v4.0) ncchinfo.bin 33 | // this combination means seed crypto rather than FixedKey 34 | if ((entry->ncchFlag7 == 0x01) && entry->ncchFlag3) 35 | entry->ncchFlag7 = 0x20; 36 | 37 | // workaround (2) for older (v4.1) ncchinfo.bin 38 | if (!entry->size_b) entry->size_b = entry->size_mb * 1024 * 1024; 39 | 40 | return 0; 41 | } 42 | 43 | u32 BuildNcchInfoXorpad(void* buffer, NcchInfoEntry* entry, u32 size, u32 offset) { 44 | // set NCCH key 45 | // build faux NCCH header from entry 46 | NcchHeader ncch = { 0 }; 47 | memcpy(ncch.signature, entry->keyY, 16); 48 | ncch.flags[3] = (u8) entry->ncchFlag3; 49 | ncch.flags[7] = (u8) (entry->ncchFlag7 & ~0x04); 50 | ncch.programId = ncch.partitionId = entry->titleId; 51 | if (SetNcchKey(&ncch, NCCH_GET_CRYPTO(&ncch), 1) != 0) 52 | return 1; 53 | 54 | // write xorpad 55 | memset(buffer, 0, size); 56 | ctr_decrypt_byte(buffer, buffer, size, offset, AES_CNT_CTRNAND_MODE, entry->ctr); 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Makefile.common: -------------------------------------------------------------------------------- 1 | 2 | dirname = $(shell dirname $(1)) 3 | 4 | rwildcard = $(foreach d, $(wildcard $1*), \ 5 | $(filter $(subst *, %, $2), $d) \ 6 | $(call rwildcard, $d/, $2)) 7 | 8 | FLAVOR ?= GodMode9 9 | SPLASH = resources/$(FLAVOR)_splash.png 10 | 11 | ifeq ($(FLAVOR),SafeMode9) 12 | CFLAGS += -DSAFEMODE 13 | else ifeq ($(FLAVOR),GodMode64) 14 | OVERRIDE_FONT := resources/fonts/font_c64_8x8.pbm 15 | CFLAGS += -DDEFAULT_FONT=\"font_c64_8x8.pbm\" 16 | CFLAGS += -DCOLOR_STD_FONT="RGB(0x7B, 0x71, 0xD5)" 17 | CFLAGS += -DCOLOR_STD_BG="RGB(0x41, 0x30, 0xA4)" 18 | else ifeq ($(FLAVOR),BrickedMode9) 19 | OVERRIDE_FONT := resources/fonts/font_nbraille_4x6.pbm 20 | CFLAGS += -DDEFAULT_FONT=\"font_nbraille_4x6.pbm\" 21 | CFLAGS += -DCOLOR_STD_FONT="RGB(0xFF, 0xFF, 0x00)" 22 | CFLAGS += -DCOLOR_STD_BG="RGB(0x00, 0x00, 0xFF)" 23 | else ifeq ($(FLAVOR),ZuishMode9) 24 | OVERRIDE_FONT := resources/fonts/font_zuish_8x8.pbm 25 | CFLAGS += -DDEFAULT_FONT=\"font_zuish_8x8.pbm\" 26 | endif 27 | 28 | ifeq ($(SALTMODE),1) 29 | CFLAGS += -DSALTMODE 30 | endif 31 | 32 | ifeq ($(SWITCH_SCREENS),1) 33 | CFLAGS += -DSWITCH_SCREENS 34 | endif 35 | 36 | ifeq ($(SCRIPT_RUNNER),1) 37 | CFLAGS += -DSCRIPT_RUNNER 38 | endif 39 | 40 | ifeq ($(AUTO_UNLOCK),1) 41 | CFLAGS += -DAUTO_UNLOCK 42 | endif 43 | 44 | ifeq ($(TIMER_UNLOCK),1) 45 | CFLAGS += -DTIMER_UNLOCK 46 | endif 47 | 48 | ifeq ($(HIDE_HIDDEN),1) 49 | CFLAGS += -DHIDE_HIDDEN 50 | endif 51 | 52 | ifeq ($(SHOW_FREE),1) 53 | CFLAGS += -DSHOW_FREE 54 | endif 55 | 56 | ifdef FIXED_BRIGHTNESS 57 | CFLAGS += -DFIXED_BRIGHTNESS=$(FIXED_BRIGHTNESS) 58 | endif 59 | 60 | ifdef SD_TIMEOUT 61 | CFLAGS += -DSD_TIMEOUT=$(SD_TIMEOUT) 62 | endif 63 | 64 | ifdef N_PANES 65 | CFLAGS += -DN_PANES=$(N_PANES) 66 | endif 67 | 68 | ifeq ($(MONITOR_HEAP),1) 69 | CFLAGS += -DMONITOR_HEAP 70 | endif 71 | 72 | ifdef NTRBOOT 73 | FTFLAGS = -S spi-retail 74 | FTDFLAGS = -S spi-dev 75 | FIRM = $(OUTDIR)/$(FLAVOR)_ntr.firm 76 | FIRMD = $(OUTDIR)/$(FLAVOR)_ntr_dev.firm 77 | else 78 | FTFLAGS = -S nand-retail 79 | FTDFLAGS = -S nand-dev 80 | FIRM = $(OUTDIR)/$(FLAVOR).firm 81 | FIRMD = $(OUTDIR)/$(FLAVOR)_dev.firm 82 | endif 83 | -------------------------------------------------------------------------------- /arm11/source/hw/i2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of fastboot 3DS 3 | * Copyright (C) 2017 derrek, profi200 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | 25 | #define I2C_STOP (1u) 26 | #define I2C_START (1u<<1) 27 | #define I2C_ERROR (1u<<2) 28 | #define I2C_ACK (1u<<4) 29 | #define I2C_DIRE_WRITE (0u) 30 | #define I2C_DIRE_READ (1u<<5) 31 | #define I2C_IRQ_ENABLE (1u<<6) 32 | #define I2C_ENABLE (1u<<7) 33 | 34 | #define I2C_GET_ACK(reg) ((bool)((reg)>>4 & 1u)) 35 | 36 | 37 | /** 38 | * @brief Initializes the I2C buses. Call this only once. 39 | */ 40 | void I2C_init(void); 41 | 42 | /** 43 | * @brief Reads data from a I2C register to a buffer. 44 | * 45 | * @param[in] devId The device ID. Use the enum above. 46 | * @param[in] regAddr The register address. 47 | * @param out The output buffer pointer. 48 | * @param[in] size The read size. 49 | * 50 | * @return Returns true on success and false on failure. 51 | */ 52 | bool I2C_readRegBuf(int devId, u8 regAddr, u8 *out, u32 size); 53 | 54 | /** 55 | * @brief Writes a buffer to a I2C register. 56 | * 57 | * @param[in] devId The device ID. Use the enum above. 58 | * @param[in] regAddr The register address. 59 | * @param[in] in The input buffer pointer. 60 | * @param[in] size The write size. 61 | * 62 | * @return Returns true on success and false on failure. 63 | */ 64 | bool I2C_writeRegBuf(int devId, u8 regAddr, const u8 *in, u32 size); 65 | -------------------------------------------------------------------------------- /arm9/source/game/tmd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define TMD_MAX_CONTENTS 1000 // 383 // theme CIAs contain maximum 100 themes + 1 index content 6 | 7 | #define TMD_SIZE_MIN sizeof(TitleMetaData) 8 | #define TMD_SIZE_MAX (sizeof(TitleMetaData) + (TMD_MAX_CONTENTS*sizeof(TmdContentChunk))) 9 | #define TMD_SIZE_N(n) (sizeof(TitleMetaData) + (n*sizeof(TmdContentChunk))) 10 | #define TMD_CDNCERT_SIZE 0x700 11 | 12 | #define TMD_ISSUER "Root-CA00000003-CP0000000b" 13 | #define TMD_ISSUER_DEV "Root-CA00000004-CP0000000a" 14 | #define TMD_SIG_TYPE 0x00, 0x01, 0x00, 0x04 // RSA_2048 SHA256 15 | 16 | #define DLC_TID_HIGH 0x00, 0x04, 0x00, 0x8C // title id high for DLC 17 | 18 | // from: https://github.com/profi200/Project_CTR/blob/02159e17ee225de3f7c46ca195ff0f9ba3b3d3e4/ctrtool/tmd.h#L18-L59; 19 | typedef struct { 20 | u8 id[4]; 21 | u8 index[2]; 22 | u8 type[2]; 23 | u8 size[8]; 24 | u8 hash[0x20]; 25 | } __attribute__((packed, aligned(4))) TmdContentChunk; 26 | 27 | typedef struct { 28 | u8 index[2]; 29 | u8 cmd_count[2]; 30 | u8 hash[0x20]; 31 | } __attribute__((packed, aligned(4))) TmdContentInfo; 32 | 33 | typedef struct { 34 | u8 sig_type[4]; 35 | u8 signature[0x100]; 36 | u8 padding[0x3C]; 37 | u8 issuer[0x40]; 38 | u8 version; 39 | u8 ca_crl_version; 40 | u8 signer_crl_version; 41 | u8 reserved0; 42 | u8 system_version[8]; 43 | u8 title_id[8]; 44 | u8 title_type[4]; 45 | u8 group_id[2]; 46 | u8 save_size[4]; 47 | u8 twl_privsave_size[4]; 48 | u8 reserved1[4]; 49 | u8 twl_flag; 50 | u8 reserved2[0x31]; 51 | u8 access_rights[4]; 52 | u8 title_version[2]; 53 | u8 content_count[2]; 54 | u8 boot_content[2]; 55 | u8 reserved3[2]; 56 | u8 contentinfo_hash[0x20]; 57 | TmdContentInfo contentinfo[64]; 58 | } __attribute__((packed, aligned(4))) TitleMetaData; 59 | 60 | u32 ValidateTmd(TitleMetaData* tmd); 61 | u32 ValidateTmdSignature(TitleMetaData* tmd); 62 | u32 VerifyTmd(TitleMetaData* tmd); 63 | u32 GetTmdCtr(u8* ctr, TmdContentChunk* chunk); 64 | u32 FixTmdHashes(TitleMetaData* tmd); 65 | u32 BuildFakeTmd(TitleMetaData* tmd, u8* title_id, u32 n_contents, u32 save_size, u32 twl_privsave_size); 66 | u32 BuildTmdCert(u8* tmdcert); 67 | -------------------------------------------------------------------------------- /arm9/source/filesys/image.c: -------------------------------------------------------------------------------- 1 | #include "image.h" 2 | #include "vff.h" 3 | 4 | static FIL mount_file; 5 | static u64 mount_state = 0; 6 | 7 | static char mount_path[256] = { 0 }; 8 | 9 | 10 | int ReadImageBytes(void* buffer, u64 offset, u64 count) { 11 | UINT bytes_read; 12 | UINT ret; 13 | if (!count) return -1; 14 | if (!mount_state) return FR_INVALID_OBJECT; 15 | if (fvx_tell(&mount_file) != offset) { 16 | if (fvx_size(&mount_file) < offset) return -1; 17 | fvx_lseek(&mount_file, offset); 18 | } 19 | ret = fvx_read(&mount_file, buffer, count, &bytes_read); 20 | return (ret != 0) ? (int) ret : (bytes_read != count) ? -1 : 0; 21 | } 22 | 23 | int WriteImageBytes(const void* buffer, u64 offset, u64 count) { 24 | UINT bytes_written; 25 | UINT ret; 26 | if (!count) return -1; 27 | if (!mount_state) return FR_INVALID_OBJECT; 28 | if (fvx_tell(&mount_file) != offset) 29 | fvx_lseek(&mount_file, offset); 30 | ret = fvx_write(&mount_file, buffer, count, &bytes_written); 31 | return (ret != 0) ? (int) ret : (bytes_written != count) ? -1 : 0; 32 | } 33 | 34 | int ReadImageSectors(void* buffer, u32 sector, u32 count) { 35 | return ReadImageBytes(buffer, sector * 0x200, count * 0x200); 36 | } 37 | 38 | int WriteImageSectors(const void* buffer, u32 sector, u32 count) { 39 | return WriteImageBytes(buffer, sector * 0x200, count * 0x200); 40 | } 41 | 42 | int SyncImage(void) { 43 | return mount_state ? fvx_sync(&mount_file) : FR_INVALID_OBJECT; 44 | } 45 | 46 | u64 GetMountSize(void) { 47 | return mount_state ? fvx_size(&mount_file) : 0; 48 | } 49 | 50 | u64 GetMountState(void) { 51 | return mount_state; 52 | } 53 | 54 | const char* GetMountPath(void) { 55 | return mount_path; 56 | } 57 | 58 | u64 MountImage(const char* path) { 59 | u64 type = (path) ? IdentifyFileType(path) : 0; 60 | if (mount_state) { 61 | fvx_close(&mount_file); 62 | mount_state = 0; 63 | *mount_path = 0; 64 | } 65 | if (!type) return 0; 66 | if ((fvx_open(&mount_file, path, FA_READ | FA_WRITE | FA_OPEN_EXISTING) != FR_OK) && 67 | (fvx_open(&mount_file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)) 68 | return 0; 69 | fvx_lseek(&mount_file, 0); 70 | fvx_sync(&mount_file); 71 | strncpy(mount_path, path, 255); 72 | return (mount_state = type); 73 | } 74 | -------------------------------------------------------------------------------- /arm9/source/game/smdh.c: -------------------------------------------------------------------------------- 1 | #include "smdh.h" 2 | #include "utf.h" 3 | 4 | #define SMDH_STRING(str, src, len) utf16_to_utf8((u8*) str, src, len, len) 5 | // shamelessly stolen from bch2obj.py / 3ds_hb_menu :) 6 | #define SMDH_LUT 0, 1, 8, 9, 2, 3, 10, 11, 16, 17, 24, 25, 18, 19, 26, 27, \ 7 | 4, 5, 12, 13, 6, 7, 14, 15, 20, 21, 28, 29, 22, 23, 30, 31, \ 8 | 32, 33, 40, 41, 34, 35, 42, 43, 48, 49, 56, 57, 50, 51, 58, 59, \ 9 | 36, 37, 44, 45, 38, 39, 46, 47, 52, 53, 60, 61, 54, 55, 62, 63 10 | 11 | u32 ConvertSmdhIcon(u16* icon, const u16* smdh_icon, u32 w, u32 h) { 12 | const u32 lut[8*8] = { SMDH_LUT }; 13 | u16* pix565 = (u16*) smdh_icon; 14 | for (u32 y = 0; y < h; y += 8) { 15 | for (u32 x = 0; x < w; x += 8) { 16 | for (u32 i = 0; i < 8*8; i++) { 17 | u32 ix = x + (lut[i] & 0x7); 18 | u32 iy = y + (lut[i] >> 3); 19 | icon[(iy * w) + ix] = *(pix565++); 20 | } 21 | } 22 | } 23 | return 0; 24 | } 25 | 26 | // short desc is max 64(+1) chars long 27 | u32 GetSmdhDescShort(char* desc, const Smdh* smdh) { 28 | const SmdhAppTitle* title = &(smdh->apptitles[1]); // english title 29 | memset(desc, 0, SMDH_SIZE_DESC_SHORT + 1); 30 | SMDH_STRING(desc, title->short_desc, SMDH_SIZE_DESC_SHORT); 31 | return 0; 32 | } 33 | 34 | // long desc is max 128(+1) chars long 35 | u32 GetSmdhDescLong(char* desc, const Smdh* smdh) { 36 | const SmdhAppTitle* title = &(smdh->apptitles[1]); // english title 37 | memset(desc, 0, SMDH_SIZE_DESC_LONG + 1); 38 | SMDH_STRING(desc, title->long_desc, SMDH_SIZE_DESC_LONG); 39 | return 0; 40 | } 41 | 42 | // publisher is max 64(+1) chars long 43 | u32 GetSmdhPublisher(char* pub, const Smdh* smdh) { 44 | const SmdhAppTitle* title = &(smdh->apptitles[1]); // english title 45 | memset(pub, 0, SMDH_SIZE_PUBLISHER + 1); 46 | SMDH_STRING(pub, title->publisher, SMDH_SIZE_PUBLISHER); 47 | return 0; 48 | } 49 | 50 | // small icons are 24x24 => 0x480 bytes in RGB565 51 | u32 GetSmdhIconSmall(u16* icon, const Smdh* smdh) { 52 | return ConvertSmdhIcon(icon, smdh->icon_small, SMDH_DIM_ICON_SMALL, SMDH_DIM_ICON_SMALL); 53 | } 54 | 55 | // big icons are 48x48 => 0x1200 byte in RGB565 56 | u32 GetSmdhIconBig(u16* icon, const Smdh* smdh) { 57 | return ConvertSmdhIcon(icon, smdh->icon_big, SMDH_DIM_ICON_BIG, SMDH_DIM_ICON_BIG); 58 | } 59 | -------------------------------------------------------------------------------- /arm9/source/system/xrq_handler.s: -------------------------------------------------------------------------------- 1 | /* 2 | Written by Wolfvak, specially sublicensed under the GPLv2 3 | Read LICENSE for more details 4 | */ 5 | 6 | .arm 7 | 8 | #include 9 | #include 10 | #include "memmap.h" 11 | 12 | .macro TRAP_ENTRY xrq_id 13 | msr cpsr_f, #(\xrq_id << 29) @ preserve xrq id (idea grabbed from fb3ds) 14 | .endm 15 | 16 | .section .vectors, "ax" 17 | .global XRQ_Start 18 | XRQ_Start: 19 | ldr pc, IRQ_Vector 20 | IRQ_Vector: .word IRQ_Handler 21 | ldr pc, FIQ_Vector 22 | FIQ_Vector: .word FIQ_Handler 23 | ldr pc, SVC_Vector 24 | SVC_Vector: .word SVC_Handler 25 | ldr pc, UND_Vector 26 | UND_Vector: .word UND_Handler 27 | ldr pc, PABT_Vector 28 | PABT_Vector: .word PABT_Handler 29 | ldr pc, DABT_Vector 30 | DABT_Vector: .word DABT_Handler 31 | .global XRQ_End 32 | XRQ_End: 33 | 34 | 35 | .section .text.xrqs 36 | IRQ_Handler: 37 | TRAP_ENTRY 6 38 | b XRQ_Fatal 39 | 40 | FIQ_Handler: 41 | TRAP_ENTRY 7 42 | b XRQ_Fatal 43 | 44 | SVC_Handler: 45 | TRAP_ENTRY 2 46 | b XRQ_Fatal 47 | 48 | UND_Handler: 49 | TRAP_ENTRY 1 50 | b XRQ_Fatal 51 | 52 | PABT_Handler: 53 | TRAP_ENTRY 3 54 | b XRQ_Fatal 55 | 56 | DABT_Handler: 57 | sub lr, lr, #4 @ R14_abt = PC + 8, so it needs a small additional fixup 58 | TRAP_ENTRY 4 59 | @b XRQ_Fatal 60 | 61 | XRQ_Fatal: 62 | sub lr, lr, #4 @ PC exception fixup 63 | 64 | ldr sp, =(__STACK_ABT_TOP - 18*4) @ Set up abort stack, 8 byte aligned 65 | stmia sp, {r0-r7} @ Preserve non-banked GPRs 66 | 67 | mrs r1, cpsr 68 | orr r0, r1, #SR_NOINT 69 | msr cpsr_c, r0 @ Disable interrupts 70 | 71 | lsr r0, r1, #29 @ Retrieve exception source 72 | 73 | mrs r2, spsr 74 | str lr, [sp, #15*4] 75 | str r2, [sp, #16*4] @ Preserve exception PC and CPSR 76 | 77 | ands r2, r2, #SR_PMODE_MASK 78 | orreq r2, r2, #SR_SYS_MODE @ Force a switch to system mode if 79 | @ the exception happened in user mode 80 | orr r2, r2, #(0x10 | SR_NOINT) @ With interrupts disabled 81 | 82 | add r3, sp, #8*4 83 | msr cpsr_c, r2 84 | nop 85 | nop 86 | stmia r3, {r8-r14} @ Preserve banked GPRs (R8-R12, SP_xrq, LR_xrq) 87 | nop 88 | nop 89 | msr cpsr_c, r1 90 | 91 | mov r1, sp 92 | bl XRQ_DumpRegisters @ XRQ_DumpRegisters(exception_number, saved_regs); 93 | 94 | mov r0, #0 95 | 1: 96 | mcr p15, 0, r0, c7, c0, 4 97 | b 1b 98 | -------------------------------------------------------------------------------- /arm11/source/hw/nvram.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include "hw/nvram.h" 23 | 24 | // returns manuf id, memory type and size 25 | // size = (1 << id[2]) ? 26 | // apparently unreliable on some Sanyo chips? 27 | #define CMD_RDID 0x9F 28 | 29 | #define CMD_READ 0x03 30 | #define CMD_WREN 0x06 31 | #define CMD_WRDI 0x04 32 | 33 | #define CMD_RDSR 0x05 34 | 35 | #define CMD_DPD 0xB9 // deep power down 36 | #define CMD_RDP 0xAB // release from deep power down 37 | 38 | static u32 NVRAM_SendStatusCommand(u32 cmd, u32 width) 39 | { 40 | u32 ret; 41 | SPI_XferInfo xfer[2]; 42 | 43 | xfer[0].buf = &cmd; 44 | xfer[0].len = 1; 45 | xfer[0].read = false; 46 | 47 | xfer[1].buf = &ret; 48 | xfer[1].len = width; 49 | xfer[1].read = true; 50 | 51 | ret = 0; 52 | SPI_DoXfer(SPI_DEV_NVRAM, xfer, 2, true); 53 | return ret; 54 | } 55 | 56 | u32 NVRAM_Status(void) 57 | { 58 | return NVRAM_SendStatusCommand(CMD_RDSR, 1); 59 | } 60 | 61 | u32 NVRAM_ReadID(void) 62 | { 63 | return NVRAM_SendStatusCommand(CMD_RDID, 3); 64 | } 65 | 66 | void NVRAM_DeepStandby(void) 67 | { 68 | NVRAM_SendStatusCommand(CMD_DPD, 0); 69 | } 70 | 71 | void NVRAM_Wakeup(void) 72 | { 73 | NVRAM_SendStatusCommand(CMD_RDP, 0); 74 | } 75 | 76 | void NVRAM_Read(u32 address, u32 *buffer, u32 len) 77 | { 78 | SPI_XferInfo xfer[2]; 79 | u32 cmd; 80 | 81 | address &= BIT(24) - 1; 82 | cmd = __builtin_bswap32(address) | CMD_READ; 83 | 84 | xfer[0].buf = &cmd; 85 | xfer[0].len = 4; 86 | xfer[0].read = false; 87 | 88 | xfer[1].buf = buffer; 89 | xfer[1].len = len; 90 | xfer[1].read = true; 91 | 92 | SPI_DoXfer(SPI_DEV_NVRAM, xfer, 2, true); 93 | } 94 | -------------------------------------------------------------------------------- /arm9/source/filesys/fsdrive.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "fsdir.h" 5 | 6 | #define NORM_FS 10 7 | #define IMGN_FS 3 // image normal filesystems 8 | 9 | // primary drive types 10 | #define DRV_UNKNOWN (0<<0) 11 | #define DRV_FAT (1UL<<0) 12 | #define DRV_VIRTUAL (1UL<<1) 13 | // secondary drive types 14 | #define DRV_SDCARD (1UL<<2) 15 | #define DRV_SYSNAND (1UL<<3) 16 | #define DRV_EMUNAND (1UL<<4) 17 | #define DRV_CTRNAND (1UL<<5) 18 | #define DRV_TWLNAND (1UL<<6) 19 | #define DRV_IMAGE (1UL<<7) 20 | #define DRV_XORPAD (1UL<<8) 21 | #define DRV_RAMDRIVE (1UL<<9) 22 | #define DRV_MEMORY (1UL<<10) 23 | #define DRV_GAME (1UL<<11) 24 | #define DRV_CART (1UL<<12) 25 | #define DRV_VRAM (1UL<<13) 26 | #define DRV_ALIAS (1UL<<14) 27 | #define DRV_BONUS (1UL<<15) 28 | #define DRV_SEARCH (1UL<<16) 29 | #define DRV_STDFAT (1UL<<17) // standard FAT drive without limitations 30 | 31 | #define DRV_LABEL_LEN (36) 32 | 33 | #define FS_DRVNAME \ 34 | "SDCARD", \ 35 | "SYSNAND CTRNAND", "SYSNAND TWLN", "SYSNAND TWLP", "SYSNAND SD", "SYSNAND VIRTUAL", \ 36 | "EMUNAND CTRNAND", "EMUNAND TWLN", "EMUNAND TWLP", "EMUNAND SD", "EMUNAND VIRTUAL", \ 37 | "IMGNAND CTRNAND", "IMGNAND TWLN", "IMGNAND TWLP", "IMGNAND VIRTUAL", \ 38 | "GAMECART", \ 39 | "GAME IMAGE", "AESKEYDB IMAGE", "TICKET.DB IMAGE", "DISA/DIFF IMAGE", \ 40 | "MEMORY VIRTUAL", \ 41 | "VRAM VIRTUAL", \ 42 | "LAST SEARCH" \ 43 | 44 | #define FS_DRVNUM \ 45 | "0:", "1:", "2:", "3:", "A:", "S:", "4:", "5:", "6:", "B:", "E:", "7:", "8:", "9:", "I:", "C:", "G:", "K:", "T:", "D:", "M:", "V:", "Z:" 46 | 47 | /** Function to identify the type of a drive **/ 48 | int DriveType(const char* path); 49 | 50 | /** Set search pattern / path / mode for special Z: drive **/ 51 | void SetFSSearch(const char* pattern, const char* path, bool mode); 52 | 53 | /** Read the FAT volume label of a partition **/ 54 | bool GetFATVolumeLabel(const char* drv, char* label); 55 | 56 | /** Get directory content under a given path **/ 57 | void GetDirContents(DirStruct* contents, const char* path); 58 | 59 | /** Gets remaining space in filesystem in bytes */ 60 | uint64_t GetFreeSpace(const char* path); 61 | 62 | /** Gets total spacein filesystem in bytes */ 63 | uint64_t GetTotalSpace(const char* path); 64 | 65 | /** Return the offset - in sectors - of the FAT partition on the drive **/ 66 | uint64_t GetPartitionOffsetSector(const char* path); 67 | -------------------------------------------------------------------------------- /arm9/source/common/mmio.s: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of fastboot 3DS 3 | * Copyright (C) 2019 Aurora Wright, TuxSH, derrek, profi200 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | @ Based on https://github.com/AuroraWright/Luma3DS/blob/master/arm9/source/alignedseqmemcpy.s 20 | 21 | #include "asmfunc.h" 22 | 23 | .arm 24 | .cpu arm946e-s 25 | .fpu softvfp 26 | 27 | 28 | 29 | @ void iomemcpy(vu32 *restrict dst, const vu32 *restrict src, u32 size) 30 | ASM_FUNC iomemcpy 31 | bics r12, r2, #31 32 | beq iomemcpy_test_words 33 | stmfd sp!, {r4-r10} 34 | iomemcpy_blocks_lp: 35 | ldmia r1!, {r3-r10} 36 | stmia r0!, {r3-r10} 37 | subs r12, #32 38 | bne iomemcpy_blocks_lp 39 | ldmfd sp!, {r4-r10} 40 | iomemcpy_test_words: 41 | ands r12, r2, #28 42 | beq iomemcpy_halfword_byte 43 | iomemcpy_words_lp: 44 | ldr r3, [r1], #4 45 | str r3, [r0], #4 46 | subs r12, #4 47 | bne iomemcpy_words_lp 48 | iomemcpy_halfword_byte: 49 | tst r2, #2 50 | ldrneh r3, [r1], #2 51 | strneh r3, [r0], #2 52 | tst r2, #1 53 | ldrneb r3, [r1] 54 | strneb r3, [r0] 55 | bx lr 56 | 57 | 58 | @ void iomemset(vu32 *ptr, u32 value, u32 size) 59 | ASM_FUNC iomemset 60 | bics r12, r2, #31 61 | beq iomemset_test_words 62 | stmfd sp!, {r4-r9} 63 | mov r3, r1 64 | mov r4, r1 65 | mov r5, r1 66 | mov r6, r1 67 | mov r7, r1 68 | mov r8, r1 69 | mov r9, r1 70 | iomemset_blocks_lp: 71 | stmia r0!, {r1, r3-r9} 72 | subs r12, #32 73 | bne iomemset_blocks_lp 74 | ldmfd sp!, {r4-r9} 75 | iomemset_test_words: 76 | ands r12, r2, #28 77 | beq iomemset_halfword_byte 78 | iomemset_words_lp: 79 | str r1, [r0], #4 80 | subs r12, #4 81 | bne iomemset_words_lp 82 | iomemset_halfword_byte: 83 | tst r2, #2 84 | strneh r1, [r0], #2 85 | tst r2, #1 86 | strneb r1, [r0] 87 | bx lr 88 | -------------------------------------------------------------------------------- /arm9/source/virtual/virtual.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "nand.h" 5 | 6 | #define VRT_SYSNAND NAND_SYSNAND 7 | #define VRT_EMUNAND NAND_EMUNAND 8 | #define VRT_IMGNAND NAND_IMGNAND 9 | #define VRT_XORPAD NAND_ZERONAND 10 | #define VRT_MEMORY (1UL<<4) 11 | #define VRT_GAME (1UL<<5) 12 | #define VRT_TICKDB (1UL<<6) 13 | #define VRT_KEYDB (1UL<<7) 14 | #define VRT_CART (1UL<<8) 15 | #define VRT_VRAM (1UL<<9) 16 | #define VRT_DISADIFF (1UL<<10) 17 | 18 | #define VRT_SOURCE (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND|VRT_XORPAD|VRT_MEMORY|VRT_GAME|VRT_TICKDB|VRT_KEYDB|VRT_CART|VRT_VRAM|VRT_DISADIFF) 19 | 20 | #define VFLAG_DIR (1UL<<11) 21 | #define VFLAG_ROOT (1UL<<12) 22 | #define VFLAG_READONLY (1UL<<13) 23 | #define VFLAG_DELETABLE (1UL<<14) 24 | #define VFLAG_LV3 (1UL<<15) 25 | 26 | 27 | #define VRT_DRIVES {'S', VRT_SYSNAND}, {'E', VRT_EMUNAND}, {'I', VRT_IMGNAND}, {'X', VRT_XORPAD }, \ 28 | {'M', VRT_MEMORY}, {'G', VRT_GAME}, {'K', VRT_KEYDB}, {'T', VRT_TICKDB}, {'C', VRT_CART}, {'V', VRT_VRAM}, {'D', VRT_DISADIFF} 29 | 30 | // virtual file flag (subject to change): 31 | // bits 0...3 : reserved for NAND virtual sources and info 32 | // bits 4...10 : reserved for other virtual sources 33 | // bits 11...15: reserved for external flags 34 | // bits 16...31: reserved for internal flags (different per source, see vgame.c) 35 | typedef struct { 36 | char name[32]; 37 | u64 offset; // must be a multiple of 0x200 (for NAND access) 38 | u64 size; 39 | u32 keyslot; 40 | u32 flags; 41 | } VirtualFile; 42 | 43 | // virtual dirs are only relevant for virtual game drives 44 | typedef struct { 45 | int index; 46 | u64 offset; 47 | u64 size; 48 | u32 flags; 49 | } VirtualDir; 50 | 51 | u32 GetVirtualSource(const char* path); 52 | void DeinitVirtualImageDrive(void); 53 | bool InitVirtualImageDrive(void); 54 | bool CheckVirtualDrive(const char* path); 55 | 56 | bool ReadVirtualDir(VirtualFile* vfile, VirtualDir* vdir); 57 | bool OpenVirtualRoot(VirtualDir* vdir, u32 virtual_src); 58 | bool OpenVirtualDir(VirtualDir* vdir, VirtualFile* ventry); 59 | 60 | bool GetVirtualFile(VirtualFile* vfile, const char* path); 61 | bool GetVirtualDir(VirtualDir* vdir, const char* path); 62 | bool GetVirtualFilename(char* name, const VirtualFile* vfile, u32 n_chars); 63 | 64 | int ReadVirtualFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count, u32* bytes_read); 65 | int WriteVirtualFile(const VirtualFile* vfile, const void* buffer, u64 offset, u64 count, u32* bytes_written); 66 | int DeleteVirtualFile(const VirtualFile* vfile); 67 | 68 | u64 GetVirtualDriveSize(const char* path); 69 | -------------------------------------------------------------------------------- /arm9/source/common/swkbd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "ui.h" 5 | #include "touchcal.h" 6 | 7 | 8 | // special key ids 9 | enum { 10 | KEY_DUMMY = 0x80, 11 | KEY_BKSPC = 0x81, 12 | KEY_INSERT = 0x82, 13 | KEY_ENTER = 0x83, 14 | KEY_CAPS = 0x84, 15 | KEY_SPECIAL = 0x85, 16 | KEY_NUMPAD = 0x86, 17 | KEY_ALPHA = 0x87, 18 | KEY_LEFT = 0x88, 19 | KEY_RIGHT = 0x89, 20 | KEY_ESCAPE = 0x8A, 21 | KEY_TXTBOX = 0xFF 22 | }; 23 | 24 | // special key strings 25 | #define SWKBD_KEYSTR "", "DEL", "INS", "SUBMIT", "CAPS", "#$@", "123", "ABC", "\x1b", "\x1a", "ESC" 26 | 27 | #define COLOR_SWKBD_NORMAL COLOR_GREY 28 | #define COLOR_SWKBD_PRESSED COLOR_LIGHTGREY 29 | #define COLOR_SWKBD_BOX COLOR_DARKGREY 30 | #define COLOR_SWKBD_TEXTBOX COLOR_DARKGREY 31 | #define COLOR_SWKBD_CHARS COLOR_BLACK 32 | #define COLOR_SWKBD_ENTER COLOR_TINTEDBLUE 33 | #define COLOR_SWKBD_CAPS COLOR_TINTEDYELLOW 34 | 35 | #define SWKBD_TEXTBOX_WIDTH 240 36 | #define SWKBD_STDKEY_WIDTH 18 37 | #define SWKBD_STDKEY_HEIGHT 20 38 | #define SWKDB_KEY_SPACING 1 39 | 40 | #define SWKBD_KEYS_ALPHABET \ 41 | '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '+', '-', KEY_BKSPC, \ 42 | 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '&', KEY_ENTER, \ 43 | 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '(', ')', '[', ']', \ 44 | 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '_', '#', '!', \ 45 | KEY_CAPS, ' ', KEY_NUMPAD, KEY_SPECIAL, KEY_LEFT, KEY_RIGHT 46 | 47 | #define SWKBD_KEYS_SPECIAL \ 48 | '(', ')', '{', '}', '[', ']', \ 49 | '.', ',', '?', '!', '`', '\'', \ 50 | '^', '*', '+', '-', '_', '=', \ 51 | '@', '#', '$', '%', '&', '~', \ 52 | KEY_ALPHA, ' ', KEY_BKSPC 53 | 54 | #define SWKBD_KEYS_NUMPAD \ 55 | '7', '8', '9', 'F', 'E', \ 56 | '4', '5', '6', 'D', 'C', \ 57 | '3', '2', '1', 'B', 'A', \ 58 | '0', '.', '_', KEY_LEFT, KEY_RIGHT, \ 59 | KEY_ALPHA, ' ', KEY_BKSPC 60 | 61 | // offset, num of keys in row, width of special keys (...), 0 62 | #define SWKBD_LAYOUT_ALPHABET \ 63 | 13, 32, 0, \ 64 | 12, 51, 0, \ 65 | 13, 0, \ 66 | 12, 0, \ 67 | 6, 32, 123, 32, 32, 18, 18, 0, \ 68 | 0 69 | 70 | #define SWKBD_LAYOUT_SPECIAL \ 71 | 6, 0, \ 72 | 6, 0, \ 73 | 6, 0, \ 74 | 6, 0, \ 75 | 3, 32, 46, 32, 0, \ 76 | 0 77 | 78 | #define SWKBD_LAYOUT_NUMPAD \ 79 | 5, 0, \ 80 | 5, 0, \ 81 | 5, 0, \ 82 | 5, 18, 18, 0, \ 83 | 3, 30, 34, 30, 0, \ 84 | 0 85 | 86 | 87 | #define ShowKeyboardOrPrompt (TouchIsCalibrated() ? ShowKeyboard : ShowStringPrompt) 88 | bool ShowKeyboard(char* inputstr, u32 max_size, const char *format, ...); 89 | -------------------------------------------------------------------------------- /arm9/source/game/firm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define FIRM_MAGIC 'F', 'I', 'R', 'M' 6 | 7 | #define FIRM_MAX_SIZE 0x400000 // 4MB, due to FIRM partition size 8 | #define ARM11NCCH_OFFSET 0, 0x2A000, 0x2B000, 0x2C000 9 | #define ARM9BIN_OFFSET 0x800 10 | // ARM9 entrypoint after decryption - TWL/AGB and NATIVE/SAFE_MODE 11 | // see: https://github.com/AuroraWright/Luma3DS/blob/master/source/firm.c#L349 12 | // and: https://github.com/AuroraWright/Luma3DS/blob/master/source/firm.c#L424 13 | // and: https://github.com/AuroraWright/Luma3DS/blob/master/source/firm.c#L463 14 | #define ARM9ENTRY_FIX(firm) (((firm)->sections[3].offset) ? 0x801301C : 0x0801B01C) 15 | 16 | #define FIRM_NDMA_CPY 0 17 | #define FIRM_XDMA_CPY 1 18 | #define FIRM_CPU_MEMCPY 2 19 | 20 | #define IsInstallableFirm(firm, firm_size) (ValidateFirm(firm, firm_size, true) == 0) 21 | #define IsBootableFirm(firm, firm_size) (ValidateFirm(firm, firm_size, false) == 0) 22 | 23 | 24 | // see: https://www.3dbrew.org/wiki/FIRM#Firmware_Section_Headers 25 | typedef struct { 26 | u32 offset; 27 | u32 address; 28 | u32 size; 29 | u32 method; 30 | u8 hash[0x20]; 31 | } PACKED_STRUCT FirmSectionHeader; 32 | 33 | // see: https://www.3dbrew.org/wiki/FIRM#FIRM_Header 34 | typedef struct { 35 | u8 magic[4]; 36 | u8 dec_magic[4]; 37 | u32 entry_arm11; 38 | u32 entry_arm9; 39 | u8 reserved0[0x30]; 40 | FirmSectionHeader sections[4]; 41 | u8 signature[0x100]; 42 | } __attribute__((packed, aligned(16))) FirmHeader; 43 | 44 | // see: https://www.3dbrew.org/wiki/FIRM#New_3DS_FIRM 45 | typedef struct { 46 | u8 keyX0x15[0x10]; // this is encrypted 47 | u8 keyY0x150x16[0x10]; 48 | u8 ctr[0x10]; 49 | char size_ascii[0x8]; 50 | u8 reserved[0x8]; 51 | u8 control[0x10]; 52 | u8 k9l[0x10]; 53 | u8 keyX0x16[0x10]; // this is encrypted 54 | u8 padding[0x190]; 55 | } __attribute__((packed, aligned(16))) FirmA9LHeader; 56 | 57 | u32 ValidateFirmHeader(FirmHeader* header, u32 data_size); 58 | u32 ValidateFirmA9LHeader(FirmA9LHeader* header); 59 | u32 ValidateFirm(void* firm, u32 firm_size, bool installable); 60 | u32 GetFirmSize(FirmHeader* header); 61 | 62 | FirmSectionHeader* FindFirmArm9Section(FirmHeader* firm); 63 | u32 GetArm9BinarySize(FirmA9LHeader* a9l); 64 | 65 | u32 SetupArm9BinaryCrypto(FirmA9LHeader* header); 66 | u32 DecryptA9LHeader(FirmA9LHeader* header); 67 | u32 DecryptFirm(void* data, u32 offset, u32 size, FirmHeader* firm, FirmA9LHeader* a9l); 68 | u32 DecryptArm9Binary(void* data, u32 offset, u32 size, FirmA9LHeader* a9l); 69 | u32 DecryptFirmSequential(void* data, u32 offset, u32 size); 70 | u32 DecryptFirmFull(void* data, u32 size); 71 | -------------------------------------------------------------------------------- /arm9/source/system/tar.c: -------------------------------------------------------------------------------- 1 | #include "tar.h" 2 | 3 | 4 | u64 ReadAsciiOctal(char* num, u32 len) { 5 | u64 res = 0; 6 | 7 | if ((num[len-1] != '\0') && (num[len-1] != ' ')) 8 | return (u64) -1; 9 | 10 | for (u32 i = 0; i < (len-1); i++) { 11 | res <<= 3; 12 | if ((num[i] >= '0') && (num[i] < '8')) res |= (num[i] - '0'); 13 | else return (u64) -1; 14 | } 15 | 16 | return res; 17 | } 18 | 19 | u32 ValidateTarHeader(void* tardata, void* tardata_end) { 20 | TarHeader* tar = tardata; 21 | 22 | // available space 23 | if ((u8*) tardata_end < (u8*) tardata + sizeof(TarHeader)) 24 | return 1; 25 | 26 | // filename prefix is not supported here 27 | if (*(tar->fname_prefix)) return 1; 28 | 29 | // check filesize 30 | u64 fsize_max = ((u8*) tardata_end - (u8*) tardata) - sizeof(TarHeader); 31 | if (ReadAsciiOctal(tar->fsize, 12) > fsize_max) 32 | return 1; 33 | 34 | // type can only be standard file or dir 35 | if (tar->ftype && (tar->ftype != '0') && (tar->ftype != '5')) 36 | return 1; 37 | 38 | // checksum 39 | u8* data = (u8*) tardata; 40 | u64 checksum = 0; 41 | for (u32 i = 0; i < sizeof(TarHeader); i++) 42 | checksum += ((i < 148) || (i >= 156)) ? data[i] : (u64) ' '; 43 | if (checksum != ReadAsciiOctal(tar->checksum, 7)) 44 | return 1; 45 | 46 | return 0; 47 | } 48 | 49 | void* GetTarFileInfo(void* tardata, char* fname, u64* fsize, bool* is_dir) { 50 | // this assumes a valid TAR header 51 | TarHeader* tar = tardata; 52 | 53 | if (fname) snprintf(fname, 101, "%.100s", tar->fname); 54 | if (fsize) *fsize = ReadAsciiOctal(tar->fsize, 12); 55 | if (is_dir) *is_dir = (tar->ftype == '5'); 56 | 57 | return (void*) (tar + 1); 58 | } 59 | 60 | void* NextTarEntry(void* tardata, void* tardata_end) { 61 | // this assumes a valid TAR header 62 | TarHeader* tar = tardata; 63 | u8* data = (u8*) tardata; 64 | u64 fsize = ReadAsciiOctal(tar->fsize, 12); 65 | 66 | data += sizeof(TarHeader) + align(fsize, 512); 67 | if (ValidateTarHeader(data, tardata_end) != 0) 68 | return NULL; 69 | 70 | return data; 71 | } 72 | 73 | void* FindTarFileInfo(void* tardata, void* tardata_end, const char* fname, u64* fsize) { 74 | while (tardata && (tardata < tardata_end)) { 75 | TarHeader* tar = tardata; 76 | 77 | if (ValidateTarHeader(tardata, tardata_end) != 0) break; 78 | if ((strncasecmp(tar->fname, fname, 100) == 0) && (!tar->ftype || (tar->ftype == '0'))) 79 | return GetTarFileInfo(tardata, NULL, fsize, NULL); 80 | tardata = ((u8*) tardata) + sizeof(TarHeader) + align(ReadAsciiOctal(tar->fsize, 12), 512); 81 | } 82 | 83 | return NULL; 84 | } 85 | -------------------------------------------------------------------------------- /arm9/source/game/ncsd.c: -------------------------------------------------------------------------------- 1 | #include "ncsd.h" 2 | #include "ncch.h" 3 | 4 | u32 ValidateNcsdHeader(NcsdHeader* header) { 5 | u8 zeroes[16] = { 0 }; 6 | if ((memcmp(header->magic, "NCSD", 4) != 0) || // check magic number 7 | (memcmp(header->partitions_fs_type, zeroes, 8) != 0) || !header->mediaId) // prevent detection of NAND images 8 | return 1; 9 | 10 | u32 data_units = 0; 11 | for (u32 i = 0; i < 8; i++) { 12 | NcchPartition* partition = header->partitions + i; 13 | if ((i == 0) && !partition->size) return 1; // first content must be there 14 | else if (!partition->size) continue; 15 | if (partition->offset < data_units) 16 | return 1; // overlapping partitions, failed 17 | data_units = partition->offset + partition->size; 18 | } 19 | if (data_units > header->size) 20 | return 1; 21 | 22 | return 0; 23 | } 24 | 25 | u64 GetNcsdTrimmedSize(NcsdHeader* header) { 26 | u32 data_units = 0; 27 | for (u32 i = 0; i < 8; i++) { 28 | NcchPartition* partition = header->partitions + i; 29 | u32 partition_end = partition->offset + partition->size; 30 | if (!partition->size) continue; 31 | data_units = (partition_end > data_units) ? partition_end : data_units; 32 | } 33 | 34 | return data_units * NCSD_MEDIA_UNIT; 35 | } 36 | 37 | // on the fly decryptor for NCSD 38 | u32 CryptNcsdSequential(void* data, u32 offset_data, u32 size_data, u16 crypto) { 39 | // warning: this will only work for sequential processing 40 | static NcsdHeader ncsd; 41 | 42 | // fetch ncsd header from data 43 | if ((offset_data == 0) && (size_data >= sizeof(NcsdHeader))) 44 | memcpy(&ncsd, data, sizeof(NcsdHeader)); 45 | 46 | for (u32 i = 0; i < 8; i++) { 47 | NcchPartition* partition = ncsd.partitions + i; 48 | u32 offset_p = partition->offset * NCSD_MEDIA_UNIT; 49 | u32 size_p = partition->size * NCSD_MEDIA_UNIT; 50 | // check if partition in data 51 | if ((offset_p >= offset_data + size_data) || 52 | (offset_data >= offset_p + size_p) || 53 | !size_p) { 54 | continue; // section not in data 55 | } 56 | // determine data / offset / size 57 | u8* data8 = (u8*)data; 58 | u8* data_i = data8; 59 | u32 offset_i = 0; 60 | u32 size_i = size_p; 61 | if (offset_p < offset_data) 62 | offset_i = offset_data - offset_p; 63 | else data_i = data8 + (offset_p - offset_data); 64 | size_i = size_p - offset_i; 65 | if (size_i > size_data - (data_i - data8)) 66 | size_i = size_data - (data_i - data8); 67 | // decrypt ncch segment 68 | if (CryptNcchSequential(data_i, offset_i, size_i, crypto) != 0) 69 | return 1; 70 | } 71 | 72 | return 0; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /arm9/source/system/i2c.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * This file is part of fastboot 3DS 5 | * Copyright (C) 2017 derrek, profi200 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "types.h" 22 | 23 | typedef enum 24 | { 25 | I2C_DEV_POWER = 0, // Unconfirmed 26 | I2C_DEV_CAMERA = 1, // Unconfirmed 27 | I2C_DEV_CAMERA2 = 2, // Unconfirmed 28 | I2C_DEV_MCU = 3, 29 | I2C_DEV_GYRO = 10, 30 | I2C_DEV_DEBUG_PAD = 12, 31 | I2C_DEV_IR = 13, 32 | I2C_DEV_EEPROM = 14, // Unconfirmed 33 | I2C_DEV_NFC = 15, 34 | I2C_DEV_QTM = 16, 35 | I2C_DEV_N3DS_HID = 17 36 | } I2cDevice; 37 | 38 | /** 39 | * @brief Reads data from a I2C register to a buffer. 40 | * 41 | * @param[in] devId The device ID. Use the enum above. 42 | * @param[in] regAddr The register address. 43 | * @param out The output buffer pointer. 44 | * @param[in] size The read size. 45 | * 46 | * @return Returns true on success and false on failure. 47 | */ 48 | bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size); 49 | 50 | /** 51 | * @brief Writes a buffer to a I2C register. 52 | * 53 | * @param[in] devId The device ID. Use the enum above. 54 | * @param[in] regAddr The register address. 55 | * @param[in] in The input buffer pointer. 56 | * @param[in] size The write size. 57 | * 58 | * @return Returns true on success and false on failure. 59 | */ 60 | bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size); 61 | 62 | /** 63 | * @brief Reads a byte from a I2C register. 64 | * 65 | * @param[in] devId The device ID. Use the enum above. 66 | * @param[in] regAddr The register address. 67 | * 68 | * @return Returns the value read on success otherwise 0xFF. 69 | */ 70 | u8 I2C_readReg(I2cDevice devId, u8 regAddr); 71 | 72 | /** 73 | * @brief Writes a byte to a I2C register. 74 | * 75 | * @param[in] devId The device ID. Use the enum above. 76 | * @param[in] regAddr The register address. 77 | * @param[in] data The data to write. 78 | * 79 | * @return Returns true on success and false on failure. 80 | */ 81 | bool I2C_writeReg(I2cDevice devId, u8 regAddr, u8 data); 82 | -------------------------------------------------------------------------------- /arm9/source/common/colors.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define RGB(r,g,b) \ 4 | (((u32)(r) >> 3) << 11 | \ 5 | ((u32)(g) >> 2) << 5 | \ 6 | ((u32)(b) >> 3)) 7 | 8 | // a base set of colors below 9 | #define COLOR_BLACK RGB(0x00, 0x00, 0x00) 10 | #define COLOR_WHITE RGB(0xFF, 0xFF, 0xFF) 11 | #define COLOR_GREY RGB(0x80, 0x80, 0x80) 12 | 13 | #define COLOR_RED RGB(0xFF, 0x00, 0x00) 14 | #define COLOR_GREEN RGB(0x00, 0xFF, 0x00) 15 | #define COLOR_BLUE RGB(0x00, 0x00, 0xFF) 16 | #define COLOR_YELLOW RGB(0xFF, 0xFF, 0x00) 17 | #define COLOR_CYAN RGB(0xFF, 0x00, 0xFF) 18 | #define COLOR_ORANGE RGB(0xFF, 0xA5, 0x00) 19 | 20 | #define COLOR_BRIGHTRED RGB(0xFF, 0x30, 0x30) 21 | #define COLOR_DARKRED RGB(0x80, 0x00, 0x00) 22 | #define COLOR_BRIGHTYELLOW RGB(0xFF, 0xFF, 0x30) 23 | #define COLOR_BRIGHTGREEN RGB(0x30, 0xFF, 0x30) 24 | #define COLOR_BRIGHTBLUE RGB(0x30, 0x30, 0xFF) 25 | 26 | #define COLOR_TINTEDBLUE RGB(0x60, 0x60, 0x80) 27 | #define COLOR_TINTEDYELLOW RGB(0xD0, 0xD0, 0x60) 28 | #define COLOR_TINTEDGREEN RGB(0x70, 0x80, 0x70) 29 | #define COLOR_LIGHTGREY RGB(0xB0, 0xB0, 0xB0) 30 | #define COLOR_LIGHTERGREY RGB(0xD0, 0xD0, 0xD0) 31 | #define COLOR_DARKGREY RGB(0x50, 0x50, 0x50) 32 | #define COLOR_DARKESTGREY RGB(0x20, 0x20, 0x20) 33 | #define COLOR_SUPERFUCHSIA RGB(0xFF, 0x00, 0xEF) 34 | 35 | // standard colors - used everywhere 36 | #ifndef COLOR_STD_BG 37 | #define COLOR_STD_BG COLOR_BLACK 38 | #endif 39 | #ifndef COLOR_STD_FONT 40 | #define COLOR_STD_FONT COLOR_WHITE 41 | #endif 42 | 43 | // colors for GodMode9 file browser 44 | #define COLOR_SIDE_BAR COLOR_DARKGREY 45 | #define COLOR_MARKED COLOR_TINTEDYELLOW 46 | #define COLOR_FILE COLOR_TINTEDGREEN 47 | #define COLOR_DIR COLOR_TINTEDBLUE 48 | #define COLOR_ROOT COLOR_GREY 49 | #define COLOR_ENTRY(e) (((e)->marked) ? COLOR_MARKED : ((e)->type == T_DIR) ? COLOR_DIR : ((e)->type == T_FILE) ? COLOR_FILE : ((e)->type == T_ROOT) ? COLOR_ROOT : COLOR_GREY) 50 | 51 | // hex viewer colors 52 | #define COLOR_HVOFFS RGB(0x40, 0x60, 0x50) 53 | #define COLOR_HVOFFSI COLOR_DARKESTGREY 54 | #define COLOR_HVASCII RGB(0x40, 0x80, 0x50) 55 | #define COLOR_HVHEX(i) ((i % 2) ? RGB(0x30, 0x90, 0x30) : RGB(0x30, 0x80, 0x30)) 56 | 57 | // text viewer / script viewer colors 58 | #define COLOR_TVOFFS RGB(0x40, 0x40, 0x40) 59 | #define COLOR_TVOFFSL RGB(0x30, 0x30, 0x30) 60 | #define COLOR_TVTEXT RGB(0xA0, 0xA0, 0xA0) 61 | #define COLOR_TVRUN RGB(0xC0, 0x00, 0x00) 62 | #define COLOR_TVCMT RGB(0x60, 0x60, 0x70) 63 | #define COLOR_TVCMD RGB(0xA0, 0xA0, 0xA0) 64 | 65 | // battery symbol colors 66 | #define COLOR_BATTERY_CHARGING RGB(0x3D, 0xB7, 0xE4) 67 | #define COLOR_BATTERY_FULL RGB(0x0F, 0xB0, 0x1B) 68 | #define COLOR_BATTERY_MEDIUM RGB(0xFF, 0x88, 0x49) 69 | #define COLOR_BATTERY_LOW RGB(0xB4, 0x00, 0x00) 70 | -------------------------------------------------------------------------------- /arm9/source/virtual/vkeydb.c: -------------------------------------------------------------------------------- 1 | #include "vtickdb.h" 2 | #include "image.h" 3 | #include "keydb.h" 4 | 5 | #define VKEYDB_BUFFER_SIZE STD_BUFFER_SIZE // 1MB, enough for 32768 entries 6 | 7 | #define NAME_LEGKEY "slot0x%02lXKey%.10s%s.bin" // keyslot / type string / unit extension 8 | 9 | static AesKeyInfo* key_info = NULL; 10 | static u32 n_keys = 0; 11 | 12 | void DeinitVKeyDbDrive(void) { 13 | if (key_info) free(key_info); 14 | key_info = NULL; 15 | } 16 | 17 | u64 InitVKeyDbDrive(void) { // prerequisite: aeskeydb.bin mounted as image 18 | if (!(GetMountState() & BIN_KEYDB)) return 0; 19 | n_keys = 0; 20 | 21 | // sanity check 22 | u64 fsize = GetMountSize(); 23 | if (!fsize || (fsize % sizeof(AesKeyInfo)) || (fsize > VKEYDB_BUFFER_SIZE)) { 24 | n_keys = 0; 25 | return 0; 26 | } 27 | 28 | // setup vkeydb buffer 29 | DeinitVKeyDbDrive(); // dangerous shit 30 | key_info = (AesKeyInfo*) malloc(VKEYDB_BUFFER_SIZE); 31 | if (!key_info) return 0; 32 | 33 | // load the full database into memory 34 | n_keys = fsize / sizeof(AesKeyInfo); 35 | if (ReadImageBytes((u8*) key_info, 0, fsize) != 0) n_keys = 0; 36 | 37 | // decrypt keys if required 38 | for (u32 i = 0; i < n_keys; i++) { 39 | if (key_info[i].isEncrypted) CryptAesKeyInfo(&(key_info[i])); 40 | } 41 | 42 | if (!n_keys) DeinitVKeyDbDrive(); 43 | return (n_keys) ? BIN_KEYDB : 0; 44 | } 45 | 46 | u64 CheckVKeyDbDrive(void) { 47 | if ((GetMountState() & BIN_KEYDB) && key_info) // very basic sanity check 48 | return BIN_KEYDB; 49 | return 0; 50 | } 51 | 52 | bool ReadVKeyDbDir(VirtualFile* vfile, VirtualDir* vdir) { 53 | if (++vdir->index < (int) n_keys) { 54 | AesKeyInfo* key_entry = key_info + vdir->index; 55 | u32 keyslot = key_entry->slot; 56 | char typestr[16] = { 0 }; 57 | char* unitext = 58 | (key_entry->keyUnitType == KEYS_DEVKIT) ? ".dev" : 59 | (key_entry->keyUnitType == KEYS_RETAIL) ? ".ret" : ""; 60 | snprintf(typestr, 12 + 1, "%s%.10s", (key_entry->type == 'I') ? "IV" : 61 | (key_entry->type == 'X') ? "X" : (key_entry->type == 'Y') ? "Y" : "", key_entry->id); 62 | 63 | memset(vfile, 0, sizeof(VirtualFile)); 64 | snprintf(vfile->name, 32, NAME_LEGKEY, keyslot, typestr, unitext); 65 | vfile->offset = vdir->index * sizeof(AesKeyInfo); 66 | vfile->size = 16; // standard size of a key 67 | vfile->keyslot = 0xFF; 68 | vfile->flags = VFLAG_READONLY; 69 | 70 | return true; // found 71 | } 72 | 73 | return false; 74 | } 75 | 76 | int ReadVKeyDbFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count) { 77 | AesKeyInfo* key_entry = key_info + (vfile->offset / sizeof(AesKeyInfo)); 78 | memcpy(buffer, key_entry->key + offset, count); 79 | return 0; 80 | } 81 | 82 | u64 GetVKeyDbDriveSize(void) { 83 | return (n_keys) ? GetMountSize() : 0; 84 | } 85 | -------------------------------------------------------------------------------- /arm9/source/fatfs/diskio.h: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------/ 2 | / Low level disk interface modlue include file (C)ChaN, 2014 / 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO_DEFINED 6 | #define _DISKIO_DEFINED 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #define _USE_WRITE 1 /* 1: Enable disk_write function */ 13 | #define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */ 14 | 15 | 16 | /* Status of Disk Functions */ 17 | typedef BYTE DSTATUS; 18 | 19 | /* Results of Disk Functions */ 20 | typedef enum { 21 | RES_OK = 0, /* 0: Successful */ 22 | RES_ERROR, /* 1: R/W Error */ 23 | RES_WRPRT, /* 2: Write Protected */ 24 | RES_NOTRDY, /* 3: Not Ready */ 25 | RES_PARERR /* 4: Invalid Parameter */ 26 | } DRESULT; 27 | 28 | 29 | /*---------------------------------------*/ 30 | /* Prototypes for disk control functions */ 31 | 32 | 33 | DWORD get_fattime( void ); // not a disk control function, but fits here 34 | DSTATUS disk_initialize (BYTE pdrv); 35 | DSTATUS disk_status (BYTE pdrv); 36 | DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); 37 | DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); 38 | DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); 39 | 40 | 41 | /* Disk Status Bits (DSTATUS) */ 42 | 43 | #define STA_NOINIT 0x01 /* Drive not initialized */ 44 | #define STA_NODISK 0x02 /* No medium in the drive */ 45 | #define STA_PROTECT 0x04 /* Write protected */ 46 | 47 | 48 | /* Command code for disk_ioctrl fucntion */ 49 | 50 | /* Generic command (Used by FatFs) */ 51 | #define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ 52 | #define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ 53 | #define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ 54 | #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ 55 | #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ 56 | 57 | /* Generic command (Not used by FatFs) */ 58 | #define CTRL_POWER 5 /* Get/Set power status */ 59 | #define CTRL_LOCK 6 /* Lock/Unlock media removal */ 60 | #define CTRL_EJECT 7 /* Eject media */ 61 | #define CTRL_FORMAT 8 /* Create physical format on the media */ 62 | 63 | /* MMC/SDC specific ioctl command */ 64 | #define MMC_GET_TYPE 10 /* Get card type */ 65 | #define MMC_GET_CSD 11 /* Get CSD */ 66 | #define MMC_GET_CID 12 /* Get CID */ 67 | #define MMC_GET_OCR 13 /* Get OCR */ 68 | #define MMC_GET_SDSTAT 14 /* Get SD status */ 69 | #define ISDIO_READ 55 /* Read data form SD iSDIO register */ 70 | #define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ 71 | #define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ 72 | 73 | /* ATA/CF specific ioctl command */ 74 | #define ATA_GET_REV 20 /* Get F/W revision */ 75 | #define ATA_GET_MODEL 21 /* Get model name */ 76 | #define ATA_GET_SN 22 /* Get serial number */ 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /arm9/source/crypto/rsa.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * This file is part of fastboot 3DS 5 | * Copyright (C) 2017 derrek, profi200 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "common.h" 22 | 23 | 24 | 25 | ////////////////////////////////// 26 | // RSA // 27 | ////////////////////////////////// 28 | 29 | // REG_RSA_CNT 30 | #define RSA_ENABLE (1u) 31 | #define RSA_UNK_BIT1 (1u<<1) 32 | #define RSA_KEYSLOT(k) ((k)<<4) 33 | #define RSA_GET_KEYSLOT ((REG_RSA_CNT & RSA_KEYSLOT(0xFu))>>4) 34 | #define RSA_INPUT_BIG (1u<<8) 35 | #define RSA_INPUT_LITTLE (0u) 36 | #define RSA_INPUT_NORMAL (1u<<9) 37 | #define RSA_INPUT_REVERSED (0u) 38 | 39 | // RSA_SLOTCNT 40 | #define RSA_KEY_STAT_SET (1u) 41 | #define RSA_KEY_WR_PROT (1u<<1) 42 | #define RSA_KEY_UNK_BIT31 (1u<<31) 43 | 44 | // RSA_SLOTSIZE 45 | #define RSA_SLOTSIZE_2048 (0x40u) 46 | 47 | 48 | /** 49 | * @brief Initializes the RSA hardware. 50 | */ 51 | void RSA_init(void); 52 | 53 | /** 54 | * @brief Selects the given keyslot for all following RSA operations. 55 | * 56 | * @param[in] keyslot The keyslot to select. 57 | */ 58 | void RSA_selectKeyslot(u8 keyslot); 59 | 60 | /** 61 | * @brief Sets a RSA modulus + exponent in the specified keyslot. 62 | * 63 | * @param[in] keyslot The keyslot this key will be set for. 64 | * @param[in] mod Pointer to 2048-bit RSA modulus data. 65 | * @param[in] exp The exponent to set. 66 | * 67 | * @return Returns true on success, false otherwise. 68 | */ 69 | bool RSA_setKey2048(u8 keyslot, const u32 *const mod, u32 exp); 70 | 71 | /** 72 | * @brief Decrypts a RSA 2048 signature. 73 | * 74 | * @param decSig Pointer to decrypted destination signature. 75 | * @param[in] encSig Pointer to encrypted source signature. 76 | * 77 | * @return Returns true on success, false otherwise. 78 | */ 79 | bool RSA_decrypt2048(u32 *const decSig, const u32 *const encSig); 80 | 81 | /** 82 | * @brief Verifies a RSA 2048 SHA 256 signature. 83 | * @brief Note: This function skips the ASN.1 data and is therefore not safe. 84 | * 85 | * @param[in] encSig Pointer to encrypted source signature. 86 | * @param[in] data Pointer to the data to hash. 87 | * @param[in] size The hash data size. 88 | * 89 | * @return Returns true if the signature is valid, false otherwise. 90 | */ 91 | bool RSA_verify2048(const u32 *const encSig, const u32 *const data, u32 size); 92 | -------------------------------------------------------------------------------- /common/pxi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2017-2019 Wolfvak 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #pragma once 20 | #include 21 | 22 | #ifdef ARM9 23 | #define PXI_BASE (0x10008000) 24 | #define PXI_RX_INTERRUPT (14) 25 | #else 26 | #define PXI_BASE (0x10163000) 27 | #define PXI_RX_INTERRUPT (83) 28 | #endif 29 | 30 | enum { 31 | PXI_LEGACY_MODE = 0, 32 | PXI_GET_SHMEM, 33 | PXI_SET_VMODE, 34 | 35 | PXI_I2C_READ, 36 | PXI_I2C_WRITE, 37 | 38 | PXI_NVRAM_ONLINE, 39 | PXI_NVRAM_READ, 40 | 41 | PXI_NOTIFY_LED, 42 | PXI_BRIGHTNESS, 43 | 44 | PXI_XALLOC, 45 | }; 46 | 47 | /* 48 | * These should be somewhat "unusual" 49 | * IDs and shouldnt be similar to 50 | * those used by any other software 51 | */ 52 | enum { 53 | ARM11_READY_BARRIER = 19, 54 | }; 55 | 56 | #define PXI_FIFO_LEN (16) 57 | #define PXI_MAX_ARGS (64) 58 | 59 | #define PXI_SYNC_RECV ((vu8*)(PXI_BASE + 0x00)) 60 | #define PXI_SYNC_SEND ((vu8*)(PXI_BASE + 0x01)) 61 | #define PXI_SYNC_IRQ ((vu8*)(PXI_BASE + 0x03)) 62 | #define PXI_CNT ((vu16*)(PXI_BASE + 0x04)) 63 | #define PXI_SEND ((vu32*)(PXI_BASE + 0x08)) 64 | #define PXI_RECV ((vu32*)(PXI_BASE + 0x0C)) 65 | 66 | #define PXI_CNT_SEND_FIFO_EMPTY (BIT(0)) 67 | #define PXI_CNT_SEND_FIFO_FULL (BIT(1)) 68 | #define PXI_CNT_SEND_FIFO_EMPTY_IRQ (BIT(2)) 69 | #define PXI_CNT_SEND_FIFO_FLUSH (BIT(3)) 70 | #define PXI_CNT_RECV_FIFO_EMPTY (BIT(8)) 71 | #define PXI_CNT_RECV_FIFO_FULL (BIT(9)) 72 | #define PXI_CNT_RECV_FIFO_AVAIL_IRQ (BIT(10)) 73 | #define PXI_CNT_ACKNOWLEDGE_ERROR (BIT(14)) 74 | #define PXI_CNT_ENABLE_FIFO (BIT(15)) 75 | 76 | static inline void PXI_SetRemote(u8 msg) 77 | { 78 | *PXI_SYNC_SEND = msg; 79 | } 80 | 81 | static inline u8 PXI_GetRemote(void) 82 | { 83 | return *PXI_SYNC_RECV; 84 | } 85 | 86 | static inline void PXI_WaitRemote(u8 msg) 87 | { 88 | while(PXI_GetRemote() != msg); 89 | } 90 | 91 | static inline void PXI_Send(u32 w) 92 | { 93 | while(*PXI_CNT & PXI_CNT_SEND_FIFO_FULL); 94 | *PXI_SEND = w; 95 | } 96 | 97 | static inline u32 PXI_Recv(void) 98 | { 99 | while(*PXI_CNT & PXI_CNT_RECV_FIFO_EMPTY); 100 | return *PXI_RECV; 101 | } 102 | 103 | void PXI_Barrier(u8 barrier_id); 104 | void PXI_Reset(void); 105 | 106 | void PXI_SendArray(const u32 *w, u32 c); 107 | void PXI_RecvArray(u32 *w, u32 c); 108 | 109 | u32 PXI_DoCMD(u32 cmd, const u32 *args, u32 argc); 110 | -------------------------------------------------------------------------------- /arm9/source/filesys/fsutil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | // move / copy flags 6 | #define OVERRIDE_PERM (1UL<<0) 7 | #define NO_CANCEL (1UL<<1) 8 | #define SILENT (1UL<<2) 9 | #define CALC_SHA (1UL<<3) 10 | #define BUILD_PATH (1UL<<4) 11 | #define ALLOW_EXPAND (1UL<<5) 12 | #define ASK_ALL (1UL<<6) 13 | #define SKIP_ALL (1UL<<7) 14 | #define OVERWRITE_ALL (1UL<<8) 15 | #define APPEND_ALL (1UL<<9) 16 | 17 | // file selector flags 18 | #define NO_DIRS (1UL<<0) 19 | #define NO_FILES (1UL<<1) 20 | #define HIDE_EXT (1UL<<2) 21 | #define SELECT_DIRS (1UL<<3) 22 | 23 | 24 | /** Return total size of SD card **/ 25 | uint64_t GetSDCardSize(); 26 | 27 | /** Format the SD card **/ 28 | bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label); 29 | 30 | /** Format the bonus drive area **/ 31 | bool SetupBonusDrive(void); 32 | 33 | /** Check for file lock, offer to unlock if possible **/ 34 | bool FileUnlock(const char* path); 35 | 36 | /** Create / open file and write the provided data to it **/ 37 | bool FileSetData(const char* path, const void* data, size_t size, size_t foffset, bool create); 38 | 39 | /** Read data from file@offset **/ 40 | size_t FileGetData(const char* path, void* data, size_t size, size_t foffset); 41 | 42 | /** Get size of file **/ 43 | size_t FileGetSize(const char* path); 44 | 45 | /** Get SHA-256 of file **/ 46 | bool FileGetSha256(const char* path, u8* sha256, u64 offset, u64 size); 47 | 48 | /** Find data in file **/ 49 | u32 FileFindData(const char* path, u8* data, u32 size_data, u32 offset_file); 50 | 51 | /** Inject file into file @offset **/ 52 | bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_orig, u64 size, u32* flags); 53 | 54 | /** Fill (a portion of) a file with a fillbyte **/ 55 | bool FileSetByte(const char* dest, u64 offset, u64 size, u8 fillbyte, u32* flags); 56 | 57 | /** Create a dummy file at dest **/ 58 | bool FileCreateDummy(const char* cpath, const char* filename, u64 size); 59 | 60 | /** Create a new directory in cpath **/ 61 | bool DirCreate(const char* cpath, const char* dirname); 62 | 63 | /** Get # of files, subdirs and total size for directory **/ 64 | bool DirInfo(const char* path, u64* tsize, u32* tdirs, u32* tfiles); 65 | 66 | /** True if path exists **/ 67 | bool PathExist(const char* path); 68 | 69 | /** Direct recursive move / copy of files or directories **/ 70 | bool PathMoveCopy(const char* dest, const char* orig, u32* flags, bool move); 71 | 72 | /** Recursively copy a file or directory **/ 73 | bool PathCopy(const char* destdir, const char* orig, u32* flags); 74 | 75 | /** Recursively move a file or directory **/ 76 | bool PathMove(const char* destdir, const char* orig, u32* flags); 77 | 78 | /** Recursively delete a file or directory **/ 79 | bool PathDelete(const char* path); 80 | 81 | /** Rename file / folder in path to new name **/ 82 | bool PathRename(const char* path, const char* newname); 83 | 84 | /** Change the attributes on a file/directory **/ 85 | bool PathAttr(const char* path, u8 attr, u8 mask); 86 | 87 | /** Select a file **/ 88 | bool FileSelector(char* result, const char* text, const char* path, const char* pattern, u32 flags, bool new_style); 89 | -------------------------------------------------------------------------------- /arm9/source/gamecart/card_spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is based on SPI.h from TWLSaveTool. Its copyright notice is 3 | * reproduced below. 4 | * 5 | * Copyright (C) 2015-2016 TuxSH 6 | * 7 | * TWLSaveTool is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see 19 | */ 20 | 21 | #pragma once 22 | #include "common.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | typedef struct CardSPITypeData CardSPITypeData; 29 | 30 | typedef struct { 31 | const CardSPITypeData *chip; 32 | bool infrared; 33 | } CardSPIType; 34 | 35 | struct CardSPITypeData { 36 | int (*enableWriting) (CardSPIType type); 37 | int (*readSaveData) (CardSPIType type, u32 offset, void* data, u32 size); 38 | int (*writeSaveData) (CardSPIType type, u32 offset, const void* data, u32 size); 39 | int (*eraseSector) (CardSPIType type, u32 offset); 40 | u32 jedecId; 41 | u32 capacity; 42 | u32 eraseSize; 43 | u32 pageSize; 44 | u32 writeSize; 45 | u8 writeCommand; 46 | u8 programCommand; 47 | u8 eraseCommand; 48 | }; 49 | 50 | #define NO_CHIP NULL 51 | 52 | const CardSPITypeData * const EEPROM_512B; 53 | 54 | const CardSPITypeData * const EEPROM_8KB; 55 | const CardSPITypeData * const EEPROM_64KB; 56 | const CardSPITypeData * const EEPROM_128KB; 57 | 58 | const CardSPITypeData * const FLASH_256KB_1; 59 | const CardSPITypeData * const FLASH_256KB_2; 60 | const CardSPITypeData * const FLASH_512KB_1; 61 | const CardSPITypeData * const FLASH_512KB_2; 62 | const CardSPITypeData * const FLASH_1MB; 63 | const CardSPITypeData * const FLASH_8MB; 64 | 65 | const CardSPITypeData * const FLASH_128KB_CTR; // Most common, including Ocarina of time 3D 66 | const CardSPITypeData * const FLASH_512KB_CTR; // Also common, including Detective Pikachu 67 | const CardSPITypeData * const FLASH_1MB_CTR; // For example Pokemon Ultra Sun 68 | 69 | int CardSPIWriteRead(CardSPIType type, const void* cmd, u32 cmdSize, void* answer, u32 answerSize, const void* data, u32 dataSize); 70 | int CardSPIWaitWriteEnd(CardSPIType type, u32 timeout); 71 | int CardSPIEnableWriting(CardSPIType type); 72 | int CardSPIReadJEDECIDAndStatusReg(CardSPIType type, u32* id, u8* statusReg); 73 | int CardSPIGetCardSPIType(CardSPIType* type, bool infrared); 74 | u32 CardSPIGetPageSize(CardSPIType type); 75 | u32 CardSPIGetCapacity(CardSPIType type); 76 | u32 CardSPIGetEraseSize(CardSPIType type); 77 | 78 | int CardSPIWriteSaveData(CardSPIType type, u32 offset, const void* data, u32 size); 79 | int CardSPIReadSaveData(CardSPIType type, u32 offset, void* data, u32 size); 80 | 81 | int CardSPIEraseSector(CardSPIType type, u32 offset); 82 | int CardSPIErase(CardSPIType type); 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | -------------------------------------------------------------------------------- /arm9/source/game/boss.c: -------------------------------------------------------------------------------- 1 | #include "boss.h" 2 | #include "sha.h" 3 | #include "aes.h" 4 | 5 | // http://3dbrew.org/wiki/SpotPass#Content_Header 6 | u32 CheckBossHash(BossHeader* boss, bool encrypted) { 7 | u8 hash_area[0x14] __attribute__((aligned(4))) = { 0 }; 8 | u8 boss_sha256[0x20]; 9 | u8 l_sha256[0x20]; 10 | 11 | // calculate hash 12 | memcpy(hash_area, ((u8*) boss) + 0x28, 0x12); 13 | memcpy(boss_sha256, boss->hash_header, 0x20); 14 | if (encrypted) { 15 | CryptBoss(hash_area, 0x28, 0x12, boss); 16 | CryptBoss(boss_sha256, 0x28 + 0x12, 0x20, boss); 17 | } 18 | sha_quick(l_sha256, hash_area, 0x14, SHA256_MODE); 19 | 20 | return (memcmp(boss_sha256, l_sha256, 0x20) == 0) ? 0 : 1; 21 | } 22 | 23 | u32 ValidateBossHeader(BossHeader* header, u32 fsize) { 24 | u8 boss_magic[] = { BOSS_MAGIC }; 25 | 26 | // base checks 27 | if ((memcmp(header->magic, boss_magic, sizeof(boss_magic)) != 0) || 28 | (fsize && (fsize != getbe32(header->filesize))) || 29 | (getbe32(header->filesize) < sizeof(BossHeader)) || 30 | (getbe16(header->unknown0) != 0x0001) || 31 | (getbe16(header->cnthdr_hash_type) != 0x0002) || 32 | (getbe16(header->cnthdr_rsa_size) != 0x0002)) 33 | return 1; 34 | 35 | // hash check 36 | if ((CheckBossHash(header, false) != 0) && 37 | (CheckBossHash(header, true) != 0)) 38 | return 1; 39 | 40 | return 0; 41 | } 42 | 43 | u32 GetBossPayloadHashHeader(u8* header, BossHeader* boss) { 44 | memset(header, 0, BOSS_SIZE_PAYLOAD_HEADER); 45 | memcpy(header, ((u8*) boss) + 0x15A, 0x1C); 46 | return 0; 47 | } 48 | 49 | u32 CheckBossEncrypted(BossHeader* boss) { 50 | return CheckBossHash(boss, true); 51 | } 52 | 53 | // on the fly de-/encryptor for BOSS 54 | u32 CryptBoss(void* data, u32 offset, u32 size, BossHeader* boss) { 55 | // check data area (encrypted area starts @0x28) 56 | if (offset + size < 0x28) return 0; 57 | else if (offset < 0x28) { 58 | data = ((u8*)data + 0x28 - offset); 59 | size -= 0x28 - offset; 60 | offset = 0x28; 61 | } 62 | 63 | // decrypt BOSS data 64 | u8 ctr[16] = { 0 }; 65 | memcpy(ctr, boss->ctr12, 12); 66 | ctr[15] = 0x01; 67 | use_aeskey(0x38); 68 | ctr_decrypt_byte(data, data, size, offset - 0x28, AES_CNT_CTRNAND_MODE, ctr); 69 | 70 | return 0; 71 | } 72 | 73 | // on the fly de-/encryptor for BOSS - sequential 74 | u32 CryptBossSequential(void* data, u32 offset, u32 size) { 75 | // warning: this will only work for sequential processing 76 | // unexpected results otherwise 77 | static BossHeader boss = { 0 }; 78 | static BossHeader* bossptr = NULL; 79 | 80 | // fetch boss header from data 81 | if ((offset == 0) && (size >= sizeof(BossHeader))) { 82 | bossptr = NULL; 83 | memcpy(&boss, data, sizeof(BossHeader)); 84 | if (((CheckBossEncrypted(&boss) == 0) && 85 | (CryptBoss((u8*) &boss, 0, sizeof(BossHeader), &boss) != 0)) || 86 | (ValidateBossHeader(&boss, 0) != 0)) 87 | return 1; 88 | bossptr = &boss; 89 | } 90 | 91 | // safety check, boss pointer 92 | if (!bossptr) return 1; 93 | 94 | return CryptBoss(data, offset, size, bossptr); 95 | } 96 | --------------------------------------------------------------------------------