summaryrefslogtreecommitdiff
path: root/romstr.py
diff options
context:
space:
mode:
authorBryan Bishop <kanzure@gmail.com>2012-06-10 18:26:18 -0500
committerBryan Bishop <kanzure@gmail.com>2012-06-10 18:26:18 -0500
commitdc5aed94e9a9db28a43830b4b1d95e4ab40c700f (patch)
treea582233c6acbe6fd92ea22478e7a2e408b11494a /romstr.py
parent71a06d372cdf2072236c3ce0cef3db50fc1e4231 (diff)
backtracking and labeling for the disassembler
original-commit-id: cd60a1f0e42773d82f8c2533b104e8dcc2f76d41
Diffstat (limited to 'romstr.py')
-rw-r--r--romstr.py84
1 files changed, 55 insertions, 29 deletions
diff --git a/romstr.py b/romstr.py
index f7bc449..2416050 100644
--- a/romstr.py
+++ b/romstr.py
@@ -150,7 +150,7 @@ class Asm:
asm_commands = {}
offset = start_address
-
+
last_hl_address = None
last_a_address = None
used_3d97 = False
@@ -161,16 +161,20 @@ class Asm:
# read the current opcode byte
current_byte = ord(rom[offset])
current_byte_number = len(asm_commands.keys())
-
+
# setup this next/upcoming command
- asm_command = {
- "address": offset,
+ if offset in asm_commands.keys():
+ asm_command = asm_commands[offset]
+ else:
+ asm_command = {}
+
+ asm_command["address"] = offset
+ if not "references" in asm_command.keys():
# This counts how many times relative jumps reference this
# byte. This is used to determine whether or not to print out a
# label later.
- "references": 0,
- }
+ asm_command["references"] = 0
# some commands have two opcodes
next_byte = ord(rom[offset+1])
@@ -185,7 +189,7 @@ class Asm:
op_code = possible_opcode
else:
op_code = current_byte
-
+
op = opt_table[op_code]
opstr = op[0].lower()
@@ -195,29 +199,35 @@ class Asm:
asm_command["id"] = op_code
asm_command["format"] = opstr
asm_command["opnumberthing"] = optype
-
+
if "x" in opstr:
for x in range(0, opstr.count("x")):
insertion = ord(rom[offset + 1])
+
+ # Certain opcodes will have a local relative jump label
+ # here instead of a raw hex value, but this is
+ # controlled through asm output.
insertion = "$" + hex(insertion)[2:]
-
+
opstr = opstr[:opstr.find("x")].lower() + insertion + opstr[opstr.find("x")+1:].lower()
-
+
current_byte_number += 1
- offset += 1
+ offset += 1
if "?" in opstr:
for y in range(0, opstr.count("?")):
byte1 = ord(rom[offset + 1])
byte2 = ord(rom[offset + 2])
-
+
number = byte1
number += byte2 << 8;
-
+
+ # In most cases, you can use a label here. Labels will
+ # be shown during asm output.
insertion = "$%.4x" % (number)
-
+
opstr = opstr[:opstr.find("?")].lower() + insertion + opstr[opstr.find("?")+1:].lower()
-
+
current_byte_number += 2
offset += 2
@@ -227,19 +237,35 @@ class Asm:
# generate a label for the byte we're jumping to
target_address = offset + 2 + c_int8(ord(rom[offset + 1])).value
- if target_address in byte_labels.keys():
- byte_labels[target_address]["usage"] = 1 + byte_labels[target_address]["usage"]
- line_label2 = byte_labels[target_address]["name"]
+ if target_address in asm_commands.keys():
+ asm_commands[target_address]["references"] += 1
+ remote_label = "asm_" + hex(target_address)
+ asm_commands[target_address]["current_label"] = remote_label
+ asm_command["remote_label"] = remote_label
+ asm_command["use_remote_label"] = True
else:
- line_label2 = asm_label(target_address)
- byte_labels[target_address] = {}
- byte_labels[target_address]["name"] = line_label2
- byte_labels[target_address]["usage"] = 1
- byte_labels[target_address]["definition"] = False
-
- insertion = line_label2.lower()
- include_comment = True
+ remote_label = "asm_" + hex(target_address)
+
+ # This remote address might not be part of this
+ # function.
+ asm_commands[target_address] = {
+ "references": 1,
+ "current_label": remote_label,
+ }
+ # Also, target_address can be negative (before the
+ # start_address that the user originally requested),
+ # and it shouldn't be shown on asm output because the
+ # intermediate bytes (between a negative target_address
+ # and start_address) won't be disassembled.
+
+ # Don't know yet if this remote address is part of this
+ # function or not. When the remote address is not part
+ # of this function, the label name should not be used,
+ # because that label will not be disassembled in the
+ # output, until the user asks it to.
+ asm_command["use_remote_label"] = "unknown"
+ asm_command["remote_label"] = remote_label
elif current_byte == 0x3e:
last_a_address = ord(rom[offset + 1])
@@ -253,7 +279,7 @@ class Asm:
if current_byte == 0xcd:
if number == 0x3d97:
used_3d97 = True
-
+
if current_byte == 0xc3 or current_byte in relative_unconditional_jumps:
if current_byte == 0xc3:
if number == 0x3d97:
@@ -280,9 +306,9 @@ class Asm:
# ROM probably doesn't represent instructions.
asm_command["type"] = "data" # db
asm_command["value"] = current_byte
-
+
# save this new command in the list
- asm_commands[current_byte_number] = asm_command
+ asm_commands[asm_command["address"]] = asm_command
def __str__(self):
""" ASM pretty printer.