├── .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 |
--------------------------------------------------------------------------------