It is currently Tue Oct 16, 2018 9:05 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Wed Oct 10, 2018 11:54 am 
Offline
User avatar

Joined: Thu Aug 13, 2015 4:40 pm
Posts: 297
Location: Rio de Janeiro - Brazil
I have been trying to get ca65 to generate labels that are compatible with multiple banks for use with fceux's debugger, but I don't know how to get it to export the gamename.labels.txt file with bank information on each line.

The best way I got was to edit the example_fceux_symbols.py script made by I forgot who (dougeff perhaps?) rainwarrior (thanks!) so it would at least sort the labels that have prefixes to them. For example, every bank 5 label must start with "bk5_" prefix, then it will go to the .5.nl file. All labels with no prefixes go to bank 0 by default (0x0000 - 0x7FF ones go to .ram.nl).

Is there another way to do this?

Code:
#############################################################
# CA65 labels.txt to fceux's .nl files converter script
# Original script by rainwarrior.
# Edited for multiple banks compatibility by Nesrocks 2018
# Visit nesrocks.com
# version 1.3
#############################################################


# All labels that have a bk<number>_ prefix will go to the appropriate file.
# For example "bk7_reset_handler:" will go to the gamename.nes.7.nl file.
#
# Labels that have no prefix in this format and have address 0x8000+ will go to bank 0 file
# and may be randomly overwritten if the memory address is the same.
# Ram and zeropage labels do not need prefixes, they are sorted by the address.
#
# Warning: this script will delete .nl files with the same rom name that weren't freshly created.
# Script best used in a batch sequence on game compile.
#
# Original folder structure:
# compile.bat
# src/main.asm
# src/system/example_fceux_symbols.py
#
# batch command calling this script:
# cd src
# system\example_fceux_symbols.py
#
# You may need to edit this script to adjust for paths in your project folder structure.


#################
# User parameters
#################

banks = 8 # Set your bank count here. i.e: 8 = banks 0-7. If set to 2 it will go into "old" mode and generate files based on addresses only (ram.nl, 0.nl and 1.nl)
trim_prefix = 1 # 0-1. Option to remove the label prefixes on the converted debug file. can help readability on fceux's debugger.
romname = "gamename" # Write your ROM name here, minus .nes extension. No special characters.

#################
# User params end
#################

import sys
import os
assert sys.version_info[0] >= 3, "Python 3 required."

from collections import OrderedDict


def label_to_nl(label_file):
    rawlabels = []

    try:
        of = open(label_file, "rt")
        rawlabels = of.readlines()
    except IOError:
        print("skipped: "+label_file)
        return

    labels = [] # a list of lists. finally will contain a list of labels for each bank. will overwrite labels with same address on the same bank
    ramlabels = [] # zeropage and ram labels go here
    ramstrout = ""
    str_outs = []
    nl_files = []
    prefixes = []

    for bank in range(banks):
        str_outs.append("")
        nl_files.append("..\\" + romname + ".nes." + str(bank) + ".nl")
        prefixes.append("bk" + str(bank) + "_")
        labels.append([])

    # read the raw labels string and populate the labels list of lists
    for line in rawlabels:

        # get a list of words, splitting on spaces
        words = line.split()

        if (words[0] == "al"):
            address = int(words[1], 16) # the memory address
            label = words[2] # the actual symbol
            label = label.lstrip('.') # remove everything to the left of ".", including it

            if (label[0] == '_' and label[1] == '_'): # if the first and second letters of the symbol are _ _
                continue # skip compiler internals


            hasbank = 0 # flag to know if the label on this line has a prefix. if it doesn't, throw it into bank 0

            if (address >= 0x0000 and address <= 0x7FF):
                ramlabels.append(label)
                ramstrout += ("$%04X#%s#\n" % (address, label))

            else:
                for bank in range(banks):
                    if label.startswith(prefixes[bank]):
                        if trim_prefix:
                            label = label[4:]
                        labels[bank].append(label)
                        str_outs[bank] += ("$%04X#%s#\n" % (address, label))
                        hasbank = 1 # set the flag so it skips the next part

                # no prefix detected flag
                if hasbank == 0:
                    # throw into bank 0 if generic amount of banks or if address is bank 0
                    if banks != 2 or (address >= 0x8000 and address <= 0xBFFF):
                        labels[0].append(label)
                        str_outs[0] += ("$%04X#%s#\n" % (address, label))
                    # address must be bank 1
                    elif (address >= 0xC000 and address <= 0xFFFF):
                        labels[1].append(label)
                        str_outs[1] += ("$%04X#%s#\n" % (address, label))

    # write each file that isn't empty
    for bank in range(banks):
        if str_outs[bank] != "":
            open(nl_files[bank], "wt").write(str_outs[bank])
            print("debug symbols: " + nl_files[bank])

        # delete old nl files if they exist
        elif os.path.isfile(nl_files[bank]):
            os.remove(nl_files[bank])

    if ramlabels != "":
        open("..\\" + romname + ".nes.ram.nl", "wt").write(ramstrout)
        print("debug symbols: " + "..\\" + romname + ".nes.ram.nl")


if __name__ == "__main__":
    label_to_nl("..\\" + romname + ".labels.txt")

_________________
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!


Last edited by nesrocks on Thu Oct 11, 2018 6:13 am, edited 12 times in total.

Top
 Profile  
 
PostPosted: Wed Oct 10, 2018 11:59 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6875
Location: Canada
I think the script is mine.

I think a better way is probably to parse the debug file instead of an nl file. With that you can get a list of segments/etc. and you could sort out the banks with that.

The example I gave doesn't deal with banks. With Lizard I had 32k banking, so it seemed okay just to split up each bank into a separate link (keeps the symbols separated, neatly deals with the issue of duplicate code conflicts due to there being no fixed bank, etc.). With a fixed bank I'd probably want to do them in one big build instead, and for that I'd need to parse segments.


Top
 Profile  
 
PostPosted: Wed Oct 10, 2018 12:14 pm 
Offline
User avatar

Joined: Thu Aug 13, 2015 4:40 pm
Posts: 297
Location: Rio de Janeiro - Brazil
Thanks for the original script! It's a godsend :)

Oh for some reason I had in my mind that the dbg file was binary compressed, not plain text. Interesting! Will look into that.
I also noticed that I destroyed the .ram file creation, so ranges 0x000 - 0x7FF are going to .0.nl which is no good. I'll udpate that before going the debug file route.
edit: post updated with proper .ram file sorting

_________________
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!


Top
 Profile  
 
PostPosted: Wed Oct 10, 2018 2:31 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 3132
Location: Tampere, Finland
If you speak C, there's an "official" library for parsing the debug files at https://github.com/cc65/cc65/tree/master/src/dbginfo

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi


Top
 Profile  
 
PostPosted: Wed Oct 10, 2018 5:37 pm 
Offline
User avatar

Joined: Thu Aug 13, 2015 4:40 pm
Posts: 297
Location: Rio de Janeiro - Brazil
That sounds like it would be very useful. I skimmed through the three files and I have no idea what to do with them or how to use them. I'm not versed in C at all.
I had never used python before, so for this purpose I guess I'll just try to parse the debug file using python for now, since I managed to get something done.

edit: updated the original post to add the ability to use old style bank assigning by address instead of prefixes. Just set banks to 2.

_________________
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group