]> git.sur5r.net Git - cc65/commitdiff
Use a collection to manage the segments.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 5 Aug 2011 13:45:33 +0000 (13:45 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 5 Aug 2011 13:45:33 +0000 (13:45 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@5124 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/main.c
src/ca65/segment.c
src/ca65/segment.h
src/ca65/span.c

index 2ae3c8a76efb36f87dc85ae8db4d921efd2e1cc3..f41ddb6834b584eb9fedbb3694bedf4ba9353696 100644 (file)
@@ -866,6 +866,9 @@ int main (int argc, char* argv [])
     /* Initialize the include search paths */
     InitIncludePaths ();
 
+    /* Create the predefined segments */
+    InitSegments ();
+
     /* Enter the base lexical level. We must do that here, since we may
      * define symbols using -D.
      */
@@ -991,8 +994,8 @@ int main (int argc, char* argv [])
         SetMemoryModel (MMODEL_NEAR);
     }
 
-    /* Initialize the segments */
-    InitSegments ();
+    /* Set the default segment sizes according to the memory model */
+    SetSegmentSizes ();
 
     /* Initialize the scanner, open the input file */
     InitScanner (InFile);
index b94123058e82f81ba21431782141708e7c6259f5..a089a5d88b1611a67d42cb9e09d97b346bb5780f 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2007 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -38,6 +38,7 @@
 
 /* common */
 #include "addrsize.h"
+#include "coll.h"
 #include "mmodel.h"
 #include "segnames.h"
 #include "xmalloc.h"
 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, 1, 0, 0, segdef }
-
 /* Definitions for predefined segments */
 SegDef NullSegDef     = STATIC_SEGDEF_INITIALIZER (SEGNAME_NULL,     ADDR_SIZE_ABS);
 SegDef ZeropageSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_ZEROPAGE, ADDR_SIZE_ZP);
@@ -81,23 +78,11 @@ SegDef BssSegDef      = STATIC_SEGDEF_INITIALIZER (SEGNAME_BSS,      ADDR_SIZE_A
 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);
-static Segment ZeropageSeg = SEG (&ZeropageSegDef, 4, &NullSeg);
-static Segment DataSeg     = SEG (&DataSegDef,     3, &ZeropageSeg);
-static Segment BssSeg      = SEG (&BssSegDef,      2, &DataSeg);
-static Segment RODataSeg   = SEG (&RODataSegDef,   1, &BssSeg);
-static Segment CodeSeg     = SEG (&CodeSegDef,     0, &RODataSeg);
-
-/* Number of segments */
-static unsigned SegmentCount = 6;
-
-/* List of all segments */
-Segment* SegmentList = &CodeSeg;
-static Segment* SegmentLast = &NullSeg;
+/* Collection containing all segments */
+Collection SegmentList = STATIC_COLLECTION_INITIALIZER;
 
 /* Currently active segment */
-Segment* ActiveSeg = &CodeSeg;
+Segment* ActiveSeg;
 
 
 
@@ -107,39 +92,27 @@ Segment* ActiveSeg = &CodeSeg;
 
 
 
