From 9f02a29dfa947162900f5bb17421b6bedbbbe5f8 Mon Sep 17 00:00:00 2001 From: uz Date: Fri, 5 Aug 2011 13:45:33 +0000 Subject: [PATCH] Use a collection to manage the segments. git-svn-id: svn://svn.cc65.org/cc65/trunk@5124 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/main.c | 7 ++- src/ca65/segment.c | 145 ++++++++++++++++++++++----------------------- src/ca65/segment.h | 19 +++--- src/ca65/span.c | 10 ++-- 4 files changed, 91 insertions(+), 90 deletions(-) diff --git a/src/ca65/main.c b/src/ca65/main.c index 2ae3c8a76..f41ddb683 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -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); diff --git a/src/ca65/segment.c b/src/ca65/segment.c index b94123058..a089a5d88 100644 --- a/src/ca65/segment.c +++ b/src/ca65/segment.c @@ -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" @@ -69,10 +70,6 @@ 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 */ diff --git a/src/ca65/segment.h b/src/ca65/segment.h index e1e902783..84982236a 100644 --- a/src/ca65/segment.h +++ b/src/ca65/segment.h @@ -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 */ diff --git a/src/ca65/span.c b/src/ca65/span.c index 9c29b0fd1..70bc85167 100644 --- a/src/ca65/span.c +++ b/src/ca65/span.c @@ -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; } } -- 2.39.5