+unsigned GetGranularity (attr_t Style)
+/* Get the granularity for the given style */
+{
+ switch (Style) {
+ case atDefault: return 1;
+ case atCode: return 1;
+ case atIllegal: return 1;
+ case atByteTab: return 1;
+ case atDByteTab: return 2;
+ case atWordTab: return 2;
+ case atDWordTab: return 4;
+ case atAddrTab: return 2;
+ case atRtsTab: return 2;
+ case atTextTab: return 1;
+
+ case atSkip:
+ default:
+ Internal ("GetGraularity called for style = %d", Style);
+ return 0;
+ }
+}
+
+
+
void MarkRange (unsigned Start, unsigned End, attr_t Attr)
/* Mark a range with the given attribute */
{
/* Must not have two symbols for one address */
if (ExistingAttr != atNoLabel) {
- /* Allow redefinition if identical */
+ /* Allow redefinition if identical */
if (ExistingAttr == Attr && strcmp (SymTab[Addr], Name) == 0) {
- return;
- }
- Error ("Duplicate label for address %04X: %s/%s", Addr, SymTab[Addr], Name);
+ return;
+ }
+ Error ("Duplicate label for address $%04X: %s/%s", Addr, SymTab[Addr], Name);
}
/* Create a new label */
-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".
+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);
+
+ /* 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, atExtLabel, Name);
+ AddLabel (Addr, Attr, Name);
/* Define dependent labels if necessary */
if (Count > 1) {
- unsigned Offs;
+ 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);
- char* DepOffs = DepName + NameLen + 1;
+ /* 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] = '+';
+ /* 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, atDepLabel, DepName);
- }
+ /* 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);
+ /* 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 */
{
while (Addr < CodeStart) {
if (MustDefLabel (Addr)) {
DefineConst (Addr);
- }
+ }
++Addr;
}
/* */
/* */
/* */
-/* (C) 2000-2003 Ullrich von Bassewitz */
+/* (C) 2000-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
atNoLabel = 0x00, /* No label for this address */
atExtLabel = 0x10, /* External label */
atIntLabel = 0x20, /* Internally generated label */
- atDepLabel = 0x30, /* Dependent label (always extern) */
+ atDepLabel = 0x40, /* Dependent label */
atStyleMask = 0x0F, /* Output style */
- atLabelMask = 0x30 /* Label information */
+ atLabelMask = 0x70 /* Label information */
} attr_t;
+unsigned GetGranularity (attr_t Style);
+/* Get the granularity for the given style */
+
void MarkRange (unsigned Start, unsigned End, attr_t Attr);
/* Mark a range with the given attribute */
void AddLabel (unsigned Addr, attr_t Attr, const char* Name);
/* Add a 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".
/* */
/* */
/* */
-/* (C) 2000-2003 Ullrich von Bassewitz */
+/* (C) 2000-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
const char* Label = GetLabel (Addr);
if (Label == 0) {
/* OOPS! Should not happen */
- Internal ("OOPS - Label for address %04X disappeard!", Addr);
+ Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
}
Indent (MIndent);
Output (".addr");
const char* Label = GetLabel (Addr);
if (Label == 0) {
/* OOPS! Should not happen */
- Internal ("OOPS - Label for address %04X disappeard!", Addr);
+ Internal ("OOPS - Label for address 0x%06X disappeard!", Addr);
}
Indent (MIndent);
Output (".word");
/* */
/* */
/* */
-/* (C) 2000-2003 Ullrich von Bassewitz */
+/* (C) 2000-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
static void GenerateLabel (unsigned Flags, unsigned Addr)
/* Generate a label in pass one if requested */
{
- if (Pass == 1 && !HaveLabel (Addr)) {
- if ((Flags & flGenLabel) != 0 ||
- ((Flags & flUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd)) {
+ /* Generate labels in pass #1, and only if we don't have a label already */
+ if (Pass == 1 && !HaveLabel (Addr) &&
+ /* Check if we must create a label */
+ ((Flags & flGenLabel) != 0 ||
+ ((Flags & flUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd))) {
+
+ /* As a special case, handle ranges with tables or similar. Within
+ * such a range with a granularity > 1, do only generate dependent
+ * labels for all addresses but the first one. Be sure to generate
+ * a label for the start of the range, however.
+ */
+ attr_t Style = GetStyleAttr (Addr);
+ unsigned Granularity = GetGranularity (Style);
+
+ if (Granularity == 1) {
+ /* Just add the label */
AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
+ } else {
+ /* Search for the start of the range or the last non dependent
+ * label in the range.
+ */
+ unsigned Offs;
+ attr_t LabelAttr;
+ unsigned LabelAddr = Addr;
+ while (LabelAddr > CodeStart) {
+
+ if (Style != GetStyleAttr (LabelAddr-1)) {
+ /* End of range reached */
+ break;
+ }
+ --LabelAddr;
+ LabelAttr = GetLabelAttr (LabelAddr);
+ if ((LabelAttr & (atIntLabel|atExtLabel)) != 0 &&
+ (LabelAttr & atDepLabel) == 0) {
+ /* The address has an internal or external label */
+ break;
+ }
+ }
+
+ /* If the proposed label address doesn't have a label, define one */
+ if ((GetLabelAttr (LabelAddr) & (atIntLabel|atExtLabel)) == 0) {
+ AddLabel (LabelAddr, atIntLabel, MakeLabelName (LabelAddr));
+ }
+
+ /* Create the label */
+ Offs = Addr - LabelAddr;
+ if (Offs == 0) {
+ AddLabel (Addr, atIntLabel, MakeLabelName (Addr));
+ } else {
+ AddDepLabel (Addr, atIntLabel, GetLabel (LabelAddr), Offs);
+ }
}
}
}
/* */
/* */
/* */
-/* (C) 2000-2003 Ullrich von Bassewitz */
+/* (C) 2000-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
unsigned End = 0;
unsigned char Type = 0;
char* Name = 0;
+ unsigned MemberSize = 0;
+
/* Skip the token */
InfoNextTok ();
InfoNextTok ();
InfoSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "TYPE");
switch (InfoTok) {
- case INFOTOK_ADDRTAB: Type = atAddrTab; break;
- case INFOTOK_BYTETAB: Type = atByteTab; break;
- case INFOTOK_CODE: Type = atCode; break;
- case INFOTOK_DBYTETAB: Type = atDByteTab; break;
- case INFOTOK_DWORDTAB: Type = atDWordTab; break;
- case INFOTOK_RTSTAB: Type = atRtsTab; break;
- case INFOTOK_SKIP: Type = atSkip; break;
- case INFOTOK_TEXTTAB: Type = atTextTab; break;
- case INFOTOK_WORDTAB: Type = atWordTab; break;
+ case INFOTOK_ADDRTAB: Type = atAddrTab; MemberSize = 2; break;
+ case INFOTOK_BYTETAB: Type = atByteTab; MemberSize = 1; break;
+ case INFOTOK_CODE: Type = atCode; MemberSize = 1; break;
+ case INFOTOK_DBYTETAB: Type = atDByteTab; MemberSize = 2; break;
+ case INFOTOK_DWORDTAB: Type = atDWordTab; MemberSize = 4; break;
+ case INFOTOK_RTSTAB: Type = atRtsTab; MemberSize = 2; break;
+ case INFOTOK_SKIP: Type = atSkip; MemberSize = 1; break;
+ case INFOTOK_TEXTTAB: Type = atTextTab; MemberSize = 1; break;
+ case INFOTOK_WORDTAB: Type = atWordTab; MemberSize = 2; break;
}
InfoNextTok ();
break;
InfoError ("Start value must not be greater than end value");
}
+ /* Check the granularity */
+ if (((End - Start + 1) % MemberSize) != 0) {
+ InfoError ("Type of range needs a granularity of %u", MemberSize);
+ }
+
/* Set the range */
MarkRange (Start, End, Type);