├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── ci.yml ├── .gitignore ├── Makefile ├── Makefile.build ├── Makefile.common ├── README.md ├── arm11 ├── Makefile ├── link.ld └── source │ ├── arm │ ├── gic.c │ ├── gic.h │ ├── mmu.c │ ├── mmu.h │ ├── scu.c │ ├── scu.h │ ├── timer.c │ ├── timer.h │ ├── xrq.c │ ├── xrq.h │ └── xrqVectors.s │ ├── boot.s │ ├── hw │ ├── codec.c │ ├── codec.h │ ├── gpio.h │ ├── gpulcd.c │ ├── gpulcd.h │ ├── hid.c │ ├── hid.h │ ├── i2c.c │ ├── i2c.h │ ├── mcu.c │ ├── mcu.h │ ├── nvram.c │ └── nvram.h │ ├── main.c │ └── system │ ├── event.h │ ├── sections.h │ ├── sys.c │ └── sys.h ├── arm9 ├── Makefile ├── link.ld └── source │ ├── common │ ├── asmfunc.h │ ├── colors.h │ ├── hid.c │ ├── hid.h │ ├── memcpy.s │ ├── mmio.h │ ├── mmio.s │ ├── power.c │ ├── power.h │ ├── rtc.c │ ├── rtc.h │ ├── screenshot.c │ ├── screenshot.h │ ├── sighax.c │ ├── sighax.h │ ├── swkbd.c │ ├── swkbd.h │ ├── timer.c │ ├── timer.h │ ├── touchcal.c │ ├── touchcal.h │ ├── ui.c │ ├── ui.h │ ├── unittype.h │ ├── utf.c │ └── utf.h │ ├── crypto │ ├── aes.c │ ├── aes.h │ ├── crc16.c │ ├── crc16.h │ ├── crc32.c │ ├── crc32.h │ ├── keydb.c │ ├── keydb.h │ ├── rsa.c │ ├── rsa.h │ ├── sha.c │ └── sha.h │ ├── fatfs │ ├── 00history.txt │ ├── 00readme.txt │ ├── LICENSE.txt │ ├── diskio.c │ ├── diskio.h │ ├── ff.c │ ├── ff.h │ ├── ffconf.h │ ├── ffsystem.c │ ├── ffunicode.c │ ├── ramdrive.c │ └── ramdrive.h │ ├── filesys │ ├── fatmbr.c │ ├── fatmbr.h │ ├── filetype.c │ ├── filetype.h │ ├── fs.h │ ├── fsdir.c │ ├── fsdir.h │ ├── fsdrive.c │ ├── fsdrive.h │ ├── fsgame.c │ ├── fsgame.h │ ├── fsinit.c │ ├── fsinit.h │ ├── fsperm.c │ ├── fsperm.h │ ├── fsutil.c │ ├── fsutil.h │ ├── image.c │ ├── image.h │ ├── sddata.c │ ├── sddata.h │ ├── support.c │ ├── support.h │ ├── vff.c │ └── vff.h │ ├── game │ ├── 3dsx.h │ ├── bdri.c │ ├── bdri.h │ ├── boss.c │ ├── boss.h │ ├── bps.c │ ├── bps.h │ ├── cert.c │ ├── cert.h │ ├── cia.c │ ├── cia.h │ ├── cifinish.h │ ├── cmd.c │ ├── cmd.h │ ├── codelzss.c │ ├── codelzss.h │ ├── disadiff.c │ ├── disadiff.h │ ├── exefs.c │ ├── exefs.h │ ├── firm.c │ ├── firm.h │ ├── game.h │ ├── gba.c │ ├── gba.h │ ├── ips.c │ ├── ips.h │ ├── ncch.c │ ├── ncch.h │ ├── ncchinfo.c │ ├── ncchinfo.h │ ├── ncsd.c │ ├── ncsd.h │ ├── nds.c │ ├── nds.h │ ├── region.c │ ├── region.h │ ├── romfs.c │ ├── romfs.h │ ├── seedsave.c │ ├── seedsave.h │ ├── smdh.c │ ├── smdh.h │ ├── tad.c │ ├── tad.h │ ├── ticket.c │ ├── ticket.h │ ├── ticketdb.c │ ├── ticketdb.h │ ├── tie.c │ ├── tie.h │ ├── tmd.c │ └── tmd.h │ ├── gamecart │ ├── card_ntr.c │ ├── card_ntr.h │ ├── card_spi.c │ ├── card_spi.h │ ├── command_ak2i.c │ ├── command_ak2i.h │ ├── command_ctr.c │ ├── command_ctr.h │ ├── command_ntr.c │ ├── command_ntr.h │ ├── gamecart.c │ ├── gamecart.h │ ├── ndscard.h │ ├── protocol.c │ ├── protocol.h │ ├── protocol_ctr.c │ ├── protocol_ctr.h │ ├── protocol_ntr.c │ ├── protocol_ntr.h │ ├── secure_ntr.c │ └── secure_ntr.h │ ├── godmode.c │ ├── godmode.h │ ├── language.c │ ├── language.h │ ├── lodepng │ ├── lodepng.c │ └── lodepng.h │ ├── lua │ ├── README.md │ ├── gm9internalfs.c │ ├── gm9internalfs.h │ ├── gm9internalsys.c │ ├── gm9internalsys.h │ ├── gm9loader.c │ ├── gm9loader.h │ ├── gm9lua.c │ ├── gm9lua.h │ ├── gm9os.c │ ├── gm9os.h │ ├── gm9title.c │ ├── gm9title.h │ ├── gm9ui.c │ ├── gm9ui.h │ ├── lapi.c │ ├── lapi.h │ ├── lauxlib.c │ ├── lauxlib.h │ ├── lbaselib.c │ ├── lcode.c │ ├── lcode.h │ ├── lcorolib.c │ ├── lctype.c │ ├── lctype.h │ ├── ldblib.c │ ├── ldebug.c │ ├── ldebug.h │ ├── ldo.c │ ├── ldo.h │ ├── ldump.c │ ├── lfunc.c │ ├── lfunc.h │ ├── lgc.c │ ├── lgc.h │ ├── linit.c │ ├── ljumptab.h │ ├── llex.c │ ├── llex.h │ ├── llimits.h │ ├── lmathlib.c │ ├── lmem.c │ ├── lmem.h │ ├── loadlib.c │ ├── lobject.c │ ├── lobject.h │ ├── lopcodes.c │ ├── lopcodes.h │ ├── lopnames.h │ ├── lparser.c │ ├── lparser.h │ ├── lprefix.h │ ├── lstate.c │ ├── lstate.h │ ├── lstring.c │ ├── lstring.h │ ├── lstrlib.c │ ├── ltable.c │ ├── ltable.h │ ├── ltablib.c │ ├── ltm.c │ ├── ltm.h │ ├── lua.h │ ├── luaconf.h │ ├── lualib.h │ ├── lundump.c │ ├── lundump.h │ ├── lutf8lib.c │ ├── lvm.c │ ├── lvm.h │ ├── lzio.c │ └── lzio.h │ ├── main.c │ ├── nand │ ├── essentials.h │ ├── nand.c │ ├── nand.h │ ├── sdmmc.c │ └── sdmmc.h │ ├── qrcodegen │ ├── qrcodegen.c │ └── qrcodegen.h │ ├── start.s │ ├── system │ ├── bootfirm.h │ ├── bootfirm.s │ ├── i2c.c │ ├── i2c.h │ ├── itcm.h │ ├── memmap.h │ ├── mymalloc.c │ ├── mymalloc.h │ ├── png.c │ ├── png.h │ ├── spiflash.c │ ├── spiflash.h │ ├── tar.c │ ├── tar.h │ ├── vram0.h │ ├── vram_data.s │ ├── xrq.c │ └── xrq_handler.s │ ├── utils │ ├── ctrtransfer.c │ ├── ctrtransfer.h │ ├── gameutil.c │ ├── gameutil.h │ ├── keydbutil.c │ ├── keydbutil.h │ ├── nandcmac.c │ ├── nandcmac.h │ ├── nandutil.c │ ├── nandutil.h │ ├── paint9.c │ ├── paint9.h │ ├── scripting.c │ ├── scripting.h │ ├── sysinfo.c │ ├── sysinfo.h │ └── utils.h │ └── virtual │ ├── vbdri.c │ ├── vbdri.h │ ├── vcart.c │ ├── vcart.h │ ├── vdisadiff.c │ ├── vdisadiff.h │ ├── vgame.c │ ├── vgame.h │ ├── virtual.c │ ├── virtual.h │ ├── vkeydb.c │ ├── vkeydb.h │ ├── vmem.c │ ├── vmem.h │ ├── vnand.c │ ├── vnand.h │ ├── vvram.c │ └── vvram.h ├── common ├── arm.h ├── bfn.h ├── common.h ├── entrypoints.h ├── fixp.h ├── hid_map.h ├── pxi.c ├── pxi.h ├── shmem.h ├── spi.c ├── spi.h ├── types.h └── vram.h ├── crowdin.yml ├── data ├── aeskeydb.bin ├── easter.bin ├── font_default.frf ├── luapackages │ ├── fs.lua │ ├── io.lua │ ├── json.lua │ ├── sys.lua │ └── util.lua └── preload.lua ├── license.txt ├── resources ├── BrickedMode9_splash.png ├── GodMode64_splash.png ├── GodMode9_splash.png ├── GodMode9_splash_2nd_anniversary.png ├── GodMode9_splash_3rd_anniversary.png ├── GodMode9_splash_4th_anniversary.png ├── GodMode9_splash_5th_anniversary.png ├── GodMode9_splash_6th_anniversary.png ├── GodMode9_splash_default.png ├── GodMode9_splash_default_pre2.0.0.png ├── SafeMode9_splash.png ├── ZuishMode9_splash.png ├── fonts │ ├── cp_437.txt │ ├── font_6x10.pbm │ ├── font_6x10.txt │ ├── font_6x10_japanese.pbm │ ├── font_6x10_japanese.txt │ ├── font_acorn_8x8.pbm │ ├── font_c64_8x8.pbm │ ├── font_gb_7x6.pbm │ ├── font_nbraille_4x6.pbm │ ├── font_original_8x8.pbm │ ├── font_sheikah_8x8.pbm │ ├── font_tiny_4x6.pbm │ ├── font_zuish_8x8.pbm │ └── fusion │ │ ├── font_fusion_hans_8x8.frf │ │ ├── font_fusion_hans_8x8.pbm │ │ ├── font_fusion_hans_8x8.txt │ │ ├── font_fusion_hant_8x8.frf │ │ ├── font_fusion_hant_8x8.pbm │ │ ├── font_fusion_hant_8x8.txt │ │ ├── font_fusion_ja_8x8.frf │ │ ├── font_fusion_ja_8x8.pbm │ │ ├── font_fusion_ja_8x8.txt │ │ ├── font_fusion_ko_8x8.frf │ │ ├── font_fusion_ko_8x8.pbm │ │ └── font_fusion_ko_8x8.txt ├── gm9 │ ├── languages │ │ ├── ja.frf │ │ ├── ry.frf │ │ ├── zh-CN.frf │ │ └── zh-TW.frf │ ├── scripts │ │ ├── GM9Megascript.gm9 │ │ └── NANDManager.gm9 │ └── support │ │ ├── decTitleKeys.bin.here │ │ └── seeddb.bin.here ├── languages │ ├── de.json │ ├── en.json │ ├── es.json │ ├── fr.json │ ├── id.json │ ├── it.json │ ├── ja-KANA.json │ ├── ja.json │ ├── nl.json │ ├── pl.json │ ├── ru.json │ ├── ry.json │ ├── source.json │ ├── zh-CN.json │ └── zh-TW.json ├── logo.png ├── lua-doc.md ├── sample │ ├── HelloBranching.gm9 │ ├── HelloScript.gm9 │ ├── HelloScript.lua │ └── HelloSpaghetti.gm9 └── wiki.png └── utils ├── add2tar.py ├── fontriff.py ├── patch.json.gz ├── transcp.py ├── transriff.py └── unmark.py /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | container: devkitpro/devkitarm 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | 13 | - name: Fix apt sources 14 | run: | 15 | apt-get update 16 | apt-get -y install dirmngr 17 | echo 'deb http://us.archive.ubuntu.com/ubuntu/ bionic main' >> /etc/apt/sources.list 18 | apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32 19 | apt-get update 20 | 21 | - name: Install and update packages 22 | run: | 23 | apt-get -y install python3 python3-pip p7zip-full libarchive13 24 | python3 --version 25 | python3 -m pip install --upgrade pip setuptools 26 | python3 -m pip install cryptography git+https://github.com/TuxSH/firmtool.git 27 | 28 | - name: Build Project 29 | run: make release -j$(nproc) 30 | 31 | - name: Prepare build artifact 32 | working-directory: release 33 | run: | 34 | ZIPNAME=$(ls GodMode9-*.zip) 35 | rm $ZIPNAME 36 | echo "OUTNAME=${ZIPNAME%.zip}" >> $GITHUB_ENV 37 | 38 | - uses: actions/upload-artifact@v4 39 | with: 40 | name: ${{ env.OUTNAME }} 41 | path: release/* 42 | if-no-files-found: error 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.d 3 | *.o 4 | *.ko 5 | *.obj 6 | *.elf 7 | *.map 8 | *.dis 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Libraries 15 | *.lib 16 | *.a 17 | *.la 18 | *.lo 19 | 20 | # Shared objects (inc. Windows DLLs) 21 | *.dll 22 | *.so 23 | *.so.* 24 | *.dylib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | *.i*86 31 | *.x86_64 32 | *.hex 33 | 34 | # Debug files 35 | *.dSYM/ 36 | 37 | # OS leftovers 38 | desktop.ini 39 | .DS_Store 40 | 41 | # Sublime files 42 | *.sublime-* 43 | 44 | # Visual Studio Code files 45 | .vscode 46 | 47 | # Build directories 48 | /build 49 | /output 50 | /release 51 | 52 | # Build leftovers 53 | /data/README_internal.md 54 | 55 | # User additions 56 | /zzz_backup 57 | /arm9/source/language.inl 58 | *.trf 59 | -------------------------------------------------------------------------------- /Makefile.build: -------------------------------------------------------------------------------- 1 | 2 | LIBS ?= 3 | 4 | OBJECTS := $(patsubst $(SOURCE)/%.s, $(BUILD)/%.o, \ 5 | $(patsubst $(SOURCE)/%.c, $(BUILD)/%.o, \ 6 | $(call rwildcard, $(SOURCE), *.s *.c))) 7 | 8 | OBJECTS_COMMON := $(patsubst $(COMMON_DIR)/%.c, $(BUILD)/%.cmn.o, \ 9 | $(call rwildcard, $(COMMON_DIR), *.c)) 10 | 11 | .PHONY: all 12 | all: $(TARGET).elf 13 | 14 | .PHONY: clean 15 | clean: 16 | @rm -rf $(BUILD) $(TARGET).elf $(TARGET).dis $(TARGET).map 17 | 18 | $(TARGET).elf: $(OBJECTS) $(OBJECTS_COMMON) 19 | @mkdir -p "$(@D)" 20 | @$(CC) $(LDFLAGS) $^ -o $@ $(LIBS) 21 | @$(OBJDUMP) -S -h $@ > $@.dis 22 | 23 | $(BUILD)/%.cmn.o: $(COMMON_DIR)/%.c 24 | @mkdir -p "$(@D)" 25 | @echo "[$(PROCESSOR)] $<" 26 | @$(CC) -c $(CFLAGS) -o $@ $< 27 | 28 | $(BUILD)/%.o: $(SOURCE)/%.c 29 | @mkdir -p "$(@D)" 30 | @echo "[$(PROCESSOR)] $<" 31 | @$(CC) -c $(CFLAGS) -o $@ $< 32 | 33 | $(BUILD)/%.o: $(SOURCE)/%.s 34 | @mkdir -p "$(@D)" 35 | @echo "[$(PROCESSOR)] $<" 36 | @$(CC) -c $(ASFLAGS) -o $@ $< 37 | 38 | include $(call rwildcard, $(BUILD), *.d) 39 | -------------------------------------------------------------------------------- /Makefile.common: -------------------------------------------------------------------------------- 1 | export OBJDUMP := arm-none-eabi-objdump 2 | 3 | dirname = $(shell dirname $(1)) 4 | 5 | rwildcard = $(foreach d, $(wildcard $1*), \ 6 | $(filter $(subst *, %, $2), $d) \ 7 | $(call rwildcard, $d/, $2)) 8 | 9 | FLAVOR ?= GodMode9 10 | SPLASH = resources/$(FLAVOR)_splash.png 11 | 12 | ifeq ($(FLAVOR),SafeMode9) 13 | CFLAGS += -DSAFEMODE 14 | else ifeq ($(FLAVOR),GodMode64) 15 | OVERRIDE_FONT := resources/fonts/font_c64_8x8.pbm 16 | CFLAGS += -DDEFAULT_FONT=\"font_c64_8x8.pbm\" 17 | CFLAGS += -DCOLOR_STD_FONT="RGB(0x7B, 0x71, 0xD5)" 18 | CFLAGS += -DCOLOR_STD_BG="RGB(0x41, 0x30, 0xA4)" 19 | else ifeq ($(FLAVOR),BrickedMode9) 20 | OVERRIDE_FONT := resources/fonts/font_nbraille_4x6.pbm 21 | CFLAGS += -DDEFAULT_FONT=\"font_nbraille_4x6.pbm\" 22 | CFLAGS += -DCOLOR_STD_FONT="RGB(0xFF, 0xFF, 0x00)" 23 | CFLAGS += -DCOLOR_STD_BG="RGB(0x00, 0x00, 0xFF)" 24 | else ifeq ($(FLAVOR),ZuishMode9) 25 | OVERRIDE_FONT := resources/fonts/font_zuish_8x8.pbm 26 | CFLAGS += -DDEFAULT_FONT=\"font_zuish_8x8.pbm\" 27 | endif 28 | 29 | ifeq ($(LARGEDLC),1) 30 | CFLAGS += -DTITLE_MAX_CONTENTS=1536 31 | else 32 | CFLAGS += -DTITLE_MAX_CONTENTS=1024 33 | endif 34 | 35 | ifeq ($(SALTMODE),1) 36 | CFLAGS += -DSALTMODE 37 | endif 38 | 39 | ifeq ($(SWITCH_SCREENS),1) 40 | CFLAGS += -DSWITCH_SCREENS 41 | endif 42 | 43 | ifeq ($(SCRIPT_RUNNER),1) 44 | CFLAGS += -DSCRIPT_RUNNER 45 | endif 46 | 47 | ifeq ($(AUTO_UNLOCK),1) 48 | CFLAGS += -DAUTO_UNLOCK 49 | endif 50 | 51 | ifeq ($(TIMER_UNLOCK),1) 52 | CFLAGS += -DTIMER_UNLOCK 53 | endif 54 | 55 | ifeq ($(HIDE_HIDDEN),1) 56 | CFLAGS += -DHIDE_HIDDEN 57 | endif 58 | 59 | ifeq ($(SHOW_FREE),1) 60 | CFLAGS += -DSHOW_FREE 61 | endif 62 | 63 | ifdef FIXED_BRIGHTNESS 64 | CFLAGS += -DFIXED_BRIGHTNESS=$(FIXED_BRIGHTNESS) 65 | endif 66 | 67 | ifdef SD_TIMEOUT 68 | CFLAGS += -DSD_TIMEOUT=$(SD_TIMEOUT) 69 | endif 70 | 71 | ifeq ($(NO_LUA),1) 72 | CFLAGS += -DNO_LUA 73 | endif 74 | 75 | ifdef N_PANES 76 | CFLAGS += -DN_PANES=$(N_PANES) 77 | endif 78 | 79 | ifeq ($(MONITOR_HEAP),1) 80 | CFLAGS += -DMONITOR_HEAP 81 | endif 82 | 83 | ifdef NTRBOOT 84 | FTFLAGS = -S spi-retail 85 | FTDFLAGS = -S spi-dev 86 | FIRM = $(OUTDIR)/$(FLAVOR)_ntr.firm 87 | FIRMD = $(OUTDIR)/$(FLAVOR)_ntr_dev.firm 88 | else 89 | FTFLAGS = -S nand-retail 90 | FTDFLAGS = -S nand-dev 91 | FIRM = $(OUTDIR)/$(FLAVOR).firm 92 | FIRMD = $(OUTDIR)/$(FLAVOR)_dev.firm 93 | endif 94 | -------------------------------------------------------------------------------- /arm11/Makefile: -------------------------------------------------------------------------------- 1 | PROCESSOR := ARM11 2 | 3 | TARGET := $(shell basename "$(CURDIR)") 4 | 5 | SOURCE := source 6 | BUILD := build 7 | 8 | SUBARCH := -D$(PROCESSOR) -march=armv6k -mtune=mpcore -marm -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,--use-blx,-Map,$(TARGET).map -flto 15 | 16 | include ../Makefile.common 17 | include ../Makefile.build 18 | -------------------------------------------------------------------------------- /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 = 96K 8 | HIGHRAM (RWX) : ORIGIN = 0xFFFF0000, LENGTH = 4K 9 | } 10 | 11 | SECTIONS 12 | { 13 | .text : ALIGN(4K) 14 | { 15 | __text_pa = LOADADDR(.text); 16 | __text_va = ABSOLUTE(.); 17 | *(.text*) 18 | . = ALIGN(4K); 19 | __text_va_end = .; 20 | } >AXIWRAM 21 | 22 | .data : ALIGN(4K) 23 | { 24 | __data_pa = LOADADDR(.data); 25 | __data_va = ABSOLUTE(.); 26 | *(.data*) 27 | . = ALIGN(4K); 28 | __data_va_end = .; 29 | } >AXIWRAM 30 | 31 | .rodata : ALIGN(4K) 32 | { 33 | __rodata_pa = LOADADDR(.rodata); 34 | __rodata_va = ABSOLUTE(.); 35 | *(.rodata*) 36 | . = ALIGN(4K); 37 | __rodata_va_end = .; 38 | } >AXIWRAM 39 | 40 | .shared (NOLOAD) : ALIGN(4K) 41 | { 42 | __shared_pa = LOADADDR(.shared); 43 | __shared_va = ABSOLUTE(.); 44 | *(.shared*) 45 | . = ALIGN(4K); 46 | __shared_va_end = .; 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_va_end = .; 56 | } >AXIWRAM 57 | } 58 | -------------------------------------------------------------------------------- /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 { 24 | MMU_STRONG_ORDER = 0, 25 | MMU_UNCACHEABLE, 26 | MMU_DEV_SHARED, 27 | MMU_DEV_NONSHARED, 28 | MMU_CACHE_WT, 29 | MMU_CACHE_WB, 30 | MMU_CACHE_WBA, 31 | MMU_MEMORY_TYPES, 32 | }; 33 | 34 | enum { 35 | MMU_NO_ACCESS = 0, 36 | MMU_READ_ONLY, 37 | MMU_READ_WRITE, 38 | MMU_ACCESS_TYPES, 39 | }; 40 | 41 | #define MMU_FLAGS(t, ap, nx, s) ((s) << 25 | (nx) << 24 | (ap) << 8 | (t)) 42 | 43 | #define MMU_FLAGS_TYPE(f) ((f) & 0xFF) 44 | #define MMU_FLAGS_ACCESS(f) (((f) >> 8) & 0xFF) 45 | 46 | #define MMU_FLAGS_NOEXEC(f) ((f) & BIT(24)) 47 | #define MMU_FLAGS_SHARED(f) ((f) & BIT(25)) 48 | 49 | u32 mmuMapArea(u32 va, u32 pa, u32 size, u32 flags); 50 | 51 | void mmuInvalidate(void); 52 | void mmuInvalidateVA(u32 addr); // DO NOT USE 53 | 54 | void mmuInitRegisters(void); 55 | -------------------------------------------------------------------------------- /arm11/source/arm/scu.c: -------------------------------------------------------------------------------- 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 | #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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | 34 | static inline void TIMER_WaitMS(u32 ms) { 35 | TIMER_WaitTicks(CLK_MS_TO_TICKS(ms)); 36 | } 37 | -------------------------------------------------------------------------------- /arm11/source/arm/xrq.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of GodMode9 3 | * Copyright (C) 2020 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 | u32 xrqInstallVectorTable(void); 22 | -------------------------------------------------------------------------------- /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 | u16 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 | -------------------------------------------------------------------------------- /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 | #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 | if (cpad_x > 0) { 34 | ret |= BUTTON_RIGHT; 35 | } else if (cpad_x < 0) { 36 | ret |= BUTTON_LEFT; 37 | } 38 | 39 | if (cpad_y > 0) { 40 | ret |= BUTTON_UP; 41 | } else if (cpad_y < 0) { 42 | ret |= BUTTON_DOWN; 43 | } 44 | 45 | return ret; 46 | } 47 | 48 | u64 HID_GetState(void) 49 | { 50 | CODEC_Input codec; 51 | u64 ret = 0; 52 | 53 | CODEC_Get(&codec); 54 | 55 | ret = REG_HID | mcuGetSpecialHID(); 56 | if (!(ret & BUTTON_ARROW)) 57 | ret |= HID_ConvertCPAD(codec.cpad_x, codec.cpad_y); 58 | 59 | if (codec.ts_x <= 0xFFF) 60 | ret |= BUTTON_TOUCH; 61 | 62 | ret |= (((u64)codec.ts_x << 16) | (u64)codec.ts_y) << 32; 63 | 64 | return ret; 65 | } 66 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 "arm/timer.h" 24 | #include "hw/i2c.h" 25 | 26 | #define MCU_INTERRUPT (0x71) 27 | #define I2C_MCU_DEVICE (3) 28 | 29 | enum { 30 | MCUEV_HID_PWR_DOWN = BIT(0), 31 | MCUEV_HID_PWR_HOLD = BIT(1), 32 | MCUEV_HID_HOME_DOWN = BIT(2), 33 | MCUEV_HID_HOME_UP = BIT(3), 34 | MCUEV_HID_WIFI_SWITCH = BIT(4), 35 | MCUEV_HID_SHELL_CLOSE = BIT(5), 36 | MCUEV_HID_SHELL_OPEN = BIT(6), 37 | MCUEV_HID_VOLUME_SLIDER = BIT(22), 38 | }; 39 | 40 | u8 mcuGetVolumeSlider(void); 41 | u32 mcuGetSpecialHID(void); 42 | 43 | void mcuSetStatusLED(u32 period_ms, u32 color); 44 | void mcuResetLEDs(void); 45 | 46 | void mcuReset(void); 47 | 48 | static inline u8 mcuReadReg(u8 addr) 49 | { 50 | u8 val; 51 | I2C_readRegBuf(I2C_MCU_DEVICE, addr, &val, 1); 52 | return val; 53 | } 54 | 55 | static inline bool mcuReadRegBuf(u8 addr, u8 *buf, u32 size) 56 | { 57 | return I2C_readRegBuf(I2C_MCU_DEVICE, addr, buf, size); 58 | } 59 | 60 | static inline bool mcuWriteReg(u8 addr, u8 val) 61 | { 62 | return I2C_writeRegBuf(I2C_MCU_DEVICE, addr, &val, 1); 63 | } 64 | 65 | static inline bool mcuWriteRegBuf(u8 addr, const u8 *buf, u32 size) 66 | { 67 | return I2C_writeRegBuf(I2C_MCU_DEVICE, addr, buf, size); 68 | } 69 | 70 | static inline void MCU_controlLCDPower(u8 bits) 71 | { 72 | mcuWriteReg(0x22u, bits); 73 | } 74 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/system/event.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef struct { 6 | void (*reset)(void); 7 | u32 (*test)(u32 param, u32 clear); 8 | } EventInterface; 9 | 10 | const EventInterface *getEventIRQ(void); 11 | const EventInterface *getEventMCU(void); 12 | 13 | static inline void eventReset(const EventInterface *ei) { 14 | ei->reset(); 15 | } 16 | 17 | static inline u32 eventTest(const EventInterface *ei, u32 param, u32 clear) { 18 | return ei->test(param, clear); 19 | } 20 | 21 | static inline u32 eventWait(const EventInterface *ei, u32 param, u32 clear) { 22 | while(1) { 23 | u32 ret = ei->test(param, clear); 24 | if (ret) return ret; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /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##_va_end; 24 | DEF_SECT_(text) 25 | DEF_SECT_(data) 26 | DEF_SECT_(rodata) 27 | DEF_SECT_(bss) 28 | DEF_SECT_(shared) 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##_va_end) - (u32)(&__##n##_va))) 34 | 35 | #define SECTION_TRI(n) SECTION_VA(n), SECTION_PA(n), SECTION_LEN(n) 36 | -------------------------------------------------------------------------------- /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/Makefile: -------------------------------------------------------------------------------- 1 | PROCESSOR := ARM9 2 | 3 | TARGET := $(shell basename "$(CURDIR)") 4 | 5 | SOURCE := source 6 | BUILD := build 7 | 8 | SUBARCH := -D$(PROCESSOR) -march=armv5te -mtune=arm946e-s -mthumb -mfloat-abi=soft 9 | INCDIRS := source source/common source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/lodepng source/lua 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,--use-blx,-Map,$(TARGET).map -flto 15 | LIBS += -lm 16 | 17 | include ../Makefile.common 18 | include ../Makefile.build 19 | 20 | arm9_data.elf: arm9.elf 21 | $(OBJCOPY) -O elf32-littlearm -j .rodata* -j .data* -j .bss* $< $@ 22 | 23 | arm9_code.elf: arm9.elf 24 | $(OBJCOPY) -O elf32-littlearm -j .text* -j .vectors* $< $@ 25 | -------------------------------------------------------------------------------- /arm9/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 2 | OUTPUT_ARCH(arm) 3 | ENTRY(_start) 4 | 5 | MEMORY 6 | { 7 | VECTORS (RX) : ORIGIN = 0x08000000, LENGTH = 64 8 | CODEMEM (RX) : ORIGIN = 0x08000040, LENGTH = 512K - 64 9 | BOOTROM (R) : ORIGIN = 0x08080000, LENGTH = 128K /* BootROM mirrors, don't touch! */ 10 | DATAMEM (RW) : ORIGIN = 0x080A0000, LENGTH = 384K 11 | } 12 | 13 | SECTIONS 14 | { 15 | .vectors : ALIGN(4) { 16 | __vectors_lma = LOADADDR(.vectors); 17 | __vectors_vma = ABSOLUTE(.); 18 | KEEP(*(.vectors)); 19 | . = ALIGN(4); 20 | __vectors_len = ABSOLUTE(.) - __vectors_vma; 21 | } >VECTORS AT>CODEMEM 22 | 23 | .text : ALIGN(4) { 24 | __text_s = ABSOLUTE(.); 25 | *(.text.start); 26 | *(.text*); 27 | . = ALIGN(4); 28 | __text_e = ABSOLUTE(.); 29 | } >CODEMEM 30 | 31 | .rodata : ALIGN(4) { 32 | *(.rodata*); 33 | . = ALIGN(4); 34 | __exidx_start = .; 35 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 36 | __exidx_end = .; 37 | . = ALIGN(4); 38 | } >DATAMEM 39 | 40 | .data : ALIGN(4) { 41 | *(.data*); 42 | . = ALIGN(4); 43 | } >DATAMEM 44 | 45 | .bss (NOLOAD) : ALIGN(4) { 46 | __bss_start = .; 47 | *(.bss*); 48 | . = ALIGN(4); 49 | __bss_end = .; 50 | } >DATAMEM 51 | 52 | __end__ = ABSOLUTE(.); 53 | } 54 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/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(PXICMD_SET_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/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/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 | -------------------------------------------------------------------------------- /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/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, sizeof(filename), 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/common/screenshot.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void CreateScreenshot(void); 4 | -------------------------------------------------------------------------------- /arm9/source/common/sighax.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | extern const u8 sig_nand_firm_retail[256]; 6 | extern const u8 sig_nand_firm_retail_alt[256]; 7 | extern const u8 sig_nand_firm_dev[256]; 8 | extern const u8 sig_nand_ncsd_retail[256]; 9 | extern const u8 sig_nand_ncsd_dev[256]; 10 | -------------------------------------------------------------------------------- /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/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/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/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/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/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 | static 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/crypto/crc16.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | u16 crc16_quick(const void* src, u32 len); 6 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/fatfs/00readme.txt: -------------------------------------------------------------------------------- 1 | FatFs Module Source Files R0.14 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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/filesys/fsgame.c: -------------------------------------------------------------------------------- 1 | #include "fsgame.h" 2 | #include "fsperm.h" 3 | #include "gameutil.h" 4 | #include "language.h" 5 | #include "tie.h" 6 | #include "ui.h" 7 | #include "vff.h" 8 | 9 | void SetupTitleManager(DirStruct* contents) { 10 | char goodname[256]; 11 | ShowProgress(0, 0, ""); 12 | for (u32 s = 0; s < contents->n_entries; s++) { 13 | DirEntry* entry = &(contents->entry[s]); 14 | // set good name for entry 15 | u32 plen = strnlen(entry->path, 256); 16 | if (!ShowProgress(s+1, contents->n_entries, entry->path)) break; 17 | if ((GetGoodName(goodname, entry->path, false) != 0) || 18 | (plen + 1 + strnlen(goodname, 256) + 1 > 256)) 19 | continue; 20 | entry->p_name = plen + 1; 21 | entry->name = entry->path + entry->p_name; 22 | snprintf(entry->name, 256 - entry->p_name, "%s", goodname); 23 | // grab title size from tie 24 | TitleInfoEntry tie; 25 | if (fvx_qread(entry->path, &tie, 0, sizeof(TitleInfoEntry), NULL) != FR_OK) 26 | continue; 27 | entry->size = tie.title_size; 28 | } 29 | } 30 | 31 | bool GoodRenamer(DirEntry* entry, bool ask) { 32 | char goodname[256]; // get goodname 33 | if ((GetGoodName(goodname, entry->path, false) != 0) || 34 | (strncmp(goodname + strnlen(goodname, 256) - 4, ".tmd", 4) == 0)) // no TMD, please 35 | return false; 36 | 37 | if (ask) { // ask for confirmatiom 38 | char oldname_tr[UTF_BUFFER_BYTESIZE(32)]; 39 | char newname_ww[256]; 40 | TruncateString(oldname_tr, entry->name, 32, 8); 41 | strncpy(newname_ww, goodname, 256); 42 | WordWrapString(newname_ww, 32); 43 | if (!ShowPrompt(true, "%s\n%s\n \n%s", oldname_tr, STR_RENAME_TO_GOOD_NAME, newname_ww)) 44 | return true; // call it a success because user choice 45 | } 46 | 47 | char npath[256]; // get new path 48 | strncpy(npath, entry->path, 256); 49 | char* nname = strrchr(npath, '/'); 50 | if (!nname) return false; 51 | nname++; 52 | strncpy(nname, goodname, 256 - 1 - (nname - npath)); 53 | // actual rename 54 | if (!CheckDirWritePermissions(entry->path)) return false; 55 | if (f_rename(entry->path, npath) != FR_OK) return false; 56 | strncpy(entry->path, npath, 256); 57 | entry->name = entry->path + (nname - npath); 58 | 59 | return true; 60 | } 61 | -------------------------------------------------------------------------------- /arm9/source/filesys/fsgame.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "fsdir.h" 5 | 6 | void SetupTitleManager(DirStruct* contents); 7 | bool GoodRenamer(DirEntry* entry, bool ask); 8 | -------------------------------------------------------------------------------- /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/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|(PERM_SDDATA&~PERM_SDCARD))) 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/filesys/image.c: -------------------------------------------------------------------------------- 1 | #include "image.h" 2 | #include "vff.h" 3 | #include "nandcmac.h" 4 | 5 | static FIL mount_file; 6 | static u64 mount_state = 0; 7 | 8 | static char mount_path[256] = { 0 }; 9 | 10 | static bool fix_cmac = false; 11 | 12 | 13 | int ReadImageBytes(void* buffer, u64 offset, u64 count) { 14 | UINT bytes_read; 15 | UINT ret; 16 | if (!count) return -1; 17 | if (!mount_state) return FR_INVALID_OBJECT; 18 | if (fvx_tell(&mount_file) != offset) { 19 | if (fvx_size(&mount_file) < offset) return -1; 20 | fvx_lseek(&mount_file, offset); 21 | } 22 | ret = fvx_read(&mount_file, buffer, count, &bytes_read); 23 | return (ret != 0) ? (int) ret : (bytes_read != count) ? -1 : 0; 24 | } 25 | 26 | int WriteImageBytes(const void* buffer, u64 offset, u64 count) { 27 | UINT bytes_written; 28 | UINT ret; 29 | if (!count) return -1; 30 | if (!mount_state) return FR_INVALID_OBJECT; 31 | if (fvx_tell(&mount_file) != offset) 32 | fvx_lseek(&mount_file, offset); 33 | ret = fvx_write(&mount_file, buffer, count, &bytes_written); 34 | if (ret == 0) fix_cmac = true; 35 | return (ret != 0) ? (int) ret : (bytes_written != count) ? -1 : 0; 36 | } 37 | 38 | int ReadImageSectors(void* buffer, u32 sector, u32 count) { 39 | return ReadImageBytes(buffer, sector * 0x200, count * 0x200); 40 | } 41 | 42 | int WriteImageSectors(const void* buffer, u32 sector, u32 count) { 43 | return WriteImageBytes(buffer, sector * 0x200, count * 0x200); 44 | } 45 | 46 | int SyncImage(void) { 47 | return mount_state ? fvx_sync(&mount_file) : FR_INVALID_OBJECT; 48 | } 49 | 50 | u64 GetMountSize(void) { 51 | return mount_state ? fvx_size(&mount_file) : 0; 52 | } 53 | 54 | u64 GetMountState(void) { 55 | return mount_state; 56 | } 57 | 58 | const char* GetMountPath(void) { 59 | return mount_path; 60 | } 61 | 62 | u64 MountImage(const char* path) { 63 | if (mount_state) { 64 | fvx_close(&mount_file); 65 | if (fix_cmac) FixFileCmac(mount_path, false); 66 | fix_cmac = false; 67 | mount_state = 0; 68 | *mount_path = 0; 69 | } 70 | u64 type = (path) ? IdentifyFileType(path) : 0; 71 | if (!type) return 0; 72 | if ((fvx_open(&mount_file, path, FA_READ | FA_WRITE | FA_OPEN_EXISTING) != FR_OK) && 73 | (fvx_open(&mount_file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)) 74 | return 0; 75 | fvx_lseek(&mount_file, 0); 76 | fvx_sync(&mount_file); 77 | strncpy(mount_path, path, 256); 78 | return (mount_state = type); 79 | } 80 | -------------------------------------------------------------------------------- /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/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/filesys/support.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | // scripts / payloads dir names 6 | #define LANGUAGES_DIR "languages" 7 | #define SCRIPTS_DIR "scripts" 8 | #define LUASCRIPTS_DIR "luascripts" 9 | #define PAYLOADS_DIR "payloads" 10 | 11 | bool CheckSupportFile(const char* fname); 12 | size_t LoadSupportFile(const char* fname, void* buffer, size_t max_len); 13 | bool SaveSupportFile(const char* fname, void* buffer, size_t len); 14 | bool SetAsSupportFile(const char* fname, const char* source); 15 | 16 | bool GetSupportDir(char* path, const char* dname); 17 | bool CheckSupportDir(const char* fpath); 18 | bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern); 19 | -------------------------------------------------------------------------------- /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 | #define fvx_eof(fp) (fvx_tell(fp) == fvx_size(fp)) 12 | 13 | #define FN_ANY 0x00 14 | #define FN_HIGHEST 0x01 15 | #define FN_LOWEST 0x02 16 | 17 | // wrapper functions for ff.h + sddata.h 18 | // incomplete(!) extension to FatFS to support a common interface for virtual and FAT 19 | FRESULT fvx_open (FIL* fp, const TCHAR* path, BYTE mode); 20 | FRESULT fvx_read (FIL* fp, void* buff, UINT btr, UINT* br); 21 | FRESULT fvx_write (FIL* fp, const void* buff, UINT btw, UINT* bw); 22 | FRESULT fvx_close (FIL* fp); 23 | FRESULT fvx_lseek (FIL* fp, FSIZE_t ofs); 24 | FRESULT fvx_sync (FIL* fp); 25 | FRESULT fvx_stat (const TCHAR* path, FILINFO* fno); 26 | FRESULT fvx_rename (const TCHAR* path_old, const TCHAR* path_new); 27 | FRESULT fvx_unlink (const TCHAR* path); 28 | FRESULT fvx_mkdir (const TCHAR* path); 29 | FRESULT fvx_opendir (DIR* dp, const TCHAR* path); 30 | FRESULT fvx_closedir (DIR* dp); 31 | FRESULT fvx_readdir (DIR* dp, FILINFO* fno); 32 | 33 | // additional quick read / write / create functions 34 | FRESULT fvx_qread (const TCHAR* path, void* buff, FSIZE_t ofs, UINT btr, UINT* br); 35 | FRESULT fvx_qwrite (const TCHAR* path, const void* buff, FSIZE_t ofs, UINT btw, UINT* bw); 36 | FRESULT fvx_qcreate (const TCHAR* path, UINT btc); 37 | 38 | // additional quick file info functions 39 | FSIZE_t fvx_qsize (const TCHAR* path); 40 | 41 | // additional recursive functions 42 | FRESULT fvx_rmkdir (const TCHAR* path); 43 | FRESULT fvx_rmkpath (const TCHAR* path); 44 | FRESULT fvx_runlink (const TCHAR* path); 45 | 46 | // additional wildcard based functions 47 | FRESULT fvx_match_name(const TCHAR* path, const TCHAR* pattern); 48 | FRESULT fvx_preaddir (DIR* dp, FILINFO* fno, const TCHAR* pattern); 49 | FRESULT fvx_findpath (TCHAR* path, const TCHAR* pattern, BYTE mode); 50 | FRESULT fvx_findnopath (TCHAR* path, const TCHAR* pattern); 51 | 52 | // additional state function 53 | bool fvx_opened(const FIL* fp); 54 | -------------------------------------------------------------------------------- /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/source/game/bdri.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "ticket.h" 5 | #include "tie.h" 6 | 7 | // https://www.3dbrew.org/wiki/Inner_FAT 8 | 9 | u32 GetNumTitleInfoEntries(const char* path); 10 | u32 GetNumTickets(const char* path); 11 | u32 ListTitleInfoEntryTitleIDs(const char* path, u8* title_ids, u32 max_title_ids); 12 | u32 ListTicketTitleIDs(const char* path, u8* title_ids, u32 max_title_ids); 13 | u32 ReadTitleInfoEntryFromDB(const char* path, const u8* title_id, TitleInfoEntry* tie); 14 | u32 ReadTicketFromDB(const char* path, const u8* title_id, Ticket** ticket); 15 | u32 RemoveTitleInfoEntryFromDB(const char* path, const u8* title_id); 16 | u32 RemoveTicketFromDB(const char* path, const u8* title_id); 17 | u32 AddTitleInfoEntryToDB(const char* path, const u8* title_id, const TitleInfoEntry* tie, bool replace); 18 | u32 AddTicketToDB(const char* path, const u8* title_id, const Ticket* ticket, bool replace); 19 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/game/cert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define CERT_MAX_SIZE (sizeof(CertificateSignature) + 0x23C + sizeof(CertificateBody) + 0x238) 6 | 7 | #define CERT_RSA4096_SIG_SIZE (sizeof(CertificateSignature) + 0x23C) 8 | #define CERT_RSA2048_SIG_SIZE (sizeof(CertificateSignature) + 0x13C) 9 | #define CERT_ECC_SIG_SIZE (sizeof(CertificateSignature) + 0x7C) 10 | #define CERT_RSA4096_BODY_SIZE (sizeof(CertificateBody) + 0x238) 11 | #define CERT_RSA2048_BODY_SIZE (sizeof(CertificateBody) + 0x138) 12 | #define CERT_ECC_BODY_SIZE (sizeof(CertificateBody) + 0x78) 13 | 14 | #define CERTIFICATE_NULL_INIT ((Certificate){NULL, NULL}) 15 | 16 | // from: http://3dbrew.org/wiki/Certificates 17 | // all numbers in big endian 18 | typedef struct { 19 | u8 sig_type[4]; 20 | u8 signature[]; 21 | } PACKED_ALIGN(1) CertificateSignature; 22 | 23 | typedef struct { 24 | char issuer[0x40]; 25 | u8 keytype[4]; 26 | char name[0x40]; 27 | u8 expiration[4]; 28 | u8 pub_key_data[]; 29 | } PACKED_ALIGN(1) CertificateBody; 30 | 31 | typedef struct { 32 | CertificateSignature* sig; 33 | CertificateBody* data; 34 | } Certificate; 35 | 36 | bool Certificate_IsValid(const Certificate* cert); 37 | bool Certificate_IsRSA(const Certificate* cert); 38 | bool Certificate_IsECC(const Certificate* cert); 39 | u32 Certificate_GetSignatureSize(const Certificate* cert, u32* size); 40 | u32 Certificate_GetModulusSize(const Certificate* cert, u32* size); 41 | u32 Certificate_GetModulus(const Certificate* cert, void* mod); 42 | u32 Certificate_GetExponent(const Certificate* cert, void* exp); 43 | u32 Certificate_GetEccSingleCoordinateSize(const Certificate* cert, u32* size); 44 | u32 Certificate_GetEccXY(const Certificate* cert, void* X, void* Y); 45 | u32 Certificate_GetSignatureChunkSize(const Certificate* cert, u32* size); 46 | u32 Certificate_GetDataChunkSize(const Certificate* cert, u32* size); 47 | u32 Certificate_GetFullSize(const Certificate* cert, u32* size); 48 | u32 Certificate_VerifySignatureBlock(const Certificate* cert, const void* sig, u32 sig_size, const void* data, u32 data_size, bool sha256); 49 | u32 Certificate_MakeEditSafe(Certificate* cert); 50 | u32 Certificate_AllocCopyOut(const Certificate* cert, Certificate* out_cert); 51 | u32 Certificate_RawCopy(const Certificate* cert, void* raw); 52 | u32 Certificate_Cleanup(Certificate* cert); 53 | 54 | u32 LoadCertFromCertDb(Certificate* cert, const char* issuer); 55 | u32 BuildRawCertBundleFromCertDb(void* rawout, size_t* size, const char* const* cert_issuers, int count); 56 | -------------------------------------------------------------------------------- /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 | TicketCommon ticket; 38 | u8 ticket_padding[0x40 - (TICKET_COMMON_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, u32 ticket_size); 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/cifinish.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define CIFINISH_MAGIC "CIFINISH" 6 | #define CIFINISH_TITLE_MAGIC "TITLE" 7 | #define CIFINISH_SIZE(c) (sizeof(CifinishHeader) + ((((CifinishHeader*)(c))->n_entries) * sizeof(CifinishTitle))) 8 | 9 | // see: https://github.com/ihaveamac/custom-install/blob/ac0be9d61d7ebef9356df23036dc53e8e862011a/custominstall.py#L163 10 | typedef struct { 11 | char magic[8]; 12 | u32 version; 13 | u32 n_entries; 14 | } __attribute__((packed, aligned(4))) CifinishHeader; 15 | 16 | typedef struct { 17 | char magic[5]; 18 | u8 padding0; 19 | u8 has_seed; // 1 if it does, otherwise 0 20 | u8 padding1; 21 | u64 title_id; 22 | u8 seed[16]; 23 | } __attribute__((packed, aligned(4))) CifinishTitle; 24 | -------------------------------------------------------------------------------- /arm9/source/game/cmd.c: -------------------------------------------------------------------------------- 1 | #include "cmd.h" 2 | 3 | 4 | CmdHeader* BuildAllocCmdData(TitleMetaData* tmd) { 5 | CmdHeader proto; 6 | CmdHeader* cmd = NULL; 7 | u32 content_count = getbe16(tmd->content_count); 8 | u16 max_cnt_idx = 0; 9 | 10 | // sanity check 11 | if (!content_count) 12 | return NULL; 13 | 14 | // find max content id 15 | TmdContentChunk* chunk = (TmdContentChunk*) (tmd + 1); 16 | for (u32 i = 0; (i < content_count) && (i < TMD_MAX_CONTENTS); i++, chunk++) 17 | if (getbe16(chunk->index) > max_cnt_idx) max_cnt_idx = getbe16(chunk->index); 18 | 19 | // allocate memory for CMD / basic setup 20 | proto.cmd_id = 1; 21 | proto.n_entries = max_cnt_idx + 1; 22 | proto.n_cmacs = content_count; 23 | proto.unknown = 1; 24 | memset(proto.cmac, 0x00, 0x10); 25 | cmd = (CmdHeader*) malloc(CMD_SIZE(&proto)); 26 | if (!cmd) return NULL; 27 | memset(cmd, 0x00, CMD_SIZE(&proto)); 28 | memcpy(cmd, &proto, sizeof(CmdHeader)); 29 | cmd->unknown = 0x0; // this means no CMACs, only valid for NAND 30 | 31 | // copy content ids 32 | u32* cnt_id = (u32*) (cmd + 1); 33 | u32* cnt_id_2nd = cnt_id + cmd->n_entries; 34 | chunk = (TmdContentChunk*) (tmd + 1); 35 | memset(cnt_id, 0xFF, cmd->n_entries * sizeof(u32)); 36 | for (u32 i = 0; (i < content_count) && (i < TMD_MAX_CONTENTS); i++, chunk++) { 37 | u32 chunk_id = getbe32(chunk->id); 38 | cnt_id[getbe16(chunk->index)] = chunk_id; 39 | *(cnt_id_2nd++) = chunk_id; 40 | } 41 | 42 | // bubble sort the second content id list 43 | bool bs_finished = false; 44 | cnt_id_2nd = cnt_id + cmd->n_entries; 45 | while (!bs_finished) { 46 | bs_finished = true; 47 | for (u32 b = 1; b < cmd->n_cmacs; b++) { 48 | if (cnt_id_2nd[b] < cnt_id_2nd[b-1]) { 49 | u32 swp = cnt_id_2nd[b]; 50 | cnt_id_2nd[b] = cnt_id_2nd[b-1]; 51 | cnt_id_2nd[b-1] = swp; 52 | bs_finished = false; 53 | } 54 | } 55 | } 56 | 57 | // set CMACs to 0x00 58 | u8* cnt_cmac = (u8*) (cnt_id_2nd + cmd->n_cmacs); 59 | memset(cnt_cmac, 0x00, 0x10 * cmd->n_entries); 60 | 61 | // we still need to fix / set the CMACs inside the CMD file! 62 | return cmd; 63 | } 64 | -------------------------------------------------------------------------------- /arm9/source/game/cmd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "tmd.h" 5 | 6 | #define CMD_SIZE(cmd) (sizeof(CmdHeader) + \ 7 | (((cmd)->n_entries) * sizeof(u32)) + \ 8 | (((cmd)->n_cmacs) * sizeof(u32)) + \ 9 | (((cmd)->unknown) ? (((cmd)->n_entries) * 0x10) : 0)) 10 | 11 | // from: http://3dbrew.org/wiki/Titles#Data_Structure 12 | typedef struct { 13 | u32 cmd_id; // same as filename id, .cmd 14 | u32 n_entries; // matches highest content index 15 | u32 n_cmacs; // number of cmacs in file (excluding the one @0x10) 16 | u32 unknown; // usually 1 17 | u8 cmac[0x10]; // calculated from first 0x10 byte of data, no hashing 18 | // followed by u32 list of content ids (sorted by index, 0xFFFFFFFF for unavailable) 19 | // followed by u32 list of content ids (sorted by id?) 20 | // followed by CMACs (may contain garbage) 21 | } __attribute__((packed, aligned(4))) CmdHeader; 22 | 23 | CmdHeader* BuildAllocCmdData(TitleMetaData* tmd); 24 | -------------------------------------------------------------------------------- /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/game/disadiff.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | 6 | // info taken from here: 7 | // http://3dbrew.org/wiki/DISA_and_DIFF 8 | // https://github.com/wwylele/3ds-save-tool 9 | 10 | #define DISA_MAGIC 'D', 'I', 'S', 'A', 0x00, 0x00, 0x04, 0x00 11 | #define DIFF_MAGIC 'D', 'I', 'F', 'F', 0x00, 0x00, 0x03, 0x00 12 | #define IVFC_MAGIC 'I', 'V', 'F', 'C', 0x00, 0x00, 0x02, 0x00 13 | #define DPFS_MAGIC 'D', 'P', 'F', 'S', 0x00, 0x00, 0x01, 0x00 14 | #define DIFI_MAGIC 'D', 'I', 'F', 'I', 0x00, 0x00, 0x01, 0x00 15 | 16 | 17 | // condensed info to enable reading/writing IVFC lvl4 18 | typedef struct { 19 | u32 offset_table; 20 | u32 size_table; 21 | u32 offset_partition_hash; 22 | u32 offset_difi; 23 | u32 offset_master_hash; // relative to start of difi 24 | u32 offset_dpfs_lvl1; // relative to start of file 25 | u32 offset_dpfs_lvl2; // relative to start of file 26 | u32 offset_dpfs_lvl3; // relative to start of file 27 | u32 size_dpfs_lvl1; 28 | u32 size_dpfs_lvl2; 29 | u32 size_dpfs_lvl3; 30 | u32 log_dpfs_lvl2; 31 | u32 log_dpfs_lvl3; 32 | u32 log_ivfc_lvl1; 33 | u32 log_ivfc_lvl2; 34 | u32 log_ivfc_lvl3; 35 | u32 log_ivfc_lvl4; 36 | u32 offset_ivfc_lvl1; // relative to DPFS lvl3 37 | u32 offset_ivfc_lvl2; // relative to DPFS lvl3 38 | u32 offset_ivfc_lvl3; // relative to DPFS lvl3 39 | u32 offset_ivfc_lvl4; // relative to DPFS lvl3 if not external 40 | u32 size_ivfc_lvl1; 41 | u32 size_ivfc_lvl2; 42 | u32 size_ivfc_lvl3; 43 | u32 size_ivfc_lvl4; 44 | u8 dpfs_lvl1_selector; 45 | u8 ivfc_use_extlvl4; 46 | u8* dpfs_lvl2_cache; // optional, NULL when unused 47 | } __attribute__((packed)) DisaDiffRWInfo; 48 | 49 | u32 GetDisaDiffRWInfo(const char* path, DisaDiffRWInfo* info, bool partitionB); 50 | u32 BuildDisaDiffDpfsLvl2Cache(const char* path, const DisaDiffRWInfo* info, u8* cache, u32 cache_size); 51 | u32 ReadDisaDiffIvfcLvl4(const char* path, const DisaDiffRWInfo* info, u32 offset, u32 size, void* buffer); 52 | u32 WriteDisaDiffIvfcLvl4(const char* path, const DisaDiffRWInfo* info, u32 offset, u32 size, const void* buffer); 53 | // Not intended for external use other than vdisadiff 54 | u32 FixDisaDiffIvfcLevel(const DisaDiffRWInfo* info, u32 level, u32 offset, u32 size, u32* next_offset, u32* next_size); -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 "ticket.h" 18 | #include "tie.h" 19 | #include "cmd.h" 20 | #include "bdri.h" 21 | #include "ticketdb.h" 22 | #include "ncchinfo.h" 23 | #include "cifinish.h" 24 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /arm9/source/game/region.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "language.h" 3 | #include "region.h" 4 | 5 | // Names of system regions, short form. 6 | const char* const g_regionNamesShort[SMDH_NUM_REGIONS] = { 7 | "JPN", 8 | "USA", 9 | "EUR", 10 | "AUS", // mostly unused 11 | "CHN", 12 | "KOR", 13 | "TWN", 14 | }; 15 | 16 | // Names of system regions, long form and translatable. 17 | const char* regionNameLong(int region) { 18 | switch(region) { 19 | case REGION_JPN: return STR_REGION_JAPAN; 20 | case REGION_USA: return STR_REGION_AMERICAS; 21 | case REGION_EUR: return STR_REGION_EUROPE; 22 | case REGION_AUS: return STR_REGION_AUSTRALIA; 23 | case REGION_CHN: return STR_REGION_CHINA; 24 | case REGION_KOR: return STR_REGION_KOREA; 25 | case REGION_TWN: return STR_REGION_TAIWAN; 26 | default: return STR_REGION_UNKNOWN; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /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 and translatable. 31 | const char* regionNameLong(int region); 32 | -------------------------------------------------------------------------------- /arm9/source/game/seedsave.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "disadiff.h" 5 | 6 | #define SEEDINFO_NAME "seeddb.bin" 7 | #define SEEDINFO_SIZE(sdb) (16 + ((sdb)->n_entries * sizeof(SeedInfoEntry))) 8 | 9 | #define SEEDSAVE_MAX_ENTRIES 2000 10 | #define SEEDSAVE_AREA_OFFSET 0x3000 11 | 12 | typedef struct { 13 | u8 byte[16]; 14 | } PACKED_STRUCT Seed; 15 | 16 | typedef struct { 17 | u64 titleId; 18 | Seed seed; 19 | u8 reserved[8]; 20 | } PACKED_STRUCT SeedInfoEntry; 21 | 22 | typedef struct { 23 | u32 n_entries; 24 | u8 padding[12]; 25 | SeedInfoEntry entries[SEEDSAVE_MAX_ENTRIES]; // this number is only a placeholder 26 | } PACKED_STRUCT SeedInfo; 27 | 28 | typedef struct { 29 | u32 unknown0; 30 | u32 n_entries; 31 | u8 unknown1[0x1000 - 0x8]; 32 | u64 titleId[SEEDSAVE_MAX_ENTRIES]; 33 | Seed seed[SEEDSAVE_MAX_ENTRIES]; 34 | } PACKED_STRUCT SeedDb; 35 | 36 | u32 GetSeedPath(char* path, const char* drv); 37 | u32 FindSeed(u8* seed, u64 titleId, u32 hash_seed); 38 | u32 AddSeedToDb(SeedInfo* seed_info, SeedInfoEntry* seed_entry); 39 | u32 InstallSeedDbToSystem(SeedInfo* seed_info, bool to_emunand); 40 | u32 SetupSeedPrePurchase(u64 titleId, bool to_emunand); 41 | u32 SetupSeedSystemCrypto(u64 titleId, u32 hash_seed, bool to_emunand); 42 | -------------------------------------------------------------------------------- /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 | static 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/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/game/tad.c: -------------------------------------------------------------------------------- 1 | #include "tad.h" 2 | #include "sha.h" 3 | 4 | 5 | u32 VerifyTadStub(TadStub* tad) { 6 | TadFooter* ftr = &(tad->footer); 7 | TadHeader* hdr = &(tad->header); 8 | TadBanner* bnr = &(tad->banner); 9 | 10 | if ((strncmp(hdr->magic, TAD_HEADER_MAGIC, strlen(TAD_HEADER_MAGIC)) != 0) || 11 | (sha_cmp(ftr->banner_sha256, bnr, sizeof(TadBanner), SHA256_MODE) != 0) || 12 | (sha_cmp(ftr->header_sha256, hdr, sizeof(TadHeader), SHA256_MODE) != 0)) 13 | return 1; 14 | 15 | return 0; 16 | } 17 | 18 | u32 BuildTadContentTable(void* table, void* header) { 19 | TadHeader* hdr = (TadHeader*) header; 20 | TadContentTable* tbl = (TadContentTable*) table; 21 | 22 | if (strncmp(hdr->magic, TAD_HEADER_MAGIC, strlen(TAD_HEADER_MAGIC)) != 0) 23 | return 1; 24 | 25 | tbl->banner_end = 0 + sizeof(TadBanner) + sizeof(TadBlockMetaData); 26 | tbl->header_end = tbl->banner_end + sizeof(TadHeader) + sizeof(TadBlockMetaData); 27 | tbl->footer_end = tbl->header_end + sizeof(TadFooter) + sizeof(TadBlockMetaData); 28 | 29 | u32 content_end_last = tbl->footer_end; 30 | for (u32 i = 0; i < TAD_NUM_CONTENT; i++) { 31 | tbl->content_end[i] = content_end_last; 32 | if (!hdr->content_size[i]) continue; // non-existant section 33 | tbl->content_end[i] += align(hdr->content_size[i], 0x10) + sizeof(TadBlockMetaData); 34 | content_end_last = tbl->content_end[i]; 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /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 | typedef struct { 60 | TadBanner banner; 61 | TadBlockMetaData banner_bmd; 62 | TadHeader header; 63 | TadBlockMetaData header_bmd; 64 | TadFooter footer; 65 | TadBlockMetaData footer_bmd; 66 | } PACKED_STRUCT TadStub; 67 | 68 | u32 VerifyTadStub(TadStub* tad); 69 | u32 BuildTadContentTable(void* table, void* header); 70 | -------------------------------------------------------------------------------- /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 | u32 SetTitleKey(const u8* titlekey, Ticket* ticket); 39 | u32 FindTicket(Ticket** ticket, u8* title_id, bool force_legit, bool emunand); 40 | u32 FindTitleKey(Ticket* ticket, u8* title_id); 41 | u32 FindTitleKeyForId(u8* titlekey, u8* title_id); 42 | u32 AddTitleKeyToInfo(TitleKeysInfo* tik_info, TitleKeyEntry* tik_entry, bool decrypted_in, bool decrypted_out, bool devkit); 43 | u32 AddTicketToInfo(TitleKeysInfo* tik_info, Ticket* ticket, bool decrypt); 44 | u32 CryptTitleKeyInfo(TitleKeysInfo* tik_info, bool encrypt); 45 | -------------------------------------------------------------------------------- /arm9/source/game/tie.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "tmd.h" 5 | #include "ncch.h" 6 | #include "nds.h" 7 | 8 | // There's probably a better place to put this 9 | #define SD_TITLEDB_PATH(emu) ((emu) ? "B:/dbs/title.db" : "A:/dbs/title.db") 10 | 11 | 12 | // see: https://www.3dbrew.org/wiki/Title_Database 13 | typedef struct { 14 | u64 title_size; 15 | u32 title_type; // usually == 0x40 16 | u32 title_version; 17 | u8 flags_0[4]; 18 | u32 tmd_content_id; 19 | u32 cmd_content_id; 20 | u8 flags_1[4]; 21 | u32 extdata_id_low; // 0 if the title doesn't use extdata 22 | u8 reserved1[4]; 23 | u8 flags_2[8]; 24 | char product_code[16]; 25 | u8 reserved2[12]; 26 | u32 content0_id; // only relevant for TWL? 27 | u8 unknown[4]; // appears to not matter what's here 28 | u8 reserved3[44]; 29 | } __attribute__((packed)) TitleInfoEntry; 30 | 31 | u32 BuildTitleInfoEntryTwl(TitleInfoEntry* tie, TitleMetaData* tmd, TwlHeader* twl); 32 | u32 BuildTitleInfoEntryNcch(TitleInfoEntry* tie, TitleMetaData* tmd, NcchHeader* ncch, NcchExtHeader* exthdr, bool sd); 33 | -------------------------------------------------------------------------------- /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/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/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, 0x104822C, buffer); // Clock divider 5 (13.4 MHz). Same as Process9. 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/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 | -------------------------------------------------------------------------------- /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 9 | 10 | #include "command_ntr.h" 11 | #include "protocol_ntr.h" 12 | #include "card_ntr.h" 13 | 14 | u32 ReadDataFlags = 0; 15 | 16 | void NTR_CmdReset(void) 17 | { 18 | cardReset (); 19 | ARM_WaitCycles(0xF000 * 4); 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 | ARM_WaitCycles(167550 * 4); 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/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, u8* sa_copy, u32 CartID, int iCardDevice); 19 | 20 | -------------------------------------------------------------------------------- /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 | 14 | typedef enum CardSaveType { 15 | CARD_SAVE_NONE, 16 | CARD_SAVE_SPI, 17 | CARD_SAVE_CARD2, 18 | CARD_SAVE_RETAIL_NAND, 19 | } CardSaveType; 20 | 21 | typedef struct { 22 | u8 header[0x8000]; // NTR header + secure area / CTR header + private header 23 | u8 storage[0x8000]; // encrypted secure area + modcrypt area / unused 24 | u32 cart_type; 25 | u32 cart_id; 26 | u64 cart_size; 27 | u64 data_size; 28 | u32 save_size; 29 | CardSaveType save_type; 30 | CardSPIType spi_save_type; // Specific data for SPI save 31 | u32 arm9i_rom_offset; // TWL specific 32 | } PACKED_ALIGN(16) CartData; 33 | 34 | u32 GetCartName(char* name, CartData* cdata); 35 | u32 GetCartInfoString(char* info, size_t info_size, CartData* cdata); 36 | u32 SetSecureAreaEncryption(bool encrypted); 37 | u32 InitCartRead(CartData* cdata); 38 | u32 ReadCartSectors(void* buffer, u32 sector, u32 count, CartData* cdata, bool card2_blanking); 39 | u32 ReadCartBytes(void* buffer, u64 offset, u64 count, CartData* cdata, bool card2_blanking); 40 | u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata); 41 | u32 ReadCartInfo(u8* buffer, u64 offset, u64 count, CartData* cdata); 42 | u32 ReadCartSave(u8* buffer, u64 offset, u64 count, CartData* cdata); 43 | u32 WriteCartSave(const u8* buffer, u64 offset, u64 count, CartData* cdata); 44 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/language.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define STRING(what, def) extern const char* STR_##what; 6 | #include "language.inl" 7 | #undef STRING 8 | 9 | bool SetLanguage(const void* translation, u32 translation_size); 10 | const void* GetLanguage(const void* riff, u32 riff_size, u32* version, u32* count, char* language_name); 11 | 12 | bool LanguageMenu(char* result, const char* title); 13 | -------------------------------------------------------------------------------- /arm9/source/lua/README.md: -------------------------------------------------------------------------------- 1 | This is Lua 5.4.7 with a few modifications: 2 | * Patches made to silence warnings: https://github.com/ihaveamac/GodMode9/commit/9905b939b26aae3422c906c7858d8852764fa279 3 | * lua.c, luac.c, lua.hpp removed (not useful in GodMode9) 4 | * liolib.c, loslib.c removed (replaced with custom implementations) 5 | 6 | ## License of Lua 5.4.7 7 | 8 | Copyright © 1994–2024 Lua.org, PUC-Rio. 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | -------------------------------------------------------------------------------- /arm9/source/lua/gm9internalfs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "gm9lua.h" 3 | 4 | #define GM9LUA_INTERNALFSLIBNAME "_fs" 5 | 6 | #define SHA256_EMPTY_HASH \ 7 | 0xE3, 0xB0, 0xC4, 0x42, \ 8 | 0x98, 0xFC, 0x1C, 0x14, \ 9 | 0x9A, 0xFB, 0xF4, 0xC8, \ 10 | 0x99, 0x6F, 0xB9, 0x24, \ 11 | 0x27, 0xAE, 0x41, 0xE4, \ 12 | 0x64, 0x9B, 0x93, 0x4C, \ 13 | 0xA4, 0x95, 0x99, 0x1B, \ 14 | 0x78, 0x52, 0xB8, 0x55 15 | 16 | #define SHA1_EMPTY_HASH \ 17 | 0xDA, 0x39, 0xA3, 0xEE, \ 18 | 0x5E, 0x6B, 0x4B, 0x0D, \ 19 | 0x32, 0x55, 0xBF, 0xEF, \ 20 | 0x95, 0x60, 0x18, 0x90, \ 21 | 0xAF, 0xD8, 0x07, 0x09 22 | 23 | int gm9lua_open_internalfs(lua_State* L); 24 | -------------------------------------------------------------------------------- /arm9/source/lua/gm9internalsys.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "gm9lua.h" 3 | 4 | #define GM9LUA_INTERNALSYSLIBNAME "_sys" 5 | 6 | int gm9lua_open_internalsys(lua_State* L); 7 | -------------------------------------------------------------------------------- /arm9/source/lua/gm9loader.h: -------------------------------------------------------------------------------- 1 | #include "gm9lua.h" 2 | 3 | /* 4 | * 0:/gm9/luapackages/?.lua; 5 | * 0:/gm9/luapackages/?/init.lua; 6 | * V:/luapackages/?.lua; 7 | * V:/luapackages/?/init.lua 8 | */ 9 | #define GM9LUA_DEFAULT_PATH \ 10 | "0:/gm9/luapackages/"LUA_PATH_MARK".lua" LUA_PATH_SEP \ 11 | "0:/gm9/luapackages/"LUA_PATH_MARK"/init.lua" LUA_PATH_SEP \ 12 | "V:/luapackages/"LUA_PATH_MARK".lua" LUA_PATH_SEP \ 13 | "V:/luapackages/"LUA_PATH_MARK"/init.lua" 14 | 15 | void ResetPackageSearchersAndPath(lua_State* L); 16 | -------------------------------------------------------------------------------- /arm9/source/lua/gm9lua.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include "lua.h" 4 | #include "lauxlib.h" 5 | #include "lualib.h" 6 | #include "scripting.h" 7 | 8 | // this should probably go in filesys/fsutil.h 9 | #define RECURSIVE (1UL<<11) 10 | #define TO_EMUNAND (1UL<<12) 11 | #define LEGIT (1UL<<13) 12 | #define FIND_FIRST (1UL<<14) 13 | #define INCLUDE_DIRS (1UL<<15) 14 | #define EXPLORER (1UL<<16) 15 | #define ENCRYPTED (1UL<<17) 16 | 17 | #define FLAGS_STR "no_cancel", "silent", "calc_sha", "sha1", "skip", "overwrite", "append", "all", "recursive", "to_emunand", "legit", "first", "include_dirs", "explorer", "encrypted" 18 | #define FLAGS_CONSTS NO_CANCEL, SILENT, CALC_SHA, USE_SHA1, SKIP_ALL, OVERWRITE_ALL, APPEND_ALL, ASK_ALL, RECURSIVE, TO_EMUNAND, LEGIT, FIND_FIRST, INCLUDE_DIRS, EXPLORER, ENCRYPTED 19 | #define FLAGS_COUNT 15 20 | 21 | #define LUASCRIPT_EXT "lua" 22 | #define LUASCRIPT_MAX_SIZE STD_BUFFER_SIZE 23 | 24 | // taken from arm9/source/utils/scripting.c 25 | #define _VAR_CNT_LEN 256 26 | 27 | #ifndef NO_LUA 28 | static inline void CheckLuaArgCount(lua_State* L, int argcount, const char* cmd) { 29 | int args = lua_gettop(L); 30 | if (args != argcount) { 31 | luaL_error(L, "bad number of arguments passed to '%s' (expected %d, got %d)", cmd, argcount, args); 32 | } 33 | } 34 | // this is used in cases where a function accepts a flags table or something else 35 | static inline bool CheckLuaArgCountPlusExtra(lua_State* L, int argcount, const char* cmd) { 36 | int args = lua_gettop(L); 37 | if (args != argcount && args != argcount + 1) { 38 | luaL_error(L, "bad number of arguments passed to '%s' (expected %d or %d, got %d)", cmd, argcount, argcount + 1, args); 39 | } 40 | return args == argcount + 1; 41 | } 42 | 43 | int LoadLuaFile(lua_State* L, const char* filename); 44 | u32 GetFlagsFromTable(lua_State* L, int pos, u32 flags_ext_starter, u32 allowed_flags); 45 | void CheckWritePermissionsLuaError(lua_State* L, const char* path); 46 | #endif 47 | bool ExecuteLuaScript(const char* path_script); 48 | -------------------------------------------------------------------------------- /arm9/source/lua/gm9os.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "gm9lua.h" 3 | 4 | #define GM9LUA_OSLIBNAME "os" 5 | 6 | int gm9lua_open_os(lua_State* L); -------------------------------------------------------------------------------- /arm9/source/lua/gm9title.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "gm9lua.h" 3 | 4 | #define GM9LUA_TITLELIBNAME "title" 5 | 6 | int gm9lua_open_title(lua_State* L); 7 | -------------------------------------------------------------------------------- /arm9/source/lua/gm9ui.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "gm9lua.h" 3 | 4 | #define GM9LUA_UILIBNAME "ui" 5 | 6 | void ShiftOutputBufferUp(void); 7 | void ClearOutputBuffer(void); 8 | void RenderOutputBuffer(void); 9 | void WriteToOutputBuffer(char* text); 10 | int gm9lua_open_ui(lua_State* L); 11 | -------------------------------------------------------------------------------- /arm9/source/lua/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* Increments 'L->top.p', checking for stack overflows */ 16 | #define api_incr_top(L) {L->top.p++; \ 17 | api_check(L, L->top.p <= L->ci->top.p, \ 18 | "stack overflow");} 19 | 20 | 21 | /* 22 | ** If a call returns too many multiple returns, the callee may not have 23 | ** stack space to accommodate all results. In this case, this macro 24 | ** increases its stack space ('L->ci->top.p'). 25 | */ 26 | #define adjustresults(L,nres) \ 27 | { if ((nres) <= LUA_MULTRET && L->ci->top.p < L->top.p) \ 28 | L->ci->top.p = L->top.p; } 29 | 30 | 31 | /* Ensure the stack has at least 'n' elements */ 32 | #define api_checknelems(L,n) \ 33 | api_check(L, (n) < (L->top.p - L->ci->func.p), \ 34 | "not enough elements in the stack") 35 | 36 | 37 | /* 38 | ** To reduce the overhead of returning from C functions, the presence of 39 | ** to-be-closed variables in these functions is coded in the CallInfo's 40 | ** field 'nresults', in a way that functions with no to-be-closed variables 41 | ** with zero, one, or "all" wanted results have no overhead. Functions 42 | ** with other number of wanted results, as well as functions with 43 | ** variables to be closed, have an extra check. 44 | */ 45 | 46 | #define hastocloseCfunc(n) ((n) < LUA_MULTRET) 47 | 48 | /* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ 49 | #define codeNresults(n) (-(n) - 3) 50 | #define decodeNresults(n) (-(n) - 3) 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /arm9/source/lua/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) 15 | 16 | 17 | /* Active Lua function (given call info) */ 18 | #define ci_func(ci) (clLvalue(s2v((ci)->func.p))) 19 | 20 | 21 | #define resethookcount(L) (L->hookcount = L->basehookcount) 22 | 23 | /* 24 | ** mark for entries in 'lineinfo' array that has absolute information in 25 | ** 'abslineinfo' array 26 | */ 27 | #define ABSLINEINFO (-0x80) 28 | 29 | 30 | /* 31 | ** MAXimum number of successive Instructions WiTHout ABSolute line 32 | ** information. (A power of two allows fast divisions.) 33 | */ 34 | #if !defined(MAXIWTHABS) 35 | #define MAXIWTHABS 128 36 | #endif 37 | 38 | 39 | LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); 40 | LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, 41 | StkId *pos); 42 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 43 | const char *opname); 44 | LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); 45 | LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, 46 | const char *what); 47 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 48 | const TValue *p2); 49 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 50 | const TValue *p2, 51 | const char *msg); 52 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 53 | const TValue *p2); 54 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 55 | const TValue *p2); 56 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 57 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 58 | TString *src, int line); 59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); 61 | LUAI_FUNC int luaG_tracecall (lua_State *L); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /arm9/source/lua/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ 15 | cast_int(sizeof(TValue)) * (n)) 16 | 17 | #define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ 18 | cast_int(sizeof(TValue *)) * (n)) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | #define upisopen(up) ((up)->v.p != &(up)->u.value) 33 | 34 | 35 | #define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v.p)) 36 | 37 | 38 | /* 39 | ** maximum number of misses before giving up the cache of closures 40 | ** in prototypes 41 | */ 42 | #define MAXMISS 10 43 | 44 | 45 | 46 | /* special status to close upvalues preserving the top of the stack */ 47 | #define CLOSEKTOP (-1) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); 57 | LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy); 58 | LUAI_FUNC void luaF_unlinkupval (UpVal *uv); 59 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 60 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 61 | int pc); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /arm9/source/lua/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {LUA_GNAME, luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | {NULL, NULL} 54 | }; 55 | 56 | 57 | LUALIB_API void luaL_openlibs (lua_State *L) { 58 | const luaL_Reg *lib; 59 | /* "require" functions from 'loadedlibs' and set results to global table */ 60 | for (lib = loadedlibs; lib->func; lib++) { 61 | luaL_requiref(L, lib->name, lib->func, 1); 62 | lua_pop(L, 1); /* remove lib */ 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /arm9/source/lua/ljumptab.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ljumptab.h $ 3 | ** Jump Table for the Lua interpreter 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #undef vmdispatch 9 | #undef vmcase 10 | #undef vmbreak 11 | 12 | #define vmdispatch(x) goto *disptab[x]; 13 | 14 | #define vmcase(l) L_##l: 15 | 16 | #define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); 17 | 18 | 19 | static const void *const disptab[NUM_OPCODES] = { 20 | 21 | #if 0 22 | ** you can update the following list with this command: 23 | ** 24 | ** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h 25 | ** 26 | #endif 27 | 28 | &&L_OP_MOVE, 29 | &&L_OP_LOADI, 30 | &&L_OP_LOADF, 31 | &&L_OP_LOADK, 32 | &&L_OP_LOADKX, 33 | &&L_OP_LOADFALSE, 34 | &&L_OP_LFALSESKIP, 35 | &&L_OP_LOADTRUE, 36 | &&L_OP_LOADNIL, 37 | &&L_OP_GETUPVAL, 38 | &&L_OP_SETUPVAL, 39 | &&L_OP_GETTABUP, 40 | &&L_OP_GETTABLE, 41 | &&L_OP_GETI, 42 | &&L_OP_GETFIELD, 43 | &&L_OP_SETTABUP, 44 | &&L_OP_SETTABLE, 45 | &&L_OP_SETI, 46 | &&L_OP_SETFIELD, 47 | &&L_OP_NEWTABLE, 48 | &&L_OP_SELF, 49 | &&L_OP_ADDI, 50 | &&L_OP_ADDK, 51 | &&L_OP_SUBK, 52 | &&L_OP_MULK, 53 | &&L_OP_MODK, 54 | &&L_OP_POWK, 55 | &&L_OP_DIVK, 56 | &&L_OP_IDIVK, 57 | &&L_OP_BANDK, 58 | &&L_OP_BORK, 59 | &&L_OP_BXORK, 60 | &&L_OP_SHRI, 61 | &&L_OP_SHLI, 62 | &&L_OP_ADD, 63 | &&L_OP_SUB, 64 | &&L_OP_MUL, 65 | &&L_OP_MOD, 66 | &&L_OP_POW, 67 | &&L_OP_DIV, 68 | &&L_OP_IDIV, 69 | &&L_OP_BAND, 70 | &&L_OP_BOR, 71 | &&L_OP_BXOR, 72 | &&L_OP_SHL, 73 | &&L_OP_SHR, 74 | &&L_OP_MMBIN, 75 | &&L_OP_MMBINI, 76 | &&L_OP_MMBINK, 77 | &&L_OP_UNM, 78 | &&L_OP_BNOT, 79 | &&L_OP_NOT, 80 | &&L_OP_LEN, 81 | &&L_OP_CONCAT, 82 | &&L_OP_CLOSE, 83 | &&L_OP_TBC, 84 | &&L_OP_JMP, 85 | &&L_OP_EQ, 86 | &&L_OP_LT, 87 | &&L_OP_LE, 88 | &&L_OP_EQK, 89 | &&L_OP_EQI, 90 | &&L_OP_LTI, 91 | &&L_OP_LEI, 92 | &&L_OP_GTI, 93 | &&L_OP_GEI, 94 | &&L_OP_TEST, 95 | &&L_OP_TESTSET, 96 | &&L_OP_CALL, 97 | &&L_OP_TAILCALL, 98 | &&L_OP_RETURN, 99 | &&L_OP_RETURN0, 100 | &&L_OP_RETURN1, 101 | &&L_OP_FORLOOP, 102 | &&L_OP_FORPREP, 103 | &&L_OP_TFORPREP, 104 | &&L_OP_TFORCALL, 105 | &&L_OP_TFORLOOP, 106 | &&L_OP_SETLIST, 107 | &&L_OP_CLOSURE, 108 | &&L_OP_VARARG, 109 | &&L_OP_VARARGPREP, 110 | &&L_OP_EXTRAARG 111 | 112 | }; 113 | -------------------------------------------------------------------------------- /arm9/source/lua/lopnames.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopnames.h $ 3 | ** Opcode names 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #if !defined(lopnames_h) 8 | #define lopnames_h 9 | 10 | #include 11 | 12 | 13 | /* ORDER OP */ 14 | 15 | static const char *const opnames[] = { 16 | "MOVE", 17 | "LOADI", 18 | "LOADF", 19 | "LOADK", 20 | "LOADKX", 21 | "LOADFALSE", 22 | "LFALSESKIP", 23 | "LOADTRUE", 24 | "LOADNIL", 25 | "GETUPVAL", 26 | "SETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "GETI", 30 | "GETFIELD", 31 | "SETTABUP", 32 | "SETTABLE", 33 | "SETI", 34 | "SETFIELD", 35 | "NEWTABLE", 36 | "SELF", 37 | "ADDI", 38 | "ADDK", 39 | "SUBK", 40 | "MULK", 41 | "MODK", 42 | "POWK", 43 | "DIVK", 44 | "IDIVK", 45 | "BANDK", 46 | "BORK", 47 | "BXORK", 48 | "SHRI", 49 | "SHLI", 50 | "ADD", 51 | "SUB", 52 | "MUL", 53 | "MOD", 54 | "POW", 55 | "DIV", 56 | "IDIV", 57 | "BAND", 58 | "BOR", 59 | "BXOR", 60 | "SHL", 61 | "SHR", 62 | "MMBIN", 63 | "MMBINI", 64 | "MMBINK", 65 | "UNM", 66 | "BNOT", 67 | "NOT", 68 | "LEN", 69 | "CONCAT", 70 | "CLOSE", 71 | "TBC", 72 | "JMP", 73 | "EQ", 74 | "LT", 75 | "LE", 76 | "EQK", 77 | "EQI", 78 | "LTI", 79 | "LEI", 80 | "GTI", 81 | "GEI", 82 | "TEST", 83 | "TESTSET", 84 | "CALL", 85 | "TAILCALL", 86 | "RETURN", 87 | "RETURN0", 88 | "RETURN1", 89 | "FORLOOP", 90 | "FORPREP", 91 | "TFORPREP", 92 | "TFORCALL", 93 | "TFORLOOP", 94 | "SETLIST", 95 | "CLOSURE", 96 | "VARARG", 97 | "VARARGPREP", 98 | "EXTRAARG", 99 | NULL 100 | }; 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /arm9/source/lua/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /arm9/source/lua/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* 16 | ** Memory-allocation error message must be preallocated (it cannot 17 | ** be created after memory is exhausted) 18 | */ 19 | #define MEMERRMSG "not enough memory" 20 | 21 | 22 | /* 23 | ** Size of a TString: Size of the header plus space for the string 24 | ** itself (including final '\0'). 25 | */ 26 | #define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) 27 | 28 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 29 | (sizeof(s)/sizeof(char))-1)) 30 | 31 | 32 | /* 33 | ** test whether a string is a reserved word 34 | */ 35 | #define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) 36 | 37 | 38 | /* 39 | ** equality for short strings, which are always internalized 40 | */ 41 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) 42 | 43 | 44 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 45 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 46 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 47 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 48 | LUAI_FUNC void luaS_clearcache (global_State *g); 49 | LUAI_FUNC void luaS_init (lua_State *L); 50 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 51 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); 52 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 53 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 54 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /arm9/source/lua/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->u.next) 16 | 17 | 18 | /* 19 | ** Clear all bits of fast-access metamethods, which means that the table 20 | ** may have any of these metamethods. (First access that fails after the 21 | ** clearing will set the bit again.) 22 | */ 23 | #define invalidateTMcache(t) ((t)->flags &= ~maskflags) 24 | 25 | 26 | /* true when 't' is using 'dummynode' as its hash part */ 27 | #define isdummy(t) ((t)->lastfree == NULL) 28 | 29 | 30 | /* allocated size for hash nodes */ 31 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 32 | 33 | 34 | /* returns the Node, given the value of a table entry */ 35 | #define nodefromval(v) cast(Node *, (v)) 36 | 37 | 38 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 39 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 40 | TValue *value); 41 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 42 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 43 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 44 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, 45 | TValue *value); 46 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, 47 | const TValue *slot, TValue *value); 48 | LUAI_FUNC Table *luaH_new (lua_State *L); 49 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 50 | unsigned int nhsize); 51 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 52 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 53 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 54 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 55 | LUAI_FUNC unsigned int luaH_realasize (const Table *t); 56 | 57 | 58 | #if defined(LUA_DEBUG) 59 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 60 | #endif 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /arm9/source/lua/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* version suffix for environment variable names */ 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 16 | 17 | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_COLIBNAME "coroutine" 21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 22 | 23 | #define LUA_TABLIBNAME "table" 24 | LUAMOD_API int (luaopen_table) (lua_State *L); 25 | 26 | #define LUA_IOLIBNAME "io" 27 | LUAMOD_API int (luaopen_io) (lua_State *L); 28 | 29 | #define LUA_OSLIBNAME "os" 30 | LUAMOD_API int (luaopen_os) (lua_State *L); 31 | 32 | #define LUA_STRLIBNAME "string" 33 | LUAMOD_API int (luaopen_string) (lua_State *L); 34 | 35 | #define LUA_UTF8LIBNAME "utf8" 36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | 48 | /* open all previous libraries */ 49 | LUALIB_API void (luaL_openlibs) (lua_State *L); 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /arm9/source/lua/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | /* 22 | ** Encode major-minor version in one byte, one nibble for each 23 | */ 24 | #define LUAC_VERSION (((LUA_VERSION_NUM / 100) * 16) + LUA_VERSION_NUM % 100) 25 | 26 | #define LUAC_FORMAT 0 /* this is the official format */ 27 | 28 | /* load one chunk; from lundump.c */ 29 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 30 | 31 | /* dump one chunk; from ldump.c */ 32 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 33 | void* data, int strip); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /arm9/source/lua/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /arm9/source/lua/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /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 | SystemSHMEM *shmemBasePtr; 11 | 12 | void main(int argc, char** argv, int entrypoint) 13 | { 14 | (void) argc; 15 | (void) argv; 16 | 17 | PXI_Reset(); 18 | 19 | // Don't even try to send any messages until the 20 | // ARM11 says it's ready 21 | PXI_Barrier(PXI_BOOT_BARRIER); 22 | 23 | // A pointer to the shared memory region is 24 | // stored in the thread ID register in the ARM9 25 | ARM_InitSHMEM(); 26 | 27 | #ifdef SCRIPT_RUNNER 28 | // Run the script runner 29 | if (ScriptRunner(entrypoint) == GODMODE_EXIT_REBOOT) 30 | #else 31 | // Run the main program 32 | if (GodMode(entrypoint) == GODMODE_EXIT_REBOOT) 33 | #endif 34 | Reboot(); 35 | 36 | PowerOff(); 37 | } 38 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /arm9/source/system/bootfirm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | void __attribute__((noreturn)) BootFirm(void *firm, char *path); 5 | -------------------------------------------------------------------------------- /arm9/source/system/i2c.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "arm.h" 3 | 4 | #include "i2c.h" 5 | #include "pxi.h" 6 | #include "shmem.h" 7 | 8 | bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size) 9 | { 10 | int ret; 11 | u8 *const dataBuffer = ARM_GetSHMEM()->dataBuffer.b; 12 | const u32 arg = devId | (regAddr << 8) | (size << 16); 13 | 14 | if (size >= SHMEM_BUFFER_SIZE) 15 | return false; 16 | 17 | ret = PXI_DoCMD(PXICMD_I2C_OP, &arg, 1); 18 | ARM_InvDC_Range(dataBuffer, size); 19 | 20 | memcpy(out, dataBuffer, size); 21 | return ret; 22 | } 23 | 24 | bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size) 25 | { 26 | int ret; 27 | u8 *const dataBuffer = ARM_GetSHMEM()->dataBuffer.b; 28 | const u32 arg = devId | (regAddr << 8) | (size << 16) | BIT(31); 29 | 30 | if (size >= SHMEM_BUFFER_SIZE) 31 | return false; 32 | 33 | memcpy(dataBuffer, in, size); 34 | ARM_WbDC_Range(dataBuffer, size); 35 | ARM_DSB(); 36 | 37 | ret = PXI_DoCMD(PXICMD_I2C_OP, &arg, 1); 38 | return ret; 39 | } 40 | 41 | u8 I2C_readReg(I2cDevice devId, u8 regAddr) 42 | { 43 | u8 data = 0xFF; 44 | I2C_readRegBuf(devId, regAddr, &data, 1); 45 | return data; 46 | } 47 | 48 | bool I2C_writeReg(I2cDevice devId, u8 regAddr, u8 data) 49 | { 50 | return I2C_writeRegBuf(devId, regAddr, &data, 1); 51 | } 52 | -------------------------------------------------------------------------------- /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/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 | if (!size) return NULL; // nothing, return nothing 8 | void* ptr = (void*) malloc(sizeof(size_t) + size); 9 | if (ptr) total_allocated += size; 10 | if (ptr) (*(size_t*) ptr) = size; 11 | return ptr ? (((char*) ptr) + sizeof(size_t)) : NULL; 12 | } 13 | 14 | void *my_realloc(void *ptr, size_t new_size) { 15 | if (!ptr) 16 | return my_malloc(new_size); 17 | 18 | if (!new_size) { 19 | my_free(ptr); 20 | return NULL; 21 | } 22 | 23 | void *real_ptr = (char*)ptr - sizeof(size_t); 24 | size_t old_size = *(size_t*)real_ptr; 25 | 26 | void *new_ptr = realloc(real_ptr, new_size + sizeof(size_t)); 27 | if (new_ptr) { 28 | total_allocated -= old_size; 29 | total_allocated += new_size; 30 | 31 | *(size_t*)new_ptr = new_size; 32 | return (char*)new_ptr + sizeof(size_t); 33 | } 34 | 35 | return new_ptr; 36 | } 37 | 38 | void my_free(void* ptr) { 39 | if (!ptr) return; // just like real free, dont do anything here 40 | void* ptr_fix = (char*) ptr - sizeof(size_t); 41 | total_allocated -= *(size_t*) ptr_fix; 42 | free(ptr_fix); 43 | } 44 | 45 | size_t mem_allocated(void) { 46 | return total_allocated; 47 | } 48 | 49 | size_t my_malloc_test(void) { 50 | size_t add = 1024 * 1024; 51 | for (size_t s = add;; s += add) { 52 | void* ptr = (void*) malloc(s); 53 | if (!ptr) return s; 54 | free(ptr); 55 | } 56 | return 0; // unreachable 57 | } 58 | -------------------------------------------------------------------------------- /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/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/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/system/spiflash.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "arm.h" 3 | #include "pxi.h" 4 | #include "shmem.h" 5 | 6 | bool spiflash_get_status(void) 7 | { 8 | return PXI_DoCMD(PXICMD_NVRAM_ONLINE, NULL, 0); 9 | } 10 | 11 | bool spiflash_read(u32 offset, u32 size, u8 *buf) 12 | { 13 | u32 *const dataBuffer = ARM_GetSHMEM()->dataBuffer.w; 14 | u32 args[2]; 15 | 16 | while(size > 0) { 17 | u32 blksz = min(size, SHMEM_BUFFER_SIZE); 18 | 19 | args[0] = offset; 20 | args[1] = blksz; 21 | 22 | PXI_DoCMD(PXICMD_NVRAM_READ, args, 2); 23 | ARM_InvDC_Range(dataBuffer, blksz); 24 | ARM_DSB(); 25 | 26 | memcpy(buf, dataBuffer, blksz); 27 | 28 | buf += blksz; 29 | size -= blksz; 30 | offset += blksz; 31 | } 32 | 33 | return true; 34 | } 35 | -------------------------------------------------------------------------------- /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/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/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.frf" 10 | #endif 11 | 12 | // known file names inside VRAM0 TAR 13 | #define VRAM0_AUTORUN_GM9 "autorun.gm9" 14 | #define VRAM0_AUTORUN_LUA "autorun.lua" 15 | #define VRAM0_FONT DEFAULT_FONT 16 | #define VRAM0_SCRIPTS "scripts" 17 | #define VRAM0_LUASCRIPTS "luascripts" 18 | #define VRAM0_README_MD "README_internal.md" 19 | #define VRAM0_SPLASH_PNG FLAVOR "_splash.png" 20 | #define VRAM0_EASTER_BIN "easter.bin" 21 | 22 | 23 | extern const char vram_data[]; 24 | extern const char vram_data_end[]; 25 | 26 | #define VRAM0_OFFSET (uintptr_t)(vram_data) 27 | #define VRAM0_LIMIT (uintptr_t)(vram_data_end - vram_data) 28 | 29 | #define TARDATA ((void*) VRAM0_OFFSET) 30 | #define TARDATA_(off) ((void*) (u32) (VRAM0_OFFSET + (off))) 31 | #define TARDATA_END TARDATA_(VRAM0_LIMIT) 32 | 33 | #define CheckVram0Tar() \ 34 | (ValidateTarHeader(TARDATA, TARDATA_END) == 0) 35 | 36 | #define FirstVTarEntry() \ 37 | TARDATA 38 | 39 | #define OffsetVTarEntry(off) \ 40 | TARDATA_(off) 41 | 42 | #define NextVTarEntry(tardata) \ 43 | NextTarEntry(tardata, TARDATA_END) 44 | 45 | #define GetVTarFileInfo(tardata, fname, fsize, is_dir) \ 46 | GetTarFileInfo(tardata, fname, fsize, is_dir) 47 | 48 | #define FindVTarFileInfo(fname, fsize) \ 49 | FindTarFileInfo(TARDATA, TARDATA_END, fname, fsize) 50 | -------------------------------------------------------------------------------- /arm9/source/system/vram_data.s: -------------------------------------------------------------------------------- 1 | .section .rodata.vram_data 2 | 3 | .align 2 4 | .global vram_data 5 | vram_data: 6 | .incbin "../output/vram0.tar" 7 | .global vram_data_end 8 | vram_data_end: 9 | -------------------------------------------------------------------------------- /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 "memmap.h" 10 | 11 | .macro TRAP_ENTRY xrq_id 12 | msr cpsr_f, #(\xrq_id << 29) @ preserve xrq id (idea grabbed from fb3ds) 13 | .endm 14 | 15 | .section .vectors, "ax" 16 | .global XRQ_Start 17 | XRQ_Start: 18 | ldr pc, IRQ_Vector 19 | IRQ_Vector: .word IRQ_Handler 20 | ldr pc, FIQ_Vector 21 | FIQ_Vector: .word FIQ_Handler 22 | ldr pc, SVC_Vector 23 | SVC_Vector: .word SVC_Handler 24 | ldr pc, UND_Vector 25 | UND_Vector: .word UND_Handler 26 | ldr pc, PABT_Vector 27 | PABT_Vector: .word PABT_Handler 28 | ldr pc, DABT_Vector 29 | DABT_Vector: .word DABT_Handler 30 | .global XRQ_End 31 | XRQ_End: 32 | 33 | 34 | .section .text.xrqs 35 | IRQ_Handler: 36 | TRAP_ENTRY 6 37 | b XRQ_Fatal 38 | 39 | FIQ_Handler: 40 | TRAP_ENTRY 7 41 | b XRQ_Fatal 42 | 43 | SVC_Handler: 44 | TRAP_ENTRY 2 45 | b XRQ_Fatal 46 | 47 | UND_Handler: 48 | TRAP_ENTRY 1 49 | b XRQ_Fatal 50 | 51 | PABT_Handler: 52 | TRAP_ENTRY 3 53 | b XRQ_Fatal 54 | 55 | DABT_Handler: 56 | sub lr, lr, #4 @ R14_abt = PC + 8, so it needs a small additional fixup 57 | TRAP_ENTRY 4 58 | @b XRQ_Fatal 59 | 60 | XRQ_Fatal: 61 | sub lr, lr, #4 @ PC exception fixup 62 | 63 | ldr sp, =(__STACK_ABT_TOP - 18*4) @ Set up abort stack, 8 byte aligned 64 | stmia sp, {r0-r7} @ Preserve non-banked GPRs 65 | 66 | mrs r1, cpsr 67 | orr r0, r1, #SR_NOINT 68 | msr cpsr_c, r0 @ Disable interrupts 69 | 70 | lsr r0, r1, #29 @ Retrieve exception source 71 | 72 | mrs r2, spsr 73 | str lr, [sp, #15*4] 74 | str r2, [sp, #16*4] @ Preserve exception PC and CPSR 75 | 76 | ands r2, r2, #SR_PMODE_MASK 77 | orreq r2, r2, #SR_SYS_MODE @ Force a switch to system mode if 78 | @ the exception happened in user mode 79 | orr r2, r2, #(0x10 | SR_NOINT) @ With interrupts disabled 80 | 81 | add r3, sp, #8*4 82 | msr cpsr_c, r2 83 | nop 84 | nop 85 | stmia r3, {r8-r14} @ Preserve banked GPRs (R8-R12, SP_xrq, LR_xrq) 86 | nop 87 | nop 88 | msr cpsr_c, r1 89 | 90 | mov r1, sp 91 | bl XRQ_DumpRegisters @ XRQ_DumpRegisters(exception_number, saved_regs); 92 | 93 | mov r0, #0 94 | 1: 95 | mcr p15, 0, r0, c7, c0, 4 96 | b 1b 97 | -------------------------------------------------------------------------------- /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/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 InstallGameFile(const char* path, bool to_emunand); 10 | u32 InstallCifinishFile(const char* path, bool to_emunand); 11 | u32 InstallTicketFile(const char* path, bool to_emunand); 12 | u32 DumpTicketForGameFile(const char* path, bool force_legit); 13 | u32 DumpCxiSrlFromGameFile(const char* path); 14 | u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr); 15 | u32 CompressCode(const char* path, const char* path_out); 16 | u64 GetGameFileTrimmedSize(const char* path); 17 | u32 TrimGameFile(const char* path); 18 | u32 ShowGameFileIcon(const char* path, u16* screen); 19 | u32 ShowGameCheckerInfo(const char* path); 20 | u64 GetGameFileTitleId(const char* path); 21 | u32 UninstallGameDataTie(const char* path, bool remove_tie, bool remove_ticket, bool remove_save); 22 | u32 GetTmdContentPath(char* path_content, const char* path_tmd); 23 | u32 GetTieContentPath(char* path_content, const char* path_tie); 24 | u32 BuildNcchInfoXorpads(const char* destdir, const char* path); 25 | u32 CheckHealthAndSafetyInject(const char* hsdrv); 26 | u32 InjectHealthAndSafety(const char* path, const char* destdrv); 27 | u32 BuildTitleKeyInfo(const char* path, bool dec, bool dump); 28 | u32 BuildSeedInfo(const char* path, bool dump); 29 | u32 GetGoodName(char* name, const char* path, bool quick); 30 | -------------------------------------------------------------------------------- /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/utils/nandcmac.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #define ReadFileCmac(path, cmac) ReadWriteFileCmac(path, cmac, false, true) 6 | #define WriteFileCmac(path, cmac, check_perms) ReadWriteFileCmac(path, cmac, true, check_perms) 7 | #define CheckCmdCmac(path) CheckFixCmdCmac(path, false, true) 8 | #define FixCmdCmac(path, check_perms) CheckFixCmdCmac(path, true, check_perms) 9 | 10 | u32 CheckCmacPath(const char* path); 11 | u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write, bool check_perms); 12 | u32 CalculateFileCmac(const char* path, u8* cmac); 13 | u32 CheckFileCmac(const char* path); 14 | u32 FixFileCmac(const char* path, bool check_perms); 15 | u32 FixAgbSaveCmac(void* data, u8* cmac, const char* sddrv); 16 | u32 CheckFixCmdCmac(const char* path, bool fix, bool check_perms); 17 | u32 RecursiveFixFileCmac(const char* path); 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/utils/paint9.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | u32 Paint9(void); 6 | -------------------------------------------------------------------------------- /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 for_handler(char* path, const char* dir, const char* pattern, bool recursive); 9 | 10 | bool ValidateText(const char* text, u32 size); 11 | bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script); 12 | bool MemToCViewer(const char* text, u32 len, const char* title); 13 | bool FileTextViewer(const char* path, bool as_script); 14 | bool ExecuteGM9Script(const char* path_script); 15 | -------------------------------------------------------------------------------- /arm9/source/utils/sysinfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void MyriaSysinfo(char* sysinfo_txt); 4 | -------------------------------------------------------------------------------- /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/virtual/vbdri.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | #include "virtual.h" 5 | 6 | void DeinitVBDRIDrive(void); 7 | u64 InitVBDRIDrive(void); 8 | u64 CheckVBDRIDrive(void); 9 | 10 | bool ReadVBDRIDir(VirtualFile* vfile, VirtualDir* vdir); 11 | bool GetNewVBDRIFile(VirtualFile* vfile, VirtualDir* vdir, const char* path); 12 | int ReadVBDRIFile(const VirtualFile* vfile, void* buffer, u64 offset, u64 count); 13 | int WriteVBDRIFile(VirtualFile* vfile, const void* buffer, u64 offset, u64 count); 14 | int DeleteVBDRIFile(const VirtualFile* vfile); 15 | u64 GetVBDRIDriveSize(void); 16 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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 clamp(x, min, max) \ 33 | ((x) < (max) ? ((x) > (min) ? (x) : (min)) : (max)) 34 | 35 | #define getbe16(d) \ 36 | (((d)[0]<<8) | (d)[1]) 37 | #define getbe32(d) \ 38 | ((((u32) getbe16(d))<<16) | ((u32) getbe16((d)+2))) 39 | #define getbe64(d) \ 40 | ((((u64) getbe32(d))<<32) | ((u64) getbe32((d)+4))) 41 | 42 | #define getle16(d) \ 43 | (((d)[1]<<8) | (d)[0]) 44 | #define getle32(d) \ 45 | ((((u32) getle16((d)+2))<<16) | ((u32) getle16(d))) 46 | #define getle64(d) \ 47 | ((((u64) getle32((d)+4))<<32) | ((u64) getle32(d))) 48 | 49 | #define align(v,a) \ 50 | (((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v)) 51 | 52 | #define countof(x) \ 53 | (sizeof(x) / sizeof(*(x))) 54 | 55 | #define bkpt \ 56 | do{__builtin_trap(); __builtin_unreachable();}while(0) 57 | 58 | #define assert(x) \ 59 | (!!(x) ? (void)0 : __builtin_trap()) 60 | 61 | #define STATIC_ASSERT(...) \ 62 | _Static_assert((__VA_ARGS__), #__VA_ARGS__) 63 | 64 | // standard output path (support file paths are in support.h) 65 | #define OUTPUT_PATH "0:/gm9/out" 66 | 67 | // used in several places 68 | #define STD_BUFFER_SIZE 0x100000 // must be a multiple of 0x200 69 | 70 | // buffer area defines (in use by image.c, for RAMdrive) 71 | #define RAMDRV_BUFFER ((u8*)0x22800000) // top of STACK 72 | #define RAMDRV_SIZE_O3DS (0x5800000) // 88MB 73 | #define RAMDRV_SIZE_N3DS (0xD800000) // 216MB 74 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | #define SHMEM_BUFFER_SIZE 2048 24 | 25 | typedef struct { 26 | union { 27 | struct { u32 keys, touch; }; 28 | u64 full; 29 | } hidState; 30 | 31 | union { 32 | uint8_t b[SHMEM_BUFFER_SIZE]; 33 | uint16_t s[SHMEM_BUFFER_SIZE / 2]; 34 | uint32_t w[SHMEM_BUFFER_SIZE / 4]; 35 | uint64_t q[SHMEM_BUFFER_SIZE / 8]; 36 | } dataBuffer; 37 | } __attribute__((packed, aligned(8))) SystemSHMEM; 38 | 39 | #ifdef ARM9 40 | #include 41 | 42 | extern SystemSHMEM *shmemBasePtr; 43 | 44 | static inline SystemSHMEM *ARM_GetSHMEM(void) 45 | { 46 | // shared memory contents are extremely likely to change 47 | // insert a compiler barrier to force the compiler not to assume 48 | // memory values will remain constant in between calls to getSHMEM 49 | asm_v("":::"memory", "cc"); 50 | return shmemBasePtr; 51 | } 52 | 53 | static inline void ARM_InitSHMEM(void) 54 | { 55 | shmemBasePtr = (SystemSHMEM*)PXI_DoCMD(PXICMD_GET_SHMEM_ADDRESS, NULL, 0); 56 | } 57 | #endif 58 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 int8_t s8; 28 | typedef int16_t s16; 29 | typedef int32_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 | -------------------------------------------------------------------------------- /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 | 8 | #define VRAM_TOP_LA (VRAM_START) 9 | #define VRAM_BOT_A (VRAM_TOP_LA + TOP_VRAM) 10 | 11 | #define VRAM_END (VRAM_BOT_A + BOTTOM_VRAM) 12 | -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | project_id: 559689 2 | api_token_env: CROWDIN_TOKEN 3 | preserve_hierarchy: true 4 | 5 | files: 6 | - source: /resources/languages/source.json 7 | translation: /resources/languages/%two_letters_code%.json 8 | -------------------------------------------------------------------------------- /data/aeskeydb.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/data/aeskeydb.bin -------------------------------------------------------------------------------- /data/easter.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/data/easter.bin -------------------------------------------------------------------------------- /data/font_default.frf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/data/font_default.frf -------------------------------------------------------------------------------- /data/luapackages/sys.lua: -------------------------------------------------------------------------------- 1 | local sys = {} 2 | 3 | sys.boot = _sys.boot 4 | sys.reboot = _sys.reboot 5 | sys.power_off = _sys.power_off 6 | sys.check_embedded_backup = _sys.check_embedded_backup 7 | sys.check_raw_rtc = _sys.check_raw_rtc 8 | 9 | sys.secureinfo_letter = nil 10 | sys.region = nil 11 | sys.serial = nil 12 | sys.sys_id0 = nil 13 | sys.emu_id0 = nil 14 | sys.emu_base = nil 15 | 16 | local regions = {"JPN", "USA", "EUR", "AUS", "CHN", "KOR", "TWN"} 17 | 18 | local function refresh_secureinfo() 19 | local letter = nil 20 | if fs.exists("1:/rw/sys/SecureInfo_A") then letter = "A" 21 | elseif fs.exists("1:rw/sys/SecureInfo_B") then letter = "B" 22 | else error("could not read SecureInfo") end 23 | 24 | local secinfo = fs.read_file("1:/rw/sys/SecureInfo_"..letter, 0, 0x111) 25 | 26 | -- remember, Lua starts indexes at 1 so these offsets appear off by one if you're used to other langs 27 | local serial = string.sub(secinfo, 0x103, 0x111) 28 | serial = string.gsub(serial, "\0", "") 29 | 30 | local region_byte = string.sub(secinfo, 0x101, 0x101) 31 | local region_num = string.byte(region_byte) 32 | if region_num > 6 then error("SecureInfo region byte is invalid") end 33 | 34 | sys.serial = serial 35 | sys.region = regions[region_num + 1] 36 | sys.secureinfo_letter = letter 37 | end 38 | 39 | local function refresh_id0() 40 | local sys_id0 = _sys.get_id0("1:/private/movable.sed") 41 | 42 | if fs.exists("4:/private/movable.sed") then 43 | local emu_id0 = _sys.get_id0("4:/private/movable.sed") 44 | end 45 | 46 | sys.sys_id0 = sys_id0 47 | sys.emu_id0 = emu_id0 48 | end 49 | 50 | function sys.refresh_info() 51 | refresh_secureinfo() 52 | refresh_id0() 53 | sys.emu_base = _sys.get_emu_base() 54 | end 55 | 56 | function sys.next_emu() 57 | _sys.next_emu() 58 | pcall(sys.refresh_info()) 59 | end 60 | 61 | -- in the preload scripts, we have to avoid possibilities of unhandled exceptions 62 | pcall(sys.refresh_info) 63 | 64 | return sys 65 | -------------------------------------------------------------------------------- /data/luapackages/util.lua: -------------------------------------------------------------------------------- 1 | local util = {} 2 | 3 | -- https://stackoverflow.com/a/71896879 4 | function util.bytes_to_hex(data) 5 | local hex = {} 6 | local char 7 | for i = 1, #data do 8 | char = string.sub(data, i, i) 9 | --hex = hex..string.format("%02x", string.byte(char)) 10 | table.insert(hex, string.format("%02x", string.byte(char))) 11 | end 12 | return table.concat(hex) 13 | end 14 | 15 | -- https://stackoverflow.com/a/9140231 16 | function util.hex_to_bytes(hexstring) 17 | return (string.gsub(hexstring, '..', function (cc) 18 | return string.char(tonumber(cc, 16)) 19 | end)) 20 | end 21 | 22 | -- returns something like "241202" 23 | function util.get_datestamp() 24 | return os.date("%y%m%d") 25 | end 26 | 27 | -- returns something like "010828" 28 | function util.get_timestamp() 29 | return os.date("%H%M%S") 30 | end 31 | 32 | -- https://stackoverflow.com/a/49376823 33 | function util.running_as_module() 34 | local success, _, __, required = pcall(debug.getlocal, 4, 1) 35 | if not success then 36 | -- umm uhh 37 | return false 38 | end 39 | -- for the file being executed directly, this seems to be a number 40 | -- but for a file being required by another, it returns the string given to require() 41 | -- example: if foo.lua is executed, this should return a number like 2 42 | -- but when foo.lua requires bar.lua, bar.lua should get "bar" as the result 43 | -- however, this behavior seems inconsistent between lua versions 44 | -- the Stack Overflow answer seems to suggest the call would fail on some version before 5.4 45 | -- honestly, I would've liked a better method, but i have yet to find some way to get the executing file 46 | -- in the C code in LoadLuaFile, I could set the string that contains the full filepath, but... where do I set it? 47 | return type(required) == "string" 48 | end 49 | 50 | return util 51 | -------------------------------------------------------------------------------- /data/preload.lua: -------------------------------------------------------------------------------- 1 | -- This file is executed when any Lua script is executed in GodMode9. 2 | -- The purpose of this one is to initialize some variables and modules. 3 | -- If you're looking for an auto-running script, you want "autorun.lua"! 4 | 5 | fs = require('fs') 6 | util = require('util') 7 | io = require('io') 8 | sys = require('sys') 9 | -------------------------------------------------------------------------------- /resources/BrickedMode9_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/BrickedMode9_splash.png -------------------------------------------------------------------------------- /resources/GodMode64_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/GodMode64_splash.png -------------------------------------------------------------------------------- /resources/GodMode9_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/GodMode9_splash.png -------------------------------------------------------------------------------- /resources/GodMode9_splash_2nd_anniversary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/GodMode9_splash_2nd_anniversary.png -------------------------------------------------------------------------------- /resources/GodMode9_splash_3rd_anniversary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/GodMode9_splash_3rd_anniversary.png -------------------------------------------------------------------------------- /resources/GodMode9_splash_4th_anniversary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/GodMode9_splash_4th_anniversary.png -------------------------------------------------------------------------------- /resources/GodMode9_splash_5th_anniversary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/GodMode9_splash_5th_anniversary.png -------------------------------------------------------------------------------- /resources/GodMode9_splash_6th_anniversary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/GodMode9_splash_6th_anniversary.png -------------------------------------------------------------------------------- /resources/GodMode9_splash_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/GodMode9_splash_default.png -------------------------------------------------------------------------------- /resources/GodMode9_splash_default_pre2.0.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/GodMode9_splash_default_pre2.0.0.png -------------------------------------------------------------------------------- /resources/SafeMode9_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/SafeMode9_splash.png -------------------------------------------------------------------------------- /resources/ZuishMode9_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/ZuishMode9_splash.png -------------------------------------------------------------------------------- /resources/fonts/cp_437.txt: -------------------------------------------------------------------------------- 1 | 0x0000 0x263A 0x263B 0x2665 0x2666 0x2663 0x2660 0x2022 0x25D8 0x25CB 0x25D9 0x2642 0x2640 0x266A 0x266B 0x263C 2 | 0x25BA 0x25C4 0x2195 0x203C 0x00B6 0x00A7 0x25AC 0x21A8 0x2191 0x2193 0x2192 0x2190 0x221F 0x2194 0x25B2 0x25BC 3 | 0x0020 0x0021 0x0022 0x0023 0x0024 0x0025 0x0026 0x0027 0x0028 0x0029 0x002A 0x002B 0x002C 0x002D 0x002E 0x002F 4 | 0x0030 0x0031 0x0032 0x0033 0x0034 0x0035 0x0036 0x0037 0x0038 0x0039 0x003A 0x003B 0x003C 0x003D 0x003E 0x003F 5 | 0x0040 0x0041 0x0042 0x0043 0x0044 0x0045 0x0046 0x0047 0x0048 0x0049 0x004A 0x004B 0x004C 0x004D 0x004E 0x004F 6 | 0x0050 0x0051 0x0052 0x0053 0x0054 0x0055 0x0056 0x0057 0x0058 0x0059 0x005A 0x005B 0x005C 0x005D 0x005E 0x005F 7 | 0x0060 0x0061 0x0062 0x0063 0x0064 0x0065 0x0066 0x0067 0x0068 0x0069 0x006A 0x006B 0x006C 0x006D 0x006E 0x006F 8 | 0x0070 0x0071 0x0072 0x0073 0x0074 0x0075 0x0076 0x0077 0x0078 0x0079 0x007A 0x007B 0x007C 0x007D 0x007E 0x2302 9 | 0x00C7 0x00FC 0x00E9 0x00E2 0x00E4 0x00E0 0x00E5 0x00E7 0x00EA 0x00EB 0x00E8 0x00EF 0x00EE 0x00EC 0x00C4 0x00C5 10 | 0x00C9 0x00E6 0x00C6 0x00F4 0x00F6 0x00F2 0x00FB 0x00F9 0x00FF 0x00D6 0x00DC 0x00A2 0x00A3 0x00A5 0x20A7 0x0192 11 | 0x00E1 0x00ED 0x00F3 0x00FA 0x00F1 0x00D1 0x00AA 0x00BA 0x00BF 0x2310 0x00AC 0x00BD 0x00BC 0x00A1 0x00AB 0x00BB 12 | 0x2591 0x2592 0x2593 0x2502 0x2524 0x2561 0x2562 0x2556 0x2555 0x2563 0x2551 0x2557 0x255D 0x255C 0x255B 0x2510 13 | 0x2514 0x2534 0x252C 0x251C 0x2500 0x253C 0x255E 0x255F 0x255A 0x2554 0x2569 0x2566 0x2560 0x2550 0x256C 0x2567 14 | 0x2568 0x2564 0x2565 0x2559 0x2558 0x2552 0x2553 0x256B 0x256A 0x2518 0x250C 0x2588 0x2584 0x258C 0x2590 0x2580 15 | 0x03B1 0x00DF 0x0393 0x03C0 0x03A3 0x03C3 0x00B5 0x03C4 0x03A6 0x0398 0x03A9 0x03B4 0x221E 0x03C6 0x03B5 0x2229 16 | 0x2261 0x00B1 0x2265 0x2264 0x2320 0x2321 0x00F7 0x2248 0x00B0 0x2219 0x00B7 0x221A 0x207F 0x00B2 0x25A0 0x00A0 17 | -------------------------------------------------------------------------------- /resources/fonts/font_6x10.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/font_6x10.pbm -------------------------------------------------------------------------------- /resources/fonts/font_6x10_japanese.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/font_6x10_japanese.pbm -------------------------------------------------------------------------------- /resources/fonts/font_acorn_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/font_acorn_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/font_c64_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/font_c64_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/font_gb_7x6.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/font_gb_7x6.pbm -------------------------------------------------------------------------------- /resources/fonts/font_nbraille_4x6.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/font_nbraille_4x6.pbm -------------------------------------------------------------------------------- /resources/fonts/font_original_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/font_original_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/font_sheikah_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/font_sheikah_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/font_tiny_4x6.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/font_tiny_4x6.pbm -------------------------------------------------------------------------------- /resources/fonts/font_zuish_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/font_zuish_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/fusion/font_fusion_hans_8x8.frf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/fusion/font_fusion_hans_8x8.frf -------------------------------------------------------------------------------- /resources/fonts/fusion/font_fusion_hans_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/fusion/font_fusion_hans_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/fusion/font_fusion_hant_8x8.frf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/fusion/font_fusion_hant_8x8.frf -------------------------------------------------------------------------------- /resources/fonts/fusion/font_fusion_hant_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/fusion/font_fusion_hant_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/fusion/font_fusion_ja_8x8.frf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/fusion/font_fusion_ja_8x8.frf -------------------------------------------------------------------------------- /resources/fonts/fusion/font_fusion_ja_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/fusion/font_fusion_ja_8x8.pbm -------------------------------------------------------------------------------- /resources/fonts/fusion/font_fusion_ko_8x8.frf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/fusion/font_fusion_ko_8x8.frf -------------------------------------------------------------------------------- /resources/fonts/fusion/font_fusion_ko_8x8.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/fonts/fusion/font_fusion_ko_8x8.pbm -------------------------------------------------------------------------------- /resources/gm9/languages/ja.frf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/gm9/languages/ja.frf -------------------------------------------------------------------------------- /resources/gm9/languages/ry.frf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/gm9/languages/ry.frf -------------------------------------------------------------------------------- /resources/gm9/languages/zh-CN.frf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/gm9/languages/zh-CN.frf -------------------------------------------------------------------------------- /resources/gm9/languages/zh-TW.frf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/gm9/languages/zh-TW.frf -------------------------------------------------------------------------------- /resources/gm9/support/decTitleKeys.bin.here: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/gm9/support/decTitleKeys.bin.here -------------------------------------------------------------------------------- /resources/gm9/support/seeddb.bin.here: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/gm9/support/seeddb.bin.here -------------------------------------------------------------------------------- /resources/languages/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "GM9_LANGUAGE": "English", 3 | "GM9_TRANS_VER": 1 4 | } 5 | -------------------------------------------------------------------------------- /resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/logo.png -------------------------------------------------------------------------------- /resources/wiki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/resources/wiki.png -------------------------------------------------------------------------------- /utils/patch.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/GodMode9/cf1cb1cfc5965cec3dd10ba98269aeb37b9b7a9d/utils/patch.json.gz -------------------------------------------------------------------------------- /utils/transcp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from argparse import ArgumentParser, FileType 4 | import json 5 | 6 | # Special keys 7 | LANGUAGE_NAME = "GM9_LANGUAGE" 8 | VERSION = "GM9_TRANS_VER" 9 | 10 | parser = ArgumentParser(description="Creates the language.inl file from source.json") 11 | parser.add_argument("source", type=FileType("r"), help="source.json") 12 | parser.add_argument("inl", type=FileType("w"), help="language.inl") 13 | args = parser.parse_args() 14 | 15 | # Load the JSON and handle the meta values 16 | source = json.load(args.source) 17 | version = source[VERSION] 18 | del source[VERSION] 19 | del source[LANGUAGE_NAME] 20 | 21 | # Create the header file 22 | args.inl.write("#define TRANSLATION_VER %d\n\n" % version) 23 | for key in source: 24 | # Escape \r, \n, and quotes 25 | val = source[key].replace("\r", "\\r").replace("\n", "\\n").replace('"', '\\"') 26 | args.inl.write('STRING(%s, "%s")\n' % (key, val)) 27 | --------------------------------------------------------------------------------