1
0
mirror of https://github.com/cc65/cc65.git synced 2025-02-04 13:32:54 +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 */
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);

View 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"
@ -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,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)
/* Create a new segment, insert it into the global list and return it */
{
Segment* S;
/* Check for too many segments */
if (SegmentCount >= 256) {
if (CollCount (&SegmentList) >= 256) {
Fatal ("Too many segments");
}
@ -122,27 +133,8 @@ static Segment* NewSegment (const char* Name, unsigned char AddrSize)
Error ("Illegal segment name: `%s'", Name);
}
/* Create a new segment */
S = xmalloc (sizeof (*S));
/* 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;
/* Create a new segment and return it */
return NewSegFromDef (NewSegDef (Name, AddrSize));
}
@ -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 */

View 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 */

View 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;
}
}