mirror of
https://gitlab.com/xCrystal/pokecrystal-board.git
synced 2024-11-16 11:27:33 -08:00
Merge pull request #137 from yenatch/master
gbz80disasm reads wram/gbhw/hram and spaces blocks of asm
This commit is contained in:
commit
5feb5fd208
@ -6,16 +6,15 @@ from copy import copy, deepcopy
|
||||
from ctypes import c_int8
|
||||
import random
|
||||
import json
|
||||
from wram import *
|
||||
|
||||
# New versions of json don't have read anymore.
|
||||
if not hasattr(json, "read"):
|
||||
json.read = json.loads
|
||||
|
||||
from romstr import RomStr
|
||||
|
||||
def load_rom(filename="../baserom.gbc"):
|
||||
global rom
|
||||
rom = RomStr.load(filename=filename)
|
||||
rom = bytearray(open(filename,'rb').read())
|
||||
return rom
|
||||
|
||||
spacing = "\t"
|
||||
@ -543,10 +542,11 @@ for line in temp_opt_table:
|
||||
del line
|
||||
|
||||
end_08_scripts_with = [
|
||||
0xc9, #ret
|
||||
0xd9, #reti
|
||||
0xe9, #jp hl
|
||||
#0xc3, #jp
|
||||
##0x18, #jr
|
||||
0xc9, #ret
|
||||
###0xda, 0xe9, 0xd2, 0xc2, 0xca, 0xc3, 0x38, 0x30, 0x20, 0x28, 0x18, 0xd8, 0xd0, 0xc0, 0xc8, 0xc9
|
||||
]
|
||||
relative_jumps = [0x38, 0x30, 0x20, 0x28, 0x18, 0xc3, 0xda, 0xc2]
|
||||
@ -565,27 +565,20 @@ def load_labels(filename="labels.json"):
|
||||
crystal.scan_for_predefined_labels()
|
||||
|
||||
def find_label(local_address, bank_id=0):
|
||||
global all_labels
|
||||
|
||||
# keep an integer
|
||||
if type(local_address) == str:
|
||||
local_address1 = int(local_address.replace("$", "0x"), 16)
|
||||
else: local_address1 = local_address
|
||||
local_address = int(local_address.replace("$", "0x"), 16)
|
||||
|
||||
# turn local_address into an integer
|
||||
if type(local_address) == str:
|
||||
if "0x" in local_address:
|
||||
local_address = local_address.replace("0x", "$")
|
||||
elif "$" in local_address:
|
||||
local_address = local_address.replace("$", "")
|
||||
|
||||
if type(local_address) == str:
|
||||
local_address = int(local_address, 16)
|
||||
|
||||
for label_entry in all_labels:
|
||||
if label_entry["address"] == local_address:
|
||||
if label_entry["bank"] == bank_id or (local_address1 < 0x8000 and (label_entry["bank"] == 0 or label_entry["bank"] == 1)):
|
||||
return label_entry["label"]
|
||||
if local_address < 0x8000:
|
||||
for label_entry in all_labels:
|
||||
if label_entry["address"] == local_address:
|
||||
if label_entry["bank"] == bank_id or label_entry["bank"] == 0:
|
||||
return label_entry["label"]
|
||||
if local_address in wram_labels.keys():
|
||||
return wram_labels[local_address][-1]
|
||||
for constants in [gbhw_constants, hram_constants]:
|
||||
if local_address in constants.keys():
|
||||
return constants[local_address]
|
||||
return None
|
||||
|
||||
def asm_label(address):
|
||||
@ -608,9 +601,7 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
load_labels()
|
||||
load_rom()
|
||||
|
||||
bank_id = 0
|
||||
if original_offset > 0x8000:
|
||||
bank_id = original_offset / 0x4000
|
||||
bank_id = original_offset / 0x4000
|
||||
if debug: print "bank id is: " + str(bank_id)
|
||||
|
||||
last_hl_address = None #for when we're scanning the main map script
|
||||
@ -630,7 +621,7 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
output = ""
|
||||
keep_reading = True
|
||||
while offset <= end_address and keep_reading:
|
||||
current_byte = ord(rom[offset])
|
||||
current_byte = rom[offset]
|
||||
is_data = False
|
||||
maybe_byte = current_byte
|
||||
|
||||
@ -645,6 +636,7 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
if offset in byte_labels.keys():
|
||||
line_label = byte_labels[offset]["name"]
|
||||
byte_labels[offset]["usage"] += 1
|
||||
output += "\n"
|
||||
else:
|
||||
line_label = asm_label(offset)
|
||||
byte_labels[offset] = {}
|
||||
@ -655,13 +647,13 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
|
||||
#find out if there's a two byte key like this
|
||||
temp_maybe = maybe_byte
|
||||
temp_maybe += ( ord(rom[offset+1]) << 8)
|
||||
if temp_maybe in opt_table.keys() and ord(rom[offset+1])!=0:
|
||||
temp_maybe += ( rom[offset+1] << 8)
|
||||
if temp_maybe in opt_table.keys() and rom[offset+1]!=0:
|
||||
opstr = opt_table[temp_maybe][0].lower()
|
||||
|
||||
if "x" in opstr:
|
||||
for x in range(0, opstr.count("x")):
|
||||
insertion = ord(rom[offset + 1])
|
||||
insertion = rom[offset + 1]
|
||||
insertion = "$" + hex(insertion)[2:]
|
||||
|
||||
opstr = opstr[:opstr.find("x")].lower() + insertion + opstr[opstr.find("x")+1:].lower()
|
||||
@ -670,8 +662,8 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
offset += 1
|
||||
if "?" in opstr:
|
||||
for y in range(0, opstr.count("?")):
|
||||
byte1 = ord(rom[offset + 1])
|
||||
byte2 = ord(rom[offset + 2])
|
||||
byte1 = rom[offset + 1]
|
||||
byte2 = rom[offset + 2]
|
||||
|
||||
number = byte1
|
||||
number += byte2 << 8;
|
||||
@ -695,7 +687,7 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
|
||||
#type = -1 when it's the E op
|
||||
#if op_code_type != -1:
|
||||
if op_code_type == 0 and ord(rom[offset]) == op_code_byte:
|
||||
if op_code_type == 0 and rom[offset] == op_code_byte:
|
||||
op_str = op_code[0].lower()
|
||||
|
||||
output += spacing + op_code[0].lower() #+ " ; " + hex(offset)
|
||||
@ -703,18 +695,18 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
|
||||
offset += 1
|
||||
current_byte_number += 1
|
||||
elif op_code_type == 1 and ord(rom[offset]) == op_code_byte:
|
||||
elif op_code_type == 1 and rom[offset] == op_code_byte:
|
||||
oplen = len(op_code[0])
|
||||
opstr = copy(op_code[0])
|
||||
xes = op_code[0].count("x")
|
||||
include_comment = False
|
||||
for x in range(0, xes):
|
||||
insertion = ord(rom[offset + 1])
|
||||
insertion = rom[offset + 1]
|
||||
insertion = "$" + hex(insertion)[2:]
|
||||
|
||||
if current_byte == 0x18 or current_byte==0x20 or current_byte in relative_jumps: #jr or jr nz
|
||||
#generate a label for the byte we're jumping to
|
||||
target_address = offset + 2 + c_int8(ord(rom[offset + 1])).value
|
||||
target_address = offset + 2 + c_int8(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"]
|
||||
@ -726,29 +718,34 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
byte_labels[target_address]["definition"] = False
|
||||
|
||||
insertion = line_label2.lower()
|
||||
include_comment = True
|
||||
if has_outstanding_labels(byte_labels) and all_outstanding_labels_are_reverse(byte_labels, offset):
|
||||
include_comment = True
|
||||
elif current_byte == 0x3e:
|
||||
last_a_address = ord(rom[offset + 1])
|
||||
last_a_address = rom[offset + 1]
|
||||
|
||||
opstr = opstr[:opstr.find("x")].lower() + insertion + opstr[opstr.find("x")+1:].lower()
|
||||
|
||||
# because the $ff00+$ff syntax is silly
|
||||
if opstr.count("$") > 0 and "+" in opstr:
|
||||
first_orig = opstr.split("$")[1].split("+")[0]
|
||||
first_num = "0x"+first_orig
|
||||
first_val = int(first_num, 16)
|
||||
second_orig = opstr.split("+$")[1].split("]")[0]
|
||||
second_num = "0x"+second_orig
|
||||
second_val = int(second_num, 16)
|
||||
combined_val = "$" + hex(first_val + second_val)[2:]
|
||||
replacetron = "[$"+first_orig+"+$"+second_orig+"]"
|
||||
opstr = opstr.replace(replacetron, "["+combined_val+"]")
|
||||
if opstr.count("$") > 1 and "+" in opstr:
|
||||
first_orig = opstr[opstr.find("$"):opstr.find("+")]
|
||||
first_val = eval(first_orig.replace("$","0x"))
|
||||
|
||||
second_orig = opstr[opstr.find("+$")+1:opstr.find("]")]
|
||||
second_val = eval(second_orig.replace("$","0x"))
|
||||
|
||||
combined_val = "$%.4x" % (first_val + second_val)
|
||||
result = find_label(combined_val, bank_id)
|
||||
if result != None:
|
||||
combined_val = result
|
||||
|
||||
replacetron = "[%s+%s]" % (first_orig, second_orig)
|
||||
opstr = opstr.replace(replacetron, "[%s]" % combined_val)
|
||||
|
||||
output += spacing + opstr
|
||||
if include_comment:
|
||||
output += " ; " + hex(offset)
|
||||
if current_byte in relative_jumps:
|
||||
output += " $" + hex(ord(rom[offset + 1]))[2:]
|
||||
output += " $" + hex(rom[offset + 1])[2:]
|
||||
output += "\n"
|
||||
|
||||
current_byte_number += 1
|
||||
@ -758,22 +755,21 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
current_byte_number += 1
|
||||
offset += 1
|
||||
include_comment = False
|
||||
elif op_code_type == 2 and ord(rom[offset]) == op_code_byte:
|
||||
elif op_code_type == 2 and rom[offset] == op_code_byte:
|
||||
oplen = len(op_code[0])
|
||||
opstr = copy(op_code[0])
|
||||
qes = op_code[0].count("?")
|
||||
for x in range(0, qes):
|
||||
byte1 = ord(rom[offset + 1])
|
||||
byte2 = ord(rom[offset + 2])
|
||||
byte1 = rom[offset + 1]
|
||||
byte2 = rom[offset + 2]
|
||||
|
||||
number = byte1
|
||||
number += byte2 << 8;
|
||||
number += byte2 << 8
|
||||
|
||||
insertion = "$%.4x" % (number)
|
||||
if maybe_byte in call_commands or current_byte in relative_unconditional_jumps or current_byte in relative_jumps:
|
||||
result = find_label(insertion, bank_id)
|
||||
if result != None:
|
||||
insertion = result
|
||||
result = find_label(insertion, bank_id)
|
||||
if result != None:
|
||||
insertion = result
|
||||
|
||||
opstr = opstr[:opstr.find("?")].lower() + insertion + opstr[opstr.find("?")+1:].lower()
|
||||
output += spacing + opstr #+ " ; " + hex(offset)
|
||||
@ -804,7 +800,7 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
|
||||
#stop reading at a jump, relative jump or return
|
||||
if current_byte in end_08_scripts_with:
|
||||
if not has_outstanding_labels(byte_labels) and all_outstanding_labels_are_reverse(byte_labels, offset):
|
||||
if not has_outstanding_labels(byte_labels) or all_outstanding_labels_are_reverse(byte_labels, offset):
|
||||
keep_reading = False
|
||||
is_data = False #cleanup
|
||||
break
|
||||
@ -816,7 +812,7 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
keep_reading = True
|
||||
else:
|
||||
#if is_data and keep_reading:
|
||||
output += spacing + "db $" + hex(ord(rom[offset]))[2:] #+ " ; " + hex(offset)
|
||||
output += spacing + "db $" + hex(rom[offset])[2:] #+ " ; " + hex(offset)
|
||||
output += "\n"
|
||||
offset += 1
|
||||
current_byte_number += 1
|
||||
@ -826,6 +822,9 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
#offset += 1
|
||||
#current_byte_number += 1
|
||||
|
||||
if current_byte in relative_unconditional_jumps + end_08_scripts_with:
|
||||
output += "\n"
|
||||
|
||||
first_loop = False
|
||||
|
||||
#clean up unused labels
|
||||
@ -835,6 +834,9 @@ def output_bank_opcodes(original_offset, max_byte_count=0x4000, include_last_add
|
||||
if label_line["usage"] == 0:
|
||||
output = output.replace((label_line["name"] + "\n").lower(), "")
|
||||
|
||||
#tone down excessive spacing
|
||||
output = output.replace("\n\n\n","\n\n")
|
||||
|
||||
#add the offset of the final location
|
||||
if include_last_address:
|
||||
output += "; " + hex(offset)
|
||||
|
61
extras/wram.py
Normal file
61
extras/wram.py
Normal file
@ -0,0 +1,61 @@
|
||||
# coding: utf-8
|
||||
|
||||
# RGBDS BSS section and constant parsing.
|
||||
|
||||
def read_bss_sections(bss):
|
||||
sections = []
|
||||
section = {}
|
||||
address = None
|
||||
if type(bss) is not list: bss = bss.split('\n')
|
||||
for line in bss:
|
||||
line = line.lstrip()
|
||||
if 'SECTION' in line:
|
||||
if section: sections.append(section) # last section
|
||||
|
||||
address = eval(line[line.find('[')+1:line.find(']')].replace('$','0x'))
|
||||
section = {
|
||||
'name': line.split('"')[1],
|
||||
#'type': line.split(',')[1].split('[')[0].strip(),
|
||||
'start': address,
|
||||
'labels': [],
|
||||
}
|
||||
elif ':' in line:
|
||||
# the only labels that don't use :s so far are enders,
|
||||
# which we typically don't want to end up in the output
|
||||
label = line[:line.find(':')]
|
||||
if ';' not in label:
|
||||
section['labels'] += [{'label': label, 'address': address, 'length': 0}]
|
||||
elif line[:3] == 'ds ':
|
||||
length = eval(line[3:line.find(';')].replace('$','0x'))
|
||||
address += length
|
||||
if section['labels']:
|
||||
section['labels'][-1]['length'] += length
|
||||
sections.append(section)
|
||||
return sections
|
||||
|
||||
wram_sections = read_bss_sections(open('../wram.asm', 'r').readlines())
|
||||
|
||||
|
||||
def make_wram_labels():
|
||||
wram_labels = {}
|
||||
for section in wram_sections:
|
||||
for label in section['labels']:
|
||||
if label['address'] not in wram_labels.keys():
|
||||
wram_labels[label['address']] = []
|
||||
wram_labels[label['address']] += [label['label']]
|
||||
return wram_labels
|
||||
|
||||
wram_labels = make_wram_labels()
|
||||
|
||||
|
||||
def constants_to_dict(constants):
|
||||
return dict((eval(constant[constant.find('EQU')+3:constant.find(';')].replace('$','0x')), constant[:constant.find('EQU')].strip()) for constant in constants)
|
||||
|
||||
def scrape_constants(text):
|
||||
if type(text) is not list:
|
||||
text = text.split('\n')
|
||||
return constants_to_dict([line for line in text if 'EQU' in line[:line.find(';')]])
|
||||
|
||||
hram_constants = scrape_constants(open('../hram.asm','r').readlines())
|
||||
gbhw_constants = scrape_constants(open('../gbhw.asm','r').readlines())
|
||||
|
69
main.asm
69
main.asm
@ -1281,7 +1281,7 @@ CheckDict: ; 1087
|
||||
cp $15
|
||||
jp z, $117b
|
||||
cp $4f
|
||||
jp z, Char4f
|
||||
jp z, Char4F
|
||||
cp $4e
|
||||
jp z, $12a7
|
||||
cp $16
|
||||
@ -1291,7 +1291,7 @@ CheckDict: ; 1087
|
||||
cp $4c
|
||||
jp z, $1337
|
||||
cp $4b
|
||||
jp z, $131f
|
||||
jp z, Char4B
|
||||
cp $51 ; Player name
|
||||
jp z, $12f2
|
||||
cp $49
|
||||
@ -1395,7 +1395,7 @@ CheckDict: ; 1087
|
||||
INCBIN "baserom.gbc", $117b, $1203 - $117b
|
||||
|
||||
|
||||
Char5D:
|
||||
Char5D: ; 1203
|
||||
ld a, [hBattleTurn]
|
||||
push de
|
||||
and a
|
||||
@ -1404,7 +1404,7 @@ Char5D:
|
||||
jr .asm_126a ; 0x120c $5c
|
||||
.asm_120e
|
||||
ld de, Char5AText ; Enemy
|
||||
call $1078
|
||||
call PlaceString
|
||||
ld h, b
|
||||
ld l, c
|
||||
ld de, $c616
|
||||
@ -1419,11 +1419,11 @@ Char5D:
|
||||
cp $2a
|
||||
jr z, .asm_1248 ; 0x122b $1b
|
||||
ld de, $c656
|
||||
call $1078
|
||||
call PlaceString
|
||||
ld h, b
|
||||
ld l, c
|
||||
ld de, $12a2
|
||||
call $1078
|
||||
call PlaceString
|
||||
push bc
|
||||
ld hl, $5939
|
||||
ld a, $e
|
||||
@ -1439,7 +1439,7 @@ Char5D:
|
||||
jr .asm_126a ; 0x1250 $18
|
||||
push de
|
||||
ld de, PlayerName
|
||||
call $1078
|
||||
call PlaceString
|
||||
ld h, b
|
||||
ld l, c
|
||||
ld a, [$d472]
|
||||
@ -1449,7 +1449,7 @@ Char5D:
|
||||
ld de, $12a6
|
||||
jr .asm_126a ; 0x1268 $0
|
||||
.asm_126a
|
||||
call $1078
|
||||
call PlaceString
|
||||
ld h, b
|
||||
ld l, c
|
||||
pop de
|
||||
@ -1473,36 +1473,63 @@ Char5AText: ; 0x1295
|
||||
|
||||
INCBIN "baserom.gbc", $129c, $12ea - $129c
|
||||
|
||||
Char4f: ; 12ea
|
||||
Char4F: ; 12ea
|
||||
pop hl
|
||||
ld hl, $c5e1
|
||||
hlcoord 1, 16
|
||||
push hl
|
||||
jp NextChar
|
||||
; 0x12f2
|
||||
|
||||
INCBIN "baserom.gbc", $12f2, $1345 - $12f2
|
||||
INCBIN "baserom.gbc", $12f2, $131f - $12f2
|
||||
|
||||
Char4B: ; 131f
|
||||
ld a, [InLinkBattle]
|
||||
or a
|
||||
jr nz, .asm_1328
|
||||
call $13c7
|
||||
|
||||
.asm_1328
|
||||
call $13b6
|
||||
|
||||
Char55: ; $1345
|
||||
push de
|
||||
ld de, $1354
|
||||
call $aaf
|
||||
pop de
|
||||
|
||||
ld a, [InLinkBattle]
|
||||
or a
|
||||
call z, $13cd
|
||||
|
||||
push de
|
||||
call $138c
|
||||
call $138c
|
||||
hlcoord 1, 16
|
||||
pop de
|
||||
jp NextChar
|
||||
; 1345
|
||||
|
||||
|
||||
Char55: ; 1345
|
||||
push de
|
||||
ld de, .text_1354
|
||||
ld b, h
|
||||
ld c, l
|
||||
call $1078
|
||||
call PlaceString
|
||||
ld h, b
|
||||
ld l, c
|
||||
pop de
|
||||
jp NextChar
|
||||
; 0x1354
|
||||
|
||||
; ???
|
||||
ld c, e
|
||||
ld d, b
|
||||
.text_1354
|
||||
db $4b, "@"
|
||||
; 1356
|
||||
|
||||
Char5F: ; 0x1356
|
||||
|
||||
Char5F: ; 1356
|
||||
; ends a Pokédex entry
|
||||
ld [hl],"."
|
||||
ld [hl], "."
|
||||
pop hl
|
||||
ret
|
||||
; 135a
|
||||
|
||||
INCBIN "baserom.gbc", $135a, $15d8 - $135a
|
||||
|
||||
@ -17859,7 +17886,7 @@ Function117b31:
|
||||
call $1cfd
|
||||
ld hl, $c550
|
||||
ld de, YesNo117ccc
|
||||
call $1078
|
||||
call PlaceString
|
||||
ld hl, $c54f
|
||||
ld a, "▶"
|
||||
ld [hl], a
|
||||
|
@ -314,26 +314,19 @@ def separate_comment(l):
|
||||
asm = ""
|
||||
comment = None
|
||||
in_quotes = False
|
||||
in_comment = False
|
||||
|
||||
# token either belongs to the line or to the comment
|
||||
for token in l:
|
||||
if in_comment:
|
||||
if comment:
|
||||
comment += token
|
||||
elif in_quotes and token != "\"":
|
||||
else:
|
||||
if not in_quotes:
|
||||
if token == ";":
|
||||
comment = ";"
|
||||
continue
|
||||
if token == "\"":
|
||||
in_quotes = not in_quotes
|
||||
asm += token
|
||||
elif in_quotes and token == "\"":
|
||||
in_quotes = False
|
||||
asm += token
|
||||
elif not in_quotes and token == "\"":
|
||||
in_quotes = True
|
||||
asm += token
|
||||
elif not in_quotes and token != "\"":
|
||||
if token == ";":
|
||||
in_comment = True
|
||||
comment = ";"
|
||||
else:
|
||||
asm += token
|
||||
return asm, comment
|
||||
|
||||
def quote_translator(asm):
|
||||
|
Loading…
Reference in New Issue
Block a user