Skip to content

Commit

Permalink
Major restructure
Browse files Browse the repository at this point in the history
  • Loading branch information
SeekyCt committed Nov 7, 2021
1 parent 628e510 commit d670e9f
Show file tree
Hide file tree
Showing 9 changed files with 586 additions and 412 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ Either run main.py and it will prompt you to enter the script's memory address,
### --ramfile path, -r path
Path to the MEM1 RAM dump, defaults to 'ram.raw' in the current directory if not specified

### --outfile path, -o path
Path to the text file to store the result to (will print to console if not specified)

### --address addr, -a addr
Address of the script to disassemble, such as 80e4a688 for aa1_01_init_evt in PAL revision 0

Expand Down Expand Up @@ -62,6 +59,9 @@ Disabled:
### --ttyd, -t
Changes opcodes and variable bases to their TTYD values

## --cpp, -c
Changes the output format to use C/C++ macros (C++ implementation in ttyd-tools, C imlpementation coming soon in decomp)

## Potential Update Plans
- Storing operand types for specific user_funcs for better disassembly

Expand Down
53 changes: 31 additions & 22 deletions binread.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,45 @@
from config import config
# Binary Reader: reads binary data from a RAM dump into various forms

from typing import List

class BinaryReader:
def __init__(self, path):
self._f = open(path, 'rb')

def __del__(self):
self._f.close()
def __init__(self, path: str):
with open(path, 'rb') as f:
self.dat = f.read()

def readat(self, addr, size):
self._f.seek(addr - 0x80000000)
return self._f.read(size)
# Address to ram dump offset
def addr_to_offs(self, addr: int) -> int:
return addr - 0x80000000

def readatS(self, addr):
self._f.seek(addr - 0x80000000)
# Reads bytes at an address
def read(self, addr: int, size: int) -> bytes:
offs = self.addr_to_offs(addr)
return self.dat[offs:offs+size]

# Reads a null-terminated SJIS string at an address
def read_str(self, addr: int) -> str:
offs = self.addr_to_offs(addr)
strn = bytearray()
while True:
c = self._f.read(1)[0]
c = self.dat[offs]
if c == 0:
break
strn.append(c)
offs += 1
return strn.decode("shift-jis")

def readatI(self, addr, size):
return int.from_bytes(self.readat(addr, size), 'big')
# Reads an integer at an address
def read_int(self, addr: int, size: int) -> int:
return int.from_bytes(self.read(addr, size), "big")

def readatH(self, addr):
return self.readatI(addr, 2)
# Reads a halfword at an address
def read_half(self, addr: int) -> int:
return self.read_int(addr, 2)

def readatW(self, addr):
return self.readatI(addr, 4)
# Reads a word at an address
def read_word(self, addr: int) -> int:
return self.read_int(addr, 4)

def readatWA(self, addr, length):
return [self.readatW(addr + (i * 4)) for i in range(0, length)]

ramReader = BinaryReader(config.dumpPath)
# Reads a word array at an address
def read_word_array(self, addr: int, length: int) -> List[int]:
return [self.read_word(addr + (i * 4)) for i in range(length)]
37 changes: 14 additions & 23 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,74 +1,65 @@
# Config: command line arguments for the program

import argparse

class Config:
def __init__(self):
parser = argparse.ArgumentParser()
parser.add_argument("--ramfile", "-r")
parser.add_argument("--outfile", "-o")
parser.add_argument("--address", "-a")
parser.add_argument("--map", "-m")
parser.add_argument("--showstrings", "-s", action="store_true")
parser.add_argument("--lineaddrs", "-l", action="store_true")
parser.add_argument("--nopointer", '-n', action="store_true")
parser.add_argument("--ttyd", "-t", action="store_true")
parser.add_argument("--cpp", "-c", action="store_true")
args = parser.parse_args()

# --ramfile path, -r path
# Path to the MEM1 RAM dump
if args.ramfile is not None:
self.dumpPath = args.ramfile
else:
self.dumpPath = "ram.raw"

# --outfile path, -o path
# Disassembly is stored to a text file instead of being printed to the console
if args.outfile is not None:
self.toFile = True
self.outPath = args.outfile
self.dump_path = args.ramfile
else:
self.toFile = False
self.outPath = None
self.dump_path = "ram.raw"

# --address addr, -a addr
# Address of the script to disassemble
# Ex. 80e4a688 for aa1_01_init_evt
if args.address is not None:
if args.address.startswith('0x'):
args.address = args.address[2:]
self.addr = int(args.address, 16)
else:
self.addr = int(input("addr: 0x"), 16)
self.addr = int(input("addr: "), 16)

# --map path, -m path
# Path to a symbol map, will be used
# Ex. 80e4a688 for aa1_01_init_evt
if args.map is not None:
self.useMap = True
self.mapPath = args.map
self.map_path = args.map
else:
self.useMap = False
self.mapPath = None
self.map_path = None

# --showstrings, -s
# Prints the contents of a string instead of its address for supported instructions, currently can't re-assemble
# enabled: debug_put_msg "aa1_01_init_evt"
# disabled: debug_put_msg 80CAC958
self.showStrings = args.showstrings
self.show_strings = args.showstrings

# --lineaddrs, -l
# Prints the memory address of an instruction at the start of the line
# enabled: 80e4a688: debug_put_msg 0x80CAC958
# disabled: debug_put_msg 0x80CAC958
self.showLineAddrs = args.lineaddrs
self.show_line_addrs = args.lineaddrs

# --nopointer, -n
# Prints 'ptr' instead of actual addresses, useful for comparing code from different builds
# enabled: user_func ptr, 1, 1, ptr, 1073741824
# disabled: user_func 0x800eb72c, 1, 1, 0x80caa0d0, 1073741824
self.noPointer = args.nopointer
self.no_pointer = args.nopointer

# --ttyd, -t
# Changes to TTYD values for opcodes and vriables
self.spm = not args.ttyd

config = Config()
# --cpp, -c
# Changes output format to C++ preprocessor macros
self.cpp_macros = args.cpp
Loading

0 comments on commit d670e9f

Please sign in to comment.