]> git.sur5r.net Git - cc65/commitdiff
Added labels, SIEZ attribute for labels, dependent labels etc.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 29 Sep 2000 12:26:34 +0000 (12:26 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 29 Sep 2000 12:26:34 +0000 (12:26 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@343 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/da65/attrtab.c
src/da65/attrtab.h
src/da65/config.c
src/da65/data.c
src/da65/data.h
src/da65/handler.c
src/da65/handler.h
src/da65/main.c
src/da65/opctable.c
src/da65/output.c
src/da65/scanner.h

index 20204b63bfe4be3be73958b057537d67722b249e..baa78bbb3732b5e4a3f52e389ef9a773d12303eb 100644 (file)
@@ -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);
        }
     }
index 09f71c13ff119969ab72c9033813de729e1b0af5..2bcae016d7fd4de8a053f7ad2f1820a98636f7a6 100644 (file)
 
 
 /*****************************************************************************/
-/*                                  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 */
 
index 1ed1b214159f9481cd5558fe61ce07792c0c334c..eaa64612c95ebbca0a0a804aca6e5b9d97bad293 100644 (file)
@@ -33,6 +33,7 @@
 
 
 
+#include <stdio.h>
 #if defined(_MSC_VER)
 /* Microsoft compiler */
 #  include <io.h>
@@ -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    },
     };
 
index 456755fdaaafc76e16380d8260fe74b26c1896d2..ec8a6420418932d65cd0ddc1f8be20b974c44a39 100644 (file)
@@ -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;
index 091efeb86045d3d55b1a204c73c52264414f62e7..0594f8bbb110370d2852079201ff1e4525e8aad9 100644 (file)
@@ -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 */
index 64bf6ed539f1f48dd7a0cb7c232c9ecbb21467cc..e041d69e60b734bd3d66913832339e3396d5f471 100644 (file)
@@ -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 ();
+}
+
+
+
 
index e33ba113efa2f66a52c830f3778db1116a2dee7b..4c265ee85716be0df0dc8f383919bfc8c339fdf2 100644 (file)
@@ -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);
 
 
 
index 64d858fa8636b97a1aa77e6f852bebbb10c913a3..3164c189e44e1978d4a28c89422fc77dae72bc3f 100644 (file)
@@ -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;
index fd9ee6c368e5a363dbd1203deeac9b8141eec388..e47648a028c5f0fe454bf6b949cbe46641e6a7bb 100644 (file)
@@ -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",
index cbc97371a81053d5fcc691082308379995a8aba0..6f3e3f963a9e96f61a6f34cc9ccfb184865e93ce 100644 (file)
@@ -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 ();
index 12991746e4ad0a9280f089b93c2a4004d5df5381..441ab6c0afeff8821ed66db5074a3452a4bb3aed 100644 (file)
@@ -82,7 +82,9 @@ typedef enum token_t {
     CFGTOK_RTSTAB,
 
     /* Label section */
-
+    CFGTOK_NAME,
+    CFGTOK_ADDR,
+    CFGTOK_SIZE,
 
     /* */
     CFGTOK_TRUE,