To proceed with the tutorial, it is a good idea to have a solid understanding of, in order of importance:
  • ARM assembly
  • The C programming language

Patch Methods#

There are a couple of different methods of code patching that are used in Mario Kart DS modding. The oldest and most widely used method involves using the New Super Mario Bros Editor by Szymbar. Memory use limitations with this method of patching prompted the creation of a patching method that can make better use of main memory, and that system is Runtime Code Modules (RCM). In the vein of more general code patching, TheGameratorT authored NCPatcher, a tool for code patching similar to New Super Mario Bros Editor but more streamlined and with more functionality.

NSMBe Patching#

The New Super Mario Bros. Editor patch system places new code at the beginning of the main memory arena, shifting the low address over by the size of the added code. When hooks are used, the instructions at those locations are overwritten depending on the hook's type. It is very important to be mindful of the amount of code being added so as not to cause memory shortage problems, since any memory use by your custom code is memory that can't be used for anything else anymore. To use New Super Mario Bros Editor to make an ASM hack, the following software is required:
  • Szymber's New Super Mario Bros. Editor fork
  • devkitARM with libnds

To start a hack with this method, create a folder containing a ROM with a clean ARM9 program. Alongside it in the same folder, you will need a symbols.x, linker.x, arenaoffs.txt, and Makefile. The symbols.x file contains a list of symbols used by the hack, and the linker will use this file to look up any external symbols. Use an up-to-date symbols file to be sure you have access to all symbols you may need. The linker.x file contains instructions for the linker when producing the resulting object file and can be safely harvested from another hack, likewise for the Makefile and arenaoffs.txt. Code will go into a folder called source. These can be assembly source files (.s), C source files (.c), and header files (.h).

To write a hook, write a function (C) or label (assembly) whose name starts with either arepl_XXXXXXXX, ansub_XXXXXXXX, trepl_XXXXXXXX, or tnsub_XXXXXXXX, where XXXXXXXX is the address of the instruction to patch (in DS address space). The first character of these labels indicates whether the hook should be an ARM hook (a) or THUMB hook (t), and whether to branch (nsub) or branch and link (repl). Both ansub and arepl hooks take up 1 instruction, and as such their patches only consume 4 bytes. A trepl takes one 4-byte wide instruction, and a tnsub takes 3 instructions totaling 8 bytes. The patcher treats all branch destinations as being ARM code (not thumb). Knowing the type of hook used is critical in returning to normal game code correctly (e.g. don't return with BX LR using an ansub hook, unless the hooked function should actually be returning).

To patch the code into the game, open the ROM with NSMBe, navigate to the Tools tab, then click Run Make and Insert. The first time through, since no backup folder exists, it may throw an error but create a backup folder after. If this does happen, run Make Clean, then Make and Insert and the code should patch without issue. Close NSMBe to commit the changes to the disk, and then you're left with a ROM with patched code. Under normal circumstances, do not modify the ARM9 copy kept in the backup folder, as this is what NSMBe will use as a base when patching code in the future.

Runtime Code Modules#

Runtime Code Modules were created to minimize the amount of memory being used by code patches at any given point. The way that it works is that a file called code.rcm is placed in the root of a scene archive, and when that scene is loaded, the patches from the file are processed. This allows for code that only needs to be in effect during one particular scene to remain in memory only temporarily. Because the address that an RCM file will be loaded at can't be reliably predicted, more size will be taken up by things like the relocation table.

The patch mechanisms of RCM files are similar to that of New Super Mario Bros. Editor's. It contains direct analogs for the arepl, ansub, trepl and tnsub hook types. Rather than indicating hooks to the patcher by means of specific label names, RCM uses a hook table at the end of the file instead. To write a hook table, place the following code at the end of a source file:

    //your hooks here...

Inside the parentheses goes a comma-separated list of hook definitions. These use the macro functions HOOK_ANSUB, HOOK_AREPL, HOOK_TNSUB, HOOK_TREPL, HOOK_DATA32, HOOK_DATA16, HOOK_DATA8, HOOK_LOAD, and HOOK_UNLOAD. The first four function in the same way as the hook types from the New Super Mario Bros. Editor work. The HOOK_DATAxx hook types, rather than creating branch instructions in the target code, serve to replace arbitrary data of either 32, 16, or 8 bits. This may be useful for patching some variable, a table entry, or replacing a single instruction. The HOOK_LOAD and HOOK_UNLOAD types specify a callback function that is to be called when the RCM is loaded and unloaded, and an arbitrary number can be present in the file. Any source file may contain a hook table, and hook tables from all source files get combined into one hook table during build.

For example, a hook table that replaces the code at the address 0207AA4C with a branch to MyFunction and replaces the 32-bit data at 0217AA14 with 1234, a hook table would look like:

    HOOK_ANSUB(0x0207AA4C, MyFunction),
    HOOK_DATA32(0x0217AA14, 1234)

When the RCM is unloaded, the hook table is traversed again to un-patch the previously patched code and data. Avoid writing overlapping hook destinations, and writing to patched data when unloading to avoid ordering issues.

To build an RCM file, a specific folder setup is required for the default build setup. Each code.rcm should have a folder inside the main code patching folder, alonside the source folder if using NSMBe. Inside the RCM project folder, place the Makefile and linker.x from the RuntimeCodeModules repository on GitHub. Then, simply run make in the code folder, and, on successful build, a code.rcm file will be produced. Note that for external thumb functions to work correctly, ensure that the LSB of thumb symbols is set in the parent symbols.x file, as the RCM build setup relies on this information to generate correct outgoing branch instructions.

With an RCM file built, simply place it into the root of one of the supported archive files (supported archives listed on the GitHub repository) and the loader will take care of the rest.

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-2) was last changed on 27-Jan-2023 00:22 by Garhoogin