view label.c @ 16:a2a81589380d default tip

Reformat the whole source via clang-format for better consistency.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 14 Oct 2021 01:53:20 +0300
parents 84c0facfc43c
children
line wrap: on
line source

/*\
 *  dxa -- symbolic 65xx disassembler
 *
 *  Copyright (C) 1993, 1994 Marko M\"akel\"a
 *  Copyright (C) 2019 Cameron Kaiser
 *
 *  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.
 *
\*/

#define _LABEL_C_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "opcodes.h"
#include "options.h"
#include "proto.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;)
    {
        if (entry->address == address)
            return entry->name;
    }

    for (entry = &labeltable[numLabels]; entry-- > labeltable;)
    {
        int offs = address - entry->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;
}

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);
        }
    }
}