# Part of the Fifteen-Thieves Project # Chris Xiong 2020 # License: Expat (MIT) import sys import xv.util import xv.amap wavenames = ['None'] def dfs_checkpopulated(node): node.populated = False for ch in node.children_nodes: if node.template.is_aggregate_node: if type(ch) == list: for el in ch: node.populated |= dfs_checkpopulated(el) else: node.populated |= dfs_checkpopulated(ch) else: for a in node.get_data(): if a != 0xff: node.populated = True break return node.populated def dfs_print(node, level=0, instance=None): if not node.populated: return ba_rep = ''.join([format(x, "02x") for x in xv.util.padbelist(xv.util.int2b7belist(node.base_address))]) print(f"{ba_rep}{level*' '} {node.template.name}{'['+str(instance)+']' if instance is not None else ''}") for child in node.children_nodes: if node.template.is_aggregate_node: if type(child) == list: for i, element in enumerate(child): dfs_print(element, level + 1, i) else: dfs_print(child, level + 1) else: if type(child) == list: if child[0].name == "name": print(f"{ba_rep}{(level + 1)*' '} {child[0].name} {node.data[child[0].offset:child[0].offset + 12].decode()}") else: for i, element in enumerate(child): ba_rep = ''.join([format(x, "02x") for x in xv.util.padbelist(xv.util.int2b7belist(element.offset))]) print(f"{ba_rep}{(level + 1)*' '} {element.name}[{i}] {xv.amap.get_leaf_data(node.data, element)}") else: ba_rep = ''.join([format(x, "02x") for x in xv.util.padbelist(xv.util.int2b7belist(child.offset))]) if child.name.startswith("wave_number"): try: print(f"{ba_rep}{(level + 1)*' '} {child.name} {xv.amap.get_leaf_data(node.data, child)}: {wavenames[xv.amap.get_leaf_data(node.data, child)]}") except IndexError: print(f"{ba_rep}{(level + 1)*' '} {child.name} {xv.amap.get_leaf_data(node.data, child)}: unknown") else: print(f"{ba_rep}{(level + 1)*' '} {child.name} {xv.amap.get_leaf_data(node.data, child)}") if __name__ == "__main__": if len(sys.argv) < 2: print(f"Usage: {sys.argv[0]} ") print("loading address mapping...", flush=True, file=sys.stderr) m = xv.amap.AddrMapTemplate("amaps/sd-80.amap") t = xv.amap.create_addr_map_tree(m) t.data[:] = [0xff for i in range(0, len(t.data))] print("loading wave names...", file=sys.stderr) with open("data/sdwavelist","r") as f: for l in f: wavenames += [l.split('\t')[1].strip()] print("loading memoryregion...", file=sys.stderr) mr = xv.util.load_memoryregion(sys.argv[1]) for addr, data in mr: ra = xv.util.b7belist2int(addr) t.data[ra:ra + len(data)] = data dfs_checkpopulated(t) dfs_print(t)