static void GenerateLabel (unsigned Flags, unsigned Addr) /* Generate a label in pass one if requested */ { /* 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 */ 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. */ 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) { /* 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) { AddIntLabel (LabelAddr); } /* Create the label */ Offs = Addr - LabelAddr; if (Offs == 0) { AddIntLabel (Addr); } else { AddDepLabel (Addr, atIntLabel, GetLabelName (LabelAddr), Offs); } } } }
unsigned RtsTable (void) /* Output a table of RTS addresses (address - 1) */ { unsigned long BytesLeft = GetRemainingBytes (); unsigned long Start = PC; /* Loop while table bytes left and we don't need to create a label at the ** current position. */ while (BytesLeft && GetStyleAttr (PC) == atRtsTab) { unsigned Addr; /* If just one byte is left, define it and bail out */ if (BytesLeft == 1 || GetStyleAttr (PC+1) != atRtsTab) { DataByteLine (1); ++PC; break; } /* 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; /* In pass 1, define a label, in pass 2 output the line */ if (Pass == 1) { if (!HaveLabel (Addr)) { AddIntLabel (Addr); } } else { const char* Label = GetLabel (Addr, PC); if (Label == 0) { /* OOPS! Should not happen */ Internal ("OOPS - Label for address 0x%06X disappeard!", Addr); } Indent (MCol); Output (".word"); Indent (ACol); Output ("%s-1", Label); LineComment (PC, 2); LineFeed (); } /* Next table entry */ PC += 2; BytesLeft -= 2; /* If we must define a label here, bail out */ if (BytesLeft && MustDefLabel (PC)) { break; } } /* If the next line is not a return address table line, add a separator */ if (CodeLeft() && GetStyleAttr (PC) != atRtsTab) { SeparatorLine (); } /* Return the number of bytes output */ return PC - Start; }
static void LabelSection (void) /* Parse a label section */ { static const IdentTok LabelDefs[] = { { "COMMENT", INFOTOK_COMMENT }, { "ADDR", INFOTOK_ADDR }, { "NAME", INFOTOK_NAME }, { "SIZE", INFOTOK_SIZE }, }; /* Locals - initialize to avoid gcc warnings */ char* Name = 0; char* Comment = 0; long Value = -1; long Size = -1; /* Skip the token */ InfoNextTok (); /* Expect the opening curly brace */ InfoConsumeLCurly (); /* Look for section tokens */ while (InfoTok != INFOTOK_RCURLY) { /* Convert to special token */ InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label attribute"); /* Look at the token */ switch (InfoTok) { case INFOTOK_ADDR: InfoNextTok (); if (Value >= 0) { InfoError ("Value already given"); } InfoAssureInt (); InfoRangeCheck (0, 0xFFFF); Value = InfoIVal; InfoNextTok (); break; case INFOTOK_COMMENT: InfoNextTok (); if (Comment) { InfoError ("Comment already given"); } InfoAssureStr (); if (InfoSVal[0] == '\0') { InfoError ("Comment may not be empty"); } Comment = xstrdup (InfoSVal); InfoNextTok (); break; case INFOTOK_NAME: InfoNextTok (); if (Name) { InfoError ("Name already given"); } InfoAssureStr (); Name = xstrdup (InfoSVal); InfoNextTok (); break; case INFOTOK_SIZE: InfoNextTok (); if (Size >= 0) { InfoError ("Size already given"); } InfoAssureInt (); InfoRangeCheck (1, 0x10000); Size = InfoIVal; InfoNextTok (); break; default: Internal ("Unexpected token: %u", InfoTok); } /* Directive is followed by a semicolon */ InfoConsumeSemi (); } /* Did we get the necessary data */ if (Name == 0) { 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"); } if (Size < 0) { /* Use default */ Size = 1; } if (Value + Size > 0x10000) { InfoError ("Invalid size (address out of range)"); } if (HaveLabel ((unsigned) Value)) { InfoError ("Label for address $%04lX already defined", Value); } /* Define the label(s) */ 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); xfree (Comment); /* Consume the closing brace */ InfoConsumeRCurly (); }