]> git.sur5r.net Git - cc65/commitdiff
Working on better 65816 support
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 7 Nov 2003 19:28:37 +0000 (19:28 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 7 Nov 2003 19:28:37 +0000 (19:28 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2619 b7a2c559-68d2-44c3-8de9-860c34a00d81

23 files changed:
src/ca65/error.c
src/ca65/error.h
src/ca65/expr.c
src/ca65/main.c
src/ca65/pseudo.c
src/ca65/scanner.c
src/ca65/scanner.h
src/ca65/segment.c
src/ca65/segment.h
src/ca65/symentry.c
src/ca65/symentry.h
src/ca65/symtab.c
src/ca65/symtab.h
src/common/addrsize.c [new file with mode: 0644]
src/common/addrsize.h
src/common/make/gcc.mak
src/common/make/watcom.mak
src/common/segdefs.c
src/common/segdefs.h
src/ld65/condes.c
src/ld65/segments.c
src/ld65/segments.h
src/od65/dump.c

index ce5212638346ccea2d2b1557485bf3850782d48e..9324c022f02ae37fef2ca874d2ddeb80666c2d21 100644 (file)
@@ -51,7 +51,7 @@
 
 
 /* Warning level */
-unsigned WarnLevel         = 1;
+unsigned WarnLevel     = 1;
 
 /* Statistics */
 unsigned ErrorCount    = 0;
@@ -72,11 +72,13 @@ void WarningMsg (const FilePos* Pos, unsigned WarnNum, va_list ap)
        unsigned char   Level;
        const char*     Msg;
     } Warnings [WARN_COUNT-1] = {
-               {   2,  "Symbol `%s' is defined but never used"         },
-        {   2,  "Symbol `%s' is imported but never used"       },
-       {   1,  "Cannot track processor status byte"            },
-               {   1,  "Suspicious address expression"                 },
-               {   0,  "User warning: %s"                              },
+               {   2,  "Symbol `%s' is defined but never used"                 },
+        {   2,  "Symbol `%s' is imported but never used"               },
+       {   1,  "Cannot track processor status byte"                    },
+               {   1,  "Suspicious address expression"                         },
+        {   0,  "Unnamed .PROCs are deprecated, please use .SCOPE"      },
+        {   1,  "Address size mismatch for symbol `%s'"                 },
+               {   0,  "User warning: %s"                                      },
     };
 
     if (Warnings [WarnNum-1].Level <= WarnLevel) {
@@ -149,6 +151,7 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
        "`.ENDMACRO' expected",
        "Option key expected",
        "`=' expected",
+        "Address size specifier expected",
        "Command is only valid in 65816 mode",
        "User error: %s",
        "String constant too long",
@@ -158,7 +161,6 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
        "Illegal character to start local symbols",
        "Illegal use of local symbol",
        "Illegal segment name: `%s'",
-       "Illegal segment attribute",
        "Illegal macro package name",
        "Illegal emulation feature",
         "Illegal scope specifier",
@@ -180,6 +182,7 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
        "Macro parameter expected",
        "Circular reference in symbol definition",
                "Symbol `%s' redeclaration mismatch",
+        "Address size mismatch for symbol `%s'",
         "Alignment value must be a power of 2",
        "Duplicate `.ELSE'",
                "Conditional assembly branch was never closed",
index 8809166c307bf0c9879d8b84be9ab83c5abd68ea..f376344d00fe506b4efc820462a9fcc668f4c6f1 100644 (file)
@@ -57,6 +57,8 @@ enum Warnings {
     WARN_IMPORT_NOT_REFERENCED,
     WARN_CANNOT_TRACK_STATUS,
     WARN_SUSPICIOUS_ADDREXPR,
+    WARN_UNNAMED_PROC,
+    WARN_ADDR_SIZE_MISMATCH,
     WARN_USER,
     WARN_COUNT                         /* Warning count */
 };
@@ -64,7 +66,7 @@ enum Warnings {
 /* Error numbers */
 enum Errors {
     ERR_NONE,                                  /* No error */
-    ERR_NOT_IMPLEMENTED,               /* Command/operation not implemented */
+    ERR_NOT_IMPLEMENTED,               /* Command/operation not implemented */
     ERR_CANNOT_OPEN_INCLUDE,
     ERR_CANNOT_READ_INCLUDE,
     ERR_INCLUDE_NESTING,
@@ -91,6 +93,7 @@ enum Errors {
     ERR_ENDMACRO_EXPECTED,
     ERR_OPTION_KEY_EXPECTED,
     ERR_EQ_EXPECTED,
+    ERR_ADDR_SIZE_EXPECTED,
     ERR_816_MODE_ONLY,
     ERR_USER,
     ERR_STRING_TOO_LONG,
@@ -99,8 +102,7 @@ enum Errors {
     ERR_ILLEGAL_ADDR_MODE,
     ERR_ILLEGAL_LOCALSTART,
     ERR_ILLEGAL_LOCAL_USE,
-    ERR_ILLEGAL_SEGMENT,
-    ERR_ILLEGAL_SEG_ATTR,
+    ERR_ILLEGAL_SEGMENT,    
     ERR_ILLEGAL_MACPACK,
     ERR_ILLEGAL_FEATURE,
     ERR_ILLEGAL_SCOPE,
@@ -122,6 +124,7 @@ enum Errors {
     ERR_MACRO_PARAM_EXPECTED,
     ERR_CIRCULAR_REFERENCE,
     ERR_SYM_REDECL_MISMATCH,
+    ERR_ADDR_SIZE_MISMATCH,
     ERR_ALIGN,
     ERR_DUPLICATE_ELSE,
     ERR_OPEN_IF,
@@ -156,7 +159,7 @@ enum Fatals {
     FAT_NESTING,
     FAT_IF_NESTING,
     FAT_TOO_MANY_SYMBOLS,
-    FAT_COUNT                          /* Fatal error count */
+    FAT_COUNT                          /* Fatal error count */
 };
 
 
index f72f12eee78cff780be272a9d5a5744c5e10c99f..02ae88a3670670741590bb84fce341f1567a9348 100644 (file)
@@ -917,7 +917,7 @@ ExprNode* GenCurrentPC (void)
     if (RelocMode) {
        /* Create SegmentBase + Offset */
        Root = NewExprNode (EXPR_PLUS);
-       Root->Left  = GenSectionExpr (GetSegNum ());
+       Root->Left  = GenSectionExpr (GetCurrentSegNum ());
        Root->Right = GenLiteralExpr (GetPC ());
     } else {
        /* Absolute mode, just return PC value */
@@ -950,7 +950,7 @@ ExprNode* GenBranchExpr (unsigned Offs)
     /* Create *+Offs */
     if (RelocMode) {
        N = NewExprNode (EXPR_PLUS);
-       N->Left  = GenSectionExpr (GetSegNum ());
+       N->Left  = GenSectionExpr (GetCurrentSegNum ());
        N->Right = GenLiteralExpr (GetPC () + Offs);
     } else {
        N = GenLiteralExpr (GetPC () + Offs);
@@ -1120,7 +1120,7 @@ static void CheckByteExpr (const ExprNode* N, int* IsByte)
                        break;
 
                    case EXPR_SECTION:
-                       if (GetSegType (N->V.SegNum) == SEGTYPE_ZP) {
+                       if (GetSegAddrSize (N->V.SegNum) == ADDR_SIZE_ZP) {
                            *IsByte = 1;
                        }
                        break;
index fd93fac97b5e1904b017aeeb67e17faa315cecf8..1bec12ba2bcd66b6a0ffca0dd74b11f94e0ec247 100644 (file)
@@ -39,6 +39,7 @@
 #include <time.h>
 
 /* common */
+#include "addrsize.h"
 #include "chartype.h"
 #include "cmdline.h"
 #include "print.h"
@@ -188,7 +189,7 @@ static void DefineSymbol (const char* Def)
     }
 
     /* Mark the symbol as defined */
-    SymDef (Sym, GenLiteralExpr (Val), SYM_DEFAULT);
+    SymDef (Sym, GenLiteralExpr (Val), ADDR_SIZE_DEFAULT, SF_NONE);
 }
 
 
@@ -381,18 +382,16 @@ static void OneLine (void)
             */
                    if (Tok == TOK_EQ || Tok == TOK_ASSIGN) {
                 /* If it's an assign token, we have a label */
-                unsigned Flags = (Tok == TOK_ASSIGN)? SYM_LABEL : SYM_DEFAULT;
+                unsigned Flags = (Tok == TOK_ASSIGN)? SF_LABEL : SF_NONE;
                /* Skip the '=' */
                NextTok ();
                /* Define the symbol with the expression following the '=' */
-               SymDef (Sym, Expression(), Flags);
+               SymDef (Sym, Expression(), ADDR_SIZE_DEFAULT, Flags);
                /* Don't allow anything after a symbol definition */
                Done = 1;
            } else {
-                /* Define the symbol flags */
-                unsigned Flags = IsZPSeg ()? SYM_ZP | SYM_LABEL : SYM_LABEL;
                /* Define a label */
-               SymDef (Sym, GenCurrentPC (), Flags);
+                       SymDef (Sym, GenCurrentPC (), ADDR_SIZE_DEFAULT, SF_LABEL);
                /* Skip the colon. If NoColonLabels is enabled, allow labels
                 * without a colon if there is no whitespace before the
                 * identifier.
@@ -525,7 +524,7 @@ int main (int argc, char* argv [])
     /* Enter the base lexical level. We must do that here, since we may
      * define symbols using -D.
      */
-    SymEnterLevel ("");
+    SymEnterLevel ("", ADDR_SIZE_DEFAULT);
 
     /* Check the parameters */
     I = 1;
index 1a98e855dc106493b6d6cb5d943bbe4bb8ba65b5..8e9ac1d90e4f68a49f76896c523ee4778d5dc287 100644 (file)
@@ -114,6 +114,22 @@ static void DoInvalid (void);
 
 
 
+static unsigned OptionalAddrSize (void)
+/* If a colon follows, parse an optional address size spec and return it.
+ * Otherwise return ADDR_SIZE_DEFAULT.
+ */
+{
+    unsigned AddrSize = ADDR_SIZE_DEFAULT;
+    if (Tok == TOK_COLON) {
+        NextTok ();
+        AddrSize = ParseAddrSize ();
+        NextTok ();
+    }
+    return AddrSize;
+}
+
+
+
 static void SetBoolOption (unsigned char* Flag)
 /* Read a on/off/+/- option and set flag accordingly */
 {
@@ -145,16 +161,37 @@ static void SetBoolOption (unsigned char* Flag)
 
 
 
-static void ExportImport (void (*SymFunc) (const char*))
+static void ExportImport (void (*Func) (SymEntry*, unsigned, unsigned),
+                          unsigned DefAddrSize, unsigned Flags)
 /* Export or import symbols */
 {
+    SymEntry* Sym;
+    unsigned  AddrSize;
+
     while (1) {
+
+        /* We need an identifier here */
        if (Tok != TOK_IDENT) {
                    ErrorSkip (ERR_IDENT_EXPECTED);
-           break;
+           return;
        }
-       SymFunc (SVal);
-       NextTok ();
+
+        /* Find the symbol table entry, allocate a new one if necessary */
+        Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
+
+        /* Skip the name */
+        NextTok ();
+
+        /* Get an optional address size */
+        AddrSize = OptionalAddrSize ();
+        if (AddrSize == ADDR_SIZE_DEFAULT) {
+            AddrSize = DefAddrSize;
+        }
+
+        /* Call the actual import/export function */
+        Func (Sym, AddrSize, Flags);
+
+        /* More symbols? */
        if (Tok == TOK_COMMA) {
            NextTok ();
        } else {
@@ -366,7 +403,7 @@ static void DoAssert (void)
             break;
 
         default:
-            Error (ERR_ILLEGAL_SEG_ATTR);
+            Error (ERR_ILLEGAL_ASSERT_ACTION);
     }
     NextTok ();
     ConsumeComma ();
@@ -702,7 +739,7 @@ static void DoExitMacro (void)
 static void DoExport (void)
 /* Export a symbol */
 {
-    ExportImport (SymExport);
+    ExportImport (SymExport, ADDR_SIZE_DEFAULT, SF_NONE);
 }
 
 
@@ -710,7 +747,7 @@ static void DoExport (void)
 static void DoExportZP (void)
 /* Export a zeropage symbol */
 {
-    ExportImport (SymExportZP);
+    ExportImport (SymExport, ADDR_SIZE_ZP, SF_NONE);
 }
 
 
@@ -856,7 +893,7 @@ static void DoFileOpt (void)
 static void DoForceImport (void)
 /* Do a forced import on a symbol */
 {
-    ExportImport (SymImportForced);
+    ExportImport (SymImport, ADDR_SIZE_DEFAULT, SF_FORCED);
 }
 
 
@@ -864,7 +901,7 @@ static void DoForceImport (void)
 static void DoGlobal (void)
 /* Declare a global symbol */
 {
-    ExportImport (SymGlobal);
+    ExportImport (SymGlobal, ADDR_SIZE_DEFAULT, SF_NONE);
 }
 
 
@@ -872,7 +909,7 @@ static void DoGlobal (void)
 static void DoGlobalZP (void)
 /* Declare a global zeropage symbol */
 {
-    ExportImport (SymGlobalZP);
+    ExportImport (SymGlobal, ADDR_SIZE_ZP, SF_NONE);
 }
 
 
@@ -906,7 +943,7 @@ static void DoI8 (void)
 static void DoImport (void)
 /* Import a symbol */
 {
-    ExportImport (SymImport);
+    ExportImport (SymImport, ADDR_SIZE_DEFAULT, SF_NONE);
 }
 
 
@@ -914,7 +951,7 @@ static void DoImport (void)
 static void DoImportZP (void)
 /* Import a zero page symbol */
 {
-    ExportImport (SymImportZP);
+    ExportImport (SymImport, ADDR_SIZE_ZP, SF_NONE);
 }
 
 
@@ -1244,18 +1281,35 @@ static void DoProc (void)
 /* Start a new lexical scope */
 {
     if (Tok == TOK_IDENT) {
-       /* The new scope has a name */
-       SymEntry* Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
-        unsigned Flags = SYM_LABEL;
-        if (IsZPSeg ()) {
-            Flags |= SYM_ZP;
-        }
-       SymDef (Sym, GenCurrentPC (), Flags);
-        SymEnterLevel (SVal);
-       NextTok ();
+
+        unsigned AddrSize;
+
+       /* The new scope has a name. Remember it. */
+        char Name[sizeof(SVal)];
+        strcpy (Name, SVal);
+
+        /* Search for the symbol, generate a new one if needed */
+       SymEntry* Sym = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
+
+        /* Skip the scope name */
+        NextTok ();
+
+        /* Read an optional address size specifier */
+        AddrSize = OptionalAddrSize ();
+
+        /* Mark the symbol as defined */
+       SymDef (Sym, GenCurrentPC (), AddrSize, SF_LABEL);
+
+        /* Enter a new scope with the given name */
+        SymEnterLevel (Name, AddrSize);
+
     } else {
+
+        /* A .PROC statement without a name */
         char Buf[sizeof (SVal)];
-        SymEnterLevel (AnonName (Buf, sizeof (Buf), "Scope"));
+        SymEnterLevel (AnonName (Buf, sizeof (Buf), "Scope"), ADDR_SIZE_DEFAULT);
+        Warning (WARN_UNNAMED_PROC);
+
     }
 }
 
@@ -1279,7 +1333,7 @@ static void DoPushSeg (void)
     }
 
     /* Get the current segment and push it */
-    CollAppend (&SegStack, DupSegDef (GetCurrentSeg ()));
+    CollAppend (&SegStack, DupSegDef (GetCurrentSegDef ()));
 }
 
 
@@ -1344,15 +1398,9 @@ static void DoROData (void)
 static void DoSegment (void)
 /* Switch to another segment */
 {
-    static const char* AttrTab [] = {
-       "ZEROPAGE", "DIRECT",
-       "ABSOLUTE",
-       "FAR", "LONG"
-    };
     char Name [sizeof (SVal)];
     SegDef Def;
     Def.Name = Name;
-    Def.Type = SEGTYPE_DEFAULT;
 
     if (Tok != TOK_STRCON) {
        ErrorSkip (ERR_STRCON_EXPECTED);
@@ -1362,38 +1410,8 @@ static void DoSegment (void)
        strcpy (Name, SVal);
        NextTok ();
 
-       /* Check for an optional segment attribute */
-       if (Tok == TOK_COMMA) {
-           NextTok ();
-           if (Tok != TOK_IDENT) {
-               ErrorSkip (ERR_IDENT_EXPECTED);
-           } else {
-               int Attr = GetSubKey (AttrTab, sizeof (AttrTab) / sizeof (AttrTab [0]));
-               switch (Attr) {
-
-                   case 0:
-                   case 1:
-                       /* Zeropage */
-                       Def.Type = SEGTYPE_ZP;
-                       break;
-
-                   case 2:
-                       /* Absolute */
-                       Def.Type = SEGTYPE_ABS;
-                       break;
-
-                   case 3:
-                   case 4:
-                       /* Far */
-                       Def.Type = SEGTYPE_FAR;
-                       break;
-
-                   default:
-                       Error (ERR_ILLEGAL_SEG_ATTR);
-               }
-               NextTok ();
-           }
-       }
+       /* Check for an optional address size modifier */
+        Def.AddrSize = OptionalAddrSize ();
 
        /* Set the segment */
        UseSeg (&Def);
index 7ac09acdf0877802dcb9e16031e28c9a1e023af1..8bad4f6c2b40db21709b5f4a5956d74bc03d651e 100644 (file)
@@ -42,6 +42,7 @@
 #include <sys/stat.h>
 
 /* common */
+#include "addrsize.h"
 #include "chartype.h"
 #include "check.h"
 #include "fname.h"
@@ -1135,6 +1136,41 @@ int GetSubKey (const char** Keys, unsigned Count)
 
 
 
+unsigned ParseAddrSize (void)
+/* Check if the next token is a keyword that denotes an address size specifier.
+ * If so, return the corresponding address size constant, otherwise output an
+ * error message and return ADDR_SIZE_DEFAULT.
+ */
+{
+    static const char* Keys[] = {
+        "DIRECT", "ZEROPAGE", "ZP",
+        "ABSOLUTE", "ABS", "NEAR",
+        "FAR",
+    };
+
+    /* Check for an identifier */
+    if (Tok != TOK_IDENT) {
+        Error (ERR_ADDR_SIZE_EXPECTED);
+        return ADDR_SIZE_DEFAULT;
+    }
+
+    /* Search for the attribute */
+    switch (GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]))) {
+        case 0:
+        case 1:
+        case 2: return ADDR_SIZE_FAR;
+        case 3:
+        case 4:
+        case 5: return ADDR_SIZE_ABS;
+        case 6: return ADDR_SIZE_FAR;
+        default:
+            Error (ERR_ADDR_SIZE_EXPECTED);
+            return ADDR_SIZE_DEFAULT;
+    }
+}
+
+
+
 void InitScanner (const char* InFile)
 /* Initialize the scanner, open the given input file */
 {
index f65ecde76a3ad1d75c29b5a20416736e1b287d64..4b2d0ef39f94e7bede8926e675b033a6cc3aadc4 100644 (file)
@@ -291,6 +291,12 @@ int GetSubKey (const char** Keys, unsigned Count);
  * or -1 if the keyword was not found.
  */
 
+unsigned ParseAddrSize (void);
+/* Check if the next token is a keyword that denotes an address size specifier.
+ * If so, return the corresponding address size constant, otherwise output an
+ * error message and return ADDR_SIZE_DEFAULT.
+ */
+
 void InitScanner (const char* InFile);
 /* Initialize the scanner, open the given input file */
 
index 8fd5e356f45dfa1c2d73b4604b9f0471be2832ed..3b760136cd09eb42614c498e324e87f782bb68a6 100644 (file)
 int            RelocMode = 1;
 unsigned long  AbsPC     = 0;          /* PC if in absolute mode */
 
-
-
-typedef struct Segment Segment;
-struct Segment {
-    Segment*               List;               /* List of all segments */
-    Fragment*              Root;               /* Root of fragment list */
-    Fragment*              Last;               /* Pointer to last fragment */
-    unsigned long   FragCount;          /* Number of fragments */
-    unsigned        Num;               /* Segment number */
-    unsigned        Align;             /* Segment alignment */
-    unsigned long   PC;
-    SegDef*         Def;                /* Segment definition (name and type) */
-};
-
-
+/* Segment initializer macro */
 #define SEG(segdef, num, prev)      \
     { prev, 0, 0, 0, num, 0, 0, segdef }
 
 /* Definitions for predefined segments */
-SegDef NullSegDef     = STATIC_SEGDEF_INITIALIZER (SEGNAME_NULL,     SEGTYPE_ABS);
-SegDef ZeropageSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_ZEROPAGE, SEGTYPE_ZP);
-SegDef DataSegDef     = STATIC_SEGDEF_INITIALIZER (SEGNAME_DATA,     SEGTYPE_ABS);
-SegDef BssSegDef      = STATIC_SEGDEF_INITIALIZER (SEGNAME_BSS,      SEGTYPE_ABS);
-SegDef RODataSegDef   = STATIC_SEGDEF_INITIALIZER (SEGNAME_RODATA,   SEGTYPE_ABS);
-SegDef CodeSegDef     = STATIC_SEGDEF_INITIALIZER (SEGNAME_CODE,     SEGTYPE_ABS);
+SegDef NullSegDef     = STATIC_SEGDEF_INITIALIZER (SEGNAME_NULL,     ADDR_SIZE_ABS);
+SegDef ZeropageSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_ZEROPAGE, ADDR_SIZE_ZP);
+SegDef DataSegDef     = STATIC_SEGDEF_INITIALIZER (SEGNAME_DATA,     ADDR_SIZE_ABS);
+SegDef BssSegDef      = STATIC_SEGDEF_INITIALIZER (SEGNAME_BSS,      ADDR_SIZE_ABS);
+SegDef RODataSegDef   = STATIC_SEGDEF_INITIALIZER (SEGNAME_RODATA,   ADDR_SIZE_ABS);
+SegDef CodeSegDef     = STATIC_SEGDEF_INITIALIZER (SEGNAME_CODE,     ADDR_SIZE_ABS);
 
 /* Predefined segments */
 static Segment NullSeg     = SEG (&NullSegDef,     5, NULL);
@@ -106,7 +92,7 @@ static Segment* SegmentList = &CodeSeg;
 static Segment* SegmentLast = &NullSeg;
 
 /* Currently active segment */
-static Segment*        ActiveSeg = &CodeSeg;
+Segment* ActiveSeg = &CodeSeg;
 
 
 
@@ -116,7 +102,7 @@ static Segment*     ActiveSeg = &CodeSeg;
 
 
 
-static Segment* NewSegment (const char* Name, unsigned SegType)
+static Segment* NewSegment (const char* Name, unsigned AddrSize)
 /* Create a new segment, insert it into the global list and return it */
 {
     Segment* S;
@@ -142,7 +128,7 @@ static Segment* NewSegment (const char* Name, unsigned SegType)
     S->Num       = SegmentCount++;
     S->Align     = 0;
     S->PC        = 0;
-    S->Def       = NewSegDef (Name, SegType);
+    S->Def       = NewSegDef (Name, AddrSize);
 
     /* Insert it into the segment list */
     SegmentLast->List = S;
@@ -198,10 +184,11 @@ void UseSeg (const SegDef* D)
     while (Seg) {
                if (strcmp (Seg->Def->Name, D->Name) == 0) {
            /* We found this segment. Check if the type is identical */
-           if (D->Type != SEGTYPE_DEFAULT && Seg->Def->Type != D->Type) {
+           if (D->AddrSize != ADDR_SIZE_DEFAULT &&
+                Seg->Def->AddrSize != D->AddrSize) {
                Error (ERR_SEG_ATTR_MISMATCH);
                /* Use the new attribute to avoid errors */
-               Seg->Def->Type = D->Type;
+               Seg->Def->AddrSize = D->AddrSize;
                    }
                    ActiveSeg = Seg;
            return;
@@ -211,10 +198,10 @@ void UseSeg (const SegDef* D)
     }
 
     /* Segment is not in list, create a new one */
-    if (D->Type == SEGTYPE_DEFAULT) {
-        Seg = NewSegment (D->Name, SEGTYPE_ABS);
+    if (D->AddrSize == ADDR_SIZE_DEFAULT) {
+        Seg = NewSegment (D->Name, ADDR_SIZE_ABS);
     } else {
-        Seg = NewSegment (D->Name, D->Type);
+        Seg = NewSegment (D->Name, D->AddrSize);
     }
     ActiveSeg = Seg;
 }
@@ -238,22 +225,6 @@ void SetAbsPC (unsigned long PC)
 
 
 
-const SegDef* GetCurrentSeg (void)
-/* Get a pointer to the segment defininition of the current segment */
-{
-    return ActiveSeg->Def;
-}
-
-
-
-unsigned GetSegNum (void)
-/* Get the number of the current segment */
-{
-    return ActiveSeg->Num;
-}
-
-
-
 void SegAlign (unsigned Power, int Val)
 /* Align the PC segment to 2^Power. If Val is -1, emit fill fragments (the
  * actual fill value will be determined by the linker), otherwise use the
@@ -290,24 +261,8 @@ void SegAlign (unsigned Power, int Val)
 
 
 
-int IsZPSeg (void)
-/* Return true if the current segment is a zeropage segment */
-{
-    return (ActiveSeg->Def->Type == SEGTYPE_ZP);
-}
-
-
-
-int IsFarSeg (void)
-/* Return true if the current segment is a far segment */
-{
-    return (ActiveSeg->Def->Type == SEGTYPE_FAR);
-}
-
-
-
-unsigned GetSegType (unsigned SegNum)
-/* Return the type of the segment with the given number */
+unsigned GetSegAddrSize (unsigned SegNum)
+/* Return the address size of the segment with the given number */
 {
     /* Search for the segment */
     Segment* S = SegmentList;
@@ -321,8 +276,8 @@ unsigned GetSegType (unsigned SegNum)
        FAIL ("Invalid segment number");
     }
 
-    /* Return the segment type */
-    return S->Def->Type;
+    /* Return the address size */
+    return S->Def->AddrSize;
 }
 
 
@@ -461,7 +416,7 @@ static void WriteOneSeg (Segment* Seg)
     ObjWriteVar (GetStringId (Seg->Def->Name)); /* Name of the segment */
     ObjWrite32 (Seg->PC);                       /* Size */
     ObjWrite8 (Seg->Align);                     /* Segment alignment */
-    ObjWrite8 (Seg->Def->Type);                 /* Type of the segment */
+    ObjWrite8 (Seg->Def->AddrSize);             /* Address size of the segment */
     ObjWriteVar (Seg->FragCount);               /* Number of fragments */
 
     /* Now walk through the fragment list for this segment and write the
index 1d6ce796e4ee02d7f5611f1710bfb90e95258282..85f50308b054c50880a158e3eb6a05bc8fff908c 100644 (file)
@@ -40,6 +40,7 @@
 
 /* common */
 #include "fragdefs.h"
+#include "inline.h"
 #include "segdefs.h"
 
 /* ca65 */
 
 
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                  Data                                    */
 /*****************************************************************************/
 
 
 
+/* Segment definition */
+typedef struct Segment Segment;
+struct Segment {
+    Segment*               List;               /* List of all segments */
+    Fragment*              Root;               /* Root of fragment list */
+    Fragment*              Last;               /* Pointer to last fragment */
+    unsigned long   FragCount;          /* Number of fragments */
+    unsigned        Num;                       /* Segment number */
+    unsigned        Align;                     /* Segment alignment */
+    unsigned long   PC;
+    SegDef*         Def;                /* Segment definition (name and type) */
+};
+
 /* Are we in absolute mode or in relocatable mode? */
-extern int     RelocMode;
+extern int RelocMode;
 
 /* Definitions for predefined segments */
 extern SegDef NullSegDef;
@@ -64,6 +78,9 @@ extern SegDef BssSegDef;
 extern SegDef RODataSegDef;
 extern SegDef CodeSegDef;
 
+/* Currently active segment */
+extern Segment* ActiveSeg;
+
 
 
 /*****************************************************************************/
@@ -78,11 +95,35 @@ Fragment* GenFragment (unsigned char Type, unsigned short Len);
 void UseSeg (const SegDef* D);
 /* Use the given segment */
 
-const SegDef* GetCurrentSeg (void);
+#if defined(HAVE_INLINE)
+INLINE const SegDef* GetCurrentSegDef (void)
 /* Get a pointer to the segment defininition of the current segment */
+{
+    return ActiveSeg->Def;
+}
+#else
+#  define GetCurrentSegDef()    (ActiveSeg->Def)
+#endif
 
-unsigned GetSegNum (void);
+#if defined(HAVE_INLINE)
+INLINE unsigned GetCurrentSegNum (void)
 /* Get the number of the current segment */
+{
+    return ActiveSeg->Num;
+}
+#else
+#  define GetCurrentSegNum()    (ActiveSeg->Num)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE unsigned GetCurrentSegAddrSize (void)
+/* Get the address size of the current segment */
+{
+    return ActiveSeg->Def->AddrSize;
+}
+#else
+#  define GetCurrentSegAddrSize()    (ActiveSeg->Def->AddrSize)
+#endif
 
 void SegAlign (unsigned Power, int Val);
 /* Align the PC segment to 2^Power. If Val is -1, emit fill fragments (the
@@ -90,14 +131,8 @@ void SegAlign (unsigned Power, int Val);
  * given value.
  */
 
-int IsZPSeg (void);
-/* Return true if the current segment is a zeropage segment */
-
-int IsFarSeg (void);
-/* Return true if the current segment is a far segment */
-
-unsigned GetSegType (unsigned SegNum);
-/* Return the type of the segment with the given number */
+unsigned GetSegAddrSize (unsigned SegNum);
+/* Return the address size of the segment with the given number */
 
 unsigned long GetPC (void);
 /* Get the program counter of the current segment */
index 660fdf0dfca43deeaf2748f158c0dff9b0487ffc..fd9f195fb1ff16ebeb1585470788a9903270731d 100644 (file)
@@ -1,6 +1,6 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                               symentry.c                                 */
+/*                               symentry.c                                 */
 /*                                                                           */
 /*         Symbol table entry forward for the ca65 macroassembler           */
 /*                                                                           */
@@ -36,6 +36,7 @@
 #include <string.h>
 
 /* common */
+#include "addrsize.h"
 #include "xmalloc.h"
 
 /* ca65 */
@@ -63,7 +64,7 @@ SymEntry* SymLast = 0;
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                          Code                                    */
 /*****************************************************************************/
 
 
@@ -84,6 +85,20 @@ int IsLocalNameId (unsigned Name)
 
 
 
+static unsigned SymAddrSize (const SymEntry* S)
+/* Get the default address size for a symbol. */
+{
+    /* Local symbols are always near (is this ok?) */
+    if (IsLocalNameId (S->Name)) {
+        return ADDR_SIZE_ABS;
+    }
+
+    /* Return the address size of the enclosing scope */
+    return S->SymTab->AddrSize;
+}
+
+
+
 SymEntry* NewSymEntry (const char* Name)
 /* Allocate a symbol table entry, initialize and return it */
 {
@@ -91,16 +106,18 @@ SymEntry* NewSymEntry (const char* Name)
     SymEntry* S = xmalloc (sizeof (SymEntry));
 
     /* Initialize the entry */
-    S->Left    = 0;
-    S->Right   = 0;
-    S->Locals  = 0;
-    S->SymTab  = 0;
-    S->Pos     = CurPos;
-    S->Flags   = 0;
-    S->V.Expr  = 0;
-    S->ExprRefs = AUTO_COLLECTION_INITIALIZER;
+    S->Left      = 0;
+    S->Right     = 0;
+    S->Locals    = 0;
+    S->SymTab    = 0;
+    S->Pos       = CurPos;
+    S->Flags     = 0;
+    S->V.Expr    = 0;
+    S->ExprRefs   = AUTO_COLLECTION_INITIALIZER;
+    S->ExportSize = ADDR_SIZE_DEFAULT;
+    S->AddrSize   = ADDR_SIZE_DEFAULT;
     memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
-    S->Name     = GetStringId (Name);
+    S->Name       = GetStringId (Name);
 
     /* Insert it into the list of all entries */
     S->List = SymList;
@@ -121,7 +138,7 @@ void SymRef (SymEntry* S)
 
 
 
-void SymDef (SymEntry* S, ExprNode* Expr, unsigned Flags)
+void SymDef (SymEntry* S, ExprNode* Expr, unsigned AddrSize, unsigned Flags)
 /* Define a new symbol */
 {
     if (S->Flags & SF_IMPORT) {
@@ -136,7 +153,12 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned Flags)
                return;
     }
 
-    /* Set the symbol data */
+    /* Map a default address size to a real value */
+    if (AddrSize == ADDR_SIZE_DEFAULT) {
+        AddrSize = SymAddrSize (S);
+    }
+
+    /* Set the symbol value */
     if (IsConstExpr (Expr)) {
                /* Expression is const, store the value */
                S->Flags |= SF_CONST;
@@ -146,16 +168,26 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned Flags)
                /* Not const, store the expression */
         S->V.Expr  = Expr;
     }
-    S->Flags |= SF_DEFINED;
-    if (Flags & SYM_ZP) {
-       S->Flags |= SF_ZP;
+
+    /* If the symbol is marked as global, export it */
+    if (S->Flags & SF_GLOBAL) {
+        S->ExportSize = S->AddrSize;
+        S->Flags = (S->Flags & ~SF_GLOBAL) | SF_EXPORT;
     }
-    if (Flags & SYM_LABEL) {
-       S->Flags |= SF_LABEL;
+
+    /* Mark the symbol as defined and use the given address size */
+    S->Flags |= (SF_DEFINED | Flags);
+    S->AddrSize = AddrSize;
+
+    /* If the symbol is exported, check the address sizes */
+    if (S->Flags & SF_EXPORT) {
+        if (S->AddrSize > S->ExportSize) {
+            Warning (WARN_ADDR_SIZE_MISMATCH, GetSymName (S));
+        }
     }
 
     /* If the symbol is a ZP symbol, check if the value is in correct range */
-    if (S->Flags & SF_ZP) {
+    if (S->AddrSize == ADDR_SIZE_ZP) {
        /* Already marked as ZP symbol by some means */
        if (!IsByteExpr (Expr)) {
            Error (ERR_RANGE);
@@ -170,6 +202,147 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned Flags)
 
 
 
+void SymImport (SymEntry* S, unsigned AddrSize, unsigned Flags)
+/* Mark the given symbol as an imported symbol */
+{
+    /* Don't accept local symbols */
+    if (IsLocalNameId (S->Name)) {
+       Error (ERR_ILLEGAL_LOCAL_USE);
+       return;
+    }
+
+    if (S->Flags & SF_DEFINED) {
+       Error (ERR_SYM_ALREADY_DEFINED, GetSymName (S));
+       S->Flags |= SF_MULTDEF;
+       return;
+    }
+    if (S->Flags & SF_EXPORT) {
+       /* The symbol is already marked as exported symbol */
+       Error (ERR_SYM_ALREADY_EXPORT, GetSymName (S));
+       return;
+    }
+
+    /* Map a default address size to a real value */
+    if (AddrSize == ADDR_SIZE_DEFAULT) {
+        AddrSize = SymAddrSize (S);
+    }
+
+    /* If the symbol is marked as import or global, check the symbol flags,
+     * then do silently remove the global flag
+     */
+    if (S->Flags & (SF_IMPORT | SF_GLOBAL)) {
+       if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED) ||
+            AddrSize != S->AddrSize) {
+           Error (ERR_SYM_REDECL_MISMATCH, GetSymName (S));
+       }
+        S->Flags &= ~SF_GLOBAL;
+    }
+
+    /* Set the symbol data */
+    S->Flags |= (SF_IMPORT | Flags);
+    S->AddrSize = AddrSize;
+}
+
+
+
+void SymExport (SymEntry* S, unsigned AddrSize, unsigned Flags)
+/* Mark the given symbol as an exported symbol */
+{
+    /* Don't accept local symbols */
+    if (IsLocalNameId (S->Name)) {
+       Error (ERR_ILLEGAL_LOCAL_USE);
+       return;
+    }
+
+    /* Check if it's ok to export the symbol */
+    if (S->Flags & SF_IMPORT) {
+       /* The symbol is already marked as imported external symbol */
+       Error (ERR_SYM_ALREADY_IMPORT, GetSymName (S));
+       return;
+    }
+
+    /* Map a default address size to a real value */
+    if (AddrSize == ADDR_SIZE_DEFAULT) {
+        AddrSize = SymAddrSize (S);
+    }
+
+    /* If the symbol was already marked as an export or global, check if
+     * this was done specifiying the same address size. In case of a global
+     * declaration, silently remove the global flag.
+     */
+    if (S->Flags & (SF_EXPORT | SF_GLOBAL)) {
+        if (S->ExportSize != AddrSize) {
+            Error (ERR_ADDR_SIZE_MISMATCH, GetSymName (S));
+        }
+        S->Flags &= ~SF_GLOBAL;
+    }
+    S->ExportSize = AddrSize;
+
+    /* If the symbol is already defined, check symbol size against the
+     * exported size.
+     */
+    if (S->Flags & SF_DEFINED) {
+        if (S->AddrSize > S->ExportSize) {
+            Warning (WARN_ADDR_SIZE_MISMATCH, GetSymName (S));
+        }
+    }
+
+    /* Set the symbol data */
+    S->Flags |= (SF_EXPORT | SF_REFERENCED | Flags);
+}
+
+
+
+void SymGlobal (SymEntry* S, unsigned AddrSize, unsigned Flags)
+/* Mark the given symbol as a global symbol, that is, as a symbol that is
+ * either imported or exported.
+ */
+{
+    /* Don't accept local symbols */
+    if (IsLocalNameId (S->Name)) {
+       Error (ERR_ILLEGAL_LOCAL_USE);
+       return;
+    }
+
+    /* Map a default address size to a real value */
+    if (AddrSize == ADDR_SIZE_DEFAULT) {
+        AddrSize = SymAddrSize (S);
+    }
+
+    /* If the symbol is already marked as import or export, check the
+     * size of the definition, then bail out.
+     */
+    if (S->Flags & SF_IMPORT) {
+        if (AddrSize != S->AddrSize) {
+            Error (ERR_ADDR_SIZE_MISMATCH, GetSymName (S));
+        }
+        return;
+    }
+    if (S->Flags & SF_EXPORT) {
+        if (AddrSize != S->ExportSize) {
+            Error (ERR_ADDR_SIZE_MISMATCH, GetSymName (S));
+        }
+        return;
+    }
+
+    /* If the symbol is already defined, export it. Otherwise mark it as
+     * global.
+     */
+    if (S->Flags & SF_DEFINED) {
+        /* The symbol is defined, export it */
+        if (S->ExportSize != AddrSize) {
+            Error (ERR_ADDR_SIZE_MISMATCH, GetSymName (S));
+        }
+        S->Flags |= (SF_EXPORT | Flags);
+        S->ExportSize = AddrSize;
+    } else {
+        S->Flags |= (SF_GLOBAL | Flags);
+        S->AddrSize = AddrSize;
+    }
+}
+
+
+
 int SymIsDef (const SymEntry* S)
 /* Return true if the given symbol is already defined */
 {
index 5d5aadd0a2073274ccf0778ac1b392f2803f41c4..54ce40cf63c71e252a9f28032a34b98f538c53ea 100644 (file)
 #define        SF_DEFINED      0x4000          /* Defined */
 #define SF_REFERENCED  0x8000          /* Referenced */
 
-/* Flags used in SymDef */
-#define SYM_DEFAULT     0x00
-#define SYM_ZP          0x01
-#define SYM_LABEL       0x02
-
 /* Arguments for SymFind... */
 #define SYM_FIND_EXISTING      0
 #define SYM_ALLOC_NEW          1
@@ -95,6 +90,8 @@ struct SymEntry {
        SymEntry*           Sym;        /* Symbol (if trampoline entry) */
     } V;
     Collection              ExprRefs;   /* Expressions using this symbol */
+    unsigned char           ExportSize; /* Export address size */
+    unsigned char           AddrSize;   /* Address size of label */
     unsigned char                  ConDesPrio[CD_TYPE_COUNT];  /* ConDes priorities... */
                                        /* ...actually value+1 (used as flag) */
     unsigned                Name;              /* Name index in global string pool */
@@ -143,12 +140,23 @@ INLINE void SymDelExprRef (SymEntry* Sym, struct ExprNode* Expr)
 #define SymDelExprRef(Sym,Expr)     CollDeleteItem (&(Sym)->ExprRefs, Expr)
 #endif
 
-void SymDef (SymEntry* Sym, ExprNode* Expr, unsigned Flags);
+void SymDef (SymEntry* Sym, ExprNode* Expr, unsigned AddrSize, unsigned Flags);
 /* Mark a symbol as defined */
 
 void SymRef (SymEntry* Sym);
 /* Mark the given symbol as referenced */
 
+void SymImport (SymEntry* Sym, unsigned AddrSize, unsigned Flags);
+/* Mark the given symbol as an imported symbol */
+
+void SymExport (SymEntry* Sym, unsigned AddrSize, unsigned Flags);
+/* Mark the given symbol as an exported symbol */
+
+void SymGlobal (SymEntry* S, unsigned AddrSize, unsigned Flags);
+/* Mark the given symbol as a global symbol, that is, as a symbol that is
+ * either imported or exported.
+ */
+
 int SymIsDef (const SymEntry* Sym);
 /* Return true if the given symbol is already defined */
 
index 70945c34fdff3d3af3eb32c0d9367b79f4ebce39..52d148037866de1f9931f593e057149810ae482a 100644 (file)
@@ -36,6 +36,7 @@
 #include <string.h>
 
 /* common */
+#include "addrsize.h"
 #include "check.h"
 #include "hashstr.h"
 #include "symdefs.h"
@@ -82,7 +83,7 @@ static unsigned       ExportCount = 0;/* Counter for export symbols */
 
 
 
-static unsigned SymTableSize (unsigned Level)
+static unsigned ScopeTableSize (unsigned Level)
 /* Get the size of a table for the given lexical level */
 {
     switch (Level) {
@@ -94,12 +95,12 @@ static unsigned SymTableSize (unsigned Level)
 
 
 
-static SymTable* NewSymTable (SymTable* Parent, const char* Name)
+static SymTable* NewSymTable (SymTable* Parent, unsigned AddrSize, const char* Name)
 /* Allocate a symbol table on the heap and return it */
 {
     /* Determine the lexical level and the number of table slots */
     unsigned Level = Parent? Parent->Level + 1 : 0;
-    unsigned Slots = SymTableSize (Level);
+    unsigned Slots = ScopeTableSize (Level);
 
     /* Allocate memory */
     SymTable* S = xmalloc (sizeof (SymTable) + (Slots-1) * sizeof (SymEntry*));
@@ -108,6 +109,8 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
     S->Left         = 0;
     S->Right        = 0;
     S->Childs       = 0;
+    S->AddrSize     = AddrSize;
+    S->Type         = 0;
     S->Level        = Level;
     S->TableSlots   = Slots;
     S->TableEntries = 0;
@@ -201,11 +204,17 @@ static int SearchSymTree (SymEntry* T, const char* Name, SymEntry** E)
 
 
 
-void SymEnterLevel (const char* ScopeName)
+void SymEnterLevel (const char* ScopeName, unsigned AddrSize)
 /* Enter a new lexical level */
 {
     /* ### Check existing scope */
 
+    /* Map a default address size to something real */
+    if (AddrSize == ADDR_SIZE_DEFAULT) {                            
+        /* Use the segment address size */
+        AddrSize = GetCurrentSegAddrSize ();
+    }
+
     /* Create the new table */
     CurrentScope = NewSymTable (CurrentScope, ScopeName);
 }
@@ -220,7 +229,7 @@ void SymLeaveLevel (void)
 
 
 
-SymTable* SymFindScope (SymTable* Parent, const char* Name, unsigned Flags)
+SymTable* SymFindScope (SymTable* Parent, const char* Name, int AllocNew)
 /* Find a scope in the given enclosing scope */
 {
     SymTable** T = &Parent->Childs;
@@ -237,7 +246,7 @@ SymTable* SymFindScope (SymTable* Parent, const char* Name, unsigned Flags)
     }
 
     /* Create a new scope if requested and we didn't find one */
-    if (*T == 0 && Flags == SYM_ALLOC_NEW) {
+    if (*T == 0 && AllocNew) {
         *T = NewSymTable (Parent, Name);
     }
 
@@ -359,172 +368,6 @@ static SymEntry* SymFindAny (SymTable* Scope, const char* Name)
 
 
 
-static void SymImportInternal (const char* Name, unsigned Flags)
-/* Mark the given symbol as an imported symbol */
-{
-    SymEntry* S;
-
-    /* Don't accept local symbols */
-    if (IsLocalName (Name)) {
-       Error (ERR_ILLEGAL_LOCAL_USE);
-       return;
-    }
-
-    /* Do we have such a symbol? */
-    S = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
-    if (S->Flags & SF_DEFINED) {
-       Error (ERR_SYM_ALREADY_DEFINED, Name);
-       S->Flags |= SF_MULTDEF;
-       return;
-    }
-    if (S->Flags & SF_EXPORT) {
-       /* The symbol is already marked as exported symbol */
-       Error (ERR_SYM_ALREADY_EXPORT, Name);
-       return;
-    }
-
-    /* If the symbol is marked as global, check the symbol flags, then do
-     * silently remove the global flag
-     */
-    if (S->Flags & SF_GLOBAL) {
-       if ((Flags & (SF_ZP | SF_FORCED)) != (S->Flags & (SF_ZP | SF_FORCED))) {
-           Error (ERR_SYM_REDECL_MISMATCH, Name);
-       }
-        S->Flags &= ~SF_GLOBAL;
-    }
-
-    /* Set the symbol data */
-    S->Flags |= (SF_IMPORT | Flags);
-}
-
-
-
-void SymImport (const char* Name)
-/* Mark the given symbol as an imported symbol */
-{
-    SymImportInternal (Name, SF_NONE);
-}
-
-
-
-void SymImportZP (const char* Name)
-/* Mark the given symbol as a forced imported symbol */
-{
-    SymImportInternal (Name, SF_ZP);
-}
-
-
-
-void SymImportForced (const char* Name)
-/* Mark the given symbol as a forced imported symbol */
-{
-    SymImportInternal (Name, SF_FORCED);
-}
-
-
-
-static void SymExportInternal (const char* Name, unsigned Flags)
-/* Mark the given symbol as an exported symbol */
-{
-    SymEntry* S;
-
-    /* Don't accept local symbols */
-    if (IsLocalName (Name)) {
-       Error (ERR_ILLEGAL_LOCAL_USE);
-       return;
-    }
-
-    /* Do we have such a symbol? */
-    S = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
-    if (S->Flags & SF_IMPORT) {
-       /* The symbol is already marked as imported external symbol */
-       Error (ERR_SYM_ALREADY_IMPORT, Name);
-       return;
-    }
-
-    /* If the symbol is marked as global, check the symbol size, then do
-     * silently remove the global flag
-     */
-    if (S->Flags & SF_GLOBAL) {
-               if ((Flags & SF_ZP) != (S->Flags & SF_ZP)) {
-           Error (ERR_SYM_REDECL_MISMATCH, Name);
-       }
-        S->Flags &= ~SF_GLOBAL;
-    }
-
-    /* Set the symbol data */
-    S->Flags |= (SF_EXPORT | SF_REFERENCED | Flags);
-}
-
-
-
-void SymExport (const char* Name)
-/* Mark the given symbol as an exported symbol */
-{
-    SymExportInternal (Name, SF_NONE);
-}
-
-
-
-void SymExportZP (const char* Name)
-/* Mark the given symbol as an exported zeropage symbol */
-{
-    SymExportInternal (Name, SF_ZP);
-}
-
-
-
-static void SymGlobalInternal (const char* Name, unsigned Flags)
-/* Mark the given symbol as a global symbol, that is, as a symbol that is
- * either imported or exported.
- */
-{
-    SymEntry* S;
-
-    /* Don't accept local symbols */
-    if (IsLocalName (Name)) {
-       Error (ERR_ILLEGAL_LOCAL_USE);
-       return;
-    }
-
-    /* Search for this symbol, create a new entry if needed */
-    S = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
-
-    /* If the symbol is already marked as import or export, check the
-     * size of the definition, then bail out. */
-    if (S->Flags & SF_IMPORT || S->Flags & SF_EXPORT) {
-               if ((Flags & SF_ZP) != (S->Flags & SF_ZP)) {
-           Error (ERR_SYM_REDECL_MISMATCH, Name);
-       }
-       return;
-    }
-
-    /* Mark the symbol */
-    S->Flags |= (SF_GLOBAL | Flags);
-}
-
-
-
-void SymGlobal (const char* Name)
-/* Mark the given symbol as a global symbol, that is, as a symbol that is
- * either imported or exported.
- */
-{
-    SymGlobalInternal (Name, SF_NONE);
-}
-
-
-
-void SymGlobalZP (const char* Name)
-/* Mark the given symbol as a global zeropage symbol, that is, as a symbol
- * that is either imported or exported.
- */
-{
-    SymGlobalInternal (Name, SF_ZP);
-}
-
-
-
 void SymConDes (const char* Name, unsigned Type, unsigned Prio)
 /* Mark the given symbol as a module constructor/destructor. This will also
  * mark the symbol as an export. Initializers may never be zero page symbols.
@@ -560,7 +403,7 @@ void SymConDes (const char* Name, unsigned Type, unsigned Prio)
     }
 
     /* Check if the symbol was not already defined as ZP symbol */
-    if ((S->Flags & SF_ZP) != 0) {
+    if (S->AddrSize == ADDR_SIZE_ZP) {
        Error (ERR_SYM_REDECL_MISMATCH, Name);
     }
 
index ae343a9c0be138f3837f7ba95c79420f9b506c85..8fda5f3a4cb6eef37e5239ddc69fad3a4599e089 100644 (file)
 
 
 
-/* Scope identifiers */
-#define SCOPE_ANY       0
-#define SCOPE_GLOBAL    1
-#define SCOPE_LOCAL     2
-
 /* A symbol table */
 typedef struct SymTable SymTable;
 struct SymTable {
@@ -66,6 +61,8 @@ struct SymTable {
     SymTable*           Right;          /* Pointer to greater entry */
     SymTable*                  Parent;         /* Link to enclosing scope if any */
     SymTable*           Childs;         /* Pointer to child scopes */
+    unsigned char      AddrSize;       /* Address size */
+    unsigned char       Type;           /* Type of the scope */
     unsigned            Level;          /* Lexical level */
     unsigned                   TableSlots;     /* Number of hash table slots */
     unsigned                   TableEntries;   /* Number of entries in the table */
@@ -85,13 +82,13 @@ SymTable*   RootScope;      /* Root symbol table */
 
 
 
-void SymEnterLevel (const char* ScopeName);
+void SymEnterLevel (const char* ScopeName, unsigned AddrSize);
 /* Enter a new lexical level */
 
 void SymLeaveLevel (void);
 /* Leave the current lexical level */
 
-SymTable* SymFindScope (SymTable* Parent, const char* Name, unsigned Flags);
+SymTable* SymFindScope (SymTable* Parent, const char* Name, int AllocNew);
 /* Find a scope in the given enclosing scope */
 
 SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew);
@@ -100,31 +97,6 @@ SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew);
  * new entry created, or - in case AllocNew is zero - return 0.
  */
 
-void SymImport (const char* Name);
-/* Mark the given symbol as an imported symbol */
-
-void SymImportZP (const char* Name);
-/* Mark the given symbol as a imported zeropage symbol */
-
-void SymImportForced (const char* Name);
-/* Mark the given symbol as a forced imported symbol */
-
-void SymExport (const char* Name);
-/* Mark the given symbol as an exported symbol */
-
-void SymExportZP (const char* Name);
-/* Mark the given symbol as an exported zeropage symbol */
-
-void SymGlobal (const char* Name);
-/* Mark the given symbol as a global symbol, that is, as a symbol that is
- * either imported or exported.
- */
-
-void SymGlobalZP (const char* Name);
-/* Mark the given symbol as a global zeropage symbol, that is, as a symbol
- * that is either imported or exported.
- */
-
 void SymConDes (const char* Name, unsigned Type, unsigned Prio);
 /* Mark the given symbol as a module constructor/destructor. This will also
  * mark the symbol as an export. Initializers may never be zero page symbols.
diff --git a/src/common/addrsize.c b/src/common/addrsize.c
new file mode 100644 (file)
index 0000000..845cb0e
--- /dev/null
@@ -0,0 +1,60 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                addrsize.c                                 */
+/*                                                                           */
+/*                         Address size definitions                          */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstraße 52                                              */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* common */
+#include "addrsize.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+const char* AddrSizeToStr (unsigned char AddrSize)
+/* Return the name for an address size specifier */
+{
+    switch (AddrSize) {
+        case ADDR_SIZE_DEFAULT:         return "default";
+        case ADDR_SIZE_ZP:              return "zeropage";
+        case ADDR_SIZE_ABS:             return "absolute";
+        case ADDR_SIZE_FAR:             return "far";
+        default:                        return "unknown";
+    }
+}
+
+
+
index d6297fe0a0a2d9e8313c1b186500911bcdacd50f..86ed732e933a5be1be8c9c455863832a78cee6d2 100644 (file)
 
 
 #define ADDR_SIZE_DEFAULT       0x00
-#define ADDR_SIZE_ZEROPAGE      0x01
-#define ADDR_SIZE_ABSOLUTE      0x02
+#define ADDR_SIZE_ZP            0x01
+#define ADDR_SIZE_ABS           0x02
 #define ADDR_SIZE_FAR           0x03
 
 
 
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+const char* AddrSizeToStr (unsigned char AddrSize);
+/* Return the name for an address size specifier */
+
+
+
 /* End of addrsize.h */
 
 #endif
index 1f7590ec103584aaecafbd3b8879b980faf3c383..d178f44bbb47429d63e0ec77e625f4a1a6b9bc5d 100644 (file)
@@ -10,6 +10,7 @@ LIB   = common.a
 
 
 OBJS = abend.o         \
+        addrsize.o      \
        bitops.o        \
        chartype.o      \
        check.o         \
index 346a693ced1a30d8e3ea8388d07f0c90cbbcf015..72adf688720698440053d8dad68caca7125b324f 100644 (file)
@@ -10,7 +10,7 @@ export WATCOM  = c:\\watcom
 export INCLUDE = $(WATCOM)\\h
 
 # We will use the windows compiler under linux (define as empty for windows)
-WINE = wine -- 
+WINE = wine --
 
 # Programs
 AR             = $(WINE) WLIB
@@ -55,6 +55,7 @@ endif
 # All library OBJ files
 
 OBJS = abend.obj       \
+        addrsize.obj    \
        bitops.obj      \
        chartype.obj    \
        check.obj       \
index 0473ff224b70cd2a3ed56a0c59f61f700ab2c98b..b43272c1e27c92c2dc54dbb413776dfc42ac7178 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2002      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 2002-2003 Ullrich von Bassewitz                                       */
+/*               Römerstraße 52                                              */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 
-SegDef* NewSegDef (const char* Name, unsigned Type)
+SegDef* NewSegDef (const char* Name, unsigned AddrSize)
 /* Create a new segment definition and return it */
 {
     /* Allocate memory */
     SegDef* D = xmalloc (sizeof (SegDef));
 
     /* Initialize it */
-    if (D) {
-        D->Name = xstrdup (Name);
-        D->Type = Type;
-    }
+    D->Name     = xstrdup (Name);
+    D->AddrSize = AddrSize;
 
     /* Return the result */
     return D;
@@ -75,20 +73,7 @@ void FreeSegDef (SegDef* D)
 SegDef* DupSegDef (const SegDef* Def)
 /* Duplicate a segment definition and return it */
 {
-    return NewSegDef (Def->Name, Def->Type);
-}
-
-
-
-const char* SegTypeToStr (unsigned char Type)
-/* Map a segment type into a string */
-{
-    switch (Type) {
-        case SEGTYPE_ABS:       return "abs";
-        case SEGTYPE_ZP:        return "zp";
-        case SEGTYPE_FAR:       return "far";
-        default:                return "unknown";
-    }
+    return NewSegDef (Def->Name, Def->AddrSize);
 }
 
 
index eb4fcfbb9fc1f251bfbdbe95cb8fa763d6506ab7..8c9adcbbba7939840dc2935d56bb0276902385dc 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 #define SEGDEFS_H
 
 
+                     
+/* common */
+#include "addrsize.h"
+
+
 
 /*****************************************************************************/
 /*                                          Data                                    */
 
 
 
-/* Available segment types */
-#define SEGTYPE_DEFAULT                0
-#define SEGTYPE_ABS                    1
-#define SEGTYPE_ZP                     2
-#define SEGTYPE_FAR                    3
-
 /* Segment definition */
 typedef struct SegDef SegDef;
 struct SegDef {
     char*       Name;           /* Segment name */
-    unsigned    Type;           /* Segment type, see above */
+    unsigned    AddrSize;       /* Default address size */
 };
 
 /* Initializer for static SegDefs */
-#define STATIC_SEGDEF_INITIALIZER(name, type) { (name), (type) }
+#define STATIC_SEGDEF_INITIALIZER(name, addrsize) { name, addrsize }
 
 
 
@@ -68,7 +67,7 @@ struct SegDef {
 
 
 
-SegDef* NewSegDef (const char* Name, unsigned Type);
+SegDef* NewSegDef (const char* Name, unsigned AddrSize);
 /* Create a new segment definition and return it */
 
 void FreeSegDef (SegDef* D);
@@ -77,9 +76,6 @@ void FreeSegDef (SegDef* D);
 SegDef* DupSegDef (const SegDef* D);
 /* Duplicate a segment definition and return it */
 
-const char* SegTypeToStr (unsigned char Type);
-/* Map a segment type into a string */
-
 
 
 /* End of segdefs.h */
index 2f9f29263c528565f29fe0f25fe317c6b975f720..785ba82f918cd085d026ba86a328b1a669a03faa 100644 (file)
@@ -36,6 +36,7 @@
 #include <string.h>
 
 /* common */
+#include "addrsize.h"
 #include "check.h"
 #include "coll.h"
 #include "fragdefs.h"
@@ -127,7 +128,7 @@ static int ConDesCompare (void* Data, const void* E1, const void* E2)
 static void ConDesCreateOne (ConDesDesc* CD)
 /* Create one table if requested */
 {
-    Segment*   Seg;            /* Segment for table */
+    Segment*   Seg;            /* Segment for table */
     Section*   Sec;            /* Section for table */
     unsigned   Count;          /* Number of exports */
     unsigned   I;
@@ -151,10 +152,10 @@ static void ConDesCreateOne (ConDesDesc* CD)
     CollSort (&CD->ExpList, ConDesCompare, CD);
 
     /* Get the segment for the table, create it if needed */
-    Seg = GetSegment (CD->SegName, SEGTYPE_ABS, 0);
+    Seg = GetSegment (CD->SegName, ADDR_SIZE_ABS, 0);
 
     /* Create a new section for the table */
-    Sec = NewSection (Seg, 1, SEGTYPE_ABS);
+    Sec = NewSection (Seg, 1, ADDR_SIZE_ABS);
 
     /* Walk over the exports and create a fragment for each one. We will use
      * the exported expression without copying it, since it's cheap and there
index 4a518702de31e20154420338fbe53d63ba9b9232..d42320dc8881ee0fac6124a6cdbeda90b3e12ac5 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -70,7 +70,7 @@
 static Segment*                HashTab [HASHTAB_SIZE];
 
 static unsigned                SegCount = 0;   /* Segment count */
-static Segment*                SegRoot = 0;    /* List of all segments */
+static Segment*                SegRoot = 0;    /* List of all segments */
 
 
 
@@ -80,7 +80,7 @@ static Segment*               SegRoot = 0;    /* List of all segments */
 
 
 
-static Segment* NewSegment (unsigned Name, unsigned char Type)
+static Segment* NewSegment (unsigned Name, unsigned char AddrSize)
 /* Create a new segment and initialize it */
 {
     unsigned Hash;
@@ -98,7 +98,7 @@ static Segment* NewSegment (unsigned Name, unsigned char Type)
     S->AlignObj           = 0;
     S->Align       = 0;
     S->FillVal    = 0;
-    S->Type        = Type;
+    S->AddrSize    = AddrSize;
     S->ReadOnly    = 0;
     S->Relocatable = 0;
     S->Dumped      = 0;
@@ -119,7 +119,7 @@ static Segment* NewSegment (unsigned Name, unsigned char Type)
 
 
 
-Segment* GetSegment (unsigned Name, unsigned char Type, const char* ObjName)
+Segment* GetSegment (unsigned Name, unsigned char AddrSize, const char* ObjName)
 /* Search for a segment and return an existing one. If the segment does not
  * exist, create a new one and return that. ObjName is only used for the error
  * message and may be NULL if the segment is linker generated.
@@ -133,10 +133,10 @@ Segment* GetSegment (unsigned Name, unsigned char Type, const char* ObjName)
      */
     if (S == 0) {
        /* Create a new segment */
-       S = NewSegment (Name, Type);
+       S = NewSegment (Name, AddrSize);
     } else {
-               /* Check if the existing segment has the requested type */
-               if (S->Type != Type) {
+               /* Check if the existing segment has the requested address size */
+               if (S->AddrSize != AddrSize) {
            /* Allow an empty object name */
            if (ObjName == 0) {
                ObjName = "[linker generated]";
@@ -152,7 +152,7 @@ Segment* GetSegment (unsigned Name, unsigned char Type, const char* ObjName)
 
 
 
-Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type)
+Section* NewSection (Segment* Seg, unsigned char Align, unsigned char AddrSize)
 /* Create a new section for the given segment */
 {
     unsigned long V;
@@ -168,7 +168,7 @@ Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type)
     S->FragLast = 0;
     S->Size    = 0;
     S->Align    = Align;
-    S->Type     = Type;
+    S->AddrSize = AddrSize;
 
     /* Calculate the alignment bytes needed for the section */
     V = (0x01UL << S->Align) - 1;
@@ -637,7 +637,7 @@ void PrintDbgSegments (FILE* F)
            /* Print the segment data */
                    fprintf (F, "segment\t\"%s\", 0x%06lX, 0x%04lX, %s, %s\n",
                             GetString (S->Name), S->PC, S->Size,
-                     SegTypeToStr (S->Type),
+                     AddrSizeToStr (S->AddrSize),
                      S->ReadOnly? "ro" : "rw");
        }
 
index 0df7e8fc366b8466356b3adf734e19ed9cc08e6b..aca4bf6ad7f74254226d7a3bfe9fe381842a7f78 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -64,7 +64,7 @@ struct Segment {
     struct ObjData*    AlignObj;       /* Module that requested the alignment */
     unsigned char      Align;          /* Alignment needed */
     unsigned char      FillVal;        /* Value to use for fill bytes */
-    unsigned char      Type;           /* Type of segment */
+    unsigned char      AddrSize;       /* Address size of segment */
     unsigned char       ReadOnly;       /* True for readonly segments (config) */
     unsigned char       Relocatable;    /* True if the segment is relocatable */
     unsigned char              Dumped;         /* Did we dump this segment? */
@@ -83,7 +83,7 @@ struct Section {
     unsigned long      Size;           /* Size of the section */
     unsigned char      Align;          /* Alignment */
     unsigned char      Fill;           /* Fill bytes for alignment */
-    unsigned char      Type;           /* Type of segment */
+    unsigned char      AddrSize;       /* Address size of segment */
 };
 
 
@@ -110,13 +110,13 @@ typedef unsigned (*SegWriteFunc) (ExprNode* E,          /* The expression to write
 
 
 
-Segment* GetSegment (unsigned Name, unsigned char Type, const char* ObjName);
+Segment* GetSegment (unsigned Name, unsigned char AddrSize, const char* ObjName);
 /* Search for a segment and return an existing one. If the segment does not
  * exist, create a new one and return that. ObjName is only used for the error
  * message and may be NULL if the segment is linker generated.
  */
 
-Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type);
+Section* NewSection (Segment* Seg, unsigned char Align, unsigned char AddrSize);
 /* Create a new section for the given segment */
 
 Section* ReadSection (FILE* F, struct ObjData* O);
index d3f52a9e7a5a5618735bd8d05465927ca7c2534d..c01bbcbe780a99c6e715579023ee29137c5510f6 100644 (file)
@@ -37,6 +37,7 @@
 #include <time.h>
 
 /* common */
+#include "addrsize.h"
 #include "cddefs.h"
 #include "coll.h"
 #include "exprdefs.h"
@@ -438,19 +439,9 @@ void DumpObjSegments (FILE* F, unsigned long Offset)
        unsigned      Len       = strlen (Name);
        unsigned long Size      = Read32 (F);
        unsigned      Align     = (1U << Read8 (F));
-       unsigned char Type      = Read8 (F);
+               unsigned char AddrSize  = Read8 (F);
         unsigned long FragCount = ReadVar (F);
 
-       /* Get the description for the type */
-       const char* TypeDesc;
-       switch (Type) {
-           case SEGTYPE_DEFAULT:       TypeDesc = "SEGTYPE_DEFAULT";   break;
-           case SEGTYPE_ABS:           TypeDesc = "SEGTYPE_ABS";       break;
-           case SEGTYPE_ZP:            TypeDesc = "SEGTYPE_ZP";        break;
-           case SEGTYPE_FAR:           TypeDesc = "SEGTYPE_FAR";       break;
-           default:                    TypeDesc = "SEGTYPE_UNKNOWN";   break;
-       }
-
        /* Print the header */
        printf ("    Index:%27u\n", I);
 
@@ -458,7 +449,8 @@ void DumpObjSegments (FILE* F, unsigned long Offset)
        printf ("      Name:%*s\"%s\"\n", 24-Len, "", Name);
                printf ("      Size:%26lu\n", Size);
        printf ("      Alignment:%21u\n", Align);
-       printf ("      Type:%22s0x%02X  (%s)\n", "", Type, TypeDesc);
+       printf ("      Address size:%14s0x%02X  (%s)\n", "", AddrSize,
+                AddrSizeToStr (AddrSize));
                printf ("      Fragment count:%16lu\n", FragCount);
 
         /* Seek to the end of the segment data (start of next) */