1
0
mirror of https://github.com/cc65/cc65.git synced 2025-02-09 17:33:00 +00:00

Use a collection to manage the segments.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5124 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-08-05 13:45:33 +00:00
parent a17d11cba8
commit 9f02a29dfa
4 changed files with 95 additions and 94 deletions

View File

@ -866,6 +866,9 @@ int main (int argc, char* argv [])
/* Initialize the include search paths */ /* Initialize the include search paths */
InitIncludePaths (); InitIncludePaths ();
/* Create the predefined segments */
InitSegments ();
/* Enter the base lexical level. We must do that here, since we may /* Enter the base lexical level. We must do that here, since we may
* define symbols using -D. * define symbols using -D.
*/ */
@ -991,8 +994,8 @@ int main (int argc, char* argv [])
SetMemoryModel (MMODEL_NEAR); SetMemoryModel (MMODEL_NEAR);
} }
/* Initialize the segments */ /* Set the default segment sizes according to the memory model */
InitSegments (); SetSegmentSizes ();
/* Initialize the scanner, open the input file */ /* Initialize the scanner, open the input file */
InitScanner (InFile); InitScanner (InFile);

View File

@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2007 Ullrich von Bassewitz */ /* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@ -38,6 +38,7 @@
/* common */ /* common */
#include "addrsize.h" #include "addrsize.h"
#include "coll.h"
#include "mmodel.h" #include "mmodel.h"
#include "segnames.h" #include "segnames.h"
#include "xmalloc.h" #include "xmalloc.h"
@ -69,10 +70,6 @@
static int RelocMode = 1; static int RelocMode = 1;
static unsigned long AbsPC = 0; /* PC if in absolute mode */ 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 */ /* Definitions for predefined segments */
SegDef NullSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_NULL, ADDR_SIZE_ABS); SegDef NullSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_NULL, ADDR_SIZE_ABS);
SegDef ZeropageSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_ZEROPAGE, ADDR_SIZE_ZP); 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 RODataSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_RODATA, ADDR_SIZE_ABS);
SegDef CodeSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_CODE, ADDR_SIZE_ABS); SegDef CodeSegDef = STATIC_SEGDEF_INITIALIZER (SEGNAME_CODE, ADDR_SIZE_ABS);
/* Predefined segments */ /* Collection containing all segments */
static Segment NullSeg = SEG (&NullSegDef, 5, NULL); Collection SegmentList = STATIC_COLLECTION_INITIALIZER;
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;
/* Currently active segment */ /* Currently active segment */
Segment* ActiveSeg = &CodeSeg; Segment* ActiveSeg;
@ -107,13 +92,39 @@ Segment* ActiveSeg = &CodeSeg;
static Segment* NewSegFromDef (SegDef* Def)
/* Create a new segment from a segment definition. Used only internally, no
* checks.
*/
{
/* Create a new segment */
Segment* S = xmalloc (sizeof (*S));
/* Initialize it */
S->Root = 0;
S->Last = 0;
S->FragCount = 0;
S->Num = CollCount (&SegmentList);
S->Align = 0;
S->RelocMode = 1;
S->PC = 0;
S->AbsPC = 0;
S->Def = Def;
/* Insert it into the segment list */
CollAppend (&SegmentList, S);
/* And return it... */
return S;
}
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 */ /* Create a new segment, insert it into the global list and return it */
{ {
Segment* S;
/* Check for too many segments */ /* Check for too many segments */
if (SegmentCount >= 256) { if (CollCount (&SegmentList) >= 256) {
Fatal ("Too many segments"); Fatal ("Too many segments");
} }
@ -122,27 +133,8 @@ static Segment* NewSegment (const char* Name, unsigned char AddrSize)
Error ("Illegal segment name: `%s'", Name); Error ("Illegal segment name: `%s'", Name);
} }
/* Create a new segment */ /* Create a new segment and return it */
S = xmalloc (sizeof (*S)); return NewSegFromDef (NewSegDef (Name, AddrSize));
/* Initialize it */
S->List = 0;
S->Root = 0;
S->Last = 0;
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 */
SegmentLast->List = S;
SegmentLast = S;
/* And return it... */
return S;
} }
@ -195,30 +187,28 @@ Fragment* GenFragment (unsigned char Type, unsigned short Len)
void UseSeg (const SegDef* D) void UseSeg (const SegDef* D)
/* Use the segment with the given name */ /* Use the segment with the given name */
{ {
Segment* Seg = SegmentList; unsigned I;
while (Seg) { for (I = 0; I < CollCount (&SegmentList); ++I) {
Segment* Seg = CollAtUnchecked (&SegmentList, I);
if (strcmp (Seg->Def->Name, D->Name) == 0) { if (strcmp (Seg->Def->Name, D->Name) == 0) {
/* We found this segment. Check if the type is identical */ /* We found this segment. Check if the type is identical */
if (D->AddrSize != ADDR_SIZE_DEFAULT && if (D->AddrSize != ADDR_SIZE_DEFAULT &&
Seg->Def->AddrSize != D->AddrSize) { Seg->Def->AddrSize != D->AddrSize) {
Error ("Segment attribute mismatch"); Error ("Segment attribute mismatch");
/* Use the new attribute to avoid errors */ /* Use the new attribute to avoid errors */
Seg->Def->AddrSize = D->AddrSize; Seg->Def->AddrSize = D->AddrSize;
} }
ActiveSeg = Seg; ActiveSeg = Seg;
return; return;
} }
/* Check next segment */
Seg = Seg->List;
} }
/* Segment is not in list, create a new one */ /* Segment is not in list, create a new one */
if (D->AddrSize == ADDR_SIZE_DEFAULT) { if (D->AddrSize == ADDR_SIZE_DEFAULT) {
Seg = NewSegment (D->Name, ADDR_SIZE_ABS); ActiveSeg = NewSegment (D->Name, ADDR_SIZE_ABS);
} else { } 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) unsigned char GetSegAddrSize (unsigned SegNum)
/* Return the address size of the segment with the given number */ /* Return the address size of the segment with the given number */
{ {
/* Search for the segment */ /* Is there such a segment? */
Segment* S = SegmentList; if (SegNum >= CollCount (&SegmentList)) {
while (S && SegNum) {
--SegNum;
S = S->List;
}
/* Did we find it? */
if (S == 0) {
FAIL ("Invalid segment number"); FAIL ("Invalid segment number");
} }
/* Return the address size */ /* 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) void SegCheck (void)
/* Check the segments for range and other errors */ /* Check the segments for range and other errors */
{ {
Segment* S = SegmentList; unsigned I;
while (S) { for (I = 0; I < CollCount (&SegmentList); ++I) {
Segment* S = CollAtUnchecked (&SegmentList, I);
Fragment* F = S->Root; Fragment* F = S->Root;
while (F) { while (F) {
if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) { if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
@ -421,7 +405,6 @@ void SegCheck (void)
} }
F = F->Next; F = F->Next;
} }
S = S->List;
} }
} }
@ -430,10 +413,12 @@ void SegCheck (void)
void SegDump (void) void SegDump (void)
/* Dump the contents of all segments */ /* Dump the contents of all segments */
{ {
unsigned I;
unsigned X = 0; unsigned X = 0;
Segment* S = SegmentList;
printf ("\n"); printf ("\n");
while (S) { for (I = 0; I < CollCount (&SegmentList); ++I) {
Segment* S = CollAtUnchecked (&SegmentList, I);
unsigned I; unsigned I;
Fragment* F; Fragment* F;
int State = -1; int State = -1;
@ -466,7 +451,6 @@ void SegDump (void)
F = F->Next; F = F->Next;
} }
printf ("\n End PC = $%04X\n", (unsigned)(S->PC & 0xFFFF)); printf ("\n End PC = $%04X\n", (unsigned)(S->PC & 0xFFFF));
S = S->List;
} }
printf ("\n"); printf ("\n");
} }
@ -559,6 +543,20 @@ static void WriteOneSeg (Segment* Seg)
void InitSegments (void) void InitSegments (void)
/* Initialize segments */ /* 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 /* Initialize segment sizes. The segment definitions do already contain
* the correct values for the default case (near), so we must only change * the correct values for the default case (near), so we must only change
@ -590,21 +588,18 @@ void InitSegments (void)
void WriteSegments (void) void WriteSegments (void)
/* Write the segment data to the object file */ /* 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 */ /* Tell the object file module that we're about to start the seg list */
ObjStartSegments (); ObjStartSegments ();
/* First thing is segment count */ /* First thing is segment count */
ObjWriteVar (SegmentCount); ObjWriteVar (CollCount (&SegmentList));
/* Now walk through all segments and write them to the object file */ /* Now walk through all segments and write them to the object file */
Seg = SegmentList; for (I = 0; I < CollCount (&SegmentList); ++I) {
while (Seg) {
/* Write one segment */ /* Write one segment */
WriteOneSeg (Seg); WriteOneSeg (CollAtUnchecked (&SegmentList, I));
/* Next segment */
Seg = Seg->List;
} }
/* Done writing segments */ /* Done writing segments */

