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:
parent
a17d11cba8
commit
9f02a29dfa
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user