Mercurial > hg > forks > dxa
view 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 source
/*\ * dxa v0.1.1 -- symbolic 65xx disassembler * * Copyright (C) 1993, 1994 Marko M\"akel\"a * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Contacting the author: * * Via Internet E-mail: * <Marko.Makela@FTP.FUNET.FI> * * Via Snail Mail: * Marko M\"akel\"a * Sillitie 10 A * FIN-01480 VANTAA * Finland \*/ #define _LABEL_C_ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "proto.h" #include "options.h" #include "opcodes.h" label *labeltable; char defaultlabel[512]; unsigned numLabels = 0; void AddLabel(ADDR_T address, char *name, int is_range, ADDR_T len) { label * entry = numLabels ? realloc (labeltable, (numLabels + 1) * sizeof *entry) : malloc (sizeof *entry); if (!entry) return; labeltable = entry; entry = &labeltable[numLabels++]; entry->address = address; entry->name = strdup(name); entry->is_range = is_range; entry->len = len; } int IsInsideRegion(ADDR_T address) { label *entry; for (entry = &labeltable[numLabels]; entry-- > labeltable;) { int offs = address - entry->address; if (entry->is_range && offs > 0 && offs < entry->len) return TRUE; } return FALSE; } 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; 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; } void Collect (void) { unsigned counter = 0; table *entry = NULL, *entry2; label *labels; if (fVerbose) fprintf (stderr, "%s: collecting garbage.\n", prog); while ((entry = entry2 = FindNextEntryType (entry, 0, 0))) { counter++; PutLabel (entry->address); PutLowByte (entry->address); PutHighByte (entry->address); while ((entry2 = FindNextEntry (entry2, entry->address, ~0, entry->type))) DeleteEntry (entry2); /* remove duplicate warnings */ } if ((entry = malloc (counter * sizeof *entry))) { /* compact the table */ entrycount = counter; for (entry2 = scantable; counter; entry2++) { if (!entry2->type) continue; memcpy (&entry[--counter], entry2, sizeof *entry); } free (scantable); scantable = entry; } for (labels = &labeltable[numLabels]; labels-- > labeltable;) if ((ADDR_T)(labels->address - StartAddress) < (ADDR_T)(EndAddress - StartAddress)) { PutLabel (labels->address); PutLowByte (labels->address); PutHighByte (labels->address); } }