summaryrefslogtreecommitdiff
path: root/tools/first_diff.py
diff options
context:
space:
mode:
authorDerek Hensley <hensley.derek58@gmail.com>2024-06-01 08:01:19 -0700
committerGitHub <noreply@github.com>2024-06-01 11:01:19 -0400
commit312b65d5e34878df4b70d8b9922e1082213b3662 (patch)
tree15e17c2624fb353b82bbf593ce429a430d613324 /tools/first_diff.py
parent659e2b5088eb960594844d2dd3625779c11476ca (diff)
Even more general cleanup (#1640)
* floats * obj_lightblock externs * Couple more floats * slime floats * undefined_syms * Move some tools to the tools folder * format * Update src/overlays/actors/ovl_Bg_Dblue_Waterfall/z_bg_dblue_waterfall.c Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com> --------- Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com>
Diffstat (limited to 'tools/first_diff.py')
-rwxr-xr-xtools/first_diff.py58
1 files changed, 58 insertions, 0 deletions
diff --git a/tools/first_diff.py b/tools/first_diff.py
new file mode 100755
index 000000000..78eaf9975
--- /dev/null
+++ b/tools/first_diff.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+
+import argparse
+from pathlib import Path
+
+try:
+ import rabbitizer
+except ImportError:
+ print("Missing dependency rabbitizer, install it with `python3 -m pip install 'rabbitizer>=1.0.0,<2.0.0'`")
+ exit(1)
+
+try:
+ import mapfile_parser
+except ImportError:
+ print("Missing dependency mapfile_parser, install it with `python3 -m pip install 'mapfile-parser>=1.2.1,<2.0.0'`")
+ exit(1)
+
+
+def decodeInstruction(bytesDiff: bytes, mapFile: mapfile_parser.MapFile) -> str:
+ word = (bytesDiff[0] << 24) | (bytesDiff[1] << 16) | (bytesDiff[2] << 8) | (bytesDiff[3] << 0)
+ instr = rabbitizer.Instruction(word)
+ immOverride = None
+
+ if instr.isJumpWithAddress():
+ # Instruction is a function call (jal)
+
+ # Get the embedded address of the function call
+ symAddress = instr.getInstrIndexAsVram()
+
+ # Search for the address in the mapfile
+ symInfo = mapFile.findSymbolByVramOrVrom(symAddress)
+ if symInfo is not None:
+ # Use the symbol from the mapfile instead of a raw value
+ immOverride = symInfo.symbol.name
+
+ return instr.disassemble(immOverride=immOverride, extraLJust=-20)
+
+def firstDiffMain():
+ parser = argparse.ArgumentParser(description="Find the first difference(s) between the built ROM and the base ROM.")
+
+ parser.add_argument("-c", "--count", type=int, default=5, help="find up to this many instruction difference(s)")
+ parser.add_argument("-v", "--version", help="Which version should be processed", default="n64-us")
+ parser.add_argument("-a", "--add-colons", action='store_true', help="Add colon between bytes" )
+
+ args = parser.parse_args()
+
+ buildFolder = Path(f"build/{args.version}")
+
+ BUILTROM = buildFolder / f"mm-{args.version}.z64"
+ BUILTMAP = buildFolder / f"mm-{args.version}.map"
+
+ EXPECTEDROM = Path(f"baseroms/{args.version}/baserom-decompressed.z64")
+ EXPECTEDMAP = "expected" / BUILTMAP
+
+ mapfile_parser.frontends.first_diff.doFirstDiff(BUILTMAP, EXPECTEDMAP, BUILTROM, EXPECTEDROM, args.count, mismatchSize=True, addColons=args.add_colons, bytesConverterCallback=decodeInstruction)
+
+if __name__ == "__main__":
+ firstDiffMain()