]> git.sur5r.net Git - cc65/commitdiff
New .FEATURE org_per_seg. If enabled, .org/.reloc do only influence the
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 23 Aug 2007 19:48:43 +0000 (19:48 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 23 Aug 2007 19:48:43 +0000 (19:48 +0000)
current segment. Idea by Peter Wendrich <pwsoft@syntiac.com>.

git-svn-id: svn://svn.cc65.org/cc65/trunk@3794 b7a2c559-68d2-44c3-8de9-860c34a00d81

doc/ca65.sgml
src/ca65/expr.c
src/ca65/feature.c
src/ca65/feature.h
src/ca65/global.c
src/ca65/global.h
src/ca65/listing.c
src/ca65/main.c
src/ca65/pseudo.c
src/ca65/segment.c
src/ca65/segment.h

index bb944052e5fb78891d1f1aaf27357188de972bf8..348c20390e5140ec9436a349daab4561726d8109 100644 (file)
@@ -2273,6 +2273,13 @@ Here's a list of all control commands and a description, what they do:
     <bf/Note:/ This does not work in conjunction with <tt/.FEATURE
     loose_string_term/, since in this case the input would be ambiguous.
 
+  <tag><tt>org_per_seg</tt><label id="org_per_seg"></tag>
+
+    This feature makes relocatable/absolute mode local to the current segment.
+    Using <tt><ref id=".ORG" name=".ORG"></tt> when <tt/org_per_seg/ is in
+    effect will only enable absolute mode for the current segment. Dito for
+    <tt><ref id=".RELOC" name=".RELOC"></tt>.
+
   <tag><tt>pc_assignment</tt></tag>
 
     Allow assignments to the PC symbol (`*' or `&dollar;' if <tt/dollar_is_pc/
@@ -2798,12 +2805,14 @@ Here's a list of all control commands and a description, what they do:
   assembled. Use <tt><ref id=".RELOC" name=".RELOC"></tt> to switch back to
   relocatable code.
 
-  Please note that you <em/do not need/ this command in most cases. Placing
+  By default, absolute/relocatable mode is global (valid even when switching
+  segments). Using <tt>.FEATURE <ref id="org_per_seg" name="org_per_seg"></tt>
+  it can be made segment local.
+
+  Please note that you <em/do not need/ <tt/.ORG/ in most cases. Placing
   code at a specific address is the job of the linker, not the assembler, so
   there is usually no reason to assemble code to a specific address.
 
-  You may not switch segments while inside a section of absolute code.
-
   Example:
 
   <tscreen><verb>
index f9258c5313ec3d4699e2f84a23a8c5b696970e4d..fc64f29c7e879fd0a14d38057cb0aa919dbb64c0 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2006 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
+/* (C) 1998-2007 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -1482,7 +1482,7 @@ ExprNode* GenCurrentPC (void)
 {
     ExprNode* Root;
 
-    if (RelocMode) {
+    if (GetRelocMode ()) {
        /* Create SegmentBase + Offset */
                Root = GenAddExpr (GenSectionExpr (GetCurrentSegNum ()),
                            GenLiteralExpr (GetPC ()));
@@ -1531,7 +1531,7 @@ ExprNode* GenBranchExpr (unsigned Offs)
          * (Val - PC - Offs) - Seg
          */
         Root = GenLiteralExpr (Val - GetPC () - Offs);
-        if (RelocMode) {
+        if (GetRelocMode ()) {
             N = Root;
             Root = NewExprNode (EXPR_MINUS);
             Root->Left  = N;
@@ -1549,7 +1549,7 @@ ExprNode* GenBranchExpr (unsigned Offs)
         Root = NewExprNode (EXPR_MINUS);
         Root->Left  = N;
         Root->Right = GenLiteralExpr (GetPC () + Offs);
-        if (RelocMode) {
+        if (GetRelocMode ()) {
             N = Root;
             Root = NewExprNode (EXPR_MINUS);
             Root->Left  = N;
index 91b0ae09211a54df1cb8767c166a266e6befe6ca..e5a0d4a289085464f24f875543a3e0a92ae775ae 100644 (file)
@@ -56,6 +56,7 @@ static const char* FeatureKeys[FEAT_COUNT] = {
     "at_in_identifiers",
     "dollar_in_identifiers",
     "leading_dot_in_identifiers",
+    "org_per_seg",
     "pc_assignment",
     "missing_char_term",
     "ubiquitous_idents",
@@ -108,10 +109,11 @@ feature_t SetFeature (const char* Key)
        case FEAT_AT_IN_IDENTIFIERS:          AtInIdents        = 1;    break;
        case FEAT_DOLLAR_IN_IDENTIFIERS:      DollarInIdents    = 1;    break;
                case FEAT_LEADING_DOT_IN_IDENTIFIERS: LeadingDotInIdents= 1;    break;
+        case FEAT_ORG_PER_SEG:                OrgPerSeg         = 1;    break;
        case FEAT_PC_ASSIGNMENT:              PCAssignment      = 1;    break;
         case FEAT_MISSING_CHAR_TERM:          MissingCharTerm   = 1;    break;
         case FEAT_UBIQUITOUS_IDENTS:          UbiquitousIdents  = 1;    break;
-       default:                         /* Keep gcc silent */          break;
+       default:                         /* Keep gcc silent */          break;
     }
 
     /* Return the value found */
index 2b8ec5ad3e7fb08553c6e8d83d62a77299e2260c..a297effff0544b450216a8f381219bbe3095422e 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
+/* (C) 2000-2007 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -45,7 +45,7 @@
 
 
 typedef enum {
-    FEAT_UNKNOWN               = -1,
+    FEAT_UNKNOWN               = -1,
     FEAT_DOLLAR_IS_PC,
     FEAT_LABELS_WITHOUT_COLONS,
     FEAT_LOOSE_STRING_TERM,
@@ -53,6 +53,7 @@ typedef enum {
     FEAT_AT_IN_IDENTIFIERS,
     FEAT_DOLLAR_IN_IDENTIFIERS,
     FEAT_LEADING_DOT_IN_IDENTIFIERS,
+    FEAT_ORG_PER_SEG,
     FEAT_PC_ASSIGNMENT,
     FEAT_MISSING_CHAR_TERM,
     FEAT_UBIQUITOUS_IDENTS,
index 2449ce44e8dab582502075695d4abcda398291fd..dea1dc69099a704ac8a1332ae1fa045473db7a19 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2004 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
+/* (C) 1998-2007 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -65,7 +65,7 @@ unsigned char DbgSyms          = 0;   /* Add debug symbols */
 unsigned char Listing                   = 0;   /* Create listing file */
 unsigned char LineCont          = 0;   /* Allow line continuation */
 
-/* Emulation features */
+/* Emulation features */                
 unsigned char DollarIsPC         = 0;   /* Allow the $ symbol as current PC */
 unsigned char NoColonLabels      = 0;   /* Allow labels without a colon */
 unsigned char LooseStringTerm    = 0;  /* Allow ' as string terminator */
@@ -76,6 +76,7 @@ unsigned char LeadingDotInIdents = 0;   /* Allow '.' to start an identifier */
 unsigned char PCAssignment       = 0;  /* Allow "* = $XXX" or "$ = $XXX" */
 unsigned char MissingCharTerm    = 0;   /* Allow lda #'a (no closing term) */
 unsigned char UbiquitousIdents   = 0;   /* Allow ubiquitous identifiers */
+unsigned char OrgPerSeg          = 0;   /* Make .org local to current seg */
 
 /* Misc stuff */
 const char Copyright[]           = "(C) Copyright 1998-2005 Ullrich von Bassewitz";
index 4728000620afcc5808105bf6559d985846235657..3d286c408aebc028d0dfd195d39bd3e58ea11403 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2004 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
+/* (C) 1998-2007 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -73,6 +73,7 @@ extern unsigned char    LeadingDotInIdents; /* Allow '.' to start an identifier
 extern unsigned char           PCAssignment;       /* Allow "* = $XXX" or "$ = $XXX" */
 extern unsigned char    MissingCharTerm;    /* Allow lda #'a (no closing term) */
 extern unsigned char    UbiquitousIdents;   /* Allow ubiquitous identifiers */
+extern unsigned char    OrgPerSeg;          /* Make .org local to current seg */
 
 /* Misc stuff */
 extern const char       Copyright[];        /* Copyright string */
index f18ac5910994aff6499e37dc65f2c9b57779feda..ad97d4b509b4effd0ec89d4675aa9440b8235dc2 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
+/* (C) 2000-2007 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -105,7 +105,7 @@ void NewListingLine (const char* Line, unsigned char File, unsigned char Depth)
        L->FragList     = 0;
        L->FragLast     = 0;
        L->PC           = GetPC ();
-       L->Reloc        = RelocMode;
+       L->Reloc        = GetRelocMode ();
        L->File         = File;
        L->Depth        = Depth;
        L->Output       = (ListingEnabled > 0);
@@ -181,7 +181,7 @@ void InitListingLine (void)
                /* Set the values for this line */
                CHECK (L != 0);
                L->PC            = GetPC ();
-               L->Reloc         = RelocMode;
+               L->Reloc         = GetRelocMode ();
                L->Output        = (ListingEnabled > 0);
                L->ListBytes = (unsigned char) ListBytes;
            } while (L->Next != LineLast);
@@ -191,7 +191,7 @@ void InitListingLine (void)
        /* Set the values for this line */
        CHECK (LineCur != 0);
        LineCur->PC         = GetPC ();
-       LineCur->Reloc      = RelocMode;
+       LineCur->Reloc      = GetRelocMode ();
        LineCur->Output     = (ListingEnabled > 0);
                LineCur->ListBytes  = (unsigned char) ListBytes;
     }
index 1ccef1fc4a44267670bf7dfe7063fbeb9e4d5ff0..b8a8935a36bd84b951ae815d41d5e1cbc0df4410 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2005, Ullrich von Bassewitz                                      */
-/*                Römerstraße 52                                             */
+/* (C) 1998-2007, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
 /*                                                                           */
@@ -511,7 +511,7 @@ static void DoPCAssign (void)
     if (PC < 0 || PC > 0xFFFFFF) {
        Error ("Range error");
     } else {
-       SetAbsPC (PC);
+       EnterAbsoluteMode (PC);
     }
 }
 
index cca2fbe69cc78e4b8296ac225521e10c25c7201a..cd05d182f171371acefe4add67e63447b728324d 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2005, Ullrich von Bassewitz                                      */
-/*                Römerstraße 52                                             */
+/* (C) 1998-2007, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
 /*                                                                           */
@@ -1248,7 +1248,7 @@ static void DoOrg (void)
        Error ("Range error");
        return;
     }
-    SetAbsPC (PC);
+    EnterAbsoluteMode (PC);
 }
 
 
@@ -1391,7 +1391,7 @@ static void DoPushSeg (void)
 static void DoReloc (void)
 /* Enter relocatable mode */
 {
-    RelocMode = 1;
+    EnterRelocMode ();
 }
 
 
index 2f23e2069964d01569e1951a70a97ef91d53c4a0..0f07ce52b80d3084249f637539725e6dc840db8d 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
+/* (C) 1998-2007 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 
 
 
-/* Are we in absolute mode or in relocatable mode? */
-int            RelocMode = 1;
-unsigned long  AbsPC     = 0;          /* PC if in absolute mode */
+/* If OrgPerSeg is false, all segments share the RelocMode flag and a PC
+ * used when in absolute mode. OrgPerSeg may be set by .feature org_per_seg
+ */
+static int              RelocMode = 1;
+static unsigned long    AbsPC    = 0;          /* PC if in absolute mode */
 
 /* Segment initializer macro */
 #define SEG(segdef, num, prev)      \
-    { prev, 0, 0, 0, num, 0, 0, segdef }
+    { prev, 0, 0, 0, num, 0, 1, 0, 0, segdef }
 
 /* Definitions for predefined segments */
 SegDef NullSegDef     = STATIC_SEGDEF_INITIALIZER (SEGNAME_NULL,     ADDR_SIZE_ABS);
@@ -130,7 +132,9 @@ static Segment* NewSegment (const char* Name, unsigned char AddrSize)
     S->FragCount = 0;
     S->Num       = SegmentCount++;
     S->Align     = 0;
+    S->RelocMode = 1;
     S->PC        = 0;
+    S->AbsPC     = 0;
     S->Def       = NewSegDef (Name, AddrSize);
 
     /* Insert it into the segment list */
@@ -170,8 +174,16 @@ Fragment* GenFragment (unsigned char Type, unsigned short Len)
 
     /* Increment the program counter */
     ActiveSeg->PC += F->Len;
-    if (!RelocMode) {
-       AbsPC += F->Len;
+    if (OrgPerSeg) {
+        /* Relocatable mode is switched per segment */
+        if (!ActiveSeg->RelocMode) {
+            ActiveSeg->AbsPC += F->Len;
+        }
+    } else {
+        /* Relocatable mode is switched globally */
+        if (!RelocMode) {
+            AbsPC += F->Len;
+        }
     }
 
     /* Return the fragment */
@@ -214,16 +226,61 @@ void UseSeg (const SegDef* D)
 unsigned long GetPC (void)
 /* Get the program counter of the current segment */
 {
-    return RelocMode? ActiveSeg->PC : AbsPC;
+    if (OrgPerSeg) {
+        /* Relocatable mode is switched per segment */
+        return ActiveSeg->RelocMode? ActiveSeg->PC : ActiveSeg->AbsPC;
+    } else {
+        /* Relocatable mode is switched globally */
+        return RelocMode? ActiveSeg->PC : AbsPC;
+    }
+}
+
+
+
+void EnterAbsoluteMode (unsigned long PC)
+/* Enter absolute (non relocatable mode). Depending on the OrgPerSeg flag,
+ * this will either switch the mode globally or for the current segment.
+ */
+{
+    if (OrgPerSeg) {
+        /* Relocatable mode is switched per segment */
+        ActiveSeg->RelocMode = 0;
+        ActiveSeg->AbsPC = PC;
+    } else {
+        /* Relocatable mode is switched globally */
+        RelocMode = 0;
+        AbsPC = PC;
+    }
+}
+
+
+
+int GetRelocMode (void)
+/* Return true if we're currently in relocatable mode */
+{
+    if (OrgPerSeg) {
+        /* Relocatable mode is switched per segment */
+        return ActiveSeg->RelocMode;
+    } else {
+        /* Relocatable mode is switched globally */
+        return RelocMode;
+    }
 }
 
 
 
-void SetAbsPC (unsigned long PC)
-/* Set the program counter in absolute mode */
+void EnterRelocMode (void)
+/* Enter relocatable mode. Depending on the OrgPerSeg flag, this will either
+ * switch the mode globally or for the current segment.
+ */
 {
-    RelocMode = 0;
-    AbsPC = PC;
+    if (OrgPerSeg) {
+        /* Relocatable mode is switched per segment */
+        ActiveSeg->RelocMode = 1;
+    } else {
+        /* Relocatable mode is switched globally */
+        RelocMode = 1;
+    }
 }
 
 
index fb0a02dd4269ad15210f19e140cb838b34271945..e1e9027831d1cf6b81d0ac18b25ca3fb817a008f 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
+/* (C) 1998-2007 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -63,13 +63,13 @@ struct Segment {
     unsigned long   FragCount;          /* Number of fragments */
     unsigned        Num;                       /* Segment number */
     unsigned        Align;                     /* Segment alignment */
-    unsigned long   PC;
+    int             RelocMode;          /* Relocatable mode if OrgPerSeg */
+    unsigned long   PC;                 /* PC if in relocatable mode */
+    unsigned long   AbsPC;              /* PC if in local absolute mode */
+                                        /* (OrgPerSeg is true) */
     SegDef*         Def;                /* Segment definition (name and type) */
 };
 
-/* Are we in absolute mode or in relocatable mode? */
-extern int RelocMode;
-
 /* Definitions for predefined segments */
 extern SegDef NullSegDef;
 extern SegDef ZeropageSegDef;
@@ -140,8 +140,18 @@ unsigned char GetSegAddrSize (unsigned SegNum);
 unsigned long GetPC (void);
 /* Get the program counter of the current segment */
 
-void SetAbsPC (unsigned long AbsPC);
-/* Set the program counter in absolute mode */
+int GetRelocMode (void);
+/* Return true if we're currently in relocatable mode */
+
+void EnterAbsoluteMode (unsigned long AbsPC);
+/* Enter absolute (non relocatable mode). Depending on the OrgPerSeg flag,
+ * this will either switch the mode globally or for the current segment.
+ */
+
+void EnterRelocMode (void);
+/* Enter relocatable mode. Depending on the OrgPerSeg flag, this will either
+ * switch the mode globally or for the current segment.
+ */
 
 void SegCheck (void);
 /* Check the segments for range and other errors */