From 97f96823078d73da17d43aebd01151db0ffe8822 Mon Sep 17 00:00:00 2001 From: cuz Date: Fri, 29 Sep 2000 12:26:34 +0000 Subject: [PATCH] Added labels, SIEZ attribute for labels, dependent labels etc. git-svn-id: svn://svn.cc65.org/cc65/trunk@343 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/da65/attrtab.c | 47 +++++++++++++++---- src/da65/attrtab.h | 29 +++++++++--- src/da65/config.c | 112 ++++++++++++++++++++++++++++++++++++++++---- src/da65/data.c | 80 ++++++++++++++++++++++++++++--- src/da65/data.h | 3 ++ src/da65/handler.c | 10 +++- src/da65/handler.h | 1 + src/da65/main.c | 13 +++-- src/da65/opctable.c | 4 +- src/da65/output.c | 16 +++---- src/da65/scanner.h | 4 +- 11 files changed, 272 insertions(+), 47 deletions(-) diff --git a/src/da65/attrtab.c b/src/da65/attrtab.c index 20204b63b..baa78bbb3 100644 --- a/src/da65/attrtab.c +++ b/src/da65/attrtab.c @@ -121,16 +121,16 @@ const char* MakeLabelName (unsigned Addr) -void AddLabel (unsigned Addr, const char* Name) +void AddLabel (unsigned Addr, attr_t Attr, const char* Name) /* Add a label */ { - /* Check the given address */ - AddrCheck (Addr); + /* Get an existing label attribute */ + attr_t ExistingAttr = GetLabelAttr (Addr); /* Must not have two symbols for one address */ - if (SymTab[Addr] != 0) { - if (strcmp (SymTab[Addr], Name) == 0) { - /* Allow label if it has the same name */ + if (ExistingAttr != atNoLabel) { + /* 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); @@ -138,6 +138,9 @@ void AddLabel (unsigned Addr, const char* Name) /* Create a new label */ SymTab[Addr] = xstrdup (Name); + + /* Remember the attribute */ + AttrTab[Addr] |= Attr; } @@ -154,6 +157,20 @@ int HaveLabel (unsigned Addr) +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 */ { @@ -166,7 +183,7 @@ const char* GetLabel (unsigned Addr) -unsigned char GetStyle (unsigned Addr) +unsigned char GetStyleAttr (unsigned Addr) /* Return the style attribute for the given address */ { /* Check the given address */ @@ -178,6 +195,18 @@ unsigned char GetStyle (unsigned Addr) +unsigned char GetLabelAttr (unsigned Addr) +/* Return the label attribute for the given address */ +{ + /* Check the given address */ + AddrCheck (Addr); + + /* Return the attribute */ + return (AttrTab[Addr] & atLabelMask); +} + + + static void DefineConst (unsigned Addr) /* Define an address constant */ { @@ -198,14 +227,14 @@ void DefOutOfRangeLabels (void) /* Low range */ for (Addr = 0; Addr < CodeStart; ++Addr) { - if (SymTab [Addr]) { + if (MustDefLabel (Addr)) { DefineConst (Addr); } } /* High range */ for (Addr = CodeEnd+1; Addr < 0x10000; ++Addr) { - if (SymTab [Addr]) { + if (MustDefLabel (Addr)) { DefineConst (Addr); } } diff --git a/src/da65/attrtab.h b/src/da65/attrtab.h index 09f71c13f..2bcae016d 100644 --- a/src/da65/attrtab.h +++ b/src/da65/attrtab.h @@ -39,13 +39,15 @@ /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ typedef enum attr_t attr_t; enum attr_t { + + /* Styles */ atDefault = 0x00, /* Default style */ atCode = 0x01, atIllegal = 0x02, @@ -55,13 +57,20 @@ enum attr_t { atAddrTab = 0x06, atRtsTab = 0x07, - atStyleMask = 0x0F /* Output style */ + /* Label flags */ + atNoLabel = 0x00, /* No label for this address */ + atExtLabel = 0x10, /* External label */ + atIntLabel = 0x20, /* Internally generated label */ + atDepLabel = 0x30, /* Dependent label (always extern) */ + + atStyleMask = 0x0F, /* Output style */ + atLabelMask = 0x30 /* Label information */ }; /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -77,18 +86,26 @@ const char* MakeLabelName (unsigned Addr); * static buffer. */ -void AddLabel (unsigned Addr, const char* Name); +void AddLabel (unsigned Addr, attr_t Attr, const char* Name); /* Add a label */ 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 */ +/* Return the label for an address or NULL if there is none */ -unsigned char GetStyle (unsigned Addr); +unsigned char GetStyleAttr (unsigned Addr); /* Return the style attribute for the given address */ +unsigned char 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 */ diff --git a/src/da65/config.c b/src/da65/config.c index 1ed1b2141..eaa64612c 100644 --- a/src/da65/config.c +++ b/src/da65/config.c @@ -33,6 +33,7 @@ +#include #if defined(_MSC_VER) /* Microsoft compiler */ # include @@ -200,7 +201,7 @@ static void RangeSection (void) case CFGTOK_WORDTAB: Type = atWordTab; break; case CFGTOK_DWORDTAB: Type = atDWordTab; break; case CFGTOK_ADDRTAB: Type = atAddrTab; break; - case CFGTOK_RTSTAB: Type = atRtsTab; break; + case CFGTOK_RTSTAB: Type = atRtsTab; break; } Needed |= tType; CfgNextTok (); @@ -214,12 +215,12 @@ static void RangeSection (void) /* Did we get all required values? */ if (Needed != tAll) { - Error ("Required values missing from this section"); + CfgError ("Required values missing from this section"); } /* Start must be less than end */ if (Start > End) { - Error ("Start value must not be greater than end value"); + CfgError ("Start value must not be greater than end value"); } /* Set the range */ @@ -234,12 +235,17 @@ static void RangeSection (void) static void LabelSection (void) /* Parse a label section */ { - static const IdentTok Globals[] = { - { "INPUTNAMEL", CFGTOK_INPUTNAME }, - { "OUTPUTNAME", CFGTOK_OUTPUTNAME }, - { "PAGELENGTH", CFGTOK_PAGELENGTH }, + static const IdentTok LabelDefs[] = { + { "NAME", CFGTOK_NAME }, + { "ADDR", CFGTOK_ADDR }, + { "SIZE", CFGTOK_SIZE }, }; + /* Locals - initialize to avoid gcc warnings */ + char* Name = 0; + long Value = -1; + long Size = -1; + /* Skip the token */ CfgNextTok (); @@ -249,8 +255,96 @@ static void LabelSection (void) /* Look for section tokens */ while (CfgTok != CFGTOK_RCURLY) { + /* Convert to special token */ + CfgSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label directive"); + + /* Look at the token */ + switch (CfgTok) { + + case CFGTOK_NAME: + CfgNextTok (); + if (Name) { + CfgError ("Name already given"); + } + CfgAssureStr (); + if (CfgSVal[0] == '\0') { + CfgError ("Name may not be empty"); + } + Name = xstrdup (CfgSVal); + CfgNextTok (); + break; + + case CFGTOK_ADDR: + CfgNextTok (); + if (Value >= 0) { + CfgError ("Value already given"); + } + CfgAssureInt (); + CfgRangeCheck (0, 0xFFFF); + Value = CfgIVal; + CfgNextTok (); + break; + + case CFGTOK_SIZE: + CfgNextTok (); + if (Size >= 0) { + CfgError ("Size already given"); + } + CfgAssureInt (); + CfgRangeCheck (1, 0x800); + Size = CfgIVal; + CfgNextTok (); + break; + + } + + /* Directive is followed by a semicolon */ + CfgConsumeSemi (); + } + /* Did we get the necessary data */ + if (Name == 0) { + CfgError ("Label name is missing"); + } + if (Value < 0) { + CfgError ("Label value is missing"); } + if (Size < 0) { + /* Use default */ + Size = 1; + } + if (HaveLabel ((unsigned) Value)) { + CfgError ("Label for address $%04lX already defined", Value); + } + + /* Define the label */ + AddLabel ((unsigned) Value, atExtLabel, Name); + + /* Define dependent labels if necessary */ + if (Size > 1) { + unsigned Offs; + + /* Allocate memory for the dependent label names */ + unsigned NameLen = strlen (Name); + char* DepName = xmalloc (NameLen + 7); + 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 < (unsigned) Size; ++Offs) { + sprintf (DepOffs, "%u", Offs); + AddLabel ((unsigned) Value+Offs, atDepLabel, DepName); + } + + /* Free the name buffer */ + xfree (DepName); + } + + /* Delete the dynamically allocated memory for Name */ + xfree (Name); /* Consume the closing brace */ CfgConsumeRCurly (); @@ -262,8 +356,8 @@ static void CfgParse (void) /* Parse the config file */ { static const IdentTok Globals[] = { - { "GLOBAL", CFGTOK_GLOBAL }, - { "RANGE", CFGTOK_RANGE }, + { "GLOBAL", CFGTOK_GLOBAL }, + { "RANGE", CFGTOK_RANGE }, { "LABEL", CFGTOK_LABEL }, }; diff --git a/src/da65/data.c b/src/da65/data.c index 456755fda..ec8a64204 100644 --- a/src/da65/data.c +++ b/src/da65/data.c @@ -61,7 +61,7 @@ static unsigned GetSpan (attr_t Style) */ unsigned Count = 1; while (Count < RemainingBytes) { - if (HaveLabel(PC+Count) || GetStyle (PC+Count) != Style) { + if (MustDefLabel(PC+Count) || GetStyleAttr (PC+Count) != Style) { break; } ++Count; @@ -81,6 +81,15 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u /* Count how many bytes may be output. */ unsigned Count = GetSpan (Style); + /* If the count is less than the member size, print a row of Count data + * bytes. We assume here that there is no member with a size that is less + * than BytesPerLine. + */ + if (Count < MemberSize) { + DataByteLine (Count); + return Count; + } + /* Make Count an even number of multiples of MemberSize */ Count &= ~(MemberSize-1); @@ -100,7 +109,7 @@ static unsigned DoTable (attr_t Style, unsigned MemberSize, void (*TableFunc) (u } /* If the next line is not the same style, add a separator */ - if (CodeLeft() && GetStyle (PC) != Style) { + if (CodeLeft() && GetStyleAttr (PC) != Style) { SeparatorLine (); } @@ -145,12 +154,14 @@ unsigned AddrTable (void) /* Count how many bytes may be output. */ unsigned Count = GetSpan (atAddrTab); + /* Need to handle Count == 1 here!!! ### */ + /* Make the given number even */ Count &= ~1U; /* Output as many data bytes lines as needed. For addresses, each line * will hold just one address. - */ + */ BytesLeft = Count; while (BytesLeft > 0) { @@ -160,7 +171,7 @@ unsigned AddrTable (void) /* In pass 1, define a label, in pass 2 output the line */ if (Pass == 1) { if (!HaveLabel (Addr)) { - AddLabel (Addr, MakeLabelName (Addr)); + AddLabel (Addr, atIntLabel, MakeLabelName (Addr)); } } else { const char* Label = GetLabel (Addr); @@ -182,9 +193,66 @@ unsigned AddrTable (void) } /* If the next line is not a byte table line, add a separator */ - if (CodeLeft() && GetStyle (PC) != atAddrTab) { + if (CodeLeft() && GetStyleAttr (PC) != atAddrTab) { SeparatorLine (); - } + } + + /* Return the number of bytes output */ + return Count; +} + + + +unsigned RtsTable (void) +/* Output a table of RTS addresses (address - 1) */ +{ + unsigned BytesLeft; + + /* Count how many bytes may be output. */ + unsigned Count = GetSpan (atRtsTab); + + /* Need to handle Count == 1 here!!! ### */ + + /* Make the given number even */ + Count &= ~1U; + + /* Output as many data bytes lines as needed. For addresses, each line + * will hold just one address. + */ + BytesLeft = Count; + while (BytesLeft > 0) { + + /* Get the address */ + unsigned Addr = GetCodeWord (PC) + 1; + + /* In pass 1, define a label, in pass 2 output the line */ + if (Pass == 1) { + if (!HaveLabel (Addr)) { + AddLabel (Addr, atIntLabel, MakeLabelName (Addr)); + } + } else { + const char* Label = GetLabel (Addr); + if (Label == 0) { + /* OOPS! Should not happen */ + Internal ("OOPS - Label for address %04X disappeard!", Addr); + } + Indent (MIndent); + Output (".word"); + Indent (AIndent); + Output ("%s-1", Label); + LineComment (PC, 2); + LineFeed (); + } + + /* Next line */ + PC += 2; + BytesLeft -= 2; + } + + /* If the next line is not a byte table line, add a separator */ + if (CodeLeft() && GetStyleAttr (PC) != atRtsTab) { + SeparatorLine (); + } /* Return the number of bytes output */ return Count; diff --git a/src/da65/data.h b/src/da65/data.h index 091efeb86..0594f8bbb 100644 --- a/src/da65/data.h +++ b/src/da65/data.h @@ -56,6 +56,9 @@ unsigned DWordTable (void); unsigned AddrTable (void); /* Output a table of addresses */ +unsigned RtsTable (void); +/* Output a table of RTS addresses (address - 1) */ + /* End of data.h */ diff --git a/src/da65/handler.c b/src/da65/handler.c index 64bf6ed53..e041d69e6 100644 --- a/src/da65/handler.c +++ b/src/da65/handler.c @@ -118,7 +118,7 @@ static void GenerateLabel (const OpcDesc* D, unsigned Addr) if (Pass == 1 && !HaveLabel (Addr)) { if ((D->LabelFlag & lfGenLabel) != 0 || ((D->LabelFlag & lfUseLabel) != 0 && Addr >= CodeStart && Addr <= CodeEnd)) { - AddLabel (Addr, MakeLabelName (Addr)); + AddLabel (Addr, atIntLabel, MakeLabelName (Addr)); } } } @@ -397,4 +397,12 @@ void OH_JmpAbsolute (const OpcDesc* D) +void OH_JmpAbsoluteIndirect (const OpcDesc* D) +{ + OH_AbsoluteIndirect (D); + SeparatorLine (); +} + + + diff --git a/src/da65/handler.h b/src/da65/handler.h index e33ba113e..4c265ee85 100644 --- a/src/da65/handler.h +++ b/src/da65/handler.h @@ -78,6 +78,7 @@ void OH_AbsoluteXIndirect (const OpcDesc*); /* Handlers for special instructions */ void OH_Rts (const OpcDesc*); void OH_JmpAbsolute (const OpcDesc*); +void OH_JmpAbsoluteIndirect (const OpcDesc* D); diff --git a/src/da65/main.c b/src/da65/main.c index 64d858fa8..3164c189e 100644 --- a/src/da65/main.c +++ b/src/da65/main.c @@ -174,9 +174,8 @@ static void OneOpcode (unsigned RemainingBytes) const OpcDesc* D = &OpcTable[OPC]; /* If we have a label at this address, output the label */ - const char* Label = GetLabel (PC); - if (Label) { - DefLabel (Label); + if (MustDefLabel (PC)) { + DefLabel (GetLabel (PC)); } /* Check... @@ -185,7 +184,7 @@ static void OneOpcode (unsigned RemainingBytes) * - ...if there is no label somewhere between the instruction bytes. * If any of these conditions is true, switch to data mode. */ - if (GetStyle (PC) == atDefault) { + if (GetStyleAttr (PC) == atDefault) { if (D->Size > RemainingBytes) { MarkAddr (PC, atIllegal); } else if ((D->CPU & CPU) != CPU) { @@ -202,7 +201,7 @@ static void OneOpcode (unsigned RemainingBytes) } /* Disassemble the line */ - switch (GetStyle (PC)) { + switch (GetStyleAttr (PC)) { case atDefault: case atCode: @@ -226,6 +225,10 @@ static void OneOpcode (unsigned RemainingBytes) AddrTable (); break; + case atRtsTab: + RtsTable (); + break; + default: DataByteLine (1); ++PC; diff --git a/src/da65/opctable.c b/src/da65/opctable.c index fd9ee6c36..e47648a02 100644 --- a/src/da65/opctable.c +++ b/src/da65/opctable.c @@ -500,7 +500,7 @@ const OpcDesc OpcTable[256] = { 1, 0, CPU_ALL, - OH_Implicit + OH_Rts }, { /* $41 */ "eor", @@ -808,7 +808,7 @@ const OpcDesc OpcTable[256] = { 3, lfLabel, CPU_ALL, - OH_AbsoluteIndirect + OH_JmpAbsoluteIndirect }, { /* $6d */ "adc", diff --git a/src/da65/output.c b/src/da65/output.c index cbc97371a..6f3e3f963 100644 --- a/src/da65/output.c +++ b/src/da65/output.c @@ -146,8 +146,8 @@ void LineFeed (void) ++Page; PageHeader (); Line = 4; - } - Col = 1; + } + Col = 1; } } @@ -158,7 +158,7 @@ void DefLabel (const char* Name) { Output ("%s:", Name); /* Don't start a new line if the label is fully in the left column */ - if (Col >= MIndent-1) { + if (Col > MIndent) { LineFeed (); } } @@ -174,11 +174,11 @@ void DataByteLine (unsigned ByteCount) Output (".byte"); Indent (AIndent); for (I = 0; I < ByteCount; ++I) { - if (I > 0) { - Output (",$%02X", CodeBuf[PC+I]); - } else { - Output ("$%02X", CodeBuf[PC+I]); - } + if (I > 0) { + Output (",$%02X", CodeBuf[PC+I]); + } else { + Output ("$%02X", CodeBuf[PC+I]); + } } LineComment (PC, ByteCount); LineFeed (); diff --git a/src/da65/scanner.h b/src/da65/scanner.h index 12991746e..441ab6c0a 100644 --- a/src/da65/scanner.h +++ b/src/da65/scanner.h @@ -82,7 +82,9 @@ typedef enum token_t { CFGTOK_RTSTAB, /* Label section */ - + CFGTOK_NAME, + CFGTOK_ADDR, + CFGTOK_SIZE, /* */ CFGTOK_TRUE, -- 2.39.5