59 lines
3.2 KiB
Python
59 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
# Generate port/include/fs2Symbols.h from the ld65 debug file of the
|
|
# disassembly (tmp/complete.dbg). Every label and equate becomes a
|
|
# SYM_<name> macro (scoped symbols get SYM_<scope>_<name>) so the C
|
|
# port refers to RAM cells by the same names as src/chunk*.s.
|
|
#
|
|
# Usage: python3 port/tools/genSymbols.py tmp/complete.dbg port/include/fs2Symbols.h
|
|
import re
|
|
import sys
|
|
|
|
|
|
def main():
|
|
dbgPath = sys.argv[1]
|
|
outPath = sys.argv[2]
|
|
scopes = {}
|
|
syms = []
|
|
for line in open(dbgPath):
|
|
if line.startswith("scope\t"):
|
|
fields = dict(kv.split("=", 1) for kv in line.strip().split("\t")[1].split(","))
|
|
scopes[int(fields["id"])] = fields.get("name", "").strip('"')
|
|
elif line.startswith("sym\t"):
|
|
fields = dict(kv.split("=", 1) for kv in line.strip().split("\t")[1].split(","))
|
|
if "val" not in fields or fields.get("type") not in ("lab", "equ"):
|
|
continue
|
|
name = fields["name"].strip('"')
|
|
# Assembler constants (opcodes, CPU ids, colours) are
|
|
# not addresses; keep the L00xx zero-page equates.
|
|
if fields.get("type") == "equ" and int(fields["val"], 16) < 0x100 and not name.startswith("L00"):
|
|
continue
|
|
if not re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", name):
|
|
continue
|
|
scope = scopes.get(int(fields["scope"]), "")
|
|
if scope != "" and not re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", scope):
|
|
continue
|
|
full = name if scope == "" else scope + "_" + name
|
|
syms.append((int(fields["val"], 16), full))
|
|
seen = {}
|
|
for addr, name in syms:
|
|
if name in seen and seen[name] != addr:
|
|
sys.stderr.write("warning: %s defined at %04X and %04X\n" % (name, seen[name], addr))
|
|
seen.setdefault(name, addr)
|
|
out = open(outPath, "w")
|
|
out.write("// Generated by port/tools/genSymbols.py from the ld65 debug file of\n")
|
|
out.write("// src/complete.s. Do not edit; regenerate with:\n")
|
|
out.write("// ca65 --target apple2 -g -o tmp/complete_g.o src/complete.s\n")
|
|
out.write("// ld65 --config src/asm.cfg --dbgfile tmp/complete.dbg -o /dev/null tmp/complete_g.o\n")
|
|
out.write("// python3 port/tools/genSymbols.py tmp/complete.dbg port/include/fs2Symbols.h\n")
|
|
out.write("//\n// Names are the disassembly's labels (SYM_<label>), with .proc/.scope\n")
|
|
out.write("// members as SYM_<scope>_<label>. Values are absolute 6502 addresses.\n\n")
|
|
out.write("#ifndef FS2_SYMBOLS_H\n#define FS2_SYMBOLS_H\n\n")
|
|
width = max(len(n) for n in seen) + 1
|
|
for name in sorted(seen, key=lambda n: (seen[n], n)):
|
|
out.write("#define SYM_%s%s0x%04X\n" % (name, " " * (width - len(name)), seen[name]))
|
|
out.write("\n#endif\n")
|
|
out.close()
|
|
sys.stderr.write("%d symbols\n" % len(seen))
|
|
|
|
|
|
main()
|