Mercurial > hg > forks > dxa
diff label.c @ 4:0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 25 Feb 2015 04:15:07 +0200 |
parents | ec2f8f6f1dc9 |
children | 122134900c0e |
line wrap: on
line diff
--- a/label.c Wed Feb 25 04:13:08 2015 +0200 +++ b/label.c Wed Feb 25 04:15:07 2015 +0200 @@ -40,19 +40,13 @@ #include "opcodes.h" label *labeltable; -char defaultlabel[6]; +char defaultlabel[512]; unsigned numLabels = 0; -void AddLabel (ADDR_T address, char *name) +void AddLabel(ADDR_T address, char *name, int is_range, ADDR_T len) { - label *entry; - char *buffer; - - if (!((buffer = malloc (strlen (name) + 1)))) - return; - - entry = numLabels ? + label * entry = numLabels ? realloc (labeltable, (numLabels + 1) * sizeof *entry) : malloc (sizeof *entry); @@ -62,31 +56,67 @@ entry = &labeltable[numLabels++]; entry->address = address; - entry->name = buffer; - while ((*buffer++ = *name++)); + entry->name = strdup(name); + entry->is_range = is_range; + entry->len = len; } - -char *Label (ADDR_T address, int admode) +int IsInsideRegion(ADDR_T address) { label *entry; - if (!IsLabeled (address)) { + for (entry = &labeltable[numLabels]; entry-- > labeltable;) + { + int offs = address - entry->address; + if (entry->is_range && offs > 0 && offs < entry->len) + return TRUE; + } + return FALSE; +} + - /* dirty kludge to allow zero page stuff to still work. this sometimes - guesses wrong */ - if (admode == zp) - sprintf (defaultlabel, "$%02x", address); - else - sprintf (defaultlabel, "$%04x", address); +char *Label(ADDR_T address, int admode, int allow_range) +{ + label *entry; + int match = 0; + + if (!IsLabeled (address)) { + // dirty kludge to allow zero page stuff to still work. this sometimes + // guesses wrong + if (admode == zp) + snprintf(defaultlabel, sizeof(defaultlabel), "$%02x", address); + else + snprintf(defaultlabel, sizeof(defaultlabel), "$%04x", address); + return defaultlabel; } for (entry = &labeltable[numLabels]; entry-- > labeltable;) + { + int offs = address - entry->address; + if (entry->address == address) return entry->name; - sprintf (defaultlabel, "l%x", address); + if (entry->is_range && offs >= 0 && offs < entry->len) + { + match = 1; + if (allow_range) + { + snprintf(defaultlabel, sizeof(defaultlabel), + (offs < 16) ? "%s + %d" : "%s + $%x", + entry->name, offs); + return defaultlabel; + } + else + break; + } + } + + if (match) + snprintf(defaultlabel, sizeof(defaultlabel), "XXX_%x", address); + else + snprintf(defaultlabel, sizeof(defaultlabel), "l_%x", address); return defaultlabel; }