예제 #1
0
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);
	    }
	}
    }
}
예제 #2
0
파일: data.c 프로젝트: bowlofstew/cc65
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;
}
예제 #3
0
파일: infofile.c 프로젝트: Aliandrana/cc65
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 ();
}