N64 ROM Assembly Editor
Hello! I've been doing some work on the assembly editor since last post, so there are a few more features. Anyone using it prior to this post will need to use "Re-map jumps" in the tools menu to apply a few minor changes to their jumps.data file.

It's core features are:
  • Game offset mode: Jumps/branches/addresses and navigation will be treated with the appropriate memory region offset
  • Memory region calculation: Main and Boot regions automatically calculated and supports additional memory regions
  • Hex/Binary mode
  • Assembly search engine: Search particular phrases to locate some code
  • Highlighting for jumps/branches and selected register
  • Highlighting for Load/Store instructions which can be determined to target the same memory address
  • Text boxes containing original assembly, hacked assembly and comments/notes which are constantly aligned
  • Easy address translation from memory editor to emulator
  • Checksum calculation (should work for most games)
  • CRC bypass (works for some games)
  • Jump/branch mapping which allows highlighting of "branch/jump targets" and "jumps to function" lookup
  • Changeable colour scheme
  • Hacking notes are always output to a negotiable text document in order of address they are aligned with
  • Generate a script from a script template to apply to a batch of addresses for use in other programs
  • Float/Double <--> Hex translation
  • Cutting instructions which have branches pointing to them will cause all branches within the function to be modified when you paste so that the branches point to the new paste location
  • Modifying the SP frame push or pop (ADDIU SP, SP $####) will cause all read and write instructions within the function which use SP as the base address to be offset by the same amount
  • Function optimiser (more info below)
  • Generate a runtime patch script for PJ64d (patches all changes made during session while in disassembly view)
    *comes with a server script you can run with PJ64d, which makes patching a little quicker.

It's currently functional spaghetti source code. If you would like to give it a whirl and you're on linux or mac, you will need a Python 3.5 or 3.6 interpreter, also need to install Python's "tkinter" and "keyboard" modules. If you're on Windows, there is a download link to a snapshot of my Python environment, the disassembler and a batch file to run it through python.

(For Operating Systems other than Windows)
If you haven't dabbled in python before, you likely won't have the interpreter on your machine. I'd suggest Anaconda (a Python virtual environment manager) as when you make an environment, you can specify "Anaconda" at the end of the command when creating a virtual environment in the command prompt, and it will create the python installation with a whole heap of commonly used modules, including tkinter. Anaconda might chew up to 1gb of data to install, as a forewarning.
After an update I have made, you will now also be required to install the keyboard module.
This is only because it doesn't come with Anaconda. Installing keyboard is easy, the instructions can be found here https://pypi.python.org/pypi/keyboard/

Anaconda for OSX: https://docs.conda.io/projects/conda/en/...macos.html
Anaconda for Linux: https://docs.conda.io/projects/conda/en/...linux.html
*Don't choose miniconda, from what I understand, you can get stuck in "dependency hell" while trying to obtain tkinter, which is not a place you want to be in

Source on Git: https://github.com/mitchasdf/N64-Rom-Disassembler
Download for Windows** (includes python, tkinter and keyboard): 

**You may need to disable any ad or popup blockers or add the page to the blocker's exclusion list. If you don't, you will get "failed to start action" and http errors, or the page will simply hang on loading when attempting to download. The download button is located at the top-right of the page.


In the main window, there are 4 tall text boxes. Respectively, they represent: Addresses, base file, hack file, hacking notes/comments.

When you open a rom initially, you can choose "start new" in the file menu to select the base file and then the name and location for the hack file. If you already have a hack file you wish to open, you can "open existing" and then associate it with the base file in the 2nd file navigation window.

They might feel like normal text boxes, but they have heavily modified behaviour so as to keep the code and comments aligned. You can copy/paste or backspace multiple lines of code or comments and it will be safe.

The text boxes are bound with a few hotkeys which make life a bit easier. I'll list them all here:
  • Return: Move to end of next line
  • Shift+Return: Move to end of previous line
  • Shift+Backspace or Shift+Delete: Remove line of code
  • Ctrl+B: Insert branch template (BEQ R0, R0, $)
  • Ctrl+R: Restore line of code, or selection of lines of code
  • Ctrl+Shift+R: Restore whole function
  • Ctrl+F: Follow jump or branch
  • Ctrl+G: Find all J or JAL which target any address inside the current function
  • Ctrl+O: Optimise the current function
  • Ctrl+P: Create a patch file for PJ64d to run during emulation
  • Ctrl+Comma (< key): Undo
  • Ctrl+Fullstop (> key): Redo

The rest of the hotkeys which don't affect the text boxes can be found scattered in the Menu.

Extra text box behaviours:
  • NOP will be automatically removed when typing on that line
  • Blank lines will be replaced with and treated as NOP
  • Multi-line selections will be extended to the bounds of the start and end lines you select when you attempt to action the selection
  • Hack text box will always input as upper case letters

For address translation from memory editor RAM to emulator RAM, you may use an option to set the memory editor offset for the current game, and from there you can either type in addresses manually, or, if you leave the input text box blank and just click the translate button, it will try to convert your clipboard contents instead.

The comments navigator has a "filter" option to search for comments with particular phrases. It will filter out any comment that doesn't contain each word you type in, separated by spaces. You can see an example of that in the comments navigator image below.

If you group your addresses by adding hashtags (#group name) to the end of their comments, you can then add those groups to the batch with the click of a button in the script generator window.

To use additional memory region offsets, its as simple as setting the parameters using the option in the options menu, then all jumps to that region will appear with the offset applied. All additional jumps made to that region will be encoded accordingly. Setting memory regions has no affect on the layout or placement of the code, only how it appears. The addresses list on the left side of the main window (and addresses in all other windows) will also have the offset applied during game offset mode.
Every navigation task which shifts your view will only have the region offset applied to your input during game offset mode.

Function optimisation

There are several tasks that can be done to grant yourself a few NOPs in a function in order to have room for your own logic.

For the sake of this explanation, I'll refer to registers T0 through T9 and AT as scratch registers. 

I'll refer a couple of times to "sections", which consist of areas within the function, broken up by any instruction that is targeted by a branch or returned to from a linked jumped. These are locations where any scratch register's contents can no longer safely be assumed.

The current optimisation tasks that are performed when pressing Ctrl+O are:
  • Excess pointers declared using a scratch register or the SP will be removed and all pointers using the removed register will be pointed to the original pointer. This can only be done within each "section".
  • JALs which target a function that only contain 1 or 2 instructions other than JR RA will be replaced with said instructions, so as to "merge" those 2 "sections" either side of the JAL and possibly remove more redundant pointers.
  • Branches which target the next non-NOP instruction will be removed, as there is no point in it being there.
  • Branch delay slots which are filled with NOP will be substituted with the next available non-NOP instruction, only if the instruction writes to either a scratch register or a float register. This grants 1 extra NOP per eligible branch.
  • ..
  • Not an optimisation task, but something to keep in mind: All float comparison instructions (C.#.#) and their branch functions (BC1#) require at least 1 other instruction (a NOP will suffice) in between them. This is because for all float comparison instructions, there is an additional delay on writing the result to the FP register, which is what the float branches read from to conditionally jump. If there is nothing separating the float comparison and the float branch, it will take the contents of FP prior to the float compare, resulting in not errors, but strange behaviours.


Main window

Comments window

Jumps window

Users browsing this thread: 1 Guest(s)