papermario/first_diff.py

74 lines
2.0 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
import argparse
2024-11-09 16:26:17 +01:00
import mapfile_parser
from pathlib import Path
import rabbitizer
script_dir = Path(__file__).resolve().parent
root_dir = script_dir
build_dir = root_dir / "ver" / "jp" / "build"
expected_build_dir = root_dir / "ver/jp/expected/ver/jp/build"
def decode_instruction(bytes_diff: bytes, map_file: mapfile_parser.MapFile) -> str:
word = (
(bytes_diff[0] << 24)
| (bytes_diff[1] << 16)
| (bytes_diff[2] << 8)
| (bytes_diff[3] << 0)
)
instr = rabbitizer.Instruction(word)
imm_override = None
2024-11-09 16:26:17 +01:00
if instr.isJumpWithAddress():
# Instruction is a function call (jal)
2024-11-09 16:26:17 +01:00
# Get the embedded address of the function call
sym_address = instr.getInstrIndexAsVram()
2024-11-09 16:26:17 +01:00
# Search for the address in the mapfile
sym_info = map_file.findSymbolByVramOrVrom(sym_address)
if sym_info is not None:
# Use the symbol from the mapfile instead of a raw value
imm_override = sym_info.symbol.name
2024-11-09 16:26:17 +01:00
return instr.disassemble(immOverride=imm_override, extraLJust=-20)
2024-11-09 16:26:17 +01:00
def main():
parser = argparse.ArgumentParser(
description="Find the first difference(s) between the built ROM and the base ROM."
)
2024-11-09 16:26:17 +01:00
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="us"
)
parser.add_argument(
"-a", "--add-colons", action="store_true", help="Add colon between bytes"
)
2024-11-09 16:26:17 +01:00
args = parser.parse_args()
mapfile_parser.frontends.first_diff.doFirstDiff(
build_dir / f"papermario.map",
expected_build_dir / f"papermario.map",
build_dir / f"papermario.z64",
expected_build_dir / f"papermario.z64",
args.count,
mismatchSize=True,
addColons=args.add_colons,
bytesConverterCallback=decode_instruction,
)
2024-11-09 16:26:17 +01:00
if __name__ == "__main__":
main()