/* da65 */
#include "asminc.h"
-#include "attrtab.h"
+#include "comments.h"
#include "error.h"
+#include "labels.h"
/* Apply the sign */
Val *= Sign;
- /* Define the symbol */
- AddExtLabel (Val, SB_GetConstBuf (&Ident), Comment);
+ /* Define the symbol and the comment */
+ AddExtLabel (Val, SB_GetConstBuf (&Ident));
+ SetComment (Val, Comment);
}
/* */
/* */
/* */
-/* (C) 2000-2005 Ullrich von Bassewitz */
+/* (C) 2000-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
-#include <stdio.h>
-#include <string.h>
-
-/* common */
-#include "xmalloc.h"
-#include "xsprintf.h"
-
/* da65 */
-#include "code.h"
#include "error.h"
-#include "global.h"
-#include "output.h"
#include "attrtab.h"
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
-/* Label + comment */
-typedef struct {
- const char* Name;
- const char* Comment;
-} Label;
-
-/* A whole lot of Labels, so we don't have to allocate them separately */
-static Label* LabelHeap = 0;
-static unsigned LabelsLeft = 0;
-
/* Attribute table */
-static unsigned char AttrTab [0x10000];
-
-/* Symbol table */
-static const Label* SymTab [0x10000];
-
-
-
-/*****************************************************************************/
-/* struct Label */
-/*****************************************************************************/
-
-
-
-Label* NewLabel (const char* Name, const char* Comment)
-/* Create a new Label structure, initialize and return it */
-{
- Label* L;
-
- /* Check if we have some free labels left */
- if (LabelsLeft == 0) {
- /* Allocate a new block of memory */
- LabelsLeft = 200;
- LabelHeap = xmalloc (LabelsLeft * sizeof (Label));
- }
-
- /* Get a new one from the buffer */
- L = LabelHeap++;
- --LabelsLeft;
-
- /* Initialize the new label */
- L->Name = xstrdup (Name);
- L->Comment = Comment? xstrdup (Comment) : 0;
-
- /* Return the new label */
- return L;
-}
+static unsigned short AttrTab[0x10000];
-static void AddrCheck (unsigned Addr)
+void AddrCheck (unsigned Addr)
/* Check if the given address has a valid range */
{
if (Addr >= 0x10000) {
-static const char* MakeLabelName (unsigned Addr)
-/* Make the default label name from the given address and return it in a
- * static buffer.
- */
-{
- static char LabelBuf [32];
- xsprintf (LabelBuf, sizeof (LabelBuf), "L%04X", Addr);
- return LabelBuf;
-}
-
-
-
-void AddLabel (unsigned Addr, attr_t Attr, const char* Name, const char* Comment)
-/* Add a label */
-{
- /* Get an existing label attribute */
- attr_t ExistingAttr = GetLabelAttr (Addr);
-
- /* Must not have two symbols for one address */
- if (ExistingAttr != atNoLabel) {
- /* Allow redefinition if identical */
- if (ExistingAttr == Attr && strcmp (SymTab[Addr]->Name, Name) == 0) {
- return;
- }
- Error ("Duplicate label for address $%04X: %s/%s", Addr, SymTab[Addr]->Name, Name);
- }
-
- /* Create a new label */
- SymTab[Addr] = NewLabel (Name, Comment);
-
- /* Remember the attribute */
- AttrTab[Addr] |= Attr;
-}
-
-
-
-void AddIntLabel (unsigned Addr)
-/* Add an internal label using the address to generate the name. */
-{
- AddLabel (Addr, atIntLabel, MakeLabelName (Addr), 0);
-}
-
-
-
-void AddExtLabel (unsigned Addr, const char* Name, const char* Comment)
-/* Add an external label */
-{
- AddLabel (Addr, atExtLabel, Name, Comment);
-}
-
-
-
-void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs)
-/* Add a dependent label at the given address using "base name+Offs" as the new
- * name.
- */
-{
- /* Allocate memory for the dependent label name */
- unsigned NameLen = strlen (BaseName);
- char* DepName = xmalloc (NameLen + 7); /* "+$ABCD" */
-
- /* Create the new name in the buffer */
- if (UseHexOffs) {
- sprintf (DepName, "%s+$%02X", BaseName, Offs);
- } else {
- sprintf (DepName, "%s+%u", BaseName, Offs);
- }
-
- /* Define the labels */
- AddLabel (Addr, Attr | atDepLabel, DepName, 0);
-
- /* Free the name buffer */
- xfree (DepName);
-}
-
-
-
-static void AddLabelRange (unsigned Addr, attr_t Attr,
- const char* Name, const char* Comment,
- unsigned Count)
-/* Add a label for a range. The first entry gets the label "Name" while the
- * others get "Name+offs".
- */
-{
- /* Define the label */
- AddLabel (Addr, Attr, Name, Comment);
-
- /* Define dependent labels if necessary */
- if (Count > 1) {
- unsigned Offs;
-
- /* Setup the format string */
- const char* Format = UseHexOffs? "$%02X" : "%u";
-
- /* Allocate memory for the dependent label names */
- unsigned NameLen = strlen (Name);
- char* DepName = xmalloc (NameLen + 7); /* "+$ABCD" */
- char* DepOffs = DepName + NameLen + 1;
-
- /* Copy the original name into the buffer */
- memcpy (DepName, Name, NameLen);
- DepName[NameLen] = '+';
-
- /* Define the labels */
- for (Offs = 1; Offs < Count; ++Offs) {
- sprintf (DepOffs, Format, Offs);
- AddLabel (Addr + Offs, Attr | atDepLabel, DepName, 0);
- }
-
- /* Free the name buffer */
- xfree (DepName);
- }
-}
-
-
-
-void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count)
-/* Add an internal label for a range. The first entry gets the label "Name"
- * while the others get "Name+offs".
- */
-{
- /* Define the label range */
- AddLabelRange (Addr, atIntLabel, Name, 0, Count);
-}
-
-
-
-void AddExtLabelRange (unsigned Addr, const char* Name, const char* Comment, unsigned Count)
-/* Add an external label for a range. The first entry gets the label "Name"
- * while the others get "Name+offs".
- */
-{
- /* Define the label range */
- AddLabelRange (Addr, atExtLabel, Name, Comment, Count);
-}
-
-
-
-int HaveLabel (unsigned Addr)
-/* Check if there is a label for the given address */
-{
- /* Check the given address */
- AddrCheck (Addr);
-
- /* Check for a label */
- return (SymTab[Addr] != 0);
-}
-
-
-
-int MustDefLabel (unsigned Addr)
-/* Return true if we must define a label for this address, that is, if there
- * is a label at this address, and it is an external or internal label.
- */
-{
- /* Get the label attribute */
- attr_t A = GetLabelAttr (Addr);
-
- /* Check for an internal or external label */
- return (A == atExtLabel || A == atIntLabel);
-}
-
-
-
-const char* GetLabel (unsigned Addr)
-/* Return the label for an address */
-{
- /* Check the given address */
- AddrCheck (Addr);
-
- /* Return the label if any */
- return SymTab[Addr]? SymTab[Addr]->Name : 0;
-}
-
-
-
-const char* GetComment (unsigned Addr)
-/* Return the comment for an address */
-{
- /* Check the given address */
- AddrCheck (Addr);
-
- /* Return the label if any */
- return SymTab[Addr]? SymTab[Addr]->Comment : 0;
-}
-
-
-
-unsigned char GetStyleAttr (unsigned Addr)
+attr_t GetStyleAttr (unsigned Addr)
/* Return the style attribute for the given address */
{
/* Check the given address */
-unsigned char GetLabelAttr (unsigned Addr)
+attr_t GetLabelAttr (unsigned Addr)
/* Return the label attribute for the given address */
{
/* Check the given address */
-void DefOutOfRangeLabels (void)
-/* Output any labels that are out of the loaded code range */
-{
- unsigned long Addr;
-
- SeparatorLine ();
-
- /* Low range */
- Addr = 0;
- while (Addr < CodeStart) {
- if (MustDefLabel (Addr)) {
- DefineConst (SymTab[Addr]->Name, SymTab[Addr]->Comment, Addr);
- }
- ++Addr;
- }
-
- /* Skip areas in code range */
- while (Addr <= CodeEnd) {
- if ((AttrTab[Addr] & atStyleMask) == atSkip && MustDefLabel (Addr)) {
- DefineConst (SymTab[Addr]->Name, SymTab[Addr]->Comment, Addr);
- }
- ++Addr;
- }
-
- /* High range */
- while (Addr < 0x10000) {
- if (MustDefLabel (Addr)) {
- DefineConst (SymTab[Addr]->Name, SymTab[Addr]->Comment, Addr);
- }
- ++Addr;
- }
-
- SeparatorLine ();
-}
-
-
-
/*****************************************************************************/
/* */
-/* attrtab.h */
+/* attrtab.h */
/* */
-/* Disassembler attribute table */
+/* Disassembler attribute table */
/* */
/* */
/* */
-/* (C) 2000-2005 Ullrich von Bassewitz */
+/* (C) 2000-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
typedef enum attr_t {
/* Styles */
- atDefault = 0x00, /* Default style */
- atCode = 0x01,
- atIllegal = 0x02,
- atByteTab = 0x03, /* Same as illegal */
- atDByteTab = 0x04,
- atWordTab = 0x05,
- atDWordTab = 0x06,
- atAddrTab = 0x07,
- atRtsTab = 0x08,
- atTextTab = 0x09,
- atSkip = 0x0A, /* Skip code completely */
+ atDefault = 0x0000, /* Default style */
+ atCode = 0x0001,
+ atIllegal = 0x0002,
+ atByteTab = 0x0003, /* Same as illegal */
+ atDByteTab = 0x0004,
+ atWordTab = 0x0005,
+ atDWordTab = 0x0006,
+ atAddrTab = 0x0007,
+ atRtsTab = 0x0008,
+ atTextTab = 0x0009,
+ atSkip = 0x000A, /* Skip code completely */
/* Label flags */
- atNoLabel = 0x00, /* No label for this address */
- atExtLabel = 0x10, /* External label */
- atIntLabel = 0x20, /* Internally generated label */
- atDepLabel = 0x40, /* Dependent label */
+ atNoLabel = 0x0000, /* No label for this address */
+ atExtLabel = 0x0010, /* External label */
+ atIntLabel = 0x0020, /* Internally generated label */
+ atDepLabel = 0x0040, /* Dependent label */
+ atUnnamedLabel = 0x0080, /* Unnamed label */
- atStyleMask = 0x0F, /* Output style */
- atLabelMask = 0x70 /* Label information */
+ atLabelDefined = 0x0100, /* True if we defined the label */
+
+ atStyleMask = 0x000F, /* Output style */
+ atLabelMask = 0x00F0 /* Label information */
} attr_t;
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
+void AddrCheck (unsigned Addr);
+/* Check if the given address has a valid range */
+
unsigned GetGranularity (attr_t Style);
/* Get the granularity for the given style */
void MarkAddr (unsigned Addr, attr_t Attr);
/* Mark an address with an attribute */
-void AddLabel (unsigned Addr, attr_t Attr, const char* Name, const char* Comment);
-/* Add a label */
-
-void AddIntLabel (unsigned Addr);
-/* Add an internal label using the address to generate the name. */
-
-void AddExtLabel (unsigned Addr, const char* Name, const char* Comment);
-/* Add an external label */
-
-void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs);
-/* Add a dependent label at the given address using "base name+Offs" as the new
- * name.
- */
-
-void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count);
-/* Add an internal label for a range. The first entry gets the label "Name"
- * while the others get "Name+offs".
- */
-
-void AddExtLabelRange (unsigned Addr, const char* Name, const char* Comment, unsigned Count);
-/* Add an external label for a range. The first entry gets the label "Name"
- * while the others get "Name+offs".
- */
-
-int HaveLabel (unsigned Addr);
-/* Check if there is a label for the given address */
-
-int MustDefLabel (unsigned Addr);
-/* Return true if we must define a label for this address, that is, if there
- * is a label at this address, and it is an external or internal label.
- */
-
-const char* GetLabel (unsigned Addr);
-/* Return the label for an address or NULL if there is none */
-
-const char* GetComment (unsigned Addr);
-/* Return the comment for an address */
-
-unsigned char GetStyleAttr (unsigned Addr);
+attr_t GetStyleAttr (unsigned Addr);
/* Return the style attribute for the given address */
-unsigned char GetLabelAttr (unsigned Addr);
+attr_t GetLabelAttr (unsigned Addr);
/* Return the label attribute for the given address */
-void DefOutOfRangeLabels (void);
-/* Output any labels that are out of the loaded code range */
-
/* End of attrtab.h */
--- /dev/null
+/*****************************************************************************/
+/* */
+/* comments.c */
+/* */
+/* Comment management for da65 */
+/* */
+/* */
+/* */
+/* (C) 2006 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+/* common */
+#include "xmalloc.h"
+
+/* da65 */
+#include "attrtab.h"
+#include "comments.h"
+#include "error.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Comment table */
+static const char* CommentTab[0x10000];
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+void SetComment (unsigned Addr, const char* Comment)
+/* Set a comment for the given address */
+{
+ /* Check the given address */
+ AddrCheck (Addr);
+
+ /* If we do already have a comment, warn and ignore the new one */
+ if (CommentTab[Addr]) {
+ Warning ("Duplicate comment for address $%04X", Addr);
+ } else {
+ CommentTab[Addr] = xstrdup (Comment);
+ }
+}
+
+
+
+const char* GetComment (unsigned Addr)
+/* Return the comment for an address */
+{
+ /* Check the given address */
+ AddrCheck (Addr);
+
+ /* Return the label if any */
+ return CommentTab[Addr];
+}
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* comments.h */
+/* */
+/* Comment management for da65 */
+/* */
+/* */
+/* */
+/* (C) 2006 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef COMMENTS_H
+#define COMMENTS_H
+
+
+
+#include "attrtab.h"
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+void SetComment (unsigned Addr, const char* Comment);
+/* Set a comment for the given address */
+
+const char* GetComment (unsigned Addr);
+/* Return the comment for an address */
+
+
+
+/* End of comments.h */
+#endif
+
+
+
#include "code.h"
#include "error.h"
#include "global.h"
+#include "labels.h"
#include "output.h"
#include "data.h"
break;
}
- /* More than one byte left. Check if there is a label defined within
- * the address word.
- */
- if (MustDefLabel (PC+1)) {
- /* Define the label */
- DefineConst (GetLabel (PC+1), GetComment (PC+1), PC+1);
- }
+ /* More than one byte left. Define a forward label if necessary */
+ ForwardLabel (1);
/* Now get the address from the PC */
Addr = GetCodeWord (PC);
AddIntLabel (Addr);
}
} else {
- const char* Label = GetLabel (Addr);
+ const char* Label = GetLabel (Addr, PC);
if (Label == 0) {
/* OOPS! Should not happen */
Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
break;
}
- /* More than one byte left. Check if there is a label defined within
- * the address word.
- */
- if (MustDefLabel (PC+1)) {
- /* Define the label */
- DefineConst (GetLabel (PC+1), GetComment (PC+1), PC+1);
- }
+ /* More than one byte left. Define a forward label if necessary */
+ ForwardLabel (1);
/* Now get the address from the PC */
Addr = (GetCodeWord (PC) + 1) & 0xFFFF;
AddIntLabel (Addr);
}
} else {
- const char* Label = GetLabel (Addr);
+ const char* Label = GetLabel (Addr, PC);
if (Label == 0) {
/* OOPS! Should not happen */
Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
#include "error.h"
#include "global.h"
#include "handler.h"
+#include "labels.h"
#include "opctable.h"
#include "output.h"
{
const char* Label = 0;
if (Flags & flUseLabel) {
- Label = GetLabel (Addr);
+ Label = GetLabel (Addr, PC);
}
if (Label) {
return Label;
/* Just add the label */
AddIntLabel (Addr);
} else {
+
+ /* THIS CODE IS A MESS AND WILL FAIL ON SEVERAL CONDITIONS! ### */
+
+
/* Search for the start of the range or the last non dependent
* label in the range.
*/
}
--LabelAddr;
LabelAttr = GetLabelAttr (LabelAddr);
- if ((LabelAttr & (atIntLabel|atExtLabel)) != 0 &&
- (LabelAttr & atDepLabel) == 0) {
+ if ((LabelAttr & (atIntLabel|atExtLabel)) != 0) {
/* The address has an internal or external label */
break;
}
if (Offs == 0) {
AddIntLabel (Addr);
} else {
- AddDepLabel (Addr, atIntLabel, GetLabel (LabelAddr), Offs);
+ AddDepLabel (Addr, atIntLabel, GetLabelName (LabelAddr), Offs);
}
}
}
/* da65 */
#include "asminc.h"
#include "attrtab.h"
+#include "comments.h"
#include "error.h"
#include "global.h"
#include "infofile.h"
+#include "labels.h"
#include "opctable.h"
#include "scanner.h"
/* Do we have a label? */
if (Attributes & tName) {
+
/* Define a label for the table */
- AddExtLabel (Start, Name, Comment);
+ AddExtLabel (Start, Name);
+
+ /* Set the comment if we have one */
+ if (Comment) {
+ SetComment (Start, Comment);
+ }
+
/* Delete name and comment */
xfree (Name);
xfree (Comment);
if (Value >= 0) {
InfoError ("Value already given");
}
- InfoAssureInt ();
+ InfoAssureInt ();
InfoRangeCheck (0, 0xFFFF);
Value = InfoIVal;
InfoNextTok ();
if (Name) {
InfoError ("Name already given");
}
- InfoAssureStr ();
- if (InfoSVal[0] == '\0') {
- InfoError ("Name may not be empty");
- }
+ InfoAssureStr ();
Name = xstrdup (InfoSVal);
InfoNextTok ();
break;
InfoError ("Size already given");
}
InfoAssureInt ();
- InfoRangeCheck (1, 0x10000);
+ InfoRangeCheck (1, 0x10000);
Size = InfoIVal;
InfoNextTok ();
- break;
+ break;
- }
+ }
- /* Directive is followed by a semicolon */
- InfoConsumeSemi ();
+ /* Directive is followed by a semicolon */
+ InfoConsumeSemi ();
}
/* Did we get the necessary data */
if (Name == 0) {
- InfoError ("Label name is missing");
+ InfoError ("Label name is missing");
+ }
+ if (Name[0] == '\0' && Size > 1) {
+ InfoError ("Unnamed labels must not have a size > 1");
}
if (Value < 0) {
InfoError ("Label value is missing");
}
/* Define the label(s) */
- AddExtLabelRange ((unsigned) Value, Name, Comment, Size);
+ if (Name[0] == '\0') {
+ /* Size has already beed checked */
+ AddUnnamedLabel (Value);
+ } else {
+ AddExtLabelRange ((unsigned) Value, Name, Size);
+ }
+
+ /* Define the comment */
+ if (Comment) {
+ SetComment (Value, Comment);
+ }
/* Delete the dynamically allocated memory for Name and Comment */
xfree (Name);
--- /dev/null
+/*****************************************************************************/
+/* */
+/* labels.c */
+/* */
+/* Label management for da65 */
+/* */
+/* */
+/* */
+/* (C) 2006 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#include <stdio.h>
+#include <string.h>
+
+/* common */
+#include "xmalloc.h"
+#include "xsprintf.h"
+
+/* da65 */
+#include "attrtab.h"
+#include "code.h"
+#include "comments.h"
+#include "error.h"
+#include "global.h"
+#include "labels.h"
+#include "output.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Symbol table */
+static const char* SymTab[0x10000];
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+static const char* MakeLabelName (unsigned Addr)
+/* Make the default label name from the given address and return it in a
+ * static buffer.
+ */
+{
+ static char LabelBuf [32];
+ xsprintf (LabelBuf, sizeof (LabelBuf), "L%04X", Addr);
+ return LabelBuf;
+}
+
+
+
+static void AddLabel (unsigned Addr, attr_t Attr, const char* Name)
+/* Add a label */
+{
+ /* Get an existing label attribute */
+ attr_t ExistingAttr = GetLabelAttr (Addr);
+
+ /* Must not have two symbols for one address */
+ if (ExistingAttr != atNoLabel) {
+ /* Allow redefinition if identical. Beware: Unnamed labels don't
+ * have a name (you guessed that, didn't you?).
+ */
+ if (ExistingAttr == Attr &&
+ ((Name == 0 && SymTab[Addr] == 0) || strcmp (SymTab[Addr], Name) == 0)) {
+ return;
+ }
+ Error ("Duplicate label for address $%04X: %s/%s", Addr, SymTab[Addr], Name);
+ }
+
+ /* Create a new label (xstrdup will return NULL if input NULL) */
+ SymTab[Addr] = xstrdup (Name);
+
+ /* Remember the attribute */
+ MarkAddr (Addr, Attr);
+}
+
+
+
+void AddIntLabel (unsigned Addr)
+/* Add an internal label using the address to generate the name. */
+{
+ AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
+}
+
+
+
+void AddExtLabel (unsigned Addr, const char* Name)
+/* Add an external label */
+{
+ AddLabel (Addr, atExtLabel, Name);
+}
+
+
+
+void AddUnnamedLabel (unsigned Addr)
+/* Add an unnamed label */
+{
+ AddLabel (Addr, atUnnamedLabel, 0);
+}
+
+
+
+void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs)
+/* Add a dependent label at the given address using "basename+Offs" as the new
+ * name.
+ */
+{
+ /* Allocate memory for the dependent label name */
+ unsigned NameLen = strlen (BaseName);
+ char* DepName = xmalloc (NameLen + 7); /* "+$ABCD\0" */
+
+ /* Create the new name in the buffer */
+ if (UseHexOffs) {
+ sprintf (DepName, "%s+$%02X", BaseName, Offs);
+ } else {
+ sprintf (DepName, "%s+%u", BaseName, Offs);
+ }
+
+ /* Define the labels */
+ AddLabel (Addr, Attr | atDepLabel, DepName);
+
+ /* Free the name buffer */
+ xfree (DepName);
+}
+
+
+
+static void AddLabelRange (unsigned Addr, attr_t Attr,
+ const char* Name, unsigned Count)
+/* Add a label for a range. The first entry gets the label "Name" while the
+ * others get "Name+offs".
+ */
+{
+ /* Define the label */
+ AddLabel (Addr, Attr, Name);
+
+ /* Define dependent labels if necessary */
+ if (Count > 1) {
+ unsigned Offs;
+
+ /* Setup the format string */
+ const char* Format = UseHexOffs? "$%02X" : "%u";
+
+ /* Allocate memory for the dependent label names */
+ unsigned NameLen = strlen (Name);
+ char* DepName = xmalloc (NameLen + 7); /* "+$ABCD" */
+ char* DepOffs = DepName + NameLen + 1;
+
+ /* Copy the original name into the buffer */
+ memcpy (DepName, Name, NameLen);
+ DepName[NameLen] = '+';
+
+ /* Define the labels */
+ for (Offs = 1; Offs < Count; ++Offs) {
+ sprintf (DepOffs, Format, Offs);
+ AddLabel (Addr + Offs, Attr | atDepLabel, DepName);
+ }
+
+ /* Free the name buffer */
+ xfree (DepName);
+ }
+}
+
+
+
+void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count)
+/* Add an internal label for a range. The first entry gets the label "Name"
+ * while the others get "Name+offs".
+ */
+{
+ /* Define the label range */
+ AddLabelRange (Addr, atIntLabel, Name, Count);
+}
+
+
+
+void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count)
+/* Add an external label for a range. The first entry gets the label "Name"
+ * while the others get "Name+offs".
+ */
+{
+ /* Define the label range */
+ AddLabelRange (Addr, atExtLabel, Name, Count);
+}
+
+
+
+int HaveLabel (unsigned Addr)
+/* Check if there is a label for the given address */
+{
+ /* Check for a label */
+ return (GetLabelAttr (Addr) != atNoLabel);
+}
+
+
+
+int MustDefLabel (unsigned Addr)
+/* Return true if we must define a label for this address, that is, if there
+ * is a label at this address, and it is an external or internal label.
+ */
+{
+ /* Get the label attribute */
+ attr_t A = GetLabelAttr (Addr);
+
+ /* Check for an internal, external, or unnamed label */
+ return (A == atExtLabel || A == atIntLabel || A == atUnnamedLabel);
+}
+
+
+
+const char* GetLabelName (unsigned Addr)
+/* Return the label name for an address */
+{
+ /* Get the label attribute */
+ attr_t A = GetLabelAttr (Addr);
+
+ /* Special case unnamed labels, because these don't have a named stored in
+ * the symbol table to save space.
+ */
+ if (A == atUnnamedLabel) {
+ return "";
+ } else {
+ /* Return the label if any */
+ return SymTab[Addr];
+ }
+}
+
+
+
+const char* GetLabel (unsigned Addr, unsigned RefFrom)
+/* Return the label name for an address, as it is used in a label reference.
+ * RefFrom is the address the label is referenced from. This is needed in case
+ * of unnamed labels, to determine the name.
+ */
+{
+ static const char* FwdLabels[] = {
+ ":+", ":++", ":+++", ":++++", ":+++++", ":++++++", ":+++++++",
+ ":++++++++", ":+++++++++", ":++++++++++"
+ };
+ static const char* BackLabels[] = {
+ ":-", ":--", ":---", ":----", ":-----", ":------", ":-------",
+ ":--------", ":---------", ":----------"
+ };
+
+ /* Get the label attribute */
+ attr_t A = GetLabelAttr (Addr);
+
+ /* Special case unnamed labels, because these don't have a named stored in
+ * the symbol table to save space.
+ */
+ if (A == atUnnamedLabel) {
+
+ unsigned Count = 0;
+
+ /* Search forward or backward depending in which direction the label
+ * is.
+ */
+ if (Addr <= RefFrom) {
+ /* Search backwards */
+ unsigned I = RefFrom;
+ while (Addr < I) {
+ --I;
+ A = GetLabelAttr (I);
+ if (A == atUnnamedLabel) {
+ ++Count;
+ if (Count >= sizeof (BackLabels) / sizeof (BackLabels[0])) {
+ Error ("Too many unnamed labels between label at "
+ "$%04X and reference at $%04X", Addr, RefFrom);
+ }
+ }
+ }
+
+ /* Return the label name */
+ return BackLabels[Count-1];
+
+ } else {
+ /* Search forwards */
+ unsigned I = RefFrom;
+ while (Addr > I) {
+ ++I;
+ A = GetLabelAttr (I);
+ if (A == atUnnamedLabel) {
+ ++Count;
+ if (Count >= sizeof (FwdLabels) / sizeof (FwdLabels[0])) {
+ Error ("Too many unnamed labels between label at "
+ "$%04X and reference at $%04X", Addr, RefFrom);
+ }
+ }
+ }
+
+ /* Return the label name */
+ return FwdLabels[Count-1];
+ }
+
+ } else {
+ /* Return the label if any */
+ return SymTab[Addr];
+ }
+}
+
+
+
+void ForwardLabel (unsigned Offs)
+/* If necessary, output a forward label, one that is within the next few
+ * bytes and is therefore output as "label = * + x".
+ */
+{
+ /* Calculate the actual address */
+ unsigned long Addr = PC + Offs;
+
+ /* Get the type of the label */
+ attr_t A = GetLabelAttr (Addr);
+
+ /* If there is no label, or just a dependent one, bail out */
+ if (A == atNoLabel || (A & atDepLabel) != 0) {
+ return;
+ }
+
+ /* An unnamed label cannot be output as a forward declaration, so this is
+ * an error.
+ */
+ if (A == atUnnamedLabel) {
+ Error ("Cannot define unnamed label at address $%04lX", Addr);
+ }
+
+ /* Output the label */
+ DefForward (GetLabelName (Addr), GetComment (Addr), Offs);
+}
+
+
+
+static void DefOutOfRangeLabel (unsigned long Addr)
+/* Define one label that is outside code range. */
+{
+ switch (GetLabelAttr (Addr)) {
+
+ case atIntLabel:
+ case atExtLabel:
+ DefineConst (SymTab[Addr], GetComment (Addr), Addr);
+ break;
+
+ case atUnnamedLabel:
+ Error ("Cannot define unnamed label at address $%04lX", Addr);
+ break;
+
+ default:
+ break;
+
+ }
+}
+
+
+
+void DefOutOfRangeLabels (void)
+/* Output any labels that are out of the loaded code range */
+{
+ unsigned long Addr;
+
+ SeparatorLine ();
+
+ /* Low range */
+ Addr = 0;
+ while (Addr < CodeStart) {
+ DefOutOfRangeLabel (Addr++);
+ }
+
+ /* Skip areas in code range */
+ while (Addr <= CodeEnd) {
+ if (GetStyleAttr (Addr) == atSkip) {
+ DefOutOfRangeLabel (Addr);
+ }
+ ++Addr;
+ }
+
+ /* High range */
+ while (Addr < 0x10000) {
+ DefOutOfRangeLabel (Addr++);
+ }
+
+ SeparatorLine ();
+}
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* labels.h */
+/* */
+/* Label management for da65 */
+/* */
+/* */
+/* */
+/* (C) 2006 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef LABELS_H
+#define LABELS_H
+
+
+
+#include "attrtab.h"
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+void AddIntLabel (unsigned Addr);
+/* Add an internal label using the address to generate the name. */
+
+void AddExtLabel (unsigned Addr, const char* Name);
+/* Add an external label */
+
+void AddUnnamedLabel (unsigned Addr);
+/* Add an unnamed label */
+
+void AddDepLabel (unsigned Addr, attr_t Attr, const char* BaseName, unsigned Offs);
+/* Add a dependent label at the given address using "base name+Offs" as the new
+ * name.
+ */
+
+void AddIntLabelRange (unsigned Addr, const char* Name, unsigned Count);
+/* Add an internal label for a range. The first entry gets the label "Name"
+ * while the others get "Name+offs".
+ */
+
+void AddExtLabelRange (unsigned Addr, const char* Name, unsigned Count);
+/* Add an external label for a range. The first entry gets the label "Name"
+ * while the others get "Name+offs".
+ */
+
+int HaveLabel (unsigned Addr);
+/* Check if there is a label for the given address */
+
+int MustDefLabel (unsigned Addr);
+/* Return true if we must define a label for this address, that is, if there
+ * is a label at this address, and it is an external or internal label.
+ */
+
+const char* GetLabelName (unsigned Addr);
+/* Return the label name for an address */
+
+const char* GetLabel (unsigned Addr, unsigned RefFrom);
+/* Return the label name for an address, as it is used in a label reference.
+ * RefFrom is the address the label is referenced from. This is needed in case
+ * of unnamed labels, to determine the name.
+ */
+
+void ForwardLabel (unsigned Offs);
+/* If necessary, output a forward label, one that is within the next few
+ * bytes and is therefore output as "label = * + x".
+ */
+
+void DefOutOfRangeLabels (void);
+/* Output any labels that are out of the loaded code range */
+
+
+
+/* End of labels.h */
+#endif
+
+
+
/* da65 */
#include "attrtab.h"
#include "code.h"
+#include "comments.h"
#include "data.h"
#include "error.h"
#include "global.h"
#include "infofile.h"
+#include "labels.h"
#include "opctable.h"
#include "output.h"
#include "scanner.h"
/* Print the disassembler version */
{
fprintf (stderr,
- "da65 V%u.%u.%u - (C) Copyright 2005 Ullrich von Bassewitz\n",
+ "da65 V%u.%u.%u - (C) Copyright 2000-2006, Ullrich von Bassewitz\n",
VER_MAJOR, VER_MINOR, VER_PATCH);
}
if (Comment) {
UserComment (Comment);
}
- DefLabel (GetLabel (PC));
+ DefLabel (GetLabelName (PC));
}
/* Check...
Style = atIllegal;
MarkAddr (PC, Style);
} else if (D->Flags & flIllegal) {
- Style = atIllegal;
+ Style = atIllegal;
MarkAddr (PC, Style);
} else {
unsigned I;
for (I = 1; I < D->Size; ++I) {
if (HaveLabel (PC+I)) {
- Style = atIllegal;
+ Style = atIllegal;
MarkAddr (PC, Style);
break;
}
* following insn, fall through to byte mode.
*/
if (D->Size <= RemainingBytes) {
+ /* Output labels within the next insn */
+ unsigned I;
+ for (I = 1; I < D->Size; ++I) {
+ ForwardLabel (I);
+ }
D->Handler (D);
PC += D->Size;
break;
OBJS = asminc.o \
attrtab.o \
code.o \
+ comments.o \
data.o \
error.o \
global.o \
handler.o \
infofile.o \
+ labels.o \
main.o \
opc6502.o \
opc65816.o \
OBJS = asminc.obj \
attrtab.obj \
code.obj \
+ comments.obj \
data.obj \
error.obj \
global.obj \
handler.obj \
infofile.obj \
+ labels.obj \
main.obj \
opc6502.obj \
opc65816.obj \
+void DefForward (const char* Name, const char* Comment, unsigned Offs)
+/* Define a label as "* + x", where x is the offset relative to the
+ * current PC.
+ */
+{
+ if (Pass == PassCount) {
+ Output ("%s", Name);
+ Indent (AIndent);
+ if (UseHexOffs) {
+ Output (":= * + $%04X", Offs);
+ } else {
+ Output (":= * + %u", Offs);
+ }
+ if (Comment) {
+ Indent (CIndent);
+ Output ("; %s", Comment);
+ }
+ LineFeed ();
+ }
+}
+
+
+
+void DefineConst (const char* Name, const char* Comment, unsigned Addr)
+/* Define an address constant */
+{
+ if (Pass == PassCount) {
+ Output ("%s", Name);
+ Indent (AIndent);
+ Output (":= $%04X", Addr);
+ if (Comment) {
+ Indent (CIndent);
+ Output ("; %s", Comment);
+ }
+ LineFeed ();
+ }
+}
+
+
+
void DataByteLine (unsigned ByteCount)
/* Output a line with bytes */
{
-void DefineConst (const char* Name, const char* Comment, unsigned Addr)
-/* Define an address constant */
-{
- if (Pass == PassCount) {
- Output ("%s", Name);
- Indent (AIndent);
- Output (":= $%04X", Addr);
- if (Comment) {
- Indent (CIndent);
- Output ("; %s", Comment);
- }
- LineFeed ();
- }
-}
-
-
-
void DefLabel (const char* Name);
/* Define a label with the given name */
+void DefForward (const char* Name, const char* Comment, unsigned Offs);
+/* Define a label as "* + x", where x is the offset relative to the
+ * current PC.
+ */
+
+void DefineConst (const char* Name, const char* Comment, unsigned Addr);
+/* Define an address constant */
+
void OneDataByte (void);
/* Output a .byte line with the current code byte */
void OutputSettings (void);
/* Output CPU and other settings */
-void DefineConst (const char* Name, const char* Comment, unsigned Addr);
-/* Define an address constant */
-
/* End of output.h */