Skip to content

Commit

Permalink
[BUILD] x16edit/basload trace (#325)
Browse files Browse the repository at this point in the history
* Add trace symbols for X16 Edit and BASLOAD

* Update x16edit and basload to current master

* Fix trace_info script, and update basload, changing a comment that was problematic for trace scripts

* Fix truncate issue in code listing

* Improving the trace info script, keeping code indentation and more
  • Loading branch information
stefan-b-jakobsson authored Aug 18, 2024
1 parent a2c09dc commit 5501419
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 15 deletions.
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -462,12 +462,15 @@ $(BUILD_DIR)/x16edit-rom.bin: $(X16EDIT_DEPS)
@mkdir -p $$(dirname $@)
(cd x16-edit && make clean rom)
cp x16-edit/build/x16edit-rom.bin $(BUILD_DIR)/x16edit-rom.bin
./scripts/trace_info.py 13 x16-edit/conf/x16edit-rom.cfg x16-edit/build/x16edit-rom.lst $(BUILD_DIR)/x16edit-rom_D.rlst $(BUILD_DIR)/x16edit_D_labels.h
./scripts/trace_info.py 14 x16-edit/conf/x16edit-rom.cfg x16-edit/build/x16edit-rom.lst $(BUILD_DIR)/x16edit-rom_E.rlst $(BUILD_DIR)/x16edit_E_labels.h

# Bank F: BASLOAD
$(BUILD_DIR)/basload-rom.bin: $(BASLOAD_DEPS)
@mkdir -p $$(dirname $@)
(cd basload && make clean && make)
cp basload/build/basload-rom.bin $(BUILD_DIR)/basload-rom.bin
./scripts/trace_info.py 15 basload/conf/basload-rom.cfg basload/build/basload-rom.lst $(BUILD_DIR)/basload-rom.rlst $(BUILD_DIR)/basload_labels.h

$(BUILD_DIR)/rom_labels.h: $(BANK_BINS)
./scripts/symbolize.sh 0 build/x16/kernal.sym > $@
Expand All @@ -483,6 +486,8 @@ $(BUILD_DIR)/rom_labels.h: $(BANK_BINS)
./scripts/symbolize.sh A build/x16/audio.sym >> $@
./scripts/symbolize.sh B build/x16/util.sym >> $@
./scripts/symbolize.sh C build/x16/bannex.sym >> $@
cat $@ $(BUILD_DIR)/x16edit_D_labels.h $(BUILD_DIR)/x16edit_E_labels.h $(BUILD_DIR)/basload_labels.h > $(BUILD_DIR)/rom_labels.tmp
mv $(BUILD_DIR)/rom_labels.tmp $@

$(BUILD_DIR)/rom_lst.h: $(BANK_BINS)
./scripts/trace_lst.py 0 `find build/x16/kernal/ -name \*.rlst` > $@
Expand All @@ -496,4 +501,7 @@ $(BUILD_DIR)/rom_lst.h: $(BANK_BINS)
./scripts/trace_lst.py A `find build/x16/audio/ -name \*.rlst` >> $@
./scripts/trace_lst.py B `find build/x16/util/ -name \*.rlst` >> $@
./scripts/trace_lst.py C `find build/x16/bannex/ -name \*.rlst` >> $@
./scripts/trace_lst.py D $(BUILD_DIR)/x16edit-rom_D.rlst >> $@
./scripts/trace_lst.py E $(BUILD_DIR)/x16edit-rom_E.rlst >> $@
./scripts/trace_lst.py F $(BUILD_DIR)/basload-rom.rlst >> $@

2 changes: 1 addition & 1 deletion basload/.git-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4f90428c9dd1e10b718978c0c092953e01368f7e
d325c2f72a42179a73cbc0fdc5d78cea98e40bf0
4 changes: 2 additions & 2 deletions basload/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ SRC_FILES=$(wildcard *.asm) $(wildcard *.inc)

$(BUILD_DIR)/basload-rom.bin: $(SRC_FILES)
@mkdir -p $(BUILD_DIR)
cl65 -o $@ -t cx16 -C $(CONF_DIR)/basload-rom.cfg -m $(BUILD_DIR)/basload-rom.map -Ln $(BUILD_DIR)/basload-rom.sym main.asm
cl65 -o $@ -t cx16 -C $(CONF_DIR)/basload-rom.cfg -m $(BUILD_DIR)/basload-rom.map -l $(BUILD_DIR)/basload-rom.lst -Ln $(BUILD_DIR)/basload-rom.sym main.asm
rm -f main.o

# Clean-up target
clean:
rm -f $(BUILD_DIR)/*
rm -f $(BUILD_DIR)/*
4 changes: 2 additions & 2 deletions basload/conf/basload-rom.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ MEMORY {
ZP: file = "", start = $0022, size = $0080 - $0022, define = yes;
VARMEM: file = "", start = $0400, size = $0400, define=yes;
RB1: file = "", start = $a000, size = $2000, define=yes;
ROMBANK: start = $c000, size = $3ff0, fill=yes, fillval=$aa;
SIGNATURE: start = $fff0, size = $10, fill=yes, fillval=$bb;
ROMBANK: start = $c000, size = $3ff0, fill=yes, bank=$0f, fillval=$aa;
SIGNATURE: start = $fff0, size = $10, fill=yes, bank=$0f, fillval=$bb;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define=yes;
Expand Down
4 changes: 2 additions & 2 deletions basload/line.inc
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ string:
stx state
jmp copy

; Check if backslash "\" => change state and discard char
; Check if backslash => change state and discard char
: cmp #$5c ; Backslash
bne :+
lda #LINE_BACKSLASH
Expand Down Expand Up @@ -981,4 +981,4 @@ jump_table:
option_start: .res 1
curly_start_index: .res 1
.CODE
.endproc
.endproc
208 changes: 208 additions & 0 deletions scripts/trace_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
#!/usr/bin/env python3

# Usage: trace_info.py <bank> <configfile> <listfile> <out relistfile> <out symbolsfile>
# bank: bank to output trace info for
# configfile: path to ld65 config file
# listfile: path to program list file
# out relistfile: path to relist file to be created
# out symbolsfile: path to symbols file to be created
#
# This tool was designed to output trace info for X16 Edit and BASLOAD.

import sys
import re

# Global variables
memory_areas = {} # Populated from ca65 config file
segments = {} # Populated from ca65 config file
bank = None # Holds the bank we're creating listings and symbols for
cur_bank = 0 # Holds the bank of the line that is currently parsed

# Regex
segmentParser = re.compile("^[\s]*.segment[\s]+[\"\'][\w]+[\"\']", re.IGNORECASE)
memoryDefintionParser = re.compile("memory[\s]*\{[^\}]*\}", re.IGNORECASE)
segmentDefinitionParser = re.compile("segments[\s]*\{[^\}]*\}", re.IGNORECASE)
configLineParser = re.compile("[\w]+[\s]*:[^;]*;", re.IGNORECASE)
hexnumParser = re.compile("^\$[0-9a-f]+$", re.IGNORECASE)
hexnumParser2 = re.compile("^0x[0-9a-f]+$", re.IGNORECASE)
decnumParser = re.compile("^[0-9]+$", re.IGNORECASE)
labelParser = re.compile("^[\s]*[a-z]+[a-z0-9]*\:", re.IGNORECASE)
procParser = re.compile("^[\s]*.proc[\s]+", re.IGNORECASE)

# Converts string to number
# Accepted formats: decimal numbers, hexadecimal numbers (0xn or $n)
def parseNum(str):
h = hexnumParser.search(str)
if h != None:
return int(str[h.span()[0]+1:h.span()[1]], 16)

h = hexnumParser2.search(str)
if h != None:
return int(str[h.span()[0]+2:h.span()[1]], 16)

d = decnumParser.search(str)
if d != None:
return int(str[d.span()[0]:d.span()[1]])

return None

# Parses the ca65 config file, extracting memory areas
# and memory segments
def parseConfig(config_path):
# Read whole config file
f = open(config_path, "r")
conf = ""
l = f.readline().upper()
while l:
conf = conf + l
l = f.readline().upper()
f.close()

# Get memory areas
mem_def = memoryDefintionParser.findall(conf)[0]
mem_areas = configLineParser.findall(mem_def)
for item in mem_areas:
keyvalues = {}

split_colon = item.split(":")
name = split_colon[0].strip()

split_comma = split_colon[1].split(",")
for kv in split_comma:
keyvalues[kv.split("=")[0].strip()] = kv.split("=")[1].strip()

start = keyvalues["START"]
keyvalues["curpos"] = parseNum(start)
memory_areas[name] = keyvalues

# Get memory segments
seg_def = segmentDefinitionParser.findall(conf)[0]
sgmts = configLineParser.findall(seg_def)
for item in sgmts:
keyvalues = {}

split_colon = item.split(":")
name = split_colon[0].strip()

split_comma = split_colon[1].split(",")
for kv in split_comma:
keyvalues[kv.split("=")[0].strip()] = kv.split("=")[1].strip()

segments[name] = keyvalues

# Parses a line of code and returns the name of a selected memory segment, or None
# It supports both the .segment directive, and the built-in shortcuts such as .CODE
def matchSegment(str):
shortcuts = [".BSS", ".CODE", ".DATA", ".ZEROPAGE"]

# Find .segment directive
segment = segmentParser.findall(str)
if len(segment) > 0:
return segment[0].split()[1][1:-1].upper()

else:
# Find segment shortcut
str = str.upper().strip()
for item in shortcuts:
if str.startswith(item):
return item[1:]

# No segment
return None

# Returns label name found within the passed string, else None
def getLabel(str):
l = labelParser.search(str)
if l != None:
return str[l.span()[0]:l.span()[1]-1].strip()

l = procParser.search(str)
if l != None:
return str[l.span()[1]:].strip()

return None

# Main worker, parses the original listings file, and outputs
# both a relist file and a symbols file
def parseCodeListing(listing_path, relist_path, symbols_path):
f_in = open(listing_path, "r")
f_relist = open(relist_path, "w")

symbol_addresses = []
symbol_names = []
cur_offset = 0
cursegment = None

l = f_in.readline()
while l:
header = l[:11]
disass = l[11:24]
code = l[24:].rstrip()

# Get possible memory segment selected on the line
s = matchSegment(code)

# A new segment is selected
if s != None:
# Remember current segment
cursegment = s

# Remember start of segment
cur_offset = parseNum(memory_areas[segments[s]["LOAD"]]["START"])

try:
cur_bank = parseNum(memory_areas[segments[s]["LOAD"]]["BANK"])
except:
cur_bank = 0

# The listings file will often show the address of the previous
# segment. Replace that with the current position in the selected
# segment.
addr = memory_areas[segments[s]["LOAD"]]["curpos"]

# Only output code if in the ROM area
if addr >= 0xc000 and bank == cur_bank:
f_relist.write("%0.6X a " % addr + disass + code + "\n")

# No segment was selected, output normal code
elif cursegment != None:
# Calculate absolute address
addr = cur_offset + int(header[0:6], 16)

# Remeber last address used in this segment
memory_areas[segments[cursegment]["LOAD"]]["curpos"] = addr

# Only output code if in the ROM area
if addr >= 0xc000 and bank == cur_bank:
f_relist.write("%0.6X a " % addr + disass + code + "\n")

# Store symbols
label = getLabel(code)
if label != None:
symbol_names.append(label)
symbol_addresses.append(addr)

l = f_in.readline()

f_in.close()
f_relist.close()

# Write symbols to file
f_symbols = open(symbols_path, "w")

f_symbols.write("uint16_t addresses_bank" + hex(bank).upper()[2:] + "[] = {")
for a in symbol_addresses:
f_symbols.write(hex(a) + ", ")
f_symbols.write("\n};")

f_symbols.write("\nchar *labels_bank" + hex(bank).upper()[2:] + "[] = {")
for n in symbol_names:
f_symbols.write("\"" + n + "\", ")
f_symbols.write("\n};")

f_symbols.close()

# Main
bank = parseNum(sys.argv[1])
parseConfig(sys.argv[2])
parseCodeListing(sys.argv[3], sys.argv[4], sys.argv[5])
2 changes: 1 addition & 1 deletion x16-edit/.git-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7ebc2ecedd1370131c78cc7291540c5f73a3b7ee
d77d0002f62cd468c885449f45781222889ded56
6 changes: 3 additions & 3 deletions x16-edit/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ $(BUILD_DIR)/help_short.bin: help_short.txt
# Target for RAM program
$(BUILD_DIR)/X16EDIT.PRG: $(BUILD_DIR)/help.bin $(BUILD_DIR)/help_short.bin $(SRC_FILES)
@mkdir -p $(BUILD_DIR)
cl65 --asm-args -Dtarget_mem=1 -o $@ -u __EXEHDR__ -t cx16 -C $(CONF_DIR)/cx16-asm.cfg --mapfile $(BUILD_DIR)/x16edit-ram.map -Ln $(BUILD_DIR)/x16edit-ram.sym main.asm
cl65 --asm-args -Dtarget_mem=1 -g -o $@ -u __EXEHDR__ -t cx16 -C $(CONF_DIR)/cx16-asm.cfg --mapfile $(BUILD_DIR)/x16edit-ram.map -Ln $(BUILD_DIR)/x16edit-ram.sym -l $(BUILD_DIR)/x16edit-ram.lst main.asm

# Target for ROM program
$(BUILD_DIR)/x16edit-rom.bin: $(BUILD_DIR)/help.bin $(BUILD_DIR)/help_short.bin $(SRC_FILES)
@mkdir -p $(BUILD_DIR)
cl65 --asm-args -Dtarget_mem=2 -o $@ -t cx16 -C $(CONF_DIR)/x16edit-rom.cfg --mapfile $(BUILD_DIR)/x16edit-rom.map -Ln $(BUILD_DIR)/x16edit-rom.sym -l $(BUILD_DIR)/x16edit-rom.lst main.asm
cl65 --asm-args -Dtarget_mem=2 -g -o $@ -t cx16 -C $(CONF_DIR)/x16edit-rom.cfg --mapfile $(BUILD_DIR)/x16edit-rom.map -Ln $(BUILD_DIR)/x16edit-rom.sym -l $(BUILD_DIR)/x16edit-rom.lst main.asm

# Clean-up target
clean:
rm -f $(BUILD_DIR)/*
rm -f $(BUILD_DIR)/*
8 changes: 4 additions & 4 deletions x16-edit/conf/x16edit-rom.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ MEMORY {
RAMCODE1: file = "", start = $9c00, size = $200;
RAMCODE2: file = "", start = $9c00, size = $200;
RAMCODE3: file = "", start = $9e00, size = $100;
ROMBANK: start = $c000, size = $3ff0, fill=yes, bank=1, fillval=$aa;
APPSIGMEM: start = $fff0, size = $0a, fill=yes, fillval=$aa;
VECT: start = $fffa, size = $06, fill=yes, fillval=$aa;
ROMBANK2: start = $c000, size = $4000, fill=yes, bank=2, fillval=$aa;
ROMBANK: start = $c000, size = $3ff0, fill=yes, bank=$0d, fillval=$aa;
APPSIGMEM: start = $fff0, size = $0a, fill=yes, bank=$0d, fillval=$aa;
VECT: start = $fffa, size = $06, fill=yes, bank=$0d, fillval=$aa;
ROMBANK2: start = $c000, size = $4000, fill=yes, bank=$0e, fillval=$aa;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define=yes;
Expand Down

0 comments on commit 5501419

Please sign in to comment.