View File

@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2007 Ullrich von Bassewitz */ /* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@ -39,6 +39,7 @@
/* common */ /* common */
#include "coll.h"
#include "fragdefs.h" #include "fragdefs.h"
#include "inline.h" #include "inline.h"
#include "segdefs.h" #include "segdefs.h"
@ -49,7 +50,7 @@
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
@ -57,7 +58,6 @@
/* Segment definition */ /* Segment definition */
typedef struct Segment Segment; typedef struct Segment Segment;
struct Segment { struct Segment {
Segment* List; /* List of all segments */
Fragment* Root; /* Root of fragment list */ Fragment* Root; /* Root of fragment list */
Fragment* Last; /* Pointer to last fragment */ Fragment* Last; /* Pointer to last fragment */
unsigned long FragCount; /* Number of fragments */ unsigned long FragCount; /* Number of fragments */
@ -78,8 +78,8 @@ extern SegDef BssSegDef;
extern SegDef RODataSegDef; extern SegDef RODataSegDef;
extern SegDef CodeSegDef; extern SegDef CodeSegDef;
/* List of all segments */ /* Collection containing all segments */
extern Segment* SegmentList; extern Collection SegmentList;
/* Currently active segment */ /* Currently active segment */
extern Segment* ActiveSeg; extern Segment* ActiveSeg;
@ -162,6 +162,9 @@ void SegDump (void);
void InitSegments (void); void InitSegments (void);
/* Initialize segments */ /* Initialize segments */
void SetSegmentSizes (void);
/* Set the default segment sizes according to the memory model */
void WriteSegments (void); void WriteSegments (void);
/* Write the segment data to the object file */ /* Write the segment data to the object file */

View File

@ -50,7 +50,7 @@
Span* NewSpan (struct Segment* Seg) 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. * current PC of the segment.
*/ */
{ {
@ -73,19 +73,19 @@ void AddSpans (Collection* Spans)
* currently active segment will be inserted first with all others following. * currently active segment will be inserted first with all others following.
*/ */
{ {
Segment* Seg; unsigned I;
/* Add the currently active segment */ /* Add the currently active segment */
CollAppend (Spans, NewSpan (ActiveSeg)); CollAppend (Spans, NewSpan (ActiveSeg));
/* Walk through the segment list and add all other segments */ /* Walk through the segment list and add all other segments */
Seg = SegmentList; for (I = 0; I < CollCount (&SegmentList); ++I) {
while (Seg) { Segment* Seg = CollAtUnchecked (&SegmentList, I);
/* Be sure to skip the active segment, since it was already added */ /* Be sure to skip the active segment, since it was already added */
if (Seg != ActiveSeg) { if (Seg != ActiveSeg) {
CollAppend (Spans, NewSpan (Seg)); CollAppend (Spans, NewSpan (Seg));
} }
Seg = Seg->List;
} }
} }