From d31f72d057f5867299126cddbfb458c16607113b Mon Sep 17 00:00:00 2001 From: cuz Date: Sun, 29 Jan 2006 19:00:22 +0000 Subject: [PATCH] Restructured some of the code. Attribute handling is still a mess and needs another cleanup. Added unnamed labels. git-svn-id: svn://svn.cc65.org/cc65/trunk@3700 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/da65/asminc.c | 8 +- src/da65/attrtab.c | 292 +-------------------------- src/da65/attrtab.h | 95 +++------ src/da65/comments.c | 90 +++++++++ src/da65/comments.h | 63 ++++++ src/da65/data.c | 23 +-- src/da65/handler.c | 12 +- src/da65/infofile.c | 45 +++-- src/da65/labels.c | 415 +++++++++++++++++++++++++++++++++++++++ src/da65/labels.h | 106 ++++++++++ src/da65/main.c | 15 +- src/da65/make/gcc.mak | 2 + src/da65/make/watcom.mak | 2 + src/da65/output.c | 57 ++++-- src/da65/output.h | 11 +- 15 files changed, 825 insertions(+), 411 deletions(-) create mode 100644 src/da65/comments.c create mode 100644 src/da65/comments.h create mode 100644 src/da65/labels.c create mode 100644 src/da65/labels.h diff --git a/src/da65/asminc.c b/src/da65/asminc.c index 4708a42e3..028aa03f9 100644 --- a/src/da65/asminc.c +++ b/src/da65/asminc.c @@ -42,8 +42,9 @@ /* da65 */ #include "asminc.h" -#include "attrtab.h" +#include "comments.h" #include "error.h" +#include "labels.h" @@ -220,8 +221,9 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown) /* 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); } diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c index 90233e2bb..073834ad9 100644 --- a/src/da65/attrtab.c +++ b/src/da65/attrtab.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000-2005 Ullrich von Bassewitz */ +/* (C) 2000-2006 Ullrich von Bassewitz */ /* Römerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -33,75 +33,20 @@ -#include -#include - -/* 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]; @@ -111,7 +56,7 @@ Label* NewLabel (const char* Name, const char* Comment) -static void AddrCheck (unsigned Addr) +void AddrCheck (unsigned Addr) /* Check if the given address has a valid range */ { if (Addr >= 0x10000) { @@ -175,195 +120,7 @@ void MarkAddr (unsigned Addr, attr_t Attr) -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 */ @@ -375,7 +132,7 @@ unsigned char GetStyleAttr (unsigned Addr) -unsigned char GetLabelAttr (unsigned Addr) +attr_t GetLabelAttr (unsigned Addr) /* Return the label attribute for the given address */ { /* Check the given address */ @@ -387,40 +144,3 @@ unsigned char GetLabelAttr (unsigned Addr) -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 (); -} - - - diff --git a/src/da65/attrtab.h b/src/da65/attrtab.h index 42b41a32d..2abe26576 100644 --- a/src/da65/attrtab.h +++ b/src/da65/attrtab.h @@ -1,12 +1,12 @@ /*****************************************************************************/ /* */ -/* 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 */ @@ -39,7 +39,7 @@ /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ @@ -47,36 +47,42 @@ 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 */ @@ -86,53 +92,12 @@ void MarkRange (unsigned Start, unsigned End, attr_t Attr); 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 */ diff --git a/src/da65/comments.c b/src/da65/comments.c new file mode 100644 index 000000000..3cad907e1 --- /dev/null +++ b/src/da65/comments.c @@ -0,0 +1,90 @@ +/*****************************************************************************/ +/* */ +/* 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]; +} + + + diff --git a/src/da65/comments.h b/src/da65/comments.h new file mode 100644 index 000000000..7bc2c1c4c --- /dev/null +++ b/src/da65/comments.h @@ -0,0 +1,63 @@ +/*****************************************************************************/ +/* */ +/* 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 + + + diff --git a/src/da65/data.c b/src/da65/data.c index 540231b96..9a7ffc5b4 100644 --- a/src/da65/data.c +++ b/src/da65/data.c @@ -38,6 +38,7 @@ #include "code.h" #include "error.h" #include "global.h" +#include "labels.h" #include "output.h" #include "data.h" @@ -174,13 +175,8 @@ unsigned AddrTable (void) 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); @@ -191,7 +187,7 @@ unsigned AddrTable (void) 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); @@ -244,13 +240,8 @@ unsigned RtsTable (void) 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; @@ -261,7 +252,7 @@ unsigned RtsTable (void) 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); diff --git a/src/da65/handler.c b/src/da65/handler.c index 071913c96..7ae97f7f7 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -44,6 +44,7 @@ #include "error.h" #include "global.h" #include "handler.h" +#include "labels.h" #include "opctable.h" #include "output.h" @@ -109,7 +110,7 @@ static const char* GetAddrArg (unsigned Flags, unsigned Addr) { const char* Label = 0; if (Flags & flUseLabel) { - Label = GetLabel (Addr); + Label = GetLabel (Addr, PC); } if (Label) { return Label; @@ -147,6 +148,10 @@ static void GenerateLabel (unsigned Flags, unsigned Addr) /* 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. */ @@ -161,8 +166,7 @@ static void GenerateLabel (unsigned Flags, unsigned Addr) } --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; } @@ -178,7 +182,7 @@ static void GenerateLabel (unsigned Flags, unsigned Addr) if (Offs == 0) { AddIntLabel (Addr); } else { - AddDepLabel (Addr, atIntLabel, GetLabel (LabelAddr), Offs); + AddDepLabel (Addr, atIntLabel, GetLabelName (LabelAddr), Offs); } } } diff --git a/src/da65/infofile.c b/src/da65/infofile.c index fff0feb6e..b52d9c5d3 100644 --- a/src/da65/infofile.c +++ b/src/da65/infofile.c @@ -51,9 +51,11 @@ /* 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" @@ -357,8 +359,15 @@ static void RangeSection (void) /* 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); @@ -406,7 +415,7 @@ static void LabelSection (void) if (Value >= 0) { InfoError ("Value already given"); } - InfoAssureInt (); + InfoAssureInt (); InfoRangeCheck (0, 0xFFFF); Value = InfoIVal; InfoNextTok (); @@ -430,10 +439,7 @@ static void LabelSection (void) if (Name) { InfoError ("Name already given"); } - InfoAssureStr (); - if (InfoSVal[0] == '\0') { - InfoError ("Name may not be empty"); - } + InfoAssureStr (); Name = xstrdup (InfoSVal); InfoNextTok (); break; @@ -444,20 +450,23 @@ static void LabelSection (void) 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"); @@ -474,7 +483,17 @@ static void LabelSection (void) } /* 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); diff --git a/src/da65/labels.c b/src/da65/labels.c new file mode 100644 index 000000000..ff401e7ae --- /dev/null +++ b/src/da65/labels.c @@ -0,0 +1,415 @@ +/*****************************************************************************/ +/* */ +/* 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 +#include + +/* 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 (); +} + + + diff --git a/src/da65/labels.h b/src/da65/labels.h new file mode 100644 index 000000000..53d46c6c8 --- /dev/null +++ b/src/da65/labels.h @@ -0,0 +1,106 @@ +/*****************************************************************************/ +/* */ +/* 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 + + + diff --git a/src/da65/main.c b/src/da65/main.c index ed4471e8c..34b48f4bb 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -51,10 +51,12 @@ /* 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" @@ -252,7 +254,7 @@ static void OptVersion (const char* Opt attribute ((unused)), /* 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); } @@ -278,7 +280,7 @@ static void OneOpcode (unsigned RemainingBytes) if (Comment) { UserComment (Comment); } - DefLabel (GetLabel (PC)); + DefLabel (GetLabelName (PC)); } /* Check... @@ -292,13 +294,13 @@ static void OneOpcode (unsigned RemainingBytes) 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; } @@ -319,6 +321,11 @@ static void OneOpcode (unsigned RemainingBytes) * 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; diff --git a/src/da65/make/gcc.mak b/src/da65/make/gcc.mak index fe3db010c..19cb66818 100644 --- a/src/da65/make/gcc.mak +++ b/src/da65/make/gcc.mak @@ -13,11 +13,13 @@ LDFLAGS= 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 \ diff --git a/src/da65/make/watcom.mak b/src/da65/make/watcom.mak index a6e83b91d..ce2e0c3b5 100644 --- a/src/da65/make/watcom.mak +++ b/src/da65/make/watcom.mak @@ -63,11 +63,13 @@ endif 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 \ diff --git a/src/da65/output.c b/src/da65/output.c index 90b778d13..864114040 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -176,6 +176,46 @@ void DefLabel (const char* 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. + */ +{ + 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 */ { @@ -322,20 +362,3 @@ void OutputSettings (void) -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 (); - } -} - - - diff --git a/src/da65/output.h b/src/da65/output.h index 568a1b0af..8aba0ff87 100644 --- a/src/da65/output.h +++ b/src/da65/output.h @@ -67,6 +67,14 @@ void LineFeed (void); 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 */ @@ -94,9 +102,6 @@ void LineComment (unsigned PC, unsigned Count); 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 */ -- 2.39.5