-static Segment* NewSegment (const char* Name, unsigned char AddrSize)
-/* Create a new segment, insert it into the global list and return it */
+static Segment* NewSegFromDef (SegDef* Def)
+/* Create a new segment from a segment definition. Used only internally, no
+ * checks.
+ */
 {
-    Segment* S;
-
-    /* Check for too many segments */
-    if (SegmentCount >= 256) {
-       Fatal ("Too many segments");
-    }
-
-    /* Check the segment name for invalid names */
-    if (!ValidSegName (Name)) {
-       Error ("Illegal segment name: `%s'", Name);
-    }
-
     /* Create a new segment */
-    S = xmalloc (sizeof (*S));
+    Segment* S = xmalloc (sizeof (*S));
 
     /* Initialize it */
-    S->List      = 0;
     S->Root      = 0;
     S->Last      = 0;
     S->FragCount = 0;
-    S->Num       = SegmentCount++;
+    S->Num       = CollCount (&SegmentList);
     S->Align     = 0;
     S->RelocMode = 1;
     S->PC        = 0;
     S->AbsPC     = 0;
-    S->Def       = NewSegDef (Name, AddrSize);
+    S->Def       = Def;
 
     /* Insert it into the segment list */
-    SegmentLast->List = S;
-    SegmentLast = S;
+    CollAppend (&SegmentList, S);
 
     /* And return it... */
     return S;
@@ -147,6 +120,25 @@ static Segment* NewSegment (const char* Name, unsigned char AddrSize)
 
 
 
+static Segment* NewSegment (const char* Name, unsigned char AddrSize)
+/* Create a new segment, insert it into the global list and return it */
+{
+    /* Check for too many segments */
+    if (CollCount (&SegmentList) >= 256) {
+       Fatal ("Too many segments");
+    }
+
+    /* Check the segment name for invalid names */
+    if (!ValidSegName (Name)) {
+       Error ("Illegal segment name: `%s'", Name);
+    }
+
+    /* Create a new segment and return it */
+    return NewSegFromDef (NewSegDef (Name, AddrSize));
+}
+
+
+
 Fragment* GenFragment (unsigned char Type, unsigned short Len)
 /* Generate a new fragment, add it to the current segment and return it. */
 {
@@ -195,30 +187,28 @@ Fragment* GenFragment (unsigned char Type, unsigned short Len)
 void UseSeg (const SegDef* D)
 /* Use the segment with the given name */
 {
-    Segment* Seg = SegmentList;
-    while (Seg) {
+    unsigned I;
+    for (I = 0; I < CollCount (&SegmentList); ++I) {
+        Segment* Seg = CollAtUnchecked (&SegmentList, I);
                if (strcmp (Seg->Def->Name, D->Name) == 0) {
            /* We found this segment. Check if the type is identical */
            if (D->AddrSize != ADDR_SIZE_DEFAULT &&
                 Seg->Def->AddrSize != D->AddrSize) {
-               Error ("Segment attribute mismatch");
-               /* Use the new attribute to avoid errors */
+               Error ("Segment attribute mismatch");
+               /* Use the new attribute to avoid errors */
                Seg->Def->AddrSize = D->AddrSize;
                    }
                    ActiveSeg = Seg;
            return;
        }
-       /* Check next segment */
-       Seg = Seg->List;
     }
 
     /* Segment is not in list, create a new one */
     if (D->AddrSize == ADDR_SIZE_DEFAULT) {
-        Seg = NewSegment (D->Name, ADDR_SIZE_ABS);
+        ActiveSeg = NewSegment (D->Name, ADDR_SIZE_ABS);
     } else {
-        Seg = NewSegment (D->Name, D->AddrSize);
+        ActiveSeg = NewSegment (D->Name, D->AddrSize);
     }
-    ActiveSeg = Seg;
 }
 
 
@@ -324,20 +314,13 @@ void SegAlign (unsigned Power, int Val)
 unsigned char GetSegAddrSize (unsigned SegNum)
 /* Return the address size of the segment with the given number */
 {
-    /* Search for the segment */
-    Segment* S = SegmentList;
-    while (S && SegNum) {
-       --SegNum;
-       S = S->List;
-    }
-
-    /* Did we find it? */
-    if (S == 0) {
+    /* Is there such a segment? */
+    if (SegNum >= CollCount (&SegmentList)) {
        FAIL ("Invalid segment number");
     }
 
     /* Return the address size */
-    return S->Def->AddrSize;
+    return ((Segment*) CollAtUnchecked (&SegmentList, SegNum))->Def->AddrSize;
 }
 
 
@@ -345,8 +328,9 @@ unsigned char GetSegAddrSize (unsigned SegNum)
 void SegCheck (void)
 /* Check the segments for range and other errors */
 {
-    Segment* S = SegmentList;
-    while (S) {
+    unsigned I;
+    for (I = 0; I < CollCount (&SegmentList); ++I) {
+        Segment* S = CollAtUnchecked (&SegmentList, I);
        Fragment* F = S->Root;
        while (F) {
                    if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
@@ -421,7 +405,6 @@ void SegCheck (void)
            }
            F = F->Next;
        }
-       S = S->List;
     }
 }
 
@@ -430,10 +413,12 @@ void SegCheck (void)
 void SegDump (void)
 /* Dump the contents of all segments */
 {
+    unsigned I;
     unsigned X = 0;
-    Segment* S = SegmentList;
+
     printf ("\n");
-    while (S) {
+    for (I = 0; I < CollCount (&SegmentList); ++I) {
+        Segment* S = CollAtUnchecked (&SegmentList, I);
        unsigned I;
        Fragment* F;
        int State = -1;
@@ -466,7 +451,6 @@ void SegDump (void)
            F = F->Next;
        }
        printf ("\n  End PC = $%04X\n", (unsigned)(S->PC & 0xFFFF));
-       S = S->List;
     }
     printf ("\n");
 }
@@ -559,6 +543,20 @@ static void WriteOneSeg (Segment* Seg)
 
 void InitSegments (void)
 /* Initialize segments */
+{
+    /* Create the predefined segments. Code segment is active */
+    ActiveSeg = NewSegFromDef (&CodeSegDef);
+    NewSegFromDef (&RODataSegDef);
+    NewSegFromDef (&BssSegDef);
+    NewSegFromDef (&DataSegDef);
+    NewSegFromDef (&ZeropageSegDef);
+    NewSegFromDef (&NullSegDef);
+}
+
+
+
+void SetSegmentSizes (void)
+/* Set the default segment sizes according to the memory model */
 {
     /* Initialize segment sizes. The segment definitions do already contain
      * the correct values for the default case (near), so we must only change
@@ -590,21 +588,18 @@ void InitSegments (void)
 void WriteSegments (void)
 /* Write the segment data to the object file */
 {
-    Segment* Seg;
+    unsigned I;
 
     /* Tell the object file module that we're about to start the seg list */
     ObjStartSegments ();
 
     /* First thing is segment count */
-    ObjWriteVar (SegmentCount);
+    ObjWriteVar (CollCount (&SegmentList));
 
     /* Now walk through all segments and write them to the object file */
-    Seg = SegmentList;
-    while (Seg) {
+    for (I = 0; I < CollCount (&SegmentList); ++I) {
        /* Write one segment */
-       WriteOneSeg (Seg);
-       /* Next segment */
-       Seg = Seg->List;
+       WriteOneSeg (CollAtUnchecked (&SegmentList, I));
     }
 
     /* Done writing segments */
index e1e9027831d1cf6b81d0ac18b25ca3fb817a008f..84982236a55426e64e7a748a0c819106c43b0cce 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2007 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -39,6 +39,7 @@
 
 
 /* common */
+#include "coll.h"
 #include "fragdefs.h"
 #include "inline.h"
 #include "segdefs.h"
@@ -49,7 +50,7 @@
 
 
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                  Data                                    */
 /*****************************************************************************/
 
 
@@ -57,7 +58,6 @@
 /* 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 */
@@ -78,8 +78,8 @@ extern SegDef BssSegDef;
 extern SegDef RODataSegDef;
 extern SegDef CodeSegDef;
 
-/* List of all segments */
-extern Segment* SegmentList;
+/* Collection containing all segments */
+extern Collection SegmentList;
 
 /* Currently active segment */
 extern Segment* ActiveSeg;
@@ -162,6 +162,9 @@ void SegDump (void);
 void InitSegments (void);
 /* Initialize segments */
 
+void SetSegmentSizes (void);
+/* Set the default segment sizes according to the memory model */
+
 void WriteSegments (void);
 /* Write the segment data to the object file */
 
index 9c29b0fd12cf0903ab98a22a0b8fbd793dbcb61f..70bc85167c11ffdc8aec8ed6ddd9def4bdc09234 100644 (file)
@@ -50,7 +50,7 @@
 
 
 Span* NewSpan (struct Segment* Seg)
-/* Create a new span. The segment is set to Seg, Start and End are set to the 
+/* Create a new span. The segment is set to Seg, Start and End are set to the
  * current PC of the segment.
  */
 {
@@ -73,19 +73,19 @@ void AddSpans (Collection* Spans)
  * currently active segment will be inserted first with all others following.
  */
 {
-    Segment* Seg;
+    unsigned I;
 
     /* Add the currently active segment */
     CollAppend (Spans, NewSpan (ActiveSeg));
 
     /* Walk through the segment list and add all other segments */
-    Seg = SegmentList;
-    while (Seg) {
+    for (I = 0; I < CollCount (&SegmentList); ++I) {
+        Segment* Seg = CollAtUnchecked (&SegmentList, I);
+
         /* Be sure to skip the active segment, since it was already added */
         if (Seg != ActiveSeg) {
             CollAppend (Spans, NewSpan (Seg));
         }
-        Seg = Seg->List;
     }
 }