├── .github └── workflows │ ├── nightly.yml │ └── release.yml ├── .gitignore ├── .gitmodules ├── Makefile ├── Makefile.arm7 ├── Makefile.arm9 ├── Makefile.arm9_crt0set ├── Makefile.arm9_r4ids ├── Makefile.arm9_r4isdhc ├── README.md ├── arm7 └── source │ └── main.c ├── arm9 └── source │ ├── dldi_size.s │ ├── main.c │ ├── nds_loader_arm9.c │ └── nds_loader_arm9.h ├── arm9_r4ids ├── ds_arm9_r4ids.mem └── ds_arm9_r4ids.specs ├── arm9_r4isdhc ├── ds_arm9_r4isdhc.ld ├── ds_arm9_r4isdhc.specs └── source │ └── r4i_sdhc_pad.s ├── build.sh ├── clean.sh ├── devnotes.txt ├── icon.bmp ├── license.txt └── resource ├── DSOneSDHC_DSOnei ├── MSFORSC.nds └── SCFW.SC ├── G003 ├── MuliLang.bin └── _M3_MENU.DAT ├── M3R_iTDS_R4RTS ├── SYSTEM │ ├── g6dsload.1 │ └── g6dsload.eng ├── _ds_menu.sys ├── boot.eng ├── boot.gb ├── boot.jp └── loader.eng ├── N5 └── _ax_menu.dat ├── dldinoap └── dldinoap.py ├── dsbize └── dsbize.c ├── r4denc └── r4denc.cpp └── r4isdhc └── r4isdhc.py /.github/workflows/nightly.yml: -------------------------------------------------------------------------------- 1 | name: Build flashcard-bootstrap 2 | 3 | on: 4 | push: 5 | branches: ["master"] 6 | paths-ignore: 7 | - 'README.md' 8 | pull_request: 9 | branches: ["master"] 10 | paths-ignore: 11 | - 'README.md' 12 | workflow_dispatch: 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | container: skylyrac/blocksds:slim-latest 18 | name: Build with Docker using BlocksDS 19 | steps: 20 | - name: Checkout repo 21 | uses: actions/checkout@v3 22 | with: 23 | submodules: recursive 24 | - name: Install needed packages 25 | run: | 26 | apt update 27 | apt install -y clang zip 28 | - name: Make flashcard-bootstrap 29 | run: | 30 | chmod +x build.sh 31 | ./build.sh 32 | - name: Prepare for build publishing 33 | run: | 34 | mkdir -p ~/artifacts 35 | cp bootstrap.zip ~/artifacts 36 | - name: Publish build to GH Actions 37 | uses: actions/upload-artifact@v3 38 | with: 39 | path: ~/artifacts/* 40 | name: build 41 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Build flashcard-bootstrap Release 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | container: skylyrac/blocksds:slim-latest 11 | name: Build with Docker using BlocksDS 12 | steps: 13 | - name: Checkout repo 14 | uses: actions/checkout@v3 15 | with: 16 | submodules: recursive 17 | - name: Install needed packages 18 | run: | 19 | apt update 20 | apt install -y clang zip 21 | - name: Make flashcard-bootstrap 22 | run: | 23 | chmod +x build.sh 24 | ./build.sh 25 | - name: Prepare for build publishing 26 | run: | 27 | mkdir -p ~/artifacts 28 | cp bootstrap.zip ~/artifacts 29 | - name: Publish build to GH Actions 30 | uses: actions/upload-artifact@v3 31 | with: 32 | path: ~/artifacts/* 33 | name: build 34 | - name: Make release archive 35 | run: | 36 | cp devnotes.txt bootstrap/devnotes.txt 37 | cd bootstrap 38 | zip -r bootstrap.zip * 39 | - name: Release 40 | uses: softprops/action-gh-release@v1 41 | if: startsWith(github.ref, 'refs/tags/') 42 | with: 43 | files: bootstrap.zip 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DAT 2 | *.dat 3 | *.NDS 4 | *.nds 5 | *.elf 6 | *.bin 7 | *.zip 8 | *.sys 9 | *.eng 10 | *.sc 11 | *.d 12 | *.o 13 | 14 | bootstrap 15 | data 16 | build 17 | !resource/* 18 | !resource/*/* 19 | resource/r4denc/r4denc 20 | resource/dsbize/dsbize 21 | *.exe 22 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "bootloader"] 2 | path = bootloader 3 | url = https://github.com/lifehackerhansol/blocksds-bootloader 4 | [submodule "DLDI"] 5 | path = DLDI 6 | url = https://github.com/DS-Homebrew/DLDI 7 | branch = builds 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # 3 | # SPDX-FileContributor: Antonio Niño Díaz, 2023 4 | 5 | BLOCKSDS ?= /opt/blocksds/core 6 | BLOCKSDSEXT ?= /opt/blocksds/external 7 | 8 | ifneq (,$(shell which python3)) 9 | PYTHON := python3 10 | else ifneq (,$(shell which python2)) 11 | PYTHON := python2 12 | else ifneq (,$(shell which python)) 13 | PYTHON := python 14 | else 15 | $(error "Python not found in PATH, please install it.") 16 | endif 17 | 18 | # User config 19 | # =========== 20 | 21 | NAME := bootstrap 22 | 23 | GAME_TITLE := flashcard-bootstrap 24 | GAME_SUBTITLE := kernel replacement project 25 | GAME_AUTHOR := lifehackerhansol 26 | GAME_ICON := icon.bmp 27 | 28 | # DLDI and internal SD slot of DSi 29 | # -------------------------------- 30 | 31 | # Root folder of the SD image 32 | SDROOT := sdroot 33 | # Name of the generated image it "DSi-1.sd" for no$gba in DSi mode 34 | SDIMAGE := image.bin 35 | 36 | # Source code paths 37 | # ----------------- 38 | 39 | NITROFSDIR := # A single directory that is the root of NitroFS 40 | 41 | # Tools 42 | # ----- 43 | 44 | MAKE := make 45 | RM := rm -rf 46 | 47 | # Verbose flag 48 | # ------------ 49 | 50 | ifeq ($(VERBOSE),1) 51 | V := 52 | else 53 | V := @ 54 | endif 55 | 56 | # Directories 57 | # ----------- 58 | 59 | ARM9DIR := arm9 60 | ARM7DIR := arm7 61 | DATA := $(CURDIR)/data 62 | 63 | # Build artfacts 64 | # -------------- 65 | 66 | ROM := $(NAME).nds 67 | 68 | ROM_R4ILS := $(NAME)_r4ils.nds 69 | ROM_GATEWAY := $(NAME)_gateway.nds 70 | ROM_DSONE := $(NAME)_dsone.nds 71 | ROM_R4ISDHC := $(NAME)_r4isdhc.nds 72 | ROM_02000000 := $(NAME)_02000000.nds 73 | ROM_02000450 := $(NAME)_02000450.nds 74 | ROM_02000800 := $(NAME)_02000800.nds 75 | 76 | # Targets 77 | # ------- 78 | 79 | .PHONY: all clean dist arm9 arm9_r4isdhc arm7 dldipatch sdimage 80 | 81 | all: $(ROM) \ 82 | _ds_menu.dat \ 83 | N5/_ds_menu.dat \ 84 | ez5sys.bin \ 85 | _boot_mp.nds \ 86 | bootme.nds \ 87 | r4i.sys \ 88 | ismat.dat \ 89 | _ds_menu.nds \ 90 | ez5isys.bin \ 91 | ACEP/_ds_menu.dat \ 92 | akmenu4.nds \ 93 | ttmenu.dat \ 94 | r4.dat \ 95 | _dsmenu.dat \ 96 | dsedgei.dat \ 97 | ezds.dat \ 98 | MAZE/_ds_menu.dat \ 99 | r4ids.cn/_ds_menu.dat \ 100 | R4iLS/_dsmenu.dat \ 101 | Gateway/_dsmenu.dat \ 102 | G003/g003menu.eng \ 103 | DSOneSDHC_DSOnei/ttmenu.dat \ 104 | scfw.sc \ 105 | r4dspro.com/_ds_menu.dat 106 | 107 | clean: 108 | @echo " CLEAN" 109 | $(V)$(MAKE) -f Makefile.arm9 clean --no-print-directory 110 | $(V)$(MAKE) -f Makefile.arm9_crt0set clean --no-print-directory 111 | $(V)$(MAKE) -f Makefile.arm9_r4ids clean --no-print-directory 112 | $(V)$(MAKE) -f Makefile.arm9_r4isdhc clean --no-print-directory 113 | $(V)$(MAKE) -f Makefile.arm7 clean --no-print-directory 114 | $(V)$(RM) $(ROM) $(ROM_02000000) $(ROM_02000450) $(ROM_02000800) $(ROM_DSONE) $(ROM_R4ILS) $(ROM_GATEWAY) $(ROM_R4ISDHC) build $(SDIMAGE) 115 | $(V)$(RM) bootstrap bootstrap.zip \ 116 | _ds_menu.dat N5 ez5sys.bin _boot_mp.nds bootme.nds r4i.sys ismat.dat _ds_menu.nds ez5isys.bin ACEP akmenu4.nds \ 117 | ttmenu.dat r4.dat _dsmenu.dat dsedgei.dat MAZE r4ids.cn R4iLS Gateway G003 DSOneSDHC_DSOnei scfw.sc r4dspro.com ezds.dat 118 | 119 | arm9: 120 | $(V)+$(MAKE) -f Makefile.arm9 --no-print-directory 121 | 122 | arm9_02000000: 123 | $(V)+$(MAKE) -f Makefile.arm9_crt0set --no-print-directory CRT0=0x02000000 124 | 125 | arm9_02000450: 126 | $(V)+$(MAKE) -f Makefile.arm9_crt0set --no-print-directory CRT0=0x02000450 127 | 128 | arm9_r4isdhc: 129 | $(V)+$(MAKE) -f Makefile.arm9_r4isdhc 130 | 131 | arm9_02000800: 132 | $(V)+$(MAKE) -f Makefile.arm9_r4ids --no-print-directory 133 | 134 | arm7: 135 | $(V)+$(MAKE) -f Makefile.arm7 --no-print-directory 136 | 137 | ifneq ($(strip $(NITROFSDIR)),) 138 | # Additional arguments for ndstool 139 | NDSTOOL_ARGS := -d $(NITROFSDIR) 140 | 141 | # Make the NDS ROM depend on the filesystem only if it is needed 142 | $(ROM): $(NITROFSDIR) 143 | endif 144 | 145 | # Combine the title strings 146 | ifeq ($(strip $(GAME_SUBTITLE)),) 147 | GAME_FULL_TITLE := $(GAME_TITLE);$(GAME_AUTHOR) 148 | else 149 | GAME_FULL_TITLE := $(GAME_TITLE);$(GAME_SUBTITLE);$(GAME_AUTHOR) 150 | endif 151 | 152 | $(ROM): arm9 arm7 153 | @echo " NDSTOOL $@" 154 | $(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \ 155 | -h 0x200 \ 156 | -7 build/arm7.elf -9 build/arm9.elf \ 157 | -b $(GAME_ICON) "$(GAME_FULL_TITLE)" \ 158 | $(NDSTOOL_FAT) 159 | 160 | $(ROM_GATEWAY): arm9 arm7 161 | @echo " NDSTOOL $@" 162 | $(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \ 163 | -h 0x200 -g "####" "##" "R4IT" \ 164 | -7 build/arm7.elf -9 build/arm9.elf \ 165 | -b $(GAME_ICON) "$(GAME_FULL_TITLE)" \ 166 | $(NDSTOOL_FAT) 167 | 168 | $(ROM_R4ILS): arm9 arm7 169 | @echo " NDSTOOL $@" 170 | $(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \ 171 | -h 0x200 -g "####" "##" "R4XX" \ 172 | -7 build/arm7.elf -9 build/arm9.elf \ 173 | -b $(GAME_ICON) "$(GAME_FULL_TITLE)" \ 174 | $(NDSTOOL_FAT) 175 | 176 | $(ROM_DSONE): arm9 arm7 177 | @echo " NDSTOOL $@" 178 | $(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \ 179 | -h 0x200 -g "ENG0" \ 180 | -7 build/arm7.elf -9 build/arm9.elf \ 181 | -b $(GAME_ICON) "$(GAME_FULL_TITLE)" \ 182 | $(NDSTOOL_FAT) 183 | 184 | $(ROM_02000000): arm9_02000000 arm7 185 | @echo " NDSTOOL $@" 186 | $(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \ 187 | -h 0x200 \ 188 | -7 build/arm7.elf -9 build/arm9_0x02000000.elf \ 189 | -b $(GAME_ICON) "$(GAME_FULL_TITLE)" \ 190 | $(NDSTOOL_FAT) 191 | 192 | $(ROM_02000450): arm9_02000450 arm7 193 | @echo " NDSTOOL $@" 194 | $(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \ 195 | -h 0x200 \ 196 | -7 build/arm7.elf -9 build/arm9_0x02000450.elf \ 197 | -b $(GAME_ICON) "$(GAME_FULL_TITLE)" \ 198 | $(NDSTOOL_FAT) 199 | 200 | $(ROM_02000800): arm9_02000800 arm7 201 | @echo " NDSTOOL $@" 202 | $(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \ 203 | -h 0x200 \ 204 | -7 build/arm7.elf -9 build/arm9_r4ids.elf \ 205 | -b $(GAME_ICON) "$(GAME_FULL_TITLE)" \ 206 | $(NDSTOOL_FAT) 207 | 208 | $(ROM_R4ISDHC): arm9_r4isdhc arm7 209 | @echo " NDSTOOL $@" 210 | $(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \ 211 | -h 0x200 \ 212 | -7 build/arm7.elf -9 build/arm9_r4isdhc.elf \ 213 | -b $(GAME_ICON) "$(GAME_FULL_TITLE)" \ 214 | $(NDSTOOL_FAT) 215 | @$(V)$(BLOCKSDS)/tools/ndstool/ndstool -x $@ -9 arm9.bin -7 arm7.bin -t banner.bin -h header.bin 216 | @$(PYTHON) resource/r4isdhc/r4isdhc.py arm9.bin new9.bin 217 | @$(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ -9 new9.bin -7 arm7.bin -t banner.bin -h header.bin -r9 0x02000000 218 | @rm -rf arm9.bin new9.bin arm7.bin banner.bin header.bin 219 | 220 | sdimage: 221 | @echo " MKFATIMG $(SDIMAGE) $(SDROOT)" 222 | $(V)$(BLOCKSDS)/tools/mkfatimg/mkfatimg -t $(SDROOT) $(SDIMAGE) 223 | 224 | dldipatch: $(ROM) 225 | @echo " DLDIPATCH $(ROM)" 226 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch \ 227 | $(BLOCKSDS)/sys/dldi_r4/r4tf.dldi $(ROM) 228 | 229 | dist : all 230 | @mkdir -p bootstrap/M3R_iTDS_R4RTS/_system_/_sys_data 231 | @mkdir -p bootstrap/DSOneSDHC_DSOnei 232 | @mkdir -p bootstrap/N5 233 | @mkdir -p bootstrap/G003/system 234 | @cp -r README.md _ds_menu.dat ez5sys.bin ttmenu.dat r4.dat _boot_mp.nds bootme.nds ismat.dat _ds_menu.nds ez5isys.bin akmenu4.nds _dsmenu.dat dsedgei.dat scfw.sc ezds.dat bootstrap 235 | @cp -r MAZE ACEP R4iLS Gateway r4ids.cn r4dspro.com bootstrap 236 | @cp -r resource/M3R_iTDS_R4RTS/* bootstrap/M3R_iTDS_R4RTS/ 237 | @cp -r resource/DSOneSDHC_DSOnei/* bootstrap/DSOneSDHC_DSOnei/ 238 | @cp resource/N5/_ax_menu.dat bootstrap/N5/_ax_menu.dat 239 | @cp -r resource/G003/* bootstrap/G003/system 240 | @cp G003/g003menu.eng bootstrap/G003/system 241 | @cp -r DSOneSDHC_DSOnei/* bootstrap/DSOneSDHC_DSOnei/ 242 | @cp r4i.sys bootstrap/M3R_iTDS_R4RTS/_system_/_sys_data/r4i.sys 243 | @cp N5/_ds_menu.dat bootstrap/N5/_ds_menu.dat 244 | 245 | @cd bootstrap && zip -r bootstrap.zip * 246 | @mv bootstrap/bootstrap.zip . 247 | 248 | _ds_menu.dat: $(ROM) 249 | @echo "Make original R4" 250 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch "DLDI/r4tfv3.dldi" $< 251 | @./resource/r4denc/r4denc $< $@ 252 | 253 | N5/_ds_menu.dat: $(ROM) 254 | @echo "Make N5" 255 | @[ -d N5 ] || mkdir -p "N5" 256 | @cp $< $@ 257 | 258 | ez5sys.bin: $(ROM) 259 | @echo "Make EZ-Flash V" 260 | @cp $< $@ 261 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ez5h.dldi $@ 262 | 263 | _boot_mp.nds: $(ROM) 264 | @echo "Make GBAMP" 265 | @cp $< $@ 266 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/mpcf.dldi $@ 267 | 268 | r4i.sys : $(ROM) 269 | @echo "Make M3R_iTDS_R4RTS" 270 | @cp $< $@ 271 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch "DLDI/m3ds.dldi" $@ 272 | 273 | ismat.dat: $(ROM) 274 | @echo "Make iSmart Premium" 275 | @cp $< $@ 276 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/mati.dldi $@ 277 | 278 | _ds_menu.nds: ismat.dat 279 | @echo "Make r4i.cn" 280 | @cp $< $@ 281 | 282 | ez5isys.bin: ismat.dat 283 | @echo "Make EZ-Flash Vi" 284 | @cp $< $@ 285 | 286 | bootme.nds: $(ROM) 287 | @echo "Make Games n Music" 288 | @cp $< $@ 289 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/gmtf.dldi $< 290 | 291 | ACEP/_ds_menu.dat: $(ROM) 292 | @echo "Make Ace3DS+" 293 | @[ -d ACEP ] || mkdir -p ACEP 294 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ace3ds_sd.dldi $< 295 | @./resource/r4denc/r4denc --key 0x4002 $< $@ 296 | 297 | scfw.sc: $(ROM_DSONE) 298 | @echo "Make SuperCard DSONE" 299 | @cp $< $@ 300 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/scds3.dldi $< 301 | 302 | akmenu4.nds: $(ROM_02000450) 303 | @echo "Make AK2" 304 | @cp $< $@ 305 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ak2_sd.dldi $@ 306 | 307 | r4dspro.com/_ds_menu.dat: akmenu4.nds 308 | @echo "Make AK2 (broken CMD25)" 309 | @[ -d r4dspro.com ] || mkdir -p r4dspro.com 310 | @cp $< $@ 311 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch "DLDI/ak2_sd_singlewrite.dldi" $@ 312 | 313 | ttmenu.dat: $(ROM) 314 | @echo "Make DSTT" 315 | @cp $< $@ 316 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ttio_sdhc.dldi $@ 317 | 318 | DSOneSDHC_DSOnei/ttmenu.dat: $(ROM) 319 | @echo "Make DSONE SDHC" 320 | @[ -d DSOneSDHC_DSOnei ] || mkdir -p DSOneSDHC_DSOnei 321 | @cp $< $@ 322 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/scdssdhc2.dldi $@ 323 | 324 | r4.dat: $(ROM_R4ISDHC) 325 | @echo "Make R4i-SDHC" 326 | @cp $< $@ 327 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ttio_sdhc.dldi $@ 328 | 329 | _dsmenu.dat: $(ROM_02000000) 330 | @echo "Make R4iDSN" 331 | @cp $< $@ 332 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/r4idsn_sd.dldi $@ 333 | 334 | dsedgei.dat: $(ROM_02000800) 335 | @echo "Make EDGEi" 336 | @cp $< $@ 337 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ak2_sd.dldi $@ 338 | 339 | ezds.dat: $(ROM) 340 | @echo "Make EZ-Flash Parallel" 341 | @cp $< $@ 342 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ez5n.dldi $@ 343 | @$(PYTHON) resource/dldinoap/dldinoap.py $@ 344 | 345 | MAZE/_ds_menu.dat: $(ROM_02000000) 346 | @echo "Make Amaze3DS/R4igold.cc Wood" 347 | @[ -d MAZE ] || mkdir -p MAZE 348 | @cp $< $@ 349 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ak2_sd.dldi $@ 350 | 351 | r4ids.cn/_ds_menu.dat: $(ROM_02000800) 352 | @echo "Make r4ids.cn" 353 | @[ -d r4ids.cn ] || mkdir -p r4ids.cn 354 | @cp $< $@ 355 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ak2_sd.dldi $@ 356 | 357 | R4iLS/_dsmenu.dat: $(ROM_R4ILS) 358 | @echo "Make R4iLS" 359 | @[ -d R4iLS ] || mkdir -p R4iLS 360 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ace3ds_sd.dldi $< 361 | @./resource/r4denc/r4denc --key 0x4002 $< $@ 362 | 363 | Gateway/_dsmenu.dat: $(ROM_GATEWAY) 364 | @echo "Make GW" 365 | @[ -d Gateway ] || mkdir -p Gateway 366 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/ace3ds_sd.dldi $< 367 | @./resource/r4denc/r4denc --key 0x4002 $< $@ 368 | 369 | G003/g003menu.eng: $(ROM_02000000) 370 | @echo "Make GMP-Z003" 371 | @[ -d G003 ] || mkdir -p G003 372 | $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch DLDI/g003.dldi $< 373 | @./resource/dsbize/dsbize $< $@ 0x12 374 | -------------------------------------------------------------------------------- /Makefile.arm7: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # 3 | # SPDX-FileContributor: Antonio Niño Díaz, 2023 4 | 5 | export BLOCKSDS ?= /opt/blocksds/core 6 | export BLOCKSDSEXT ?= /opt/blocksds/external 7 | 8 | export WONDERFUL_TOOLCHAIN ?= /opt/wonderful 9 | ARM_NONE_EABI_PATH ?= $(WONDERFUL_TOOLCHAIN)/toolchain/gcc-arm-none-eabi/bin/ 10 | 11 | # Source code paths 12 | # ----------------- 13 | 14 | SOURCEDIRS := arm7/source 15 | INCLUDEDIRS := 16 | BINDIRS := 17 | 18 | # Defines passed to all files 19 | # --------------------------- 20 | 21 | DEFINES := 22 | 23 | # Libraries 24 | # --------- 25 | 26 | LIBS := -lnds7 27 | LIBDIRS := $(BLOCKSDS)/libs/libnds 28 | 29 | # Build artifacts 30 | # ----------------- 31 | 32 | BUILDDIR := build/arm7 33 | NAME := arm7 34 | ELF := build/$(NAME).elf 35 | DUMP := build/$(NAME).dump 36 | MAP := build/$(NAME).map 37 | 38 | # Tools 39 | # ----- 40 | 41 | PREFIX := $(ARM_NONE_EABI_PATH)arm-none-eabi- 42 | CC := $(PREFIX)gcc 43 | CXX := $(PREFIX)g++ 44 | OBJDUMP := $(PREFIX)objdump 45 | MKDIR := mkdir 46 | RM := rm -rf 47 | 48 | # Verbose flag 49 | # ------------ 50 | 51 | ifeq ($(VERBOSE),1) 52 | V := 53 | else 54 | V := @ 55 | endif 56 | 57 | # Source files 58 | # ------------ 59 | 60 | ifneq ($(BINDIRS),) 61 | SOURCES_BIN := $(shell find -L $(BINDIRS) -name "*.bin") 62 | INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(BINDIRS)) 63 | endif 64 | 65 | SOURCES_S := $(shell find -L $(SOURCEDIRS) -name "*.s") 66 | SOURCES_C := $(shell find -L $(SOURCEDIRS) -name "*.c") 67 | SOURCES_CPP := $(shell find -L $(SOURCEDIRS) -name "*.cpp") 68 | 69 | # Compiler and linker flags 70 | # ------------------------- 71 | 72 | ARCH := -mthumb -mthumb-interwork -mcpu=arm7tdmi 73 | 74 | SPECS := $(BLOCKSDS)/sys/crts/ds_arm7.specs 75 | 76 | WARNFLAGS := -Wall 77 | 78 | ifeq ($(SOURCES_CPP),) 79 | LD := $(CC) 80 | LIBS += -lc 81 | else 82 | LD := $(CXX) 83 | LIBS += -lstdc++ -lc 84 | endif 85 | 86 | INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \ 87 | $(foreach path,$(LIBDIRS),-I$(path)/include) 88 | 89 | LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib) 90 | 91 | ASFLAGS += -x assembler-with-cpp $(DEFINES) $(INCLUDEFLAGS) \ 92 | $(ARCH) -ffunction-sections -fdata-sections \ 93 | -specs=$(SPECS) 94 | 95 | CFLAGS += -std=gnu17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ 96 | $(ARCH) -Os -ffunction-sections -fdata-sections \ 97 | -specs=$(SPECS) 98 | 99 | CXXFLAGS += -std=gnu++17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ 100 | $(ARCH) -Os -ffunction-sections -fdata-sections \ 101 | -fno-exceptions -fno-rtti \ 102 | -specs=$(SPECS) 103 | 104 | LDFLAGS := $(ARCH) $(LIBDIRSFLAGS) -Wl,-Map,$(MAP) $(DEFINES) \ 105 | -Wl,--start-group $(LIBS) -Wl,--end-group -specs=$(SPECS) 106 | 107 | # Intermediate build files 108 | # ------------------------ 109 | 110 | OBJS_ASSETS := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) 111 | 112 | HEADERS_ASSETS := $(patsubst %.bin,%_bin.h,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) 113 | 114 | OBJS_SOURCES := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_S))) \ 115 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_C))) \ 116 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_CPP))) 117 | 118 | OBJS := $(OBJS_ASSETS) $(OBJS_SOURCES) 119 | 120 | DEPS := $(OBJS:.o=.d) 121 | 122 | # Targets 123 | # ------- 124 | 125 | .PHONY: all clean dump 126 | 127 | all: $(ELF) 128 | 129 | $(ELF): $(OBJS) 130 | @echo " LD.7 $@" 131 | $(V)$(LD) -o $@ $(OBJS) $(LDFLAGS) 132 | 133 | $(DUMP): $(ELF) 134 | @echo " OBJDUMP.7 $@" 135 | $(V)$(OBJDUMP) -h -C -S $< > $@ 136 | 137 | dump: $(DUMP) 138 | 139 | clean: 140 | @echo " CLEAN.7" 141 | $(V)$(RM) $(ELF) $(DUMP) $(MAP) $(BUILDDIR) 142 | 143 | # Rules 144 | # ----- 145 | 146 | $(BUILDDIR)/%.s.o : %.s 147 | @echo " AS.7 $<" 148 | @$(MKDIR) -p $(@D) 149 | $(V)$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $< 150 | 151 | $(BUILDDIR)/%.c.o : %.c 152 | @echo " CC.7 $<" 153 | @$(MKDIR) -p $(@D) 154 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $@ $< 155 | 156 | $(BUILDDIR)/%.arm.c.o : %.arm.c 157 | @echo " CC.7 $<" 158 | @$(MKDIR) -p $(@D) 159 | $(V)$(CC) $(CFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< 160 | 161 | $(BUILDDIR)/%.cpp.o : %.cpp 162 | @echo " CXX.7 $<" 163 | @$(MKDIR) -p $(@D) 164 | $(V)$(CXX) $(CXXFLAGS) -MMD -MP -c -o $@ $< 165 | 166 | $(BUILDDIR)/%.arm.cpp.o : %.arm.cpp 167 | @echo " CXX.7 $<" 168 | @$(MKDIR) -p $(@D) 169 | $(V)$(CXX) $(CXXFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< 170 | 171 | $(BUILDDIR)/%.bin.o $(BUILDDIR)/%_bin.h : %.bin 172 | @echo " BIN2C.7 $<" 173 | @$(MKDIR) -p $(@D) 174 | $(V)$(BLOCKSDS)/tools/bin2c/bin2c $< $(@D) 175 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.bin.o $(BUILDDIR)/$*_bin.c 176 | 177 | # All assets must be built before the source code 178 | # ----------------------------------------------- 179 | 180 | $(SOURCES_S) $(SOURCES_C) $(SOURCES_CPP): $(HEADERS_ASSETS) 181 | 182 | # Include dependency files if they exist 183 | # -------------------------------------- 184 | 185 | -include $(DEPS) 186 | -------------------------------------------------------------------------------- /Makefile.arm9: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # 3 | # SPDX-FileContributor: Antonio Niño Díaz, 2023 4 | 5 | export BLOCKSDS ?= /opt/blocksds/core 6 | export BLOCKSDSEXT ?= /opt/blocksds/external 7 | 8 | export WONDERFUL_TOOLCHAIN ?= /opt/wonderful 9 | ARM_NONE_EABI_PATH ?= $(WONDERFUL_TOOLCHAIN)/toolchain/gcc-arm-none-eabi/bin/ 10 | 11 | # Source code paths 12 | # ----------------- 13 | 14 | SOURCEDIRS := arm9/source 15 | INCLUDEDIRS := 16 | GFXDIRS := 17 | BINDIRS := data 18 | AUDIODIRS := 19 | 20 | # Defines passed to all files 21 | # --------------------------- 22 | 23 | DEFINES := -D_NO_BOOTSTUB_ 24 | 25 | # Libraries 26 | # --------- 27 | 28 | LIBS := -lnds9 29 | LIBDIRS := $(BLOCKSDS)/libs/libnds 30 | 31 | # Build artifacts 32 | # --------------- 33 | 34 | NAME := arm9 35 | BUILDDIR := build/$(NAME) 36 | ELF := build/$(NAME).elf 37 | DUMP := build/$(NAME).dump 38 | MAP := build/$(NAME).map 39 | SOUNDBANKDIR := $(BUILDDIR)/maxmod 40 | 41 | # Tools 42 | # ----- 43 | 44 | PREFIX := $(ARM_NONE_EABI_PATH)arm-none-eabi- 45 | CC := $(PREFIX)gcc 46 | CXX := $(PREFIX)g++ 47 | OBJDUMP := $(PREFIX)objdump 48 | MKDIR := mkdir 49 | RM := rm -rf 50 | 51 | # Verbose flag 52 | # ------------ 53 | 54 | ifeq ($(VERBOSE),1) 55 | V := 56 | else 57 | V := @ 58 | endif 59 | 60 | # Source files 61 | # ------------ 62 | 63 | ifneq ($(BINDIRS),) 64 | SOURCES_BIN := $(shell find -L $(BINDIRS) -name "*.bin") 65 | INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(BINDIRS)) 66 | endif 67 | ifneq ($(GFXDIRS),) 68 | SOURCES_PNG := $(shell find -L $(GFXDIRS) -name "*.png") 69 | INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(GFXDIRS)) 70 | endif 71 | ifneq ($(AUDIODIRS),) 72 | SOURCES_AUDIO := $(shell find -L $(AUDIODIRS) -regex '.*\.\(it\|mod\|s3m\|wav\|xm\)') 73 | ifneq ($(SOURCES_AUDIO),) 74 | INCLUDEDIRS += $(SOUNDBANKDIR) 75 | endif 76 | endif 77 | 78 | SOURCES_S := $(shell find -L $(SOURCEDIRS) -name "*.s") 79 | SOURCES_C := $(shell find -L $(SOURCEDIRS) -name "*.c") 80 | SOURCES_CPP := $(shell find -L $(SOURCEDIRS) -name "*.cpp") 81 | 82 | # Compiler and linker flags 83 | # ------------------------- 84 | 85 | ARCH := -mthumb -mthumb-interwork -mcpu=arm946e-s+nofp 86 | 87 | SPECS := $(BLOCKSDS)/sys/crts/ds_arm9.specs 88 | 89 | WARNFLAGS := -Wall 90 | 91 | ifeq ($(SOURCES_CPP),) 92 | LD := $(CC) 93 | LIBS += -lc 94 | else 95 | LD := $(CXX) 96 | LIBS += -lstdc++ -lc 97 | endif 98 | 99 | INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \ 100 | $(foreach path,$(LIBDIRS),-I$(path)/include) 101 | 102 | LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib) 103 | 104 | ASFLAGS += -x assembler-with-cpp $(DEFINES) $(INCLUDEFLAGS) \ 105 | $(ARCH) -ffunction-sections -fdata-sections \ 106 | -specs=$(SPECS) 107 | 108 | CFLAGS += -std=gnu17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ 109 | $(ARCH) -Os -ffunction-sections -fdata-sections \ 110 | -specs=$(SPECS) 111 | 112 | CXXFLAGS += -std=gnu++17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ 113 | $(ARCH) -Os -ffunction-sections -fdata-sections \ 114 | -fno-exceptions -fno-rtti \ 115 | -specs=$(SPECS) 116 | 117 | LDFLAGS := $(ARCH) $(LIBDIRSFLAGS) -Wl,-Map,$(MAP) $(DEFINES) \ 118 | -Wl,--defsym=vfprintf=__i_vfprintf -Wl,--defsym=vfscanf=__i_vfscanf \ 119 | -Wl,--start-group $(LIBS) -Wl,--end-group -specs=$(SPECS) 120 | 121 | # Intermediate build files 122 | # ------------------------ 123 | 124 | OBJS_ASSETS := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ 125 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) 126 | 127 | HEADERS_ASSETS := $(patsubst %.bin,%_bin.h,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ 128 | $(patsubst %.png,%.h,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) 129 | 130 | ifneq ($(SOURCES_AUDIO),) 131 | OBJS_ASSETS += $(SOUNDBANKDIR)/soundbank.c.o 132 | HEADERS_ASSETS += $(SOUNDBANKDIR)/soundbank.h 133 | endif 134 | 135 | OBJS_SOURCES := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_S))) \ 136 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_C))) \ 137 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_CPP))) 138 | 139 | OBJS := $(OBJS_ASSETS) $(OBJS_SOURCES) 140 | 141 | DEPS := $(OBJS:.o=.d) 142 | 143 | # Targets 144 | # ------- 145 | 146 | .PHONY: all clean dump 147 | 148 | all: $(ELF) 149 | 150 | $(ELF): $(OBJS) 151 | @echo " LD.9 $@" 152 | $(V)$(LD) -o $@ $(OBJS) $(LDFLAGS) 153 | 154 | $(DUMP): $(ELF) 155 | @echo " OBJDUMP.9 $@" 156 | $(V)$(OBJDUMP) -h -C -S $< > $@ 157 | 158 | dump: $(DUMP) 159 | 160 | clean: 161 | @echo " CLEAN.9" 162 | $(V)$(RM) $(ELF) $(DUMP) $(MAP) $(BUILDDIR) 163 | 164 | # Rules 165 | # ----- 166 | 167 | $(BUILDDIR)/%.s.o : %.s 168 | @echo " AS.9 $<" 169 | @$(MKDIR) -p $(@D) 170 | $(V)$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $< 171 | 172 | $(BUILDDIR)/%.c.o : %.c 173 | @echo " CC.9 $<" 174 | @$(MKDIR) -p $(@D) 175 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $@ $< 176 | 177 | $(BUILDDIR)/%.arm.c.o : %.arm.c 178 | @echo " CC.9 $<" 179 | @$(MKDIR) -p $(@D) 180 | $(V)$(CC) $(CFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< 181 | 182 | $(BUILDDIR)/%.cpp.o : %.cpp 183 | @echo " CXX.9 $<" 184 | @$(MKDIR) -p $(@D) 185 | $(V)$(CXX) $(CXXFLAGS) -MMD -MP -c -o $@ $< 186 | 187 | $(BUILDDIR)/%.arm.cpp.o : %.arm.cpp 188 | @echo " CXX.9 $<" 189 | @$(MKDIR) -p $(@D) 190 | $(V)$(CXX) $(CXXFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< 191 | 192 | $(BUILDDIR)/%.bin.o $(BUILDDIR)/%_bin.h : %.bin 193 | @echo " BIN2C.9 $<" 194 | @$(MKDIR) -p $(@D) 195 | $(V)$(BLOCKSDS)/tools/bin2c/bin2c $< $(@D) 196 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.bin.o $(BUILDDIR)/$*_bin.c 197 | 198 | $(BUILDDIR)/%.png.o $(BUILDDIR)/%.h : %.png %.grit 199 | @echo " GRIT.9 $<" 200 | @$(MKDIR) -p $(@D) 201 | $(V)$(BLOCKSDS)/tools/grit/grit $< -ftc -W1 -o$(BUILDDIR)/$* 202 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.c 203 | $(V)touch $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.h 204 | 205 | $(SOUNDBANKDIR)/soundbank.h: $(SOURCES_AUDIO) 206 | @echo " MMUTIL $^" 207 | @$(MKDIR) -p $(@D) 208 | @$(BLOCKSDS)/tools/mmutil/mmutil $^ -d \ 209 | -o$(SOUNDBANKDIR)/soundbank.bin -h$(SOUNDBANKDIR)/soundbank.h 210 | 211 | $(SOUNDBANKDIR)/soundbank.c.o: $(SOUNDBANKDIR)/soundbank.h 212 | @echo " BIN2C soundbank.bin" 213 | $(V)$(BLOCKSDS)/tools/bin2c/bin2c $(SOUNDBANKDIR)/soundbank.bin \ 214 | $(SOUNDBANKDIR) 215 | @echo " CC.9 soundbank_bin.c" 216 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(SOUNDBANKDIR)/soundbank.c.o \ 217 | $(SOUNDBANKDIR)/soundbank_bin.c 218 | 219 | # All assets must be built before the source code 220 | # ----------------------------------------------- 221 | 222 | $(SOURCES_S) $(SOURCES_C) $(SOURCES_CPP): $(HEADERS_ASSETS) 223 | 224 | # Include dependency files if they exist 225 | # -------------------------------------- 226 | 227 | -include $(DEPS) 228 | -------------------------------------------------------------------------------- /Makefile.arm9_crt0set: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # 3 | # SPDX-FileContributor: Antonio Niño Díaz, 2023 4 | 5 | export BLOCKSDS ?= /opt/blocksds/core 6 | export BLOCKSDSEXT ?= /opt/blocksds/external 7 | 8 | export WONDERFUL_TOOLCHAIN ?= /opt/wonderful 9 | ARM_NONE_EABI_PATH ?= $(WONDERFUL_TOOLCHAIN)/toolchain/gcc-arm-none-eabi/bin/ 10 | 11 | # Source code paths 12 | # ----------------- 13 | 14 | SOURCEDIRS := arm9/source 15 | INCLUDEDIRS := 16 | GFXDIRS := 17 | BINDIRS := data 18 | AUDIODIRS := 19 | 20 | # Defines passed to all files 21 | # --------------------------- 22 | 23 | DEFINES := -D_NO_BOOTSTUB_ 24 | 25 | # Libraries 26 | # --------- 27 | 28 | LIBS := -lnds9 29 | LIBDIRS := $(BLOCKSDS)/libs/libnds 30 | 31 | # Build artifacts 32 | # --------------- 33 | 34 | NAME := arm9_$(CRT0) 35 | BUILDDIR := build/$(NAME) 36 | ELF := build/$(NAME).elf 37 | DUMP := build/$(NAME).dump 38 | MAP := build/$(NAME).map 39 | SOUNDBANKDIR := $(BUILDDIR)/maxmod 40 | 41 | # Tools 42 | # ----- 43 | 44 | PREFIX := $(ARM_NONE_EABI_PATH)arm-none-eabi- 45 | CC := $(PREFIX)gcc 46 | CXX := $(PREFIX)g++ 47 | OBJDUMP := $(PREFIX)objdump 48 | MKDIR := mkdir 49 | RM := rm -rf 50 | 51 | # Verbose flag 52 | # ------------ 53 | 54 | ifeq ($(VERBOSE),1) 55 | V := 56 | else 57 | V := @ 58 | endif 59 | 60 | # Source files 61 | # ------------ 62 | 63 | ifneq ($(BINDIRS),) 64 | SOURCES_BIN := $(shell find -L $(BINDIRS) -name "*.bin") 65 | INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(BINDIRS)) 66 | endif 67 | ifneq ($(GFXDIRS),) 68 | SOURCES_PNG := $(shell find -L $(GFXDIRS) -name "*.png") 69 | INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(GFXDIRS)) 70 | endif 71 | ifneq ($(AUDIODIRS),) 72 | SOURCES_AUDIO := $(shell find -L $(AUDIODIRS) -regex '.*\.\(it\|mod\|s3m\|wav\|xm\)') 73 | ifneq ($(SOURCES_AUDIO),) 74 | INCLUDEDIRS += $(SOUNDBANKDIR) 75 | endif 76 | endif 77 | 78 | SOURCES_S := $(shell find -L $(SOURCEDIRS) -name "*.s") 79 | SOURCES_C := $(shell find -L $(SOURCEDIRS) -name "*.c") 80 | SOURCES_CPP := $(shell find -L $(SOURCEDIRS) -name "*.cpp") 81 | 82 | # Compiler and linker flags 83 | # ------------------------- 84 | 85 | ARCH := -mthumb -mthumb-interwork -mcpu=arm946e-s+nofp 86 | 87 | SPECS := $(BLOCKSDS)/sys/crts/ds_arm9.specs 88 | 89 | WARNFLAGS := -Wall 90 | 91 | ifeq ($(SOURCES_CPP),) 92 | LD := $(CC) 93 | LIBS += -lc 94 | else 95 | LD := $(CXX) 96 | LIBS += -lstdc++ -lc 97 | endif 98 | 99 | INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \ 100 | $(foreach path,$(LIBDIRS),-I$(path)/include) 101 | 102 | LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib) 103 | 104 | ASFLAGS += -x assembler-with-cpp $(DEFINES) $(INCLUDEFLAGS) \ 105 | $(ARCH) -ffunction-sections -fdata-sections \ 106 | -specs=$(SPECS) 107 | 108 | CFLAGS += -std=gnu17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ 109 | $(ARCH) -Os -ffunction-sections -fdata-sections \ 110 | -specs=$(SPECS) 111 | 112 | CXXFLAGS += -std=gnu++17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ 113 | $(ARCH) -Os -ffunction-sections -fdata-sections \ 114 | -fno-exceptions -fno-rtti \ 115 | -specs=$(SPECS) 116 | 117 | LDFLAGS := $(ARCH) $(LIBDIRSFLAGS) -Wl,-Map,$(MAP) $(DEFINES) \ 118 | -Wl,--defsym,__secure_area__=0 -Wl,--section-start,.crt0=$(CRT0),--nmagic \ 119 | -Wl,--defsym=vfprintf=__i_vfprintf -Wl,--defsym=vfscanf=__i_vfscanf \ 120 | -Wl,--start-group $(LIBS) -Wl,--end-group -specs=$(SPECS) 121 | 122 | # Intermediate build files 123 | # ------------------------ 124 | 125 | OBJS_ASSETS := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ 126 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) 127 | 128 | HEADERS_ASSETS := $(patsubst %.bin,%_bin.h,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ 129 | $(patsubst %.png,%.h,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) 130 | 131 | ifneq ($(SOURCES_AUDIO),) 132 | OBJS_ASSETS += $(SOUNDBANKDIR)/soundbank.c.o 133 | HEADERS_ASSETS += $(SOUNDBANKDIR)/soundbank.h 134 | endif 135 | 136 | OBJS_SOURCES := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_S))) \ 137 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_C))) \ 138 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_CPP))) 139 | 140 | OBJS := $(OBJS_ASSETS) $(OBJS_SOURCES) 141 | 142 | DEPS := $(OBJS:.o=.d) 143 | 144 | # Targets 145 | # ------- 146 | 147 | .PHONY: all clean dump 148 | 149 | all: $(ELF) 150 | 151 | $(ELF): $(OBJS) 152 | @echo " LD.9 $@" 153 | $(V)$(LD) -o $@ $(OBJS) $(LDFLAGS) 154 | 155 | $(DUMP): $(ELF) 156 | @echo " OBJDUMP.9 $@" 157 | $(V)$(OBJDUMP) -h -C -S $< > $@ 158 | 159 | dump: $(DUMP) 160 | 161 | clean: 162 | @echo " CLEAN.9" 163 | $(V)$(RM) $(ELF) $(DUMP) $(MAP) $(BUILDDIR) 164 | 165 | # Rules 166 | # ----- 167 | 168 | $(BUILDDIR)/%.s.o : %.s 169 | @echo " AS.9 $<" 170 | @$(MKDIR) -p $(@D) 171 | $(V)$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $< 172 | 173 | $(BUILDDIR)/%.c.o : %.c 174 | @echo " CC.9 $<" 175 | @$(MKDIR) -p $(@D) 176 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $@ $< 177 | 178 | $(BUILDDIR)/%.arm.c.o : %.arm.c 179 | @echo " CC.9 $<" 180 | @$(MKDIR) -p $(@D) 181 | $(V)$(CC) $(CFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< 182 | 183 | $(BUILDDIR)/%.cpp.o : %.cpp 184 | @echo " CXX.9 $<" 185 | @$(MKDIR) -p $(@D) 186 | $(V)$(CXX) $(CXXFLAGS) -MMD -MP -c -o $@ $< 187 | 188 | $(BUILDDIR)/%.arm.cpp.o : %.arm.cpp 189 | @echo " CXX.9 $<" 190 | @$(MKDIR) -p $(@D) 191 | $(V)$(CXX) $(CXXFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< 192 | 193 | $(BUILDDIR)/%.bin.o $(BUILDDIR)/%_bin.h : %.bin 194 | @echo " BIN2C.9 $<" 195 | @$(MKDIR) -p $(@D) 196 | $(V)$(BLOCKSDS)/tools/bin2c/bin2c $< $(@D) 197 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.bin.o $(BUILDDIR)/$*_bin.c 198 | 199 | $(BUILDDIR)/%.png.o $(BUILDDIR)/%.h : %.png %.grit 200 | @echo " GRIT.9 $<" 201 | @$(MKDIR) -p $(@D) 202 | $(V)$(BLOCKSDS)/tools/grit/grit $< -ftc -W1 -o$(BUILDDIR)/$* 203 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.c 204 | $(V)touch $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.h 205 | 206 | $(SOUNDBANKDIR)/soundbank.h: $(SOURCES_AUDIO) 207 | @echo " MMUTIL $^" 208 | @$(MKDIR) -p $(@D) 209 | @$(BLOCKSDS)/tools/mmutil/mmutil $^ -d \ 210 | -o$(SOUNDBANKDIR)/soundbank.bin -h$(SOUNDBANKDIR)/soundbank.h 211 | 212 | $(SOUNDBANKDIR)/soundbank.c.o: $(SOUNDBANKDIR)/soundbank.h 213 | @echo " BIN2C soundbank.bin" 214 | $(V)$(BLOCKSDS)/tools/bin2c/bin2c $(SOUNDBANKDIR)/soundbank.bin \ 215 | $(SOUNDBANKDIR) 216 | @echo " CC.9 soundbank_bin.c" 217 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(SOUNDBANKDIR)/soundbank.c.o \ 218 | $(SOUNDBANKDIR)/soundbank_bin.c 219 | 220 | # All assets must be built before the source code 221 | # ----------------------------------------------- 222 | 223 | $(SOURCES_S) $(SOURCES_C) $(SOURCES_CPP): $(HEADERS_ASSETS) 224 | 225 | # Include dependency files if they exist 226 | # -------------------------------------- 227 | 228 | -include $(DEPS) 229 | -------------------------------------------------------------------------------- /Makefile.arm9_r4ids: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # 3 | # SPDX-FileContributor: Antonio Niño Díaz, 2023 4 | 5 | export BLOCKSDS ?= /opt/blocksds/core 6 | export BLOCKSDSEXT ?= /opt/blocksds/external 7 | 8 | export WONDERFUL_TOOLCHAIN ?= /opt/wonderful 9 | ARM_NONE_EABI_PATH ?= $(WONDERFUL_TOOLCHAIN)/toolchain/gcc-arm-none-eabi/bin/ 10 | 11 | # Source code paths 12 | # ----------------- 13 | 14 | SOURCEDIRS := arm9/source 15 | INCLUDEDIRS := 16 | GFXDIRS := 17 | BINDIRS := data 18 | AUDIODIRS := 19 | 20 | # Defines passed to all files 21 | # --------------------------- 22 | 23 | DEFINES := -D_NO_BOOTSTUB_ 24 | 25 | # Libraries 26 | # --------- 27 | 28 | LIBS := -lnds9 29 | LIBDIRS := $(BLOCKSDS)/libs/libnds 30 | 31 | # Build artifacts 32 | # --------------- 33 | 34 | NAME := arm9_r4ids 35 | BUILDDIR := build/$(NAME) 36 | ELF := build/$(NAME).elf 37 | DUMP := build/$(NAME).dump 38 | MAP := build/$(NAME).map 39 | SOUNDBANKDIR := $(BUILDDIR)/maxmod 40 | 41 | # Tools 42 | # ----- 43 | 44 | PREFIX := $(ARM_NONE_EABI_PATH)arm-none-eabi- 45 | CC := $(PREFIX)gcc 46 | CXX := $(PREFIX)g++ 47 | OBJDUMP := $(PREFIX)objdump 48 | MKDIR := mkdir 49 | RM := rm -rf 50 | 51 | # Verbose flag 52 | # ------------ 53 | 54 | ifeq ($(VERBOSE),1) 55 | V := 56 | else 57 | V := @ 58 | endif 59 | 60 | # Source files 61 | # ------------ 62 | 63 | ifneq ($(BINDIRS),) 64 | SOURCES_BIN := $(shell find -L $(BINDIRS) -name "*.bin") 65 | INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(BINDIRS)) 66 | endif 67 | ifneq ($(GFXDIRS),) 68 | SOURCES_PNG := $(shell find -L $(GFXDIRS) -name "*.png") 69 | INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(GFXDIRS)) 70 | endif 71 | ifneq ($(AUDIODIRS),) 72 | SOURCES_AUDIO := $(shell find -L $(AUDIODIRS) -regex '.*\.\(it\|mod\|s3m\|wav\|xm\)') 73 | ifneq ($(SOURCES_AUDIO),) 74 | INCLUDEDIRS += $(SOUNDBANKDIR) 75 | endif 76 | endif 77 | 78 | SOURCES_S := $(shell find -L $(SOURCEDIRS) -name "*.s") 79 | SOURCES_C := $(shell find -L $(SOURCEDIRS) -name "*.c") 80 | SOURCES_CPP := $(shell find -L $(SOURCEDIRS) -name "*.cpp") 81 | 82 | # Compiler and linker flags 83 | # ------------------------- 84 | 85 | ARCH := -mthumb -mthumb-interwork -mcpu=arm946e-s+nofp 86 | 87 | SPECS := $(CURDIR)/arm9_r4ids/ds_arm9_r4ids.specs 88 | 89 | WARNFLAGS := -Wall 90 | 91 | ifeq ($(SOURCES_CPP),) 92 | LD := $(CC) 93 | LIBS += -lc 94 | else 95 | LD := $(CXX) 96 | LIBS += -lstdc++ -lc 97 | endif 98 | 99 | INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \ 100 | $(foreach path,$(LIBDIRS),-I$(path)/include) 101 | 102 | LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib) 103 | 104 | ASFLAGS += -x assembler-with-cpp $(DEFINES) $(INCLUDEFLAGS) \ 105 | $(ARCH) -ffunction-sections -fdata-sections \ 106 | -specs=$(SPECS) 107 | 108 | CFLAGS += -std=gnu17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ 109 | $(ARCH) -Os -ffunction-sections -fdata-sections \ 110 | -specs=$(SPECS) 111 | 112 | CXXFLAGS += -std=gnu++17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ 113 | $(ARCH) -Os -ffunction-sections -fdata-sections \ 114 | -fno-exceptions -fno-rtti \ 115 | -specs=$(SPECS) 116 | 117 | LDFLAGS := $(ARCH) $(LIBDIRSFLAGS) -Wl,-Map,$(MAP) $(DEFINES) \ 118 | -Wl,--defsym=vfprintf=__i_vfprintf -Wl,--defsym=vfscanf=__i_vfscanf \ 119 | -Wl,--start-group $(LIBS) -Wl,--end-group -specs=$(SPECS) 120 | 121 | # Intermediate build files 122 | # ------------------------ 123 | 124 | OBJS_ASSETS := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ 125 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) 126 | 127 | HEADERS_ASSETS := $(patsubst %.bin,%_bin.h,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ 128 | $(patsubst %.png,%.h,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) 129 | 130 | ifneq ($(SOURCES_AUDIO),) 131 | OBJS_ASSETS += $(SOUNDBANKDIR)/soundbank.c.o 132 | HEADERS_ASSETS += $(SOUNDBANKDIR)/soundbank.h 133 | endif 134 | 135 | OBJS_SOURCES := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_S))) \ 136 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_C))) \ 137 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_CPP))) 138 | 139 | OBJS := $(OBJS_ASSETS) $(OBJS_SOURCES) 140 | 141 | DEPS := $(OBJS:.o=.d) 142 | 143 | # Targets 144 | # ------- 145 | 146 | .PHONY: all clean dump 147 | 148 | all: $(ELF) 149 | 150 | $(ELF): $(OBJS) 151 | @echo " LD.9 $@" 152 | $(V)$(LD) -o $@ $(OBJS) $(LDFLAGS) 153 | 154 | $(DUMP): $(ELF) 155 | @echo " OBJDUMP.9 $@" 156 | $(V)$(OBJDUMP) -h -C -S $< > $@ 157 | 158 | dump: $(DUMP) 159 | 160 | clean: 161 | @echo " CLEAN.9" 162 | $(V)$(RM) $(ELF) $(DUMP) $(MAP) $(BUILDDIR) 163 | 164 | # Rules 165 | # ----- 166 | 167 | $(BUILDDIR)/%.s.o : %.s 168 | @echo " AS.9 $<" 169 | @$(MKDIR) -p $(@D) 170 | $(V)$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $< 171 | 172 | $(BUILDDIR)/%.c.o : %.c 173 | @echo " CC.9 $<" 174 | @$(MKDIR) -p $(@D) 175 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $@ $< 176 | 177 | $(BUILDDIR)/%.arm.c.o : %.arm.c 178 | @echo " CC.9 $<" 179 | @$(MKDIR) -p $(@D) 180 | $(V)$(CC) $(CFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< 181 | 182 | $(BUILDDIR)/%.cpp.o : %.cpp 183 | @echo " CXX.9 $<" 184 | @$(MKDIR) -p $(@D) 185 | $(V)$(CXX) $(CXXFLAGS) -MMD -MP -c -o $@ $< 186 | 187 | $(BUILDDIR)/%.arm.cpp.o : %.arm.cpp 188 | @echo " CXX.9 $<" 189 | @$(MKDIR) -p $(@D) 190 | $(V)$(CXX) $(CXXFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< 191 | 192 | $(BUILDDIR)/%.bin.o $(BUILDDIR)/%_bin.h : %.bin 193 | @echo " BIN2C.9 $<" 194 | @$(MKDIR) -p $(@D) 195 | $(V)$(BLOCKSDS)/tools/bin2c/bin2c $< $(@D) 196 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.bin.o $(BUILDDIR)/$*_bin.c 197 | 198 | $(BUILDDIR)/%.png.o $(BUILDDIR)/%.h : %.png %.grit 199 | @echo " GRIT.9 $<" 200 | @$(MKDIR) -p $(@D) 201 | $(V)$(BLOCKSDS)/tools/grit/grit $< -ftc -W1 -o$(BUILDDIR)/$* 202 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.c 203 | $(V)touch $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.h 204 | 205 | $(SOUNDBANKDIR)/soundbank.h: $(SOURCES_AUDIO) 206 | @echo " MMUTIL $^" 207 | @$(MKDIR) -p $(@D) 208 | @$(BLOCKSDS)/tools/mmutil/mmutil $^ -d \ 209 | -o$(SOUNDBANKDIR)/soundbank.bin -h$(SOUNDBANKDIR)/soundbank.h 210 | 211 | $(SOUNDBANKDIR)/soundbank.c.o: $(SOUNDBANKDIR)/soundbank.h 212 | @echo " BIN2C soundbank.bin" 213 | $(V)$(BLOCKSDS)/tools/bin2c/bin2c $(SOUNDBANKDIR)/soundbank.bin \ 214 | $(SOUNDBANKDIR) 215 | @echo " CC.9 soundbank_bin.c" 216 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(SOUNDBANKDIR)/soundbank.c.o \ 217 | $(SOUNDBANKDIR)/soundbank_bin.c 218 | 219 | # All assets must be built before the source code 220 | # ----------------------------------------------- 221 | 222 | $(SOURCES_S) $(SOURCES_C) $(SOURCES_CPP): $(HEADERS_ASSETS) 223 | 224 | # Include dependency files if they exist 225 | # -------------------------------------- 226 | 227 | -include $(DEPS) 228 | -------------------------------------------------------------------------------- /Makefile.arm9_r4isdhc: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # 3 | # SPDX-FileContributor: Antonio Niño Díaz, 2023 4 | 5 | export BLOCKSDS ?= /opt/blocksds/core 6 | export BLOCKSDSEXT ?= /opt/blocksds/external 7 | 8 | export WONDERFUL_TOOLCHAIN ?= /opt/wonderful 9 | ARM_NONE_EABI_PATH ?= $(WONDERFUL_TOOLCHAIN)/toolchain/gcc-arm-none-eabi/bin/ 10 | 11 | # Source code paths 12 | # ----------------- 13 | 14 | SOURCEDIRS := arm9/source arm9_r4isdhc/source 15 | INCLUDEDIRS := 16 | GFXDIRS := 17 | BINDIRS := data 18 | AUDIODIRS := 19 | 20 | # Defines passed to all files 21 | # --------------------------- 22 | 23 | DEFINES := -D_NO_BOOTSTUB_ 24 | 25 | # Libraries 26 | # --------- 27 | 28 | LIBS := -lnds9 29 | LIBDIRS := $(BLOCKSDS)/libs/libnds 30 | 31 | # Build artifacts 32 | # --------------- 33 | 34 | NAME := arm9_r4isdhc 35 | BUILDDIR := build/$(NAME) 36 | ELF := build/$(NAME).elf 37 | DUMP := build/$(NAME).dump 38 | MAP := build/$(NAME).map 39 | SOUNDBANKDIR := $(BUILDDIR)/maxmod 40 | 41 | # Tools 42 | # ----- 43 | 44 | PREFIX := $(ARM_NONE_EABI_PATH)arm-none-eabi- 45 | CC := $(PREFIX)gcc 46 | CXX := $(PREFIX)g++ 47 | OBJDUMP := $(PREFIX)objdump 48 | MKDIR := mkdir 49 | RM := rm -rf 50 | 51 | # Verbose flag 52 | # ------------ 53 | 54 | ifeq ($(VERBOSE),1) 55 | V := 56 | else 57 | V := @ 58 | endif 59 | 60 | # Source files 61 | # ------------ 62 | 63 | ifneq ($(BINDIRS),) 64 | SOURCES_BIN := $(shell find -L $(BINDIRS) -name "*.bin") 65 | INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(BINDIRS)) 66 | endif 67 | ifneq ($(GFXDIRS),) 68 | SOURCES_PNG := $(shell find -L $(GFXDIRS) -name "*.png") 69 | INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(GFXDIRS)) 70 | endif 71 | ifneq ($(AUDIODIRS),) 72 | SOURCES_AUDIO := $(shell find -L $(AUDIODIRS) -regex '.*\.\(it\|mod\|s3m\|wav\|xm\)') 73 | ifneq ($(SOURCES_AUDIO),) 74 | INCLUDEDIRS += $(SOUNDBANKDIR) 75 | endif 76 | endif 77 | 78 | SOURCES_S := $(shell find -L $(SOURCEDIRS) -name "*.s") 79 | SOURCES_C := $(shell find -L $(SOURCEDIRS) -name "*.c") 80 | SOURCES_CPP := $(shell find -L $(SOURCEDIRS) -name "*.cpp") 81 | 82 | # Compiler and linker flags 83 | # ------------------------- 84 | 85 | ARCH := -mthumb -mthumb-interwork -mcpu=arm946e-s+nofp 86 | 87 | SPECS := $(CURDIR)/arm9_r4isdhc/ds_arm9_r4isdhc.specs 88 | 89 | WARNFLAGS := -Wall 90 | 91 | ifeq ($(SOURCES_CPP),) 92 | LD := $(CC) 93 | LIBS += -lc 94 | else 95 | LD := $(CXX) 96 | LIBS += -lstdc++ -lc 97 | endif 98 | 99 | INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \ 100 | $(foreach path,$(LIBDIRS),-I$(path)/include) 101 | 102 | LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib) 103 | 104 | ASFLAGS += -x assembler-with-cpp $(DEFINES) $(INCLUDEFLAGS) \ 105 | $(ARCH) -ffunction-sections -fdata-sections \ 106 | -specs=$(SPECS) 107 | 108 | CFLAGS += -std=gnu17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ 109 | $(ARCH) -Os -ffunction-sections -fdata-sections \ 110 | -specs=$(SPECS) 111 | 112 | CXXFLAGS += -std=gnu++17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ 113 | $(ARCH) -Os -ffunction-sections -fdata-sections \ 114 | -fno-exceptions -fno-rtti \ 115 | -specs=$(SPECS) 116 | 117 | LDFLAGS := $(ARCH) $(LIBDIRSFLAGS) -Wl,-Map,$(MAP) $(DEFINES) \ 118 | -Wl,--defsym=vfprintf=__i_vfprintf -Wl,--defsym=vfscanf=__i_vfscanf \ 119 | -Wl,--start-group $(LIBS) -Wl,--end-group -specs=$(SPECS) 120 | 121 | # Intermediate build files 122 | # ------------------------ 123 | 124 | OBJS_ASSETS := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ 125 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) 126 | 127 | HEADERS_ASSETS := $(patsubst %.bin,%_bin.h,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ 128 | $(patsubst %.png,%.h,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) 129 | 130 | ifneq ($(SOURCES_AUDIO),) 131 | OBJS_ASSETS += $(SOUNDBANKDIR)/soundbank.c.o 132 | HEADERS_ASSETS += $(SOUNDBANKDIR)/soundbank.h 133 | endif 134 | 135 | OBJS_SOURCES := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_S))) \ 136 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_C))) \ 137 | $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_CPP))) 138 | 139 | OBJS := $(OBJS_ASSETS) $(OBJS_SOURCES) 140 | 141 | DEPS := $(OBJS:.o=.d) 142 | 143 | # Targets 144 | # ------- 145 | 146 | .PHONY: all clean dump 147 | 148 | all: $(ELF) 149 | 150 | $(ELF): $(OBJS) 151 | @echo " LD.9 $@" 152 | $(V)$(LD) -o $@ $(OBJS) $(LDFLAGS) 153 | 154 | $(DUMP): $(ELF) 155 | @echo " OBJDUMP.9 $@" 156 | $(V)$(OBJDUMP) -h -C -S $< > $@ 157 | 158 | dump: $(DUMP) 159 | 160 | clean: 161 | @echo " CLEAN.9" 162 | $(V)$(RM) $(ELF) $(DUMP) $(MAP) $(BUILDDIR) 163 | 164 | # Rules 165 | # ----- 166 | 167 | $(BUILDDIR)/%.s.o : %.s 168 | @echo " AS.9 $<" 169 | @$(MKDIR) -p $(@D) 170 | $(V)$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $< 171 | 172 | $(BUILDDIR)/%.c.o : %.c 173 | @echo " CC.9 $<" 174 | @$(MKDIR) -p $(@D) 175 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $@ $< 176 | 177 | $(BUILDDIR)/%.arm.c.o : %.arm.c 178 | @echo " CC.9 $<" 179 | @$(MKDIR) -p $(@D) 180 | $(V)$(CC) $(CFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< 181 | 182 | $(BUILDDIR)/%.cpp.o : %.cpp 183 | @echo " CXX.9 $<" 184 | @$(MKDIR) -p $(@D) 185 | $(V)$(CXX) $(CXXFLAGS) -MMD -MP -c -o $@ $< 186 | 187 | $(BUILDDIR)/%.arm.cpp.o : %.arm.cpp 188 | @echo " CXX.9 $<" 189 | @$(MKDIR) -p $(@D) 190 | $(V)$(CXX) $(CXXFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< 191 | 192 | $(BUILDDIR)/%.bin.o $(BUILDDIR)/%_bin.h : %.bin 193 | @echo " BIN2C.9 $<" 194 | @$(MKDIR) -p $(@D) 195 | $(V)$(BLOCKSDS)/tools/bin2c/bin2c $< $(@D) 196 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.bin.o $(BUILDDIR)/$*_bin.c 197 | 198 | $(BUILDDIR)/%.png.o $(BUILDDIR)/%.h : %.png %.grit 199 | @echo " GRIT.9 $<" 200 | @$(MKDIR) -p $(@D) 201 | $(V)$(BLOCKSDS)/tools/grit/grit $< -ftc -W1 -o$(BUILDDIR)/$* 202 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.c 203 | $(V)touch $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.h 204 | 205 | $(SOUNDBANKDIR)/soundbank.h: $(SOURCES_AUDIO) 206 | @echo " MMUTIL $^" 207 | @$(MKDIR) -p $(@D) 208 | @$(BLOCKSDS)/tools/mmutil/mmutil $^ -d \ 209 | -o$(SOUNDBANKDIR)/soundbank.bin -h$(SOUNDBANKDIR)/soundbank.h 210 | 211 | $(SOUNDBANKDIR)/soundbank.c.o: $(SOUNDBANKDIR)/soundbank.h 212 | @echo " BIN2C soundbank.bin" 213 | $(V)$(BLOCKSDS)/tools/bin2c/bin2c $(SOUNDBANKDIR)/soundbank.bin \ 214 | $(SOUNDBANKDIR) 215 | @echo " CC.9 soundbank_bin.c" 216 | $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(SOUNDBANKDIR)/soundbank.c.o \ 217 | $(SOUNDBANKDIR)/soundbank_bin.c 218 | 219 | # All assets must be built before the source code 220 | # ----------------------------------------------- 221 | 222 | $(SOURCES_S) $(SOURCES_C) $(SOURCES_CPP): $(HEADERS_ASSETS) 223 | 224 | # Include dependency files if they exist 225 | # -------------------------------------- 226 | 227 | -include $(DEPS) 228 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flashcard Bootstrap 2 | 3 | https://github.com/lifehackerhansol/flashcard-bootstrap 4 | 5 | This repository aims to have an easy replacement for your flashcart kernel to automatically boot any homebrew of your choice. 6 | 7 | This will simply launch `BOOT.NDS` homebrew on the root of the SD card. 8 | 9 | Currently available flashcarts: 10 | - DSTT (ttmenu.dat) 11 | - EZ Flash V (ez5sys.bin) 12 | - Original R4 (_ds_menu.dat) 13 | - R4iDSN (_dsmenu.dat) 14 | - Acekard 2, 2.1, 2i (akmenu4.nds) 15 | - Datel Games 'n' Music, Action Replay DSi (bootme.nds) 16 | - N5 (in N5 folder) 17 | - EDGEi (not to be confused with the original EDGE or iEDGE!) (dsedgei.dat) 18 | - r4ids.cn carts, R4 Ultra, R4iTT NEW, R4iTT 3DS, r4i-gold.me, r4i3d.com carts with a year number, r4igold.cc 3DS, r4i-drive.com, r4isdhc.com carts that are ***NOT*** between 2014-2021, r4isdhc.hk carts that are ***NOT*** 2021 (in r4ids.cn folder) 19 | - Amaze3DS, Wood r4igold.cc Upgrade (in MAZE folder) 20 | - Ace3DS+ (in ACEP folder) 21 | - R4iLS, r4isdhc.com.cn, r4isdhc.hk (in R4iLS folder) 22 | - Gateway Blue (in Gateway folder) 23 | - M3 DS Real, M3i Zero (non-GMP-Z003), iTouchDS, iTouch2, R4(i)RTS (r4rts.com), R4 SDHC RTS black (in M3R_iTDS_R4RTS folder) 24 | - DSOne SDHC, DSOnei (in DSOneSDHC_DSOnei folder) 25 | - R4i-SDHC and related timebomb clones (r4.dat) 26 | - M3i Zero (GMP-Z003) (in G003 folder) 27 | - SuperCard DSONE (non-SDHC) (scfw.sc) 28 | - iSmart Premium (ismat.dat) 29 | - EZ-Flash Vi (ez5isys.bin) 30 | - r4i.cn carts (_ds_menu.nds) 31 | - r4dspro.com (in r4dspro.com folder) 32 | - EZ-Flash Parallel (ezds.dat) 33 | 34 | Copy the appropriate files to root, and then add any homebrew of your choice to root and rename it BOOT.NDS. 35 | 36 | # License 37 | 38 | ``` 39 | Copyright (C) 2005 - 2010 40 | Michael "Chishm" Chisholm 41 | Dave "WinterMute" Murphy 42 | 43 | This program is free software; you can redistribute it and/or 44 | modify it under the terms of the GNU General Public License 45 | as published by the Free Software Foundation; either version 2 46 | of the License, or (at your option) any later version. 47 | 48 | This program is distributed in the hope that it will be useful, 49 | but WITHOUT ANY WARRANTY; without even the implied warranty of 50 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51 | GNU General Public License for more details. 52 | 53 | You should have received a copy of the GNU General Public License 54 | along with this program; if not, write to the Free Software 55 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 56 | ``` 57 | -------------------------------------------------------------------------------- /arm7/source/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | flashcard-bootstrap 3 | By lifehackerhansol 4 | 5 | SPDX-License-Identifier: 0BSD 6 | */ 7 | 8 | #include 9 | 10 | void VblankHandler(void) { 11 | } 12 | 13 | int main(void) { 14 | ledBlink(0); 15 | 16 | irqInit(); 17 | fifoInit(); 18 | installSystemFIFO(); 19 | irqSet(IRQ_VBLANK, VblankHandler); 20 | irqEnable(IRQ_VBLANK); 21 | 22 | while(1) { 23 | swiWaitForVBlank(); 24 | 25 | if(fifoCheckValue32(FIFO_USER_01)) { 26 | fifoGetValue32(FIFO_USER_01); 27 | break; 28 | } 29 | } 30 | return 0; 31 | } -------------------------------------------------------------------------------- /arm9/source/dldi_size.s: -------------------------------------------------------------------------------- 1 | @ 2 | @ flashcard-bootstrap 3 | @ By lifehackerhansol 4 | @ 5 | @ SPDX-License-Identifier: 0BSD 6 | @ 7 | 8 | @ Use 32KB DLDI space, needed for legacy homebrew 9 | 10 | .global __dldi_size 11 | .equ __dldi_size, 32768 12 | -------------------------------------------------------------------------------- /arm9/source/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | flashcard-bootstrap 3 | By lifehackerhansol 4 | 5 | SPDX-License-Identifier: 0BSD 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include "nds_loader_arm9.h" 15 | 16 | int fail(char* error){ 17 | consoleDemoInit(); 18 | printf("Bootstrap fail:\n"); 19 | printf("%s\n\n", error); 20 | printf("Press START to power off."); 21 | while(1) { 22 | swiWaitForVBlank(); 23 | scanKeys(); 24 | int pressed = keysDown(); 25 | if(pressed & KEY_START) break; 26 | } 27 | fifoSendValue32(FIFO_USER_01, 1); // turn off ARM7 28 | return 0; 29 | } 30 | 31 | int main(void) { 32 | if (!fatInitDefault()) return fail("FAT init failed!\n"); 33 | if(io_dldi_data->driverSize > 0xE) return fail("DLDI driver too large!\nPlease update your kernel."); 34 | int err = runNdsFile("/BOOT.nds", 0, NULL); 35 | char message[20]; 36 | sprintf(message, "Error code: %d", err); 37 | return fail(message); 38 | } 39 | -------------------------------------------------------------------------------- /arm9/source/nds_loader_arm9.c: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------- 2 | Copyright (C) 2005 - 2010 3 | Michael "Chishm" Chisholm 4 | Dave "WinterMute" Murphy 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (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, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | ------------------------------------------------------------------*/ 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | #include "load_bin.h" 31 | 32 | #ifndef _NO_BOOTSTUB_ 33 | #include "bootstub_bin.h" 34 | #include "exceptionstub_bin.h" 35 | #endif 36 | 37 | #include "nds_loader_arm9.h" 38 | #define LCDC_BANK_C (u16*)0x06840000 39 | #define STORED_FILE_CLUSTER (*(((u32*)LCDC_BANK_C) + 1)) 40 | #define INIT_DISC (*(((u32*)LCDC_BANK_C) + 2)) 41 | #define WANT_TO_PATCH_DLDI (*(((u32*)LCDC_BANK_C) + 3)) 42 | 43 | 44 | /* 45 | b startUp 46 | 47 | storedFileCluster: 48 | .word 0x0FFFFFFF @ default BOOT.NDS 49 | initDisc: 50 | .word 0x00000001 @ init the disc by default 51 | wantToPatchDLDI: 52 | .word 0x00000001 @ by default patch the DLDI section of the loaded NDS 53 | @ Used for passing arguments to the loaded app 54 | argStart: 55 | .word _end - _start 56 | argSize: 57 | .word 0x00000000 58 | dldiOffset: 59 | .word _dldi_start - _start 60 | dsiSD: 61 | .word 0 62 | dsiMode: 63 | .word 0 64 | */ 65 | 66 | #define STORED_FILE_CLUSTER_OFFSET 4 67 | #define INIT_DISC_OFFSET 8 68 | #define WANT_TO_PATCH_DLDI_OFFSET 12 69 | #define ARG_START_OFFSET 16 70 | #define ARG_SIZE_OFFSET 20 71 | #define HAVE_DSISD_OFFSET 28 72 | #define DSIMODE_OFFSET 32 73 | 74 | 75 | typedef signed int addr_t; 76 | typedef unsigned char data_t; 77 | 78 | #define FIX_ALL 0x01 79 | #define FIX_GLUE 0x02 80 | #define FIX_GOT 0x04 81 | #define FIX_BSS 0x08 82 | 83 | enum DldiOffsets { 84 | DO_magicString = 0x00, // "\xED\xA5\x8D\xBF Chishm" 85 | DO_magicToken = 0x00, // 0xBF8DA5ED 86 | DO_magicShortString = 0x04, // " Chishm" 87 | DO_version = 0x0C, 88 | DO_driverSize = 0x0D, 89 | DO_fixSections = 0x0E, 90 | DO_allocatedSpace = 0x0F, 91 | 92 | DO_friendlyName = 0x10, 93 | 94 | DO_text_start = 0x40, // Data start 95 | DO_data_end = 0x44, // Data end 96 | DO_glue_start = 0x48, // Interworking glue start -- Needs address fixing 97 | DO_glue_end = 0x4C, // Interworking glue end 98 | DO_got_start = 0x50, // GOT start -- Needs address fixing 99 | DO_got_end = 0x54, // GOT end 100 | DO_bss_start = 0x58, // bss start -- Needs setting to zero 101 | DO_bss_end = 0x5C, // bss end 102 | 103 | // IO_INTERFACE data 104 | DO_ioType = 0x60, 105 | DO_features = 0x64, 106 | DO_startup = 0x68, 107 | DO_isInserted = 0x6C, 108 | DO_readSectors = 0x70, 109 | DO_writeSectors = 0x74, 110 | DO_clearStatus = 0x78, 111 | DO_shutdown = 0x7C, 112 | DO_code = 0x80 113 | }; 114 | 115 | static addr_t readAddr (data_t *mem, addr_t offset) { 116 | return ((addr_t*)mem)[offset/sizeof(addr_t)]; 117 | } 118 | 119 | static void writeAddr (data_t *mem, addr_t offset, addr_t value) { 120 | ((addr_t*)mem)[offset/sizeof(addr_t)] = value; 121 | } 122 | 123 | static addr_t quickFind (const data_t* data, const data_t* search, size_t dataLen, size_t searchLen) { 124 | const int* dataChunk = (const int*) data; 125 | int searchChunk = ((const int*)search)[0]; 126 | addr_t i; 127 | addr_t dataChunkEnd = (addr_t)(dataLen / sizeof(int)); 128 | 129 | for ( i = 0; i < dataChunkEnd; i++) { 130 | if (dataChunk[i] == searchChunk) { 131 | if ((i*sizeof(int) + searchLen) > dataLen) { 132 | return -1; 133 | } 134 | if (memcmp (&data[i*sizeof(int)], search, searchLen) == 0) { 135 | return i*sizeof(int); 136 | } 137 | } 138 | } 139 | 140 | return -1; 141 | } 142 | 143 | // Normal DLDI uses "\xED\xA5\x8D\xBF Chishm" 144 | // Bootloader string is different to avoid being patched 145 | static const data_t dldiMagicLoaderString[] = "\xEE\xA5\x8D\xBF Chishm"; // Different to a normal DLDI file 146 | 147 | #define DEVICE_TYPE_DLDI 0x49444C44 148 | 149 | static bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS) 150 | { 151 | addr_t memOffset; // Offset of DLDI after the file is loaded into memory 152 | addr_t patchOffset; // Position of patch destination in the file 153 | addr_t relocationOffset; // Value added to all offsets within the patch to fix it properly 154 | addr_t ddmemOffset; // Original offset used in the DLDI file 155 | addr_t ddmemStart; // Start of range that offsets can be in the DLDI file 156 | addr_t ddmemEnd; // End of range that offsets can be in the DLDI file 157 | addr_t ddmemSize; // Size of range that offsets can be in the DLDI file 158 | 159 | addr_t addrIter; 160 | 161 | data_t *pDH; 162 | data_t *pAH; 163 | 164 | size_t dldiFileSize = 0; 165 | 166 | // Find the DLDI reserved space in the file 167 | patchOffset = quickFind (binData, dldiMagicLoaderString, binSize, sizeof(dldiMagicLoaderString)); 168 | 169 | if (patchOffset < 0) { 170 | // does not have a DLDI section 171 | return false; 172 | } 173 | 174 | pDH = (data_t*)(io_dldi_data); 175 | 176 | pAH = &(binData[patchOffset]); 177 | 178 | if (*((u32*)(pDH + DO_ioType)) == DEVICE_TYPE_DLDI) { 179 | // No DLDI patch 180 | return false; 181 | } 182 | 183 | if (pDH[DO_driverSize] > pAH[DO_allocatedSpace]) { 184 | // Not enough space for patch 185 | return false; 186 | } 187 | 188 | dldiFileSize = 1 << pDH[DO_driverSize]; 189 | 190 | memOffset = readAddr (pAH, DO_text_start); 191 | if (memOffset == 0) { 192 | memOffset = readAddr (pAH, DO_startup) - DO_code; 193 | } 194 | ddmemOffset = readAddr (pDH, DO_text_start); 195 | relocationOffset = memOffset - ddmemOffset; 196 | 197 | ddmemStart = readAddr (pDH, DO_text_start); 198 | ddmemSize = (1 << pDH[DO_driverSize]); 199 | ddmemEnd = ddmemStart + ddmemSize; 200 | 201 | // Remember how much space is actually reserved 202 | pDH[DO_allocatedSpace] = pAH[DO_allocatedSpace]; 203 | // Copy the DLDI patch into the application 204 | memcpy (pAH, pDH, dldiFileSize); 205 | 206 | // Fix the section pointers in the header 207 | writeAddr (pAH, DO_text_start, readAddr (pAH, DO_text_start) + relocationOffset); 208 | writeAddr (pAH, DO_data_end, readAddr (pAH, DO_data_end) + relocationOffset); 209 | writeAddr (pAH, DO_glue_start, readAddr (pAH, DO_glue_start) + relocationOffset); 210 | writeAddr (pAH, DO_glue_end, readAddr (pAH, DO_glue_end) + relocationOffset); 211 | writeAddr (pAH, DO_got_start, readAddr (pAH, DO_got_start) + relocationOffset); 212 | writeAddr (pAH, DO_got_end, readAddr (pAH, DO_got_end) + relocationOffset); 213 | writeAddr (pAH, DO_bss_start, readAddr (pAH, DO_bss_start) + relocationOffset); 214 | writeAddr (pAH, DO_bss_end, readAddr (pAH, DO_bss_end) + relocationOffset); 215 | // Fix the function pointers in the header 216 | writeAddr (pAH, DO_startup, readAddr (pAH, DO_startup) + relocationOffset); 217 | writeAddr (pAH, DO_isInserted, readAddr (pAH, DO_isInserted) + relocationOffset); 218 | writeAddr (pAH, DO_readSectors, readAddr (pAH, DO_readSectors) + relocationOffset); 219 | writeAddr (pAH, DO_writeSectors, readAddr (pAH, DO_writeSectors) + relocationOffset); 220 | writeAddr (pAH, DO_clearStatus, readAddr (pAH, DO_clearStatus) + relocationOffset); 221 | writeAddr (pAH, DO_shutdown, readAddr (pAH, DO_shutdown) + relocationOffset); 222 | 223 | if (pDH[DO_fixSections] & FIX_ALL) { 224 | // Search through and fix pointers within the data section of the file 225 | for (addrIter = (readAddr(pDH, DO_text_start) - ddmemStart); addrIter < (readAddr(pDH, DO_data_end) - ddmemStart); addrIter++) { 226 | if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) { 227 | writeAddr (pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset); 228 | } 229 | } 230 | } 231 | 232 | if (pDH[DO_fixSections] & FIX_GLUE) { 233 | // Search through and fix pointers within the glue section of the file 234 | for (addrIter = (readAddr(pDH, DO_glue_start) - ddmemStart); addrIter < (readAddr(pDH, DO_glue_end) - ddmemStart); addrIter++) { 235 | if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) { 236 | writeAddr (pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset); 237 | } 238 | } 239 | } 240 | 241 | if (pDH[DO_fixSections] & FIX_GOT) { 242 | // Search through and fix pointers within the Global Offset Table section of the file 243 | for (addrIter = (readAddr(pDH, DO_got_start) - ddmemStart); addrIter < (readAddr(pDH, DO_got_end) - ddmemStart); addrIter++) { 244 | if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) { 245 | writeAddr (pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset); 246 | } 247 | } 248 | } 249 | 250 | if (clearBSS && (pDH[DO_fixSections] & FIX_BSS)) { 251 | // Initialise the BSS to 0, only if the disc is being re-inited 252 | memset (&pAH[readAddr(pDH, DO_bss_start) - ddmemStart] , 0, readAddr(pDH, DO_bss_end) - readAddr(pDH, DO_bss_start)); 253 | } 254 | 255 | return true; 256 | } 257 | 258 | eRunNdsRetCode runNds (const void* loader, u32 loaderSize, u32 cluster, bool initDisc, bool dldiPatchNds, int argc, const char** argv) 259 | { 260 | char* argStart; 261 | u16* argData; 262 | u16 argTempVal = 0; 263 | int argSize; 264 | const char* argChar; 265 | 266 | irqDisable(IRQ_ALL); 267 | 268 | // Direct CPU access to VRAM bank C 269 | VRAM_C_CR = VRAM_ENABLE | VRAM_C_LCD; 270 | // Load the loader/patcher into the correct address 271 | memcpy (LCDC_BANK_C, loader, loaderSize); 272 | 273 | // Set the parameters for the loader 274 | // STORED_FILE_CLUSTER = cluster; 275 | writeAddr ((data_t*) LCDC_BANK_C, STORED_FILE_CLUSTER_OFFSET, cluster); 276 | // INIT_DISC = initDisc; 277 | writeAddr ((data_t*) LCDC_BANK_C, INIT_DISC_OFFSET, initDisc); 278 | 279 | writeAddr ((data_t*) LCDC_BANK_C, DSIMODE_OFFSET, isDSiMode()); 280 | if(argv[0][0]=='s' && argv[0][1]=='d') { 281 | dldiPatchNds = false; 282 | writeAddr ((data_t*) LCDC_BANK_C, HAVE_DSISD_OFFSET, 1); 283 | } 284 | 285 | // WANT_TO_PATCH_DLDI = dldiPatchNds; 286 | writeAddr ((data_t*) LCDC_BANK_C, WANT_TO_PATCH_DLDI_OFFSET, dldiPatchNds); 287 | // Give arguments to loader 288 | argStart = (char*)LCDC_BANK_C + readAddr((data_t*)LCDC_BANK_C, ARG_START_OFFSET); 289 | argStart = (char*)(((int)argStart + 3) & ~3); // Align to word 290 | argData = (u16*)argStart; 291 | argSize = 0; 292 | 293 | for (; argc > 0 && *argv; ++argv, --argc) 294 | { 295 | for (argChar = *argv; *argChar != 0; ++argChar, ++argSize) 296 | { 297 | if (argSize & 1) 298 | { 299 | argTempVal |= (*argChar) << 8; 300 | *argData = argTempVal; 301 | ++argData; 302 | } 303 | else 304 | { 305 | argTempVal = *argChar; 306 | } 307 | } 308 | if (argSize & 1) 309 | { 310 | *argData = argTempVal; 311 | ++argData; 312 | } 313 | argTempVal = 0; 314 | ++argSize; 315 | } 316 | *argData = argTempVal; 317 | 318 | writeAddr ((data_t*) LCDC_BANK_C, ARG_START_OFFSET, (addr_t)argStart - (addr_t)LCDC_BANK_C); 319 | writeAddr ((data_t*) LCDC_BANK_C, ARG_SIZE_OFFSET, argSize); 320 | 321 | 322 | if(dldiPatchNds) { 323 | // Patch the loader with a DLDI for the card 324 | if (!dldiPatchLoader ((data_t*)LCDC_BANK_C, loaderSize, initDisc)) { 325 | return RUN_NDS_PATCH_DLDI_FAILED; 326 | } 327 | } 328 | 329 | irqDisable(IRQ_ALL); 330 | 331 | // Give the VRAM to the ARM7 332 | VRAM_C_CR = VRAM_ENABLE | VRAM_C_ARM7_0x06000000; 333 | // Reset into a passme loop 334 | REG_EXMEMCNT |= ARM7_OWNS_ROM | ARM7_OWNS_CARD; 335 | *((vu32*)0x02FFFFFC) = 0; 336 | *((vu32*)0x02FFFE04) = (u32)0xE59FF018; 337 | *((vu32*)0x02FFFE24) = (u32)0x02FFFE04; 338 | 339 | resetARM7(0x06000000); 340 | 341 | swiSoftReset(); 342 | return RUN_NDS_OK; 343 | } 344 | 345 | eRunNdsRetCode runNdsFile (const char* filename, int argc, const char** argv) { 346 | struct stat st; 347 | char filePath[PATH_MAX]; 348 | int pathLen; 349 | const char* args[1]; 350 | 351 | 352 | if (stat (filename, &st) < 0) { 353 | return RUN_NDS_STAT_FAILED; 354 | } 355 | 356 | if (argc <= 0 || !argv) { 357 | // Construct a command line if we weren't supplied with one 358 | if (!getcwd (filePath, PATH_MAX)) { 359 | return RUN_NDS_GETCWD_FAILED; 360 | } 361 | pathLen = strlen (filePath); 362 | strcpy (filePath + pathLen, filename); 363 | args[0] = filePath; 364 | argv = args; 365 | } 366 | 367 | bool havedsiSD = false; 368 | 369 | if(argv[0][0]=='s' && argv[0][1]=='d') havedsiSD = true; 370 | 371 | installBootStub(havedsiSD); 372 | 373 | return runNds (load_bin, load_bin_size, st.st_ino, true, true, argc, argv); 374 | } 375 | 376 | /* 377 | b startUp 378 | 379 | storedFileCluster: 380 | .word 0x0FFFFFFF @ default BOOT.NDS 381 | initDisc: 382 | .word 0x00000001 @ init the disc by default 383 | wantToPatchDLDI: 384 | .word 0x00000001 @ by default patch the DLDI section of the loaded NDS 385 | @ Used for passing arguments to the loaded app 386 | argStart: 387 | .word _end - _start 388 | argSize: 389 | .word 0x00000000 390 | dldiOffset: 391 | .word _dldi_start - _start 392 | dsiSD: 393 | .word 0 394 | */ 395 | 396 | void(*exceptionstub)(void) = (void(*)(void))0x2ffa000; 397 | 398 | bool installBootStub(bool havedsiSD) { 399 | #ifndef _NO_BOOTSTUB_ 400 | extern char *fake_heap_end; 401 | struct __bootstub *bootstub = (struct __bootstub *)fake_heap_end; 402 | u32 *bootloader = (u32*)(fake_heap_end+bootstub_bin_size); 403 | 404 | memcpy(bootstub,bootstub_bin,bootstub_bin_size); 405 | memcpy(bootloader,load_bin,load_bin_size); 406 | bool ret = false; 407 | 408 | bootloader[8] = isDSiMode(); 409 | if( havedsiSD) { 410 | ret = true; 411 | bootloader[3] = 0; // don't dldi patch 412 | bootloader[7] = 1; // use internal dsi SD code 413 | } else { 414 | ret = dldiPatchLoader((data_t*)bootloader, load_bin_size,false); 415 | } 416 | bootstub->arm9reboot = (VoidFn)(((u32)bootstub->arm9reboot)+fake_heap_end); 417 | bootstub->arm7reboot = (VoidFn)(((u32)bootstub->arm7reboot)+fake_heap_end); 418 | bootstub->bootsize = load_bin_size; 419 | 420 | memcpy(exceptionstub,exceptionstub_bin,exceptionstub_bin_size); 421 | 422 | exceptionstub(); 423 | 424 | DC_FlushAll(); 425 | 426 | return ret; 427 | #else 428 | return true; 429 | #endif 430 | 431 | } 432 | 433 | -------------------------------------------------------------------------------- /arm9/source/nds_loader_arm9.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------- 2 | Copyright (C) 2005 - 2010 3 | Michael "Chishm" Chisholm 4 | Dave "WinterMute" Murphy 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (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, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | 20 | ------------------------------------------------------------------*/ 21 | 22 | #ifndef NDS_LOADER_ARM9_H 23 | #define NDS_LOADER_ARM9_H 24 | 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | typedef enum { 31 | RUN_NDS_OK = 0, 32 | RUN_NDS_STAT_FAILED, 33 | RUN_NDS_GETCWD_FAILED, 34 | RUN_NDS_PATCH_DLDI_FAILED, 35 | } eRunNdsRetCode; 36 | 37 | #define LOAD_DEFAULT_NDS 0 38 | 39 | eRunNdsRetCode runNds (const void* loader, u32 loaderSize, u32 cluster, bool initDisc, bool dldiPatchNds, int argc, const char** argv); 40 | 41 | eRunNdsRetCode runNdsFile (const char* filename, int argc, const char** argv); 42 | 43 | bool installBootStub(bool havedsiSD); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif // NDS_LOADER_ARM7_H 50 | -------------------------------------------------------------------------------- /arm9_r4ids/ds_arm9_r4ids.mem: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------------- 2 | This Source Code Form is subject to the terms of the Mozilla Public License, 3 | v. 2.0. If a copy of the MPL was not distributed with this file, You can 4 | obtain one at https://mozilla.org/MPL/2.0/. 5 | --------------------------------------------------------------------------------*/ 6 | MEMORY { 7 | ewram : ORIGIN = 0x02000800, LENGTH = 4M - 512k 8 | dtcm : ORIGIN = 0x02ff0000, LENGTH = 16K 9 | vectors : ORIGIN = 0x01000000, LENGTH = 256 10 | itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256 11 | } -------------------------------------------------------------------------------- /arm9_r4ids/ds_arm9_r4ids.specs: -------------------------------------------------------------------------------- 1 | %include 2 | 3 | %rename cc1plus blocksds_cc1plus 4 | %rename cpp blocksds_cpp 5 | %rename link blocksds_link 6 | 7 | *cpp: 8 | -D__NDS__ -D__BLOCKSDS__ -DARM9 %(blocksds_cpp) 9 | 10 | *cc1_cpu: 11 | -mcpu=arm946e-s+nofp 12 | 13 | *cc1plus: 14 | %(cpp) %(blocksds_cc1plus) 15 | 16 | *link: 17 | %(blocksds_link) -T ./arm9_r4ids/ds_arm9_r4ids.mem -T %:getenv(BLOCKSDS /sys/crts/ds_arm9.ld) --gc-sections --no-warn-rwx-segments --use-blx 18 | 19 | *startfile: 20 | %:getenv(BLOCKSDS /sys/crts/ds_arm9_crt0%O) 21 | 22 | *lib: 23 | %(libgcc) 24 | -------------------------------------------------------------------------------- /arm9_r4isdhc/ds_arm9_r4isdhc.ld: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MPL-2.0 */ 2 | 3 | OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 4 | OUTPUT_ARCH(arm) 5 | ENTRY(_start) 6 | 7 | __ewram_end = ORIGIN(ewram) + LENGTH(ewram); 8 | __eheap_end = ORIGIN(ewram) + LENGTH(ewram); 9 | 10 | __dtcm_top = ORIGIN(dtcm) + LENGTH(dtcm); 11 | __irq_flags = __dtcm_top - 0x08; 12 | __irq_vector = __dtcm_top - 0x04; 13 | 14 | __sp_svc = __dtcm_top - 0x100; 15 | __sp_irq = __sp_svc - 0x100; 16 | __sp_usr = __sp_irq - 0x100; 17 | 18 | PHDRS { 19 | main PT_LOAD FLAGS(7); 20 | dtcm PT_LOAD FLAGS(7); 21 | itcm PT_LOAD FLAGS(7); 22 | vectors PT_LOAD FLAGS(7); 23 | twl PT_LOAD FLAGS(0x100007); 24 | } 25 | 26 | SECTIONS 27 | { 28 | .r4i_sdhc_pad : 29 | { 30 | KEEP(*(.r4i_sdhc_pad)) 31 | } >ewram :main = 0x00 32 | 33 | .crt0 : 34 | { 35 | __text_start = . ; 36 | KEEP (*(.crt0)) 37 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 38 | } >ewram :main = 0x00 39 | 40 | /* Create DLDI driver area. It should be zero-byte if DLDI code 41 | is not present, but set to an user-provided size if it is 42 | present. */ 43 | PROVIDE(__dldi_size = 16384); 44 | __dldi_log2_size = LOG2CEIL(__dldi_size + 1) - 1; 45 | .dldi : 46 | { 47 | __dldi_start = .; 48 | *(.dldi) 49 | . = ALIGN(4); 50 | 51 | __dldi_data_end = .; 52 | __dldi_end = __dldi_data_end > __dldi_start ? __dldi_start + __dldi_size : __dldi_start; 53 | . = __dldi_end; 54 | . = ALIGN(4); 55 | } >ewram :main = 0x00 56 | 57 | .plt : { *(.plt) } >ewram :main = 0xff 58 | 59 | .init : 60 | { 61 | KEEP (*(SORT_NONE(.init))) 62 | } >ewram :main 63 | 64 | .text : /* ALIGN (4): */ 65 | { 66 | *(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .text) 67 | *(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .stub) 68 | *(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .text.*) 69 | /* .gnu.warning sections are handled specially by elf32.em. */ 70 | *(EXCLUDE_FILE(*.twl*) .gnu.warning) 71 | *(EXCLUDE_FILE(*.twl*) .gnu.linkonce.t*) 72 | *(.glue_7) 73 | *(.glue_7t) 74 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 75 | } >ewram :main = 0xff 76 | 77 | .fini : 78 | { 79 | KEEP (*(.fini)) 80 | } >ewram :main =0xff 81 | 82 | __text_end = . ; 83 | 84 | .rodata : 85 | { 86 | *(EXCLUDE_FILE(*.twl*) .rodata) 87 | *all.rodata*(*) 88 | *(EXCLUDE_FILE(*.twl*) .roda) 89 | *(EXCLUDE_FILE(*.twl*) .rodata.*) 90 | *(EXCLUDE_FILE(*.twl*) .gnu.linkonce.r*) 91 | SORT(CONSTRUCTORS) 92 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 93 | } >ewram :main = 0xff 94 | 95 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram :main 96 | __exidx_start = .; 97 | ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram :main 98 | __exidx_end = .; 99 | 100 | /* Ensure the __preinit_array_start label is properly aligned. We 101 | could instead move the label definition inside the section, but 102 | the linker would then create the section even if it turns out to 103 | be empty, which isn't pretty. */ 104 | 105 | . = ALIGN(32 / 8); 106 | 107 | PROVIDE (__preinit_array_start = .); 108 | .preinit_array : { KEEP (*(.preinit_array)) } >ewram :main = 0xff 109 | PROVIDE (__preinit_array_end = .); 110 | PROVIDE (__init_array_start = .); 111 | .init_array : 112 | { 113 | KEEP (*(SORT(.init_array.*))) 114 | KEEP (*(.init_array)) 115 | } >ewram :main = 0xff 116 | PROVIDE (__init_array_end = .); 117 | PROVIDE (__fini_array_start = .); 118 | .fini_array : 119 | { 120 | KEEP (*(.fini_array)) 121 | KEEP (*(SORT(.fini_array.*))) 122 | } >ewram :main = 0xff 123 | 124 | PROVIDE (__fini_array_end = .); 125 | 126 | .ctors : 127 | { 128 | /* gcc uses crtbegin.o to find the start of the constructors, so 129 | we make sure it is first. Because this is a wildcard, it 130 | doesn't matter if the user does not actually link against 131 | crtbegin.o; the linker won't look for a file to match a 132 | wildcard. The wildcard also means that it doesn't matter which 133 | directory crtbegin.o is in. */ 134 | KEEP (*crtbegin.o(.ctors)) 135 | KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 136 | KEEP (*(SORT(.ctors.*))) 137 | KEEP (*(.ctors)) 138 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 139 | } >ewram :main = 0xff 140 | 141 | .dtors : 142 | { 143 | KEEP (*crtbegin.o(.dtors)) 144 | KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 145 | KEEP (*(SORT(.dtors.*))) 146 | KEEP (*(.dtors)) 147 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 148 | } >ewram :main = 0xff 149 | 150 | .eh_frame : 151 | { 152 | KEEP (*(.eh_frame)) 153 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 154 | } >ewram :main = 0xff 155 | 156 | .gcc_except_table : 157 | { 158 | *(.gcc_except_table) 159 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 160 | } >ewram :main = 0xff 161 | .jcr : { KEEP (*(.jcr)) } >ewram :main = 0 162 | .got : { *(.got.plt) *(.got) *(.rel.got) } >ewram :main = 0 163 | 164 | .ewram ALIGN(4) : 165 | { 166 | __ewram_start = ABSOLUTE(.) ; 167 | *(.ewram) 168 | *ewram.*(.text) 169 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 170 | } >ewram :main = 0xff 171 | 172 | 173 | .data ALIGN(4) : 174 | { 175 | __data_start = ABSOLUTE(.); 176 | *(EXCLUDE_FILE(*.twl*) .data) 177 | *(EXCLUDE_FILE(*.twl*) .data.*) 178 | *(EXCLUDE_FILE(*.twl*) .gnu.linkonce.d*) 179 | CONSTRUCTORS 180 | . = ALIGN(4); 181 | } >ewram :main = 0xff 182 | 183 | .tdata ALIGN(4) : 184 | { 185 | __tdata_start = ABSOLUTE(.) ; 186 | *(.tdata .tdata.* .gnu.linkonce.td.*) 187 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 188 | __tdata_end = ABSOLUTE(.) ; 189 | __data_end = . ; 190 | } >ewram :main = 0xff 191 | 192 | __tdata_size = __tdata_end - __tdata_start ; 193 | 194 | .tbss ALIGN(4) : 195 | { 196 | __tbss_start = ABSOLUTE(.) ; 197 | *(.tbss .tbss.* .gnu.linkonce.tb.*) 198 | *(.tcommon) 199 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 200 | __tbss_end = ABSOLUTE(.) ; 201 | } >ewram :main = 0 202 | 203 | __tbss_size = __tbss_end - __tbss_start ; 204 | 205 | __bss_vma = . ; 206 | 207 | .dtcm : 208 | { 209 | __dtcm_lma = LOADADDR(.dtcm); 210 | __dtcm_start = ABSOLUTE(.); 211 | *(.dtcm) 212 | *(.dtcm.*) 213 | . = ALIGN(4); 214 | __dtcm_end = ABSOLUTE(.); 215 | } >dtcm AT>ewram :dtcm = 0xff 216 | 217 | .itcm : 218 | { 219 | __itcm_lma = LOADADDR(.itcm); 220 | __itcm_start = ABSOLUTE(.); 221 | *(.itcm) 222 | *(.itcm.*) 223 | *.itcm*(.text .stub .text.*) 224 | . = ALIGN(4); 225 | __itcm_end = ABSOLUTE(.); 226 | } >itcm AT>ewram :itcm = 0xff 227 | 228 | .vectors : 229 | { 230 | __vectors_lma = LOADADDR(.vectors); 231 | __vectors_start = ABSOLUTE(.); 232 | KEEP(*(.vectors .vectors.*)) 233 | . = ALIGN(4); 234 | __vectors_end = ABSOLUTE(.); 235 | } >vectors AT>ewram :vectors = 0xff 236 | 237 | .sbss __dtcm_end (NOLOAD): 238 | { 239 | __sbss_start = ABSOLUTE(.); 240 | __sbss_start__ = ABSOLUTE(.); 241 | *(.sbss) 242 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 243 | __sbss_end = ABSOLUTE(.); 244 | } >dtcm :NONE 245 | 246 | .bss __bss_vma (NOLOAD): 247 | { 248 | __bss_start = ABSOLUTE(.); 249 | __bss_start__ = ABSOLUTE(.); 250 | *(EXCLUDE_FILE(*.twl*) .dynbss) 251 | *(EXCLUDE_FILE(*.twl*) .gnu.linkonce.b*) 252 | *(EXCLUDE_FILE(*.twl*) .bss*) 253 | *(EXCLUDE_FILE(*.twl*) COMMON) 254 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 255 | __bss_end__ = ABSOLUTE(.) ; 256 | } >ewram :NONE 257 | 258 | /* Space reserved for the thread local storage of main() */ 259 | .tls ALIGN(4) (NOLOAD) : 260 | { 261 | __tls_start = ABSOLUTE(.) ; 262 | . = . + __tdata_size + __tbss_size; 263 | __tls_end = ABSOLUTE(.) ; 264 | __end__ = ABSOLUTE(.) ; 265 | } >ewram :NONE 266 | 267 | __tls_size = __tls_end - __tls_start ; 268 | 269 | .twl __end__ : AT(MAX(0x2400000,MAX(__end__,LOADADDR(.vectors)+SIZEOF(.vectors)))) 270 | { 271 | __arm9i_lma__ = LOADADDR(.twl); 272 | __arm9i_start__ = ABSOLUTE(.); 273 | *(.twl) 274 | *(.twl.text .twl.text.*) 275 | *(.twl.rodata .twl.rodata.*) 276 | *(.twl.data .twl.data.*) 277 | *.twl*(.text .stub .text.* .gnu.linkonce.t.*) 278 | *.twl*(.rodata) 279 | *.twl*(.roda) 280 | *.twl*(.rodata.*) 281 | *.twl*(.data) 282 | *.twl*(.data.*) 283 | *.twl*(.gnu.linkonce.d*) 284 | __arm9i_end__ = ABSOLUTE(.); 285 | } :twl 286 | 287 | .twl_bss __arm9i_end__ (NOLOAD): 288 | { 289 | __twl_bss_start__ = ABSOLUTE(.); 290 | *(.twl_bss .twl_bss.*) 291 | *(.twl.bss .twl.bss.*) 292 | *.twl*(.dynbss) 293 | *.twl*(.gnu.linkonce.b*) 294 | *.twl*(.bss*) 295 | *.twl*(COMMON) 296 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 297 | __twl_bss_end__ = ABSOLUTE(.); 298 | __twl_end__ = ABSOLUTE(.); 299 | } :NONE 300 | 301 | /* Stabs debugging sections. */ 302 | .stab 0 : { *(.stab) } 303 | .stabstr 0 : { *(.stabstr) } 304 | .stab.excl 0 : { *(.stab.excl) } 305 | .stab.exclstr 0 : { *(.stab.exclstr) } 306 | .stab.index 0 : { *(.stab.index) } 307 | .stab.indexstr 0 : { *(.stab.indexstr) } 308 | .comment 0 : { *(.comment) } 309 | /* DWARF debug sections. 310 | Symbols in the DWARF debugging sections are relative to the beginning 311 | of the section so we begin them at 0. */ 312 | /* DWARF 1 */ 313 | .debug 0 : { *(.debug) } 314 | .line 0 : { *(.line) } 315 | /* GNU DWARF 1 extensions */ 316 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 317 | .debug_sfnames 0 : { *(.debug_sfnames) } 318 | /* DWARF 1.1 and DWARF 2 */ 319 | .debug_aranges 0 : { *(.debug_aranges) } 320 | .debug_pubnames 0 : { *(.debug_pubnames) } 321 | /* DWARF 2 */ 322 | .debug_info 0 : { *(.debug_info) } 323 | .debug_abbrev 0 : { *(.debug_abbrev) } 324 | .debug_line 0 : { *(.debug_line) } 325 | .debug_frame 0 : { *(.debug_frame) } 326 | .debug_str 0 : { *(.debug_str) } 327 | .debug_loc 0 : { *(.debug_loc) } 328 | .debug_macinfo 0 : { *(.debug_macinfo) } 329 | /* SGI/MIPS DWARF 2 extensions */ 330 | .debug_weaknames 0 : { *(.debug_weaknames) } 331 | .debug_funcnames 0 : { *(.debug_funcnames) } 332 | .debug_typenames 0 : { *(.debug_typenames) } 333 | .debug_varnames 0 : { *(.debug_varnames) } 334 | .stack 0x80000 : { _stack = .; *(.stack) } 335 | /* These must appear regardless of . */ 336 | } 337 | -------------------------------------------------------------------------------- /arm9_r4isdhc/ds_arm9_r4isdhc.specs: -------------------------------------------------------------------------------- 1 | %include 2 | 3 | %rename cc1plus blocksds_cc1plus 4 | %rename cpp blocksds_cpp 5 | %rename link blocksds_link 6 | 7 | *cpp: 8 | -D__NDS__ -D__BLOCKSDS__ -DARM9 %(blocksds_cpp) 9 | 10 | *cc1_cpu: 11 | -mcpu=arm946e-s+nofp 12 | 13 | *cc1plus: 14 | %(cpp) %(blocksds_cc1plus) 15 | 16 | *link: 17 | %(blocksds_link) -T %:getenv(BLOCKSDS /sys/crts/ds_arm9.mem) -T ./arm9_r4isdhc/ds_arm9_r4isdhc.ld --gc-sections --no-warn-rwx-segments --use-blx 18 | 19 | *startfile: 20 | %:getenv(BLOCKSDS /sys/crts/ds_arm9_crt0%O) 21 | 22 | *lib: 23 | %(libgcc) 24 | -------------------------------------------------------------------------------- /arm9_r4isdhc/source/r4i_sdhc_pad.s: -------------------------------------------------------------------------------- 1 | @ 2 | @ flashcard-bootstrap 3 | @ By lifehackerhansol 4 | @ 5 | @ SPDX-License-Identifier: 0BSD 6 | @ 7 | 8 | @ Needed patches before the init section to workaround R4i-SDHC's weird loading scheme 9 | 10 | .syntax unified 11 | .align 4 12 | .arm 13 | .section .r4i_sdhc_pad, "ax" 14 | 15 | b 0x2000450 16 | .space 0xEC - 0x04 17 | 18 | bl 0x2000218 19 | .space 0x450 - 0xF0 20 | 21 | .end 22 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | cc -o resource/dsbize/dsbize resource/dsbize/dsbize.c 2 | c++ -o resource/r4denc/r4denc resource/r4denc/r4denc.cpp 3 | mkdir -p data 4 | make -C bootloader LOADBIN=$PWD/data/load.bin NO_SDMMC=1 5 | make dist 6 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | make -C bootloader clean 2 | make clean 3 | rm resource/dsbize/dsbize resource/r4denc/r4denc 4 | rm -rf data 5 | -------------------------------------------------------------------------------- /devnotes.txt: -------------------------------------------------------------------------------- 1 | flashcarts that can be directly built: 2 | 3 | - All DSTT-based clones 4 | - All R4iTT 3DS based clones 5 | - in flashcard-bootstrap, we use r4ids.cn BL, since DLDI is the same, and R4iTT has no restructions. We don't need more than one :D 6 | - GBA Movie Player (Compact Flash) (NDS MP flashed) 7 | - iSmart Premium, EZ-Flash Vi, r4i.cn 8 | - EZ-Flash V (SDHC is not tested. Some outdated sources suggest that EZV SDHC does not have SD card init, and thus cannot be booted from DLDI alone.) 9 | - Datel Games 'n' Music and Action Replay DSi 10 | - Interestingly the ARDSi can run homebrew... 11 | 12 | flashcarts that have some protection built in 13 | - Original R4 14 | - encrypt using r4denc with 0x484a 15 | - Ace3DS+ 16 | - encrypt using r4denc with 0x4002 17 | - must use regular ds_arm9.ld and ds_arm7.ld to build (default one used in most DS projects) 18 | - R4 i.L.S., all r4isdhc.com.cn carts, r4isdhc.hk carts dated 2020 or newer 19 | - build with ndstool with args `-g "####" "##" "R4XX"` 20 | - encrypt using r4denc with 0x4002 21 | - must use regular ds_arm9.ld and ds_arm7.ld to build (default one used in most DS projects) 22 | - Gateway Blue (possibly R4infinity 2?) 23 | - build with ndstool with args `-g "####" "##" "R4IT"` 24 | - encrypt using r4denc with 0x4002 25 | - must use regular ds_arm9.ld and ds_arm7.ld to build (default one used in most DS projects) 26 | - R4i-SDHC, r4isdhc.com 2014+ carts 27 | - has a hash checking watermark at every 0x200 bytes 28 | - Taiju Yamada has an arm9 patcher for this. EWRAM entry (e9 entry address) must be 0x02000450 for this patcher 29 | - Extract compiled arm9, patch arm9, rebuild NDS with ndstool and set RAM address (r9 address) to 0x02000000 30 | - SuperCard DSONE (non-SDHC) 31 | - build with ndstool with args `-g "ENG0"` 32 | 33 | flashcarts with a particular load address: 34 | - all r4ids.cn carts, R4 Ultra and R4i Ultra 35 | - EWRAM entry (e9 entry address) must be 0x02000800 36 | - For some reason if you try to change this by setting CRT0 address in LDFLAGS this doesn't work. So a specs file is provided. 37 | - R4i Ultra can just be converted to an Acekard 2i. One should do that instead and get the benefits of a true Acekard 2i instead. 38 | - Acekard 2, 2.1, 2i 39 | - EWRAM entry (e9 entry address) must be 0x02000450 40 | - Amaze3DS / Wood r4igold.cc upgrade 41 | - Appears to be related to the Galaxy Eagle line? 42 | - EWRAM entry (e9 entry address) must be 0x02000000 43 | - R4iDSN 44 | - EWRAM entry (e9 entry address) must be 0x02000000 45 | 46 | flashcarts that require extra files or tools 47 | - M3 DS Real, R4RTS, iTouchDS, iTouch2, R4 SDHC RTS black 48 | - Any of these will launch /_system_/_sys_data/r4i.sys which is just a normal NDS file 49 | - all boot files are derived from the R4RTS loader, with different encryption keys 50 | - All thanks goes to Taiju Yamada, Rudolph and NDS Laboratory for tools and/or tips on getting this correct 51 | - R4RTS: 52 | - launches 'loader.eng', which launches /_system_/_sys_data/r4i.sys 53 | - R4 SDHC RTS black 54 | - launches /_DS_MENU.sys. 55 | - otherwise identical to R4RTS. No effort was put in here. Thanks r4isdhc.com team 56 | - M3 DS Real: 57 | - checks /SYSTEM/g6dsload.1, and launches /SYSTEM/g6dsloader.eng. 58 | - g6dsload.1 is a very specific stub for now, not sure what its use is but it needs to be there, so for now I just used whatever the converter spewed out 59 | - iTouchDS, iTouch2 60 | - launches `boot.*` depending on region of cart. No easy way to identify, but they are all different encryption keys. 61 | - just check which one it is manually, it's 3 files anyway 62 | - M3i Zero (GMP-Z003) 63 | - a tool by Taiju Yamada (Xenon++) named dsbize is required. dsbize source is in /resources/dsbize 64 | - Compile it for PC then run `dsbize g003menu.eng 0x12` 65 | - `_M3_MENU.dat` is the bootloader, but it is encrypted to hell and back 66 | - But this combined with a prebuilt `MuliLang.bin` makes it load `g003menu.eng`, which is what we build 67 | - Any standard NDS homebrew can replace `g003menu.eng` as long as e9==r9 and e7==r7. 68 | - The latter is done already by devkitPro 69 | - The former can be done using `arm9_crt0set` 70 | - N5 71 | - An `_AX_MENU.dat` is required. No one knows what it's for. 72 | - Seems to need to be valid, an empty `_AX_MENU.dat` doesn't do anything. 73 | - Otherwise the actual boot file, `_DS_MENU.dat` can be anything. 74 | - SuperCard DSONE SDHC / SuperCard DSOnei 75 | - For some reason if you try to directly create the DSONE SDHC bootloader you don't get access to entire hardware. This breaks YSMenu. 76 | - Thus some extra binaries are included 77 | - All thanks goes to Bliss for the initial bootloader files 78 | - MSFORSC.nds is for the older SuperCard DSONE SDHC models 79 | - SCFW.SC is presumably the newer one. 80 | - Both files are exactly the same and behave exactly the same. But for sanity check just have both. 81 | - This is meant to be a triple loader, but I don't actually remember which files it boots other than TTMenu.dat. 82 | - We are going to use TTMenu.dat for simplicity's sake. 83 | - EZ-Flash Parallel 84 | - The Parallel's bootloader uses devkitPro's bootloader; this means the bootloader will DLDI patch the boot file (`ezds.dat`). 85 | - To replace it with our custom DLDI, we need to run a script that will trick the patcher into leaving our file alone 86 | - `dldinoap.py` in this repo should do the trick 87 | 88 | random notes: 89 | - MSHL2 writes 32KB of data, regardless of what your DLDI size is. This breaks a bunch of homebrew. You need to recompile libnds with 32KB DLDI size to fix. 90 | - This is done here. 91 | -------------------------------------------------------------------------------- /icon.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/icon.bmp -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | GNU GENERAL PUBLIC LICENSE 4 | Version 2, June 1991 5 | 6 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 7 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 8 | Everyone is permitted to copy and distribute verbatim copies 9 | of this license document, but changing it is not allowed. 10 | 11 | Preamble 12 | 13 | The licenses for most software are designed to take away your 14 | freedom to share and change it. By contrast, the GNU General Public 15 | License is intended to guarantee your freedom to share and change free 16 | software--to make sure the software is free for all its users. This 17 | General Public License applies to most of the Free Software 18 | Foundation's software and to any other program whose authors commit to 19 | using it. (Some other Free Software Foundation software is covered by 20 | the GNU Library General Public License instead.) You can apply it to 21 | your programs, too. 22 | 23 | When we speak of free software, we are referring to freedom, not 24 | price. Our General Public Licenses are designed to make sure that you 25 | have the freedom to distribute copies of free software (and charge for 26 | this service if you wish), that you receive source code or can get it 27 | if you want it, that you can change the software or use pieces of it 28 | in new free programs; and that you know you can do these things. 29 | 30 | To protect your rights, we need to make restrictions that forbid 31 | anyone to deny you these rights or to ask you to surrender the rights. 32 | These restrictions translate to certain responsibilities for you if you 33 | distribute copies of the software, or if you modify it. 34 | 35 | For example, if you distribute copies of such a program, whether 36 | gratis or for a fee, you must give the recipients all the rights that 37 | you have. You must make sure that they, too, receive or can get the 38 | source code. And you must show them these terms so they know their 39 | rights. 40 | 41 | We protect your rights with two steps: (1) copyright the software, and 42 | (2) offer you this license which gives you legal permission to copy, 43 | distribute and/or modify the software. 44 | 45 | Also, for each author's protection and ours, we want to make certain 46 | that everyone understands that there is no warranty for this free 47 | software. If the software is modified by someone else and passed on, we 48 | want its recipients to know that what they have is not the original, so 49 | that any problems introduced by others will not reflect on the original 50 | authors' reputations. 51 | 52 | Finally, any free program is threatened constantly by software 53 | patents. We wish to avoid the danger that redistributors of a free 54 | program will individually obtain patent licenses, in effect making the 55 | program proprietary. To prevent this, we have made it clear that any 56 | patent must be licensed for everyone's free use or not licensed at all. 57 | 58 | The precise terms and conditions for copying, distribution and 59 | modification follow. 60 | 61 | GNU GENERAL PUBLIC LICENSE 62 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 63 | 64 | 0. This License applies to any program or other work which contains 65 | a notice placed by the copyright holder saying it may be distributed 66 | under the terms of this General Public License. The "Program", below, 67 | refers to any such program or work, and a "work based on the Program" 68 | means either the Program or any derivative work under copyright law: 69 | that is to say, a work containing the Program or a portion of it, 70 | either verbatim or with modifications and/or translated into another 71 | language. (Hereinafter, translation is included without limitation in 72 | the term "modification".) Each licensee is addressed as "you". 73 | 74 | Activities other than copying, distribution and modification are not 75 | covered by this License; they are outside its scope. The act of 76 | running the Program is not restricted, and the output from the Program 77 | is covered only if its contents constitute a work based on the 78 | Program (independent of having been made by running the Program). 79 | Whether that is true depends on what the Program does. 80 | 81 | 1. You may copy and distribute verbatim copies of the Program's 82 | source code as you receive it, in any medium, provided that you 83 | conspicuously and appropriately publish on each copy an appropriate 84 | copyright notice and disclaimer of warranty; keep intact all the 85 | notices that refer to this License and to the absence of any warranty; 86 | and give any other recipients of the Program a copy of this License 87 | along with the Program. 88 | 89 | You may charge a fee for the physical act of transferring a copy, and 90 | you may at your option offer warranty protection in exchange for a fee. 91 | 92 | 2. You may modify your copy or copies of the Program or any portion 93 | of it, thus forming a work based on the Program, and copy and 94 | distribute such modifications or work under the terms of Section 1 95 | above, provided that you also meet all of these conditions: 96 | 97 | a) You must cause the modified files to carry prominent notices 98 | stating that you changed the files and the date of any change. 99 | 100 | b) You must cause any work that you distribute or publish, that in 101 | whole or in part contains or is derived from the Program or any 102 | part thereof, to be licensed as a whole at no charge to all third 103 | parties under the terms of this License. 104 | 105 | c) If the modified program normally reads commands interactively 106 | when run, you must cause it, when started running for such 107 | interactive use in the most ordinary way, to print or display an 108 | announcement including an appropriate copyright notice and a 109 | notice that there is no warranty (or else, saying that you provide 110 | a warranty) and that users may redistribute the program under 111 | these conditions, and telling the user how to view a copy of this 112 | License. (Exception: if the Program itself is interactive but 113 | does not normally print such an announcement, your work based on 114 | the Program is not required to print an announcement.) 115 | 116 | These requirements apply to the modified work as a whole. If 117 | identifiable sections of that work are not derived from the Program, 118 | and can be reasonably considered independent and separate works in 119 | themselves, then this License, and its terms, do not apply to those 120 | sections when you distribute them as separate works. But when you 121 | distribute the same sections as part of a whole which is a work based 122 | on the Program, the distribution of the whole must be on the terms of 123 | this License, whose permissions for other licensees extend to the 124 | entire whole, and thus to each and every part regardless of who wrote it. 125 | 126 | Thus, it is not the intent of this section to claim rights or contest 127 | your rights to work written entirely by you; rather, the intent is to 128 | exercise the right to control the distribution of derivative or 129 | collective works based on the Program. 130 | 131 | In addition, mere aggregation of another work not based on the Program 132 | with the Program (or with a work based on the Program) on a volume of 133 | a storage or distribution medium does not bring the other work under 134 | the scope of this License. 135 | 136 | 3. You may copy and distribute the Program (or a work based on it, 137 | under Section 2) in object code or executable form under the terms of 138 | Sections 1 and 2 above provided that you also do one of the following: 139 | 140 | a) Accompany it with the complete corresponding machine-readable 141 | source code, which must be distributed under the terms of Sections 142 | 1 and 2 above on a medium customarily used for software interchange; or, 143 | 144 | b) Accompany it with a written offer, valid for at least three 145 | years, to give any third party, for a charge no more than your 146 | cost of physically performing source distribution, a complete 147 | machine-readable copy of the corresponding source code, to be 148 | distributed under the terms of Sections 1 and 2 above on a medium 149 | customarily used for software interchange; or, 150 | 151 | c) Accompany it with the information you received as to the offer 152 | to distribute corresponding source code. (This alternative is 153 | allowed only for noncommercial distribution and only if you 154 | received the program in object code or executable form with such 155 | an offer, in accord with Subsection b above.) 156 | 157 | The source code for a work means the preferred form of the work for 158 | making modifications to it. For an executable work, complete source 159 | code means all the source code for all modules it contains, plus any 160 | associated interface definition files, plus the scripts used to 161 | control compilation and installation of the executable. However, as a 162 | special exception, the source code distributed need not include 163 | anything that is normally distributed (in either source or binary 164 | form) with the major components (compiler, kernel, and so on) of the 165 | operating system on which the executable runs, unless that component 166 | itself accompanies the executable. 167 | 168 | If distribution of executable or object code is made by offering 169 | access to copy from a designated place, then offering equivalent 170 | access to copy the source code from the same place counts as 171 | distribution of the source code, even though third parties are not 172 | compelled to copy the source along with the object code. 173 | 174 | 4. You may not copy, modify, sublicense, or distribute the Program 175 | except as expressly provided under this License. Any attempt 176 | otherwise to copy, modify, sublicense or distribute the Program is 177 | void, and will automatically terminate your rights under this License. 178 | However, parties who have received copies, or rights, from you under 179 | this License will not have their licenses terminated so long as such 180 | parties remain in full compliance. 181 | 182 | 5. You are not required to accept this License, since you have not 183 | signed it. However, nothing else grants you permission to modify or 184 | distribute the Program or its derivative works. These actions are 185 | prohibited by law if you do not accept this License. Therefore, by 186 | modifying or distributing the Program (or any work based on the 187 | Program), you indicate your acceptance of this License to do so, and 188 | all its terms and conditions for copying, distributing or modifying 189 | the Program or works based on it. 190 | 191 | 6. Each time you redistribute the Program (or any work based on the 192 | Program), the recipient automatically receives a license from the 193 | original licensor to copy, distribute or modify the Program subject to 194 | these terms and conditions. You may not impose any further 195 | restrictions on the recipients' exercise of the rights granted herein. 196 | You are not responsible for enforcing compliance by third parties to 197 | this License. 198 | 199 | 7. If, as a consequence of a court judgment or allegation of patent 200 | infringement or for any other reason (not limited to patent issues), 201 | conditions are imposed on you (whether by court order, agreement or 202 | otherwise) that contradict the conditions of this License, they do not 203 | excuse you from the conditions of this License. If you cannot 204 | distribute so as to satisfy simultaneously your obligations under this 205 | License and any other pertinent obligations, then as a consequence you 206 | may not distribute the Program at all. For example, if a patent 207 | license would not permit royalty-free redistribution of the Program by 208 | all those who receive copies directly or indirectly through you, then 209 | the only way you could satisfy both it and this License would be to 210 | refrain entirely from distribution of the Program. 211 | 212 | If any portion of this section is held invalid or unenforceable under 213 | any particular circumstance, the balance of the section is intended to 214 | apply and the section as a whole is intended to apply in other 215 | circumstances. 216 | 217 | It is not the purpose of this section to induce you to infringe any 218 | patents or other property right claims or to contest validity of any 219 | such claims; this section has the sole purpose of protecting the 220 | integrity of the free software distribution system, which is 221 | implemented by public license practices. Many people have made 222 | generous contributions to the wide range of software distributed 223 | through that system in reliance on consistent application of that 224 | system; it is up to the author/donor to decide if he or she is willing 225 | to distribute software through any other system and a licensee cannot 226 | impose that choice. 227 | 228 | This section is intended to make thoroughly clear what is believed to 229 | be a consequence of the rest of this License. 230 | 231 | 8. If the distribution and/or use of the Program is restricted in 232 | certain countries either by patents or by copyrighted interfaces, the 233 | original copyright holder who places the Program under this License 234 | may add an explicit geographical distribution limitation excluding 235 | those countries, so that distribution is permitted only in or among 236 | countries not thus excluded. In such case, this License incorporates 237 | the limitation as if written in the body of this License. 238 | 239 | 9. The Free Software Foundation may publish revised and/or new versions 240 | of the General Public License from time to time. Such new versions will 241 | be similar in spirit to the present version, but may differ in detail to 242 | address new problems or concerns. 243 | 244 | Each version is given a distinguishing version number. If the Program 245 | specifies a version number of this License which applies to it and "any 246 | later version", you have the option of following the terms and conditions 247 | either of that version or of any later version published by the Free 248 | Software Foundation. If the Program does not specify a version number of 249 | this License, you may choose any version ever published by the Free Software 250 | Foundation. 251 | 252 | 10. If you wish to incorporate parts of the Program into other free 253 | programs whose distribution conditions are different, write to the author 254 | to ask for permission. For software which is copyrighted by the Free 255 | Software Foundation, write to the Free Software Foundation; we sometimes 256 | make exceptions for this. Our decision will be guided by the two goals 257 | of preserving the free status of all derivatives of our free software and 258 | of promoting the sharing and reuse of software generally. 259 | 260 | NO WARRANTY 261 | 262 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 263 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 264 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 265 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 266 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 267 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 268 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 269 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 270 | REPAIR OR CORRECTION. 271 | 272 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 273 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 274 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 275 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 276 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 277 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 278 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 279 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 280 | POSSIBILITY OF SUCH DAMAGES. 281 | 282 | END OF TERMS AND CONDITIONS 283 | 284 | How to Apply These Terms to Your New Programs 285 | 286 | If you develop a new program, and you want it to be of the greatest 287 | possible use to the public, the best way to achieve this is to make it 288 | free software which everyone can redistribute and change under these terms. 289 | 290 | To do so, attach the following notices to the program. It is safest 291 | to attach them to the start of each source file to most effectively 292 | convey the exclusion of warranty; and each file should have at least 293 | the "copyright" line and a pointer to where the full notice is found. 294 | 295 | 296 | Copyright (C) 297 | 298 | This program is free software; you can redistribute it and/or modify 299 | it under the terms of the GNU General Public License as published by 300 | the Free Software Foundation; either version 2 of the License, or 301 | (at your option) any later version. 302 | 303 | This program is distributed in the hope that it will be useful, 304 | but WITHOUT ANY WARRANTY; without even the implied warranty of 305 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 306 | GNU General Public License for more details. 307 | 308 | You should have received a copy of the GNU General Public License 309 | along with this program; if not, write to the Free Software 310 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 311 | 312 | 313 | Also add information on how to contact you by electronic and paper mail. 314 | 315 | If the program is interactive, make it output a short notice like this 316 | when it starts in an interactive mode: 317 | 318 | Gnomovision version 69, Copyright (C) year name of author 319 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 320 | This is free software, and you are welcome to redistribute it 321 | under certain conditions; type `show c' for details. 322 | 323 | The hypothetical commands `show w' and `show c' should show the appropriate 324 | parts of the General Public License. Of course, the commands you use may 325 | be called something other than `show w' and `show c'; they could even be 326 | mouse-clicks or menu items--whatever suits your program. 327 | 328 | You should also get your employer (if you work as a programmer) or your 329 | school, if any, to sign a "copyright disclaimer" for the program, if 330 | necessary. Here is a sample; alter the names: 331 | 332 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 333 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 334 | 335 | , 1 April 1989 336 | Ty Coon, President of Vice 337 | 338 | This General Public License does not permit incorporating your program into 339 | proprietary programs. If your program is a subroutine library, you may 340 | consider it more useful to permit linking proprietary applications with the 341 | library. If this is what you want to do, use the GNU Library General 342 | Public License instead of this License. 343 | -------------------------------------------------------------------------------- /resource/DSOneSDHC_DSOnei/MSFORSC.nds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/resource/DSOneSDHC_DSOnei/MSFORSC.nds -------------------------------------------------------------------------------- /resource/DSOneSDHC_DSOnei/SCFW.SC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/resource/DSOneSDHC_DSOnei/SCFW.SC -------------------------------------------------------------------------------- /resource/G003/MuliLang.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resource/G003/_M3_MENU.DAT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/resource/G003/_M3_MENU.DAT -------------------------------------------------------------------------------- /resource/M3R_iTDS_R4RTS/SYSTEM/g6dsload.1: -------------------------------------------------------------------------------- 1 | kari 2 | -------------------------------------------------------------------------------- /resource/M3R_iTDS_R4RTS/SYSTEM/g6dsload.eng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/resource/M3R_iTDS_R4RTS/SYSTEM/g6dsload.eng -------------------------------------------------------------------------------- /resource/M3R_iTDS_R4RTS/_ds_menu.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/resource/M3R_iTDS_R4RTS/_ds_menu.sys -------------------------------------------------------------------------------- /resource/M3R_iTDS_R4RTS/boot.eng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/resource/M3R_iTDS_R4RTS/boot.eng -------------------------------------------------------------------------------- /resource/M3R_iTDS_R4RTS/boot.gb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/resource/M3R_iTDS_R4RTS/boot.gb -------------------------------------------------------------------------------- /resource/M3R_iTDS_R4RTS/boot.jp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/resource/M3R_iTDS_R4RTS/boot.jp -------------------------------------------------------------------------------- /resource/M3R_iTDS_R4RTS/loader.eng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/resource/M3R_iTDS_R4RTS/loader.eng -------------------------------------------------------------------------------- /resource/N5/_ax_menu.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifehackerhansol/flashcard-bootstrap/29270944c4decd32d6788010107829f5a2cd86bd/resource/N5/_ax_menu.dat -------------------------------------------------------------------------------- /resource/dldinoap/dldinoap.py: -------------------------------------------------------------------------------- 1 | # 2 | # DLDI auto-patch disabler 3 | # 4 | # Copyright (C) 2024 lifehackerhansol 5 | # SPDX-License-Identifier: 0BSD 6 | # 7 | 8 | from array import array 9 | from os import stat 10 | from sys import argv, exit 11 | 12 | 13 | def main(): 14 | 15 | argc = len(argv) 16 | if (argc < 2): 17 | print("dldinoap.py in") 18 | exit(1) 19 | 20 | buf = array("B") 21 | 22 | try: 23 | input_size = stat(argv[1]).st_size 24 | with open(argv[1], "rb") as i: 25 | buf.fromfile(i, input_size) 26 | except Exception: 27 | print("cannot open input") 28 | exit(2) 29 | 30 | dldiFound = False 31 | 32 | for i in range(0, len(buf), 4): 33 | # DLDI header magic 34 | if buf[i+3] == 0xBF and buf[i+2] == 0x8D and buf[i+1] == 0xA5 and buf[i] == 0xED: 35 | dldiFound = True 36 | buf[i] = 0 37 | buf[i+1] = 0 38 | buf[i+2] = 0 39 | buf[i+3] = 0 40 | break 41 | 42 | if not dldiFound: 43 | print("DLDI section not found, exiting") 44 | exit(3) 45 | 46 | try: 47 | with open(argv[1], "wb") as o: 48 | buf.tofile(o) 49 | except Exception: 50 | print("cannot open output") 51 | exit(4) 52 | 53 | print("Success.\n") 54 | exit(0) 55 | 56 | 57 | main() 58 | -------------------------------------------------------------------------------- /resource/dsbize/dsbize.c: -------------------------------------------------------------------------------- 1 | /* 2 | dsbize (dsbooter-ize) 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define u32 uint32_t 11 | #define byte uint8_t 12 | 13 | static unsigned char dsbhead[512]={ 14 | 0x2e,0x00,0x00,0xea,0x24,0xff,0xae,0x51,0x69,0x9a,0xa2,0x21,0x3d,0x84,0x82,0x0a, 15 | 0x84,0xe4,0x09,0xad,0x11,0x24,0x8b,0x98,0xc0,0x81,0x7f,0x21,0xa3,0x52,0xbe,0x19, 16 | 0x93,0x09,0xce,0x20,0x10,0x46,0x4a,0x4a,0xf8,0x27,0x31,0xec,0x58,0xc7,0xe8,0x33, 17 | 0x82,0xe3,0xce,0xbf,0x85,0xf4,0xdf,0x94,0xce,0x4b,0x09,0xc1,0x94,0x56,0x8a,0xc0, 18 | 0x13,0x72,0xa7,0xfc,0x9f,0x84,0x4d,0x73,0xa3,0xca,0x9a,0x61,0x58,0x97,0xa3,0x27, 19 | 0xfc,0x03,0x98,0x76,0x23,0x1d,0xc7,0x61,0x03,0x04,0xae,0x56,0xbf,0x38,0x84,0x00, 20 | 0x40,0xa7,0x0e,0xfd,0xff,0x52,0xfe,0x03,0x6f,0x95,0x30,0xf1,0x97,0xfb,0xc0,0x85, 21 | 0x60,0xd6,0x80,0x25,0xa9,0x63,0xbe,0x03,0x01,0x4e,0x38,0xe2,0xf9,0xa2,0x34,0xff, 22 | 0xbb,0x3e,0x03,0x44,0x78,0x00,0x90,0xcb,0x88,0x11,0x3a,0x94,0x65,0xc0,0x7c,0x63, 23 | 0x87,0xf0,0x3c,0xaf,0xd6,0x25,0xe4,0x8b,0x38,0x0a,0xac,0x72,0x21,0xd4,0xf8,0x07, 24 | 0x44,0x53,0x42,0x6f,0x6f,0x74,0x65,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 25 | 0x30,0x31,0x96,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6e,0x00,0x00, 26 | 0x0b,0x00,0x00,0xea,0x00,0x00,0x00,0x00,0x38,0x01,0x00,0x00,0x00,0x00,0x00,0x02, 27 | 0x50,0x2b,0x07,0x00,0x2c,0x2d,0x07,0x00,0x00,0x80,0x7f,0x03,0x68,0x96,0x00,0x00, 28 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 29 | 0x00,0x00,0x00,0x00,0x40,0xc6,0xa0,0xe3,0x08,0xc2,0x8c,0xe5,0x00,0x00,0xa0,0xe3, 30 | 0x00,0x10,0xa0,0xe3,0x00,0x20,0xa0,0xe3,0x00,0x30,0xa0,0xe3,0x00,0x40,0xa0,0xe3, 31 | 0x00,0x50,0xa0,0xe3,0x00,0x60,0xa0,0xe3,0x00,0x70,0xa0,0xe3,0x80,0x87,0xa0,0xe3, 32 | 0x94,0x90,0x9f,0xe5,0xff,0x00,0xa8,0xe8,0x09,0x00,0x58,0xe1,0xfc,0xff,0xff,0x1a, 33 | 0x88,0x80,0x9f,0xe5,0x88,0x90,0x9f,0xe5,0xff,0x00,0xa8,0xe8,0x09,0x00,0x58,0xe1, 34 | 0xfc,0xff,0xff,0x1a,0xb0,0x01,0x8c,0xe5,0xb4,0x01,0x8c,0xe5,0xb8,0x01,0x8c,0xe5, 35 | 0x90,0xc0,0x4f,0xe2,0x00,0x00,0x9c,0xe5,0x04,0x10,0x9c,0xe5,0x08,0x20,0x9c,0xe5, 36 | 0x0c,0x00,0x80,0xe0,0x00,0x20,0x82,0xe0,0x02,0x00,0x50,0xe1,0x04,0x30,0x90,0x34, 37 | 0x04,0x30,0x81,0x34,0xfb,0xff,0xff,0x3a,0xac,0xc0,0x4f,0xe2,0x00,0x00,0x9c,0xe5, 38 | 0x04,0x10,0x9c,0xe5,0x08,0x20,0x9c,0xe5,0x0c,0x00,0x80,0xe0,0x00,0x20,0x82,0xe0, 39 | 0x02,0x00,0x50,0xe1,0x04,0x30,0x90,0x34,0x04,0x30,0x81,0x34,0xfb,0xff,0xff,0x3a, 40 | 0xdc,0x10,0x4f,0xe2,0x00,0x00,0x91,0xe5,0x18,0x10,0x9f,0xe5,0x00,0x00,0x81,0xe5, 41 | 0xe0,0x10,0x4f,0xe2,0x00,0x00,0x91,0xe5,0x00,0xf0,0xa0,0xe1,0x00,0x40,0x00,0x02, 42 | 0x00,0x80,0x7f,0x03,0x00,0x00,0x81,0x03,0x24,0xfe,0x7f,0x02,0x00,0x00,0x00,0x00, 43 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 44 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 45 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 46 | }; 47 | 48 | unsigned int read32(const void *p){ 49 | const unsigned char *x=(const unsigned char*)p; 50 | return x[0]|(x[1]<<8)|(x[2]<<16)|(x[3]<<24); 51 | } 52 | 53 | void write32(void *p, const unsigned int n){ 54 | unsigned char *x=(unsigned char*)p; 55 | x[0]=n&0xff,x[1]=(n>>8)&0xff,x[2]=(n>>16)&0xff,x[3]=(n>>24)&0xff; 56 | } 57 | 58 | static int make(const byte *nds,const int ndslen,const char *p,const int key){ 59 | byte *p7=NULL,*p9=NULL; 60 | u32 l7,l9,a7,a9,a7x,a9x; 61 | FILE *f=NULL; 62 | int i=0; 63 | 64 | fprintf(stderr,"p9=0x%08x\n",(u32)((p9=(byte*)nds+read32(nds+0x20))-nds)); 65 | fprintf(stderr,"l9=0x%08x\n",l9=read32(nds+0x2c)); 66 | fprintf(stderr,"e9=0x%08x\n",a9=read32(nds+0x24)); 67 | fprintf(stderr,"r9=0x%08x\n",a9x=read32(nds+0x28)); 68 | fprintf(stderr,"p7=0x%08x\n",(u32)((p7=(byte*)nds+read32(nds+0x30))-nds)); 69 | fprintf(stderr,"l7=0x%08x\n",l7=read32(nds+0x3c)); 70 | fprintf(stderr,"e7=0x%08x\n",a7=read32(nds+0x34)); 71 | fprintf(stderr,"r7=0x%08x\n",a7x=read32(nds+0x38)); 72 | if(a9!=a9x||a7!=a7x){ 73 | fprintf(stderr,"e9==r9 && e7==r7 condition isn't satisfied. Rebuild nds using ndstool.\n");return 1; 74 | } 75 | 76 | //if(p){ 77 | f=fopen(p,"wb"); 78 | //write32(dsbhead+0xc8,0x138); 79 | write32(dsbhead+0xcc,a9); 80 | write32(dsbhead+0xd0,l9); 81 | write32(dsbhead+0xd4,l9+0x138-0x0c); 82 | write32(dsbhead+0xd8,a7); 83 | write32(dsbhead+0xdc,l7); 84 | for(;i<0x200;i++) 85 | dsbhead[i]=dsbhead[i]^key; 86 | fwrite(dsbhead,1,0x200,f); 87 | fwrite(p9,1,l9,f); 88 | fwrite(p7,1,l7,f); 89 | fclose(f); 90 | //} 91 | 92 | return 0; 93 | } 94 | 95 | int main(const int argc, const char **argv){ 96 | FILE *f; 97 | struct stat st; 98 | byte *p; 99 | int key; 100 | 101 | if(argc<3){ 102 | //fprintf(stderr,"dsbize\n"); 103 | fprintf(stderr,"dsbize in out [key]\n"); 104 | return 1; 105 | } 106 | key=argv[3]?strtol(argv[3],NULL,0):0; 107 | 108 | if(!(f=fopen(argv[1],"rb+"))){fprintf(stderr,"cannot open %s\n",argv[1]);return 1;} 109 | fstat(fileno(f),&st); 110 | if(!(p=malloc(st.st_size))){fprintf(stderr,"cannot allocate %d bytes for %s\n",(int)st.st_size,argv[1]);return 2;} 111 | fread(p,1,st.st_size,f); 112 | fclose(f); 113 | //fprintf(stderr,"Decrypting %s... ",argv[1]); 114 | make(p,st.st_size,argv[2],key); 115 | free(p); 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /resource/r4denc/r4denc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright(C) 2007 yasu 3 | 2009 WinterMute 4 | 5 | http://hp.vector.co.jp/authors/VA013928/ 6 | http://www.usay.jp/ 7 | http://www.yasu.nu/ 8 | http://www.devkitpro.org 9 | 10 | 2007/04/22 21:00 - First version 11 | 12 | 2009/01/08 - combined decode/encode in single app, switch on extension (.nds/.dat) 13 | 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define BIT_AT(n, i) ((n >> i) & 1) 25 | 26 | void cryptBuffer( unsigned char *buf, size_t size, int keyvalue, bool decode, int n) { 27 | unsigned short key = n ^ keyvalue; 28 | 29 | for (int i = 0; i < size; i ++) { 30 | 31 | unsigned char xorkey = 0; 32 | if (key & 0x4000) xorkey |= 0x80; 33 | if (key & 0x1000) xorkey |= 0x40; 34 | if (key & 0x0800) xorkey |= 0x20; 35 | if (key & 0x0200) xorkey |= 0x10; 36 | if (key & 0x0080) xorkey |= 0x08; 37 | if (key & 0x0040) xorkey |= 0x04; 38 | if (key & 0x0002) xorkey |= 0x02; 39 | if (key & 0x0001) xorkey |= 0x01; 40 | 41 | if (!decode) buf[i] ^= xorkey; 42 | 43 | unsigned int k = ((buf[i] << 8) ^ key) << 16; 44 | unsigned int x = k; 45 | 46 | for (int j = 1; j < 32; j ++) 47 | x ^= k >> j; 48 | 49 | key = 0x0000; 50 | 51 | if (BIT_AT(x, 23)) key |= 0x8000; 52 | if (BIT_AT(k, 22)) key |= 0x4000; 53 | if (BIT_AT(k, 21)) key |= 0x2000; 54 | if (BIT_AT(k, 20)) key |= 0x1000; 55 | if (BIT_AT(k, 19)) key |= 0x0800; 56 | if (BIT_AT(k, 18)) key |= 0x0400; 57 | if (BIT_AT(k, 17) != BIT_AT(x, 31)) key |= 0x0200; 58 | if (BIT_AT(k, 16) != BIT_AT(x, 30)) key |= 0x0100; 59 | if (BIT_AT(k, 30) != BIT_AT(k, 29)) key |= 0x0080; 60 | if (BIT_AT(k, 29) != BIT_AT(k, 28)) key |= 0x0040; 61 | if (BIT_AT(k, 28) != BIT_AT(k, 27)) key |= 0x0020; 62 | if (BIT_AT(k, 27) != BIT_AT(k, 26)) key |= 0x0010; 63 | if (BIT_AT(k, 26) != BIT_AT(k, 25)) key |= 0x0008; 64 | if (BIT_AT(k, 25) != BIT_AT(k, 24)) key |= 0x0004; 65 | if (BIT_AT(k, 25) != BIT_AT(x, 26)) key |= 0x0002; 66 | if (BIT_AT(k, 24) != BIT_AT(x, 25)) key |= 0x0001; 67 | 68 | if (decode) buf[i] ^= xorkey; 69 | } 70 | 71 | } 72 | 73 | int findkey(FILE *in) { 74 | 75 | int r; 76 | 77 | unsigned char inbuf[16]; 78 | unsigned char decodebuf[16]; 79 | const char *gamecode = "####"; 80 | 81 | r = fread(inbuf,1,16,in); 82 | fseek(in, 0, SEEK_SET); 83 | 84 | int testkey; 85 | 86 | for (testkey=0; testkey<0xffff; testkey++) { 87 | memcpy(decodebuf,inbuf,16); 88 | cryptBuffer(decodebuf, 16, testkey, true, 0); 89 | if ( memcmp(&decodebuf[12], gamecode , 4 ) == 0) break; 90 | } 91 | 92 | return testkey; 93 | } 94 | 95 | void r4denc(FILE *in, FILE *out, int keyvalue, bool decode) { 96 | 97 | int r, n = 0; 98 | 99 | unsigned char buf[512]; 100 | 101 | while ((r = fread(buf, 1, 512, in)) > 0) { 102 | cryptBuffer(buf,512,keyvalue,decode,n); 103 | fwrite(buf, 1, r, out); 104 | n++; 105 | } 106 | } 107 | 108 | void showHelp() { 109 | 110 | puts("Usage: r4denc [options] in-file [out-file]\n"); 111 | puts("--help, -h Display this information"); 112 | puts("--findkey, -f Search for decode key"); 113 | puts("--key, -k Use as encode/decode key"); 114 | puts("\n"); 115 | } 116 | 117 | int main(int argc, char *argv[]) { 118 | 119 | puts("Yasu software - r4denc"); 120 | 121 | if (argc < 2) { 122 | showHelp(); 123 | return 1; 124 | } 125 | 126 | bool decodeFlag = false; 127 | bool findKey = false; 128 | int key = 0x484A; 129 | char *optend; 130 | 131 | while(1) { 132 | static struct option long_options[] = { 133 | {"findkey", no_argument, 0, 'f'}, 134 | {"help", no_argument, 0, 'h'}, 135 | {"key", required_argument, 0, 'k'}, 136 | {0, 0, 0, 0} 137 | }; 138 | 139 | /* getopt_long stores the option index here. */ 140 | int option_index = 0, c; 141 | 142 | c = getopt_long (argc, argv, "fhk:x", long_options, &option_index); 143 | 144 | /* Detect the end of the options. */ 145 | if (c == -1) 146 | break; 147 | 148 | switch(c) { 149 | 150 | case 'f': 151 | findKey = true; 152 | break; 153 | case 'h': 154 | showHelp(); 155 | break; 156 | case 'k': 157 | key = strtol(optarg,&optend,0); 158 | if (errno) { 159 | printf("invalid key\n"); 160 | exit(1); 161 | } 162 | break; 163 | } 164 | 165 | } 166 | 167 | std::string infile, outfile, ext, outext; 168 | size_t lastdot; 169 | 170 | if (optind < argc) infile = argv[optind++]; 171 | 172 | if ( (lastdot = infile.rfind("."))!= std::string::npos ) { 173 | ext = infile.substr(lastdot); 174 | } 175 | 176 | if (optind < argc) { 177 | outfile = argv[optind++]; 178 | } else { 179 | outfile = infile.substr(0,lastdot); 180 | } 181 | 182 | if (strcasecmp(ext.c_str(),".dat")==0) { 183 | decodeFlag=true; 184 | outext = ".nds"; 185 | } else if ( strcasecmp(ext.c_str(),".nds")==0) { 186 | decodeFlag=false; 187 | outext = ".dat"; 188 | } else { 189 | printf(".nds or .dat required\n"); 190 | exit(1); 191 | } 192 | 193 | if ( (lastdot = outfile.rfind("."))!= std::string::npos ) { 194 | outfile = outfile.substr(0,lastdot); 195 | } 196 | 197 | outfile += outext; 198 | 199 | FILE *in = fopen(infile.c_str(), "rb"); 200 | 201 | if (in == NULL) { 202 | printf("Error: cannot open %s for reading\n", infile.c_str()); 203 | exit(1); 204 | } 205 | 206 | if (findKey) { 207 | if((strcasecmp(ext.c_str(),".dat")!=0)) { 208 | fclose(in); 209 | printf("Can't search for key in .nds file\n"); 210 | exit(1); 211 | } 212 | printf("finding key ...\n"); 213 | key = findkey(in); 214 | } 215 | 216 | FILE *out = fopen(outfile.c_str(), "wb"); 217 | 218 | if (out == NULL) { 219 | fclose(in); 220 | printf("Error: cannot open %s for writing\n", outfile.c_str()); 221 | exit(1); 222 | } 223 | 224 | r4denc(in, out, key, decodeFlag); 225 | 226 | printf("%scoded %s to %s using key 0x%x\n",decodeFlag?"de":"en",infile.c_str(),outfile.c_str(),key); 227 | 228 | fclose(out); 229 | fclose(in); 230 | 231 | return 0; 232 | } 233 | -------------------------------------------------------------------------------- /resource/r4isdhc/r4isdhc.py: -------------------------------------------------------------------------------- 1 | from array import array 2 | from os import stat 3 | from sys import argv, exit 4 | 5 | TARGET_SIZE = 0x69C70 6 | 7 | def main(): 8 | 9 | argc = len(argv) 10 | if (argc < 3): 11 | print("r4isdhc.py ") 12 | exit(1) 13 | 14 | buf = array("B") 15 | 16 | try: 17 | input_size = stat(argv[1]).st_size 18 | with open(argv[1], "rb") as i: 19 | buf.fromfile(i, input_size) 20 | except: 21 | print("cannot open input") 22 | exit(2) 23 | 24 | remaining = TARGET_SIZE - input_size 25 | if remaining > 0: 26 | buf.extend([0] * remaining) 27 | 28 | try: 29 | with open(argv[2], "wb") as o: 30 | buf.tofile(o) 31 | except: 32 | print("cannot open output") 33 | exit(3) 34 | 35 | print("Success.\n") 36 | exit(0) 37 | 38 | 39 | main() 40 | --------------------------------------------------------------------------------