• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Tool: ASMAGIX

Touched

Resident ASMAGICIAN
625
Posts
9
Years
    • Age 122
    • Seen Feb 1, 2018
    ASM hacking can be irritating, that's why I'm publishing a build tool. It's a command line tool that makes the process of inserting ASM and writing hooks etc. less annoying and tedious.

    Installation

    Whatever platform you are on, download and install both devkitARM and Node.js. Windows users might want to restart after this. The devkitARM binaries MUST be in your path (try run arm-none-eabi-as --version in a console to check if it works) in order for this to work.

    After doing this, you can now install the tool. Simply run the following command in a console.
    Code:
    npm install -g asmagix
    NOTE: Linux users might need to use sudo to run this.

    Now that your installation is complete, you can run 'asmagix' from the console.

    Usage

    How this works is that you create a project directory:
    Code:
    mkdir myProject && cd myProject

    You then use the tool to create an empty project for you:
    Code:
    asmagix init

    This creates the basic directory structure and configuration file (your asmagixfile).

    To start hacking, copy ROMS in to the roms directory. Say you copy firered.gba to the ROM directory. You then would need to alter your asmagixfile.json to read something like:

    Code:
    {
      "src": "./src",
      "roms": {
        "bpre": "./roms/firered.gba"
      },
      "default": "bpre",
      "build": "./build"
    }

    In reality, these directories can be whatever you want. However the ROM keys are important. They allow you to test on multiple ROMS.

    Now that's done, its time to create some source in the source directory.

    Code:
    @@action hook 0xDEADBEEF 1
    
    main:
    bx lr

    This is an example stub code. It goes in the src directory. What's important about this file is the line at the top (a comment directive). It tells ASMAGIX to insert this file into free space, then write a hook at offset 0xDEADBEEF that jumps to this code. It uses r1 (that 1 after the offset) to load the address to this code. See README.md for more of these comment directives.

    Now we run
    Code:
    asmagix build bpre

    As you can see, we use the key specified earlier to tell what ROM to add this code to. If you specified a default key, you can leave this out. This creates a test.gba ROM in your project root which allows you to test it. I will soon allow an emulator to be run automatically after this.

    If this command gets annoying, we can do
    Code:
    asmagix dev bpre
    This command watches for changes to your source files and automatically runs the 'build' task (above) when it sees a change. This saves you having to type that command repeatedly.

    A few things to note are that the ROM key (BPRE above) is presented to your code as a constant. This means you can do conditional assembly using the constants.

    Code:
    .ifdef BPRE 
    @ Code for FR
    .elseif BPEE
    @ Code for emerald
    .endif

    Now if you run "asmagix build bpre", the "Code for FR" will be assembled, but if you run "asmagix build bpee", the "Code for emerald" will be assembled instead.

    Additionally, the parameters to the comment directives can ALSO be ASM constants. This aid the conditional assembly stuff.

    Code:
    @@action hook HOOK_LOC
    
    .ifdef BPRE 
    .equ HOOK_LOC 0xDEADBEEF
    .elseif BPEE
    .equ HOOK_LOC 0xCAFEBABE
    .endif

    This allows you to set conditional hook locations for different ROMS. You can hide those in some include file somewhere if it gets too messy.

    If you want ASMAGIX to skip an ASM file, simple add
    Code:
    @@ignore
    to the top of your file and this code will be skipped (regardless of whatever other directives are there)
     
    91
    Posts
    14
    Years
    • Seen Feb 22, 2023
    In the readme it says that you are able to overwrite existing code, how do you specify the buildscript to do that? Is there a directive for lets say writing the next piece of code / the source file to 0xDEADC0DE? Also is there a way to specify (in the json file or whaerever) to direct a whole section a specific location?

    Lastly, and i think thats currently not possible but would really enhance the usability: Can you implement the inserfion of binary files like graphics etc. (I know incbin but meh...)

    Keep up the good work i really enjoy it!

    ~SBird
     

    Touched

    Resident ASMAGICIAN
    625
    Posts
    9
    Years
    • Age 122
    • Seen Feb 1, 2018
    Thanks :D
    Sorry, I forgot to remove that from the README. I disabled that because I wasn't able to check if it was actually working - I couldn't really load a symbol table with the current setup. It will be a directive in the next version. As for external files, the best solution I've come up with is hooking into the build process with other scripts - which would be able to run grit or something to build those types of files to ASM, which would then be inserted by the build script.
    Right now it might be best to use grit manually to create those files, use the ignore directive and include them from other files to use the symbol.
     
    91
    Posts
    14
    Years
    • Seen Feb 22, 2023
    Thanks :D
    Sorry, I forgot to remove that from the README. I disabled that because I wasn't able to check if it was actually working - I couldn't really load a symbol table with the current setup. It will be a directive in the next version. As for external files, the best solution I've come up with is hooking into the build process with other scripts - which would be able to run grit or something to build those types of files to ASM, which would then be inserted by the build script.
    Right now it might be best to use grit manually to create those files, use the ignore directive and include them from other files to use the symbol.

    Thats good news. Is there already a way, however, to change the location asmagix is looking for free space? I guess many developers of bigger projects like to have control over space consumption of code, graphics etc. (I do :D)

    I am looking forward to using external symbol tables (Or actually anything that lets me write code to specific places) - for most cases the "woodhammer" version of hooking code is just too spacy (i.e. you could rather exploit an existing LOAD opcode etc.)

    ~SBird
     

    Touched

    Resident ASMAGICIAN
    625
    Posts
    9
    Years
    • Age 122
    • Seen Feb 1, 2018
    Thats good news. Is there already a way, however, to change the location asmagix is looking for free space? I guess many developers of bigger projects like to have control over space consumption of code, graphics etc. (I do :D)

    I am looking forward to using external symbol tables (Or actually anything that lets me write code to specific places) - for most cases the "woodhammer" version of hooking code is just too spacy (i.e. you could rather exploit an existing LOAD opcode etc.)

    ~SBird

    Quick answer: No there isn't any way of doing this at the moment.

    Long answer: Part of the idea behind this tool is that it will encourage collaboration and sharing of code - i.e. people saving code on GitHub. I hope to make this a "package manager" so you can insert people's code just by specifying a repo. As such, it needs some sort of starting point (the ROMs in the ROM folder). Since we can't just upload ROMs, I made it so that you can develop on clean ROMs - something which everybody has so they can just copy their own ROMs in. This gets more difficult to do if its a hack - not everybody has the version you're hacking on. I don't really know how to solve this issue properly, so this first version is basically built with the assumption that you will be hacking on a clean ROM.

    However, I will be adding an "apply" or "install" mode soon which will allow you to specify where to insert. This will be targeted at those who wish to install code into "production" ROMs (i.e. ROM hacks). The ROMs you work with while developing (the "dev" and "build" modes) are just disposable copies, so it shouldn't matter where you insert the code. The freespace finder just uses the largest block of space in the ROM so it should be safe anyway.
     
    91
    Posts
    14
    Years
    • Seen Feb 22, 2023
    Quick answer: No there isn't any way of doing this at the moment.

    Long answer: Part of the idea behind this tool is that it will encourage collaboration and sharing of code - i.e. people saving code on GitHub. I hope to make this a "package manager" so you can insert people's code just by specifying a repo. As such, it needs some sort of starting point (the ROMs in the ROM folder). Since we can't just upload ROMs, I made it so that you can develop on clean ROMs - something which everybody has so they can just copy their own ROMs in. This gets more difficult to do if its a hack - not everybody has the version you're hacking on. I don't really know how to solve this issue properly, so this first version is basically built with the assumption that you will be hacking on a clean ROM.

    However, I will be adding an "apply" or "install" mode soon which will allow you to specify where to insert. This will be targeted at those who wish to install code into "production" ROMs (i.e. ROM hacks). The ROMs you work with while developing (the "dev" and "build" modes) are just disposable copies, so it shouldn't matter where you insert the code. The freespace finder just uses the largest block of space in the ROM so it should be safe anyway.

    Even for shared code, repos or whatever you intended (Those are great ideas, don't get me wrong) people might find the idea a bit frustrating, that you cannot decide where to insert the code at. I always designate a certain space in my WIP projects for raw assembly code, just for organization purposes. Shared code would also be way easier to use if you had a config file where you can specify the entry point. Or optionally a way to use the users live console input. Something like: "ENTRY_POINT=OFFSET|CONSOLE|DYNAMIC" if you get the idea.

    More possibilities = more freedom = more power = :)

    ~SBird
     
    Back
    Top