Added an OPTIONAL segment attribute
git-svn-id: svn://svn.cc65.org/cc65/trunk@2162 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
741362f830
commit
40609f0a3c
3 changed files with 108 additions and 93 deletions
|
@ -6,10 +6,10 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2002 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* 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 */
|
||||||
|
@ -98,6 +98,7 @@ unsigned SegDescCount; /* Number of entries in list */
|
||||||
#define SA_DEFINE 0x0010
|
#define SA_DEFINE 0x0010
|
||||||
#define SA_OFFSET 0x0020
|
#define SA_OFFSET 0x0020
|
||||||
#define SA_START 0x0040
|
#define SA_START 0x0040
|
||||||
|
#define SA_OPTIONAL 0x0080
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -336,11 +337,10 @@ static SegDesc* NewSegDesc (const char* Name)
|
||||||
CfgError ("Segment `%s' defined twice", Name);
|
CfgError ("Segment `%s' defined twice", Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify that the given segment does really exist */
|
/* Search for the actual segment in the input files. The function may
|
||||||
|
* return NULL (no such segment), this is checked later.
|
||||||
|
*/
|
||||||
Seg = SegFind (Name);
|
Seg = SegFind (Name);
|
||||||
if (Seg == 0) {
|
|
||||||
CfgWarning ("Segment `%s' does not exist", Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
S = xmalloc (sizeof (SegDesc) + Len);
|
S = xmalloc (sizeof (SegDesc) + Len);
|
||||||
|
@ -608,21 +608,22 @@ static void ParseSegments (void)
|
||||||
/* Parse a SEGMENTS section */
|
/* Parse a SEGMENTS section */
|
||||||
{
|
{
|
||||||
static const IdentTok Attributes [] = {
|
static const IdentTok Attributes [] = {
|
||||||
{ "LOAD", CFGTOK_LOAD },
|
|
||||||
{ "RUN", CFGTOK_RUN },
|
|
||||||
{ "TYPE", CFGTOK_TYPE },
|
|
||||||
{ "ALIGN", CFGTOK_ALIGN },
|
{ "ALIGN", CFGTOK_ALIGN },
|
||||||
{ "DEFINE", CFGTOK_DEFINE },
|
{ "DEFINE", CFGTOK_DEFINE },
|
||||||
{ "OFFSET", CFGTOK_OFFSET },
|
{ "LOAD", CFGTOK_LOAD },
|
||||||
{ "START", CFGTOK_START },
|
{ "OFFSET", CFGTOK_OFFSET },
|
||||||
|
{ "OPTIONAL", CFGTOK_OPTIONAL },
|
||||||
|
{ "RUN", CFGTOK_RUN },
|
||||||
|
{ "START", CFGTOK_START },
|
||||||
|
{ "TYPE", CFGTOK_TYPE },
|
||||||
};
|
};
|
||||||
static const IdentTok Types [] = {
|
static const IdentTok Types [] = {
|
||||||
{ "RO", CFGTOK_RO },
|
{ "RO", CFGTOK_RO },
|
||||||
{ "RW", CFGTOK_RW },
|
{ "RW", CFGTOK_RW },
|
||||||
{ "BSS", CFGTOK_BSS },
|
{ "BSS", CFGTOK_BSS },
|
||||||
{ "ZP", CFGTOK_ZP },
|
{ "ZP", CFGTOK_ZP },
|
||||||
{ "WP", CFGTOK_WPROT },
|
{ "WP", CFGTOK_WPROT },
|
||||||
{ "WPROT", CFGTOK_WPROT },
|
{ "WPROT", CFGTOK_WPROT },
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned Count;
|
unsigned Count;
|
||||||
|
@ -653,66 +654,74 @@ static void ParseSegments (void)
|
||||||
/* Check which attribute was given */
|
/* Check which attribute was given */
|
||||||
switch (AttrTok) {
|
switch (AttrTok) {
|
||||||
|
|
||||||
case CFGTOK_LOAD:
|
|
||||||
FlagAttr (&S->Attr, SA_LOAD, "LOAD");
|
|
||||||
S->Load = CfgGetMemory (CfgSVal);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CFGTOK_RUN:
|
|
||||||
FlagAttr (&S->Attr, SA_RUN, "RUN");
|
|
||||||
S->Run = CfgGetMemory (CfgSVal);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CFGTOK_TYPE:
|
|
||||||
FlagAttr (&S->Attr, SA_TYPE, "TYPE");
|
|
||||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
|
||||||
switch (CfgTok) {
|
|
||||||
case CFGTOK_RO: S->Flags |= SF_RO; break;
|
|
||||||
case CFGTOK_RW: /* Default */ break;
|
|
||||||
case CFGTOK_BSS: S->Flags |= SF_BSS; break;
|
|
||||||
case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break;
|
|
||||||
case CFGTOK_WPROT: S->Flags |= (SF_RO | SF_WPROT); break;
|
|
||||||
default: Internal ("Unexpected token: %d", CfgTok);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CFGTOK_ALIGN:
|
case CFGTOK_ALIGN:
|
||||||
CfgAssureInt ();
|
CfgAssureInt ();
|
||||||
FlagAttr (&S->Attr, SA_ALIGN, "ALIGN");
|
FlagAttr (&S->Attr, SA_ALIGN, "ALIGN");
|
||||||
CfgRangeCheck (1, 0x10000);
|
CfgRangeCheck (1, 0x10000);
|
||||||
S->Align = BitFind (CfgIVal);
|
S->Align = BitFind (CfgIVal);
|
||||||
if ((0x01UL << S->Align) != CfgIVal) {
|
if ((0x01UL << S->Align) != CfgIVal) {
|
||||||
CfgError ("Alignment must be a power of 2");
|
CfgError ("Alignment must be a power of 2");
|
||||||
}
|
}
|
||||||
S->Flags |= SF_ALIGN;
|
S->Flags |= SF_ALIGN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CFGTOK_DEFINE:
|
case CFGTOK_DEFINE:
|
||||||
FlagAttr (&S->Attr, SA_DEFINE, "DEFINE");
|
FlagAttr (&S->Attr, SA_DEFINE, "DEFINE");
|
||||||
/* Map the token to a boolean */
|
/* Map the token to a boolean */
|
||||||
CfgBoolToken ();
|
CfgBoolToken ();
|
||||||
if (CfgTok == CFGTOK_TRUE) {
|
if (CfgTok == CFGTOK_TRUE) {
|
||||||
S->Flags |= SF_DEFINE;
|
S->Flags |= SF_DEFINE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CFGTOK_LOAD:
|
||||||
|
FlagAttr (&S->Attr, SA_LOAD, "LOAD");
|
||||||
|
S->Load = CfgGetMemory (CfgSVal);
|
||||||
|
break;
|
||||||
|
|
||||||
case CFGTOK_OFFSET:
|
case CFGTOK_OFFSET:
|
||||||
CfgAssureInt ();
|
CfgAssureInt ();
|
||||||
FlagAttr (&S->Attr, SA_OFFSET, "OFFSET");
|
FlagAttr (&S->Attr, SA_OFFSET, "OFFSET");
|
||||||
CfgRangeCheck (1, 0x1000000);
|
CfgRangeCheck (1, 0x1000000);
|
||||||
S->Addr = CfgIVal;
|
S->Addr = CfgIVal;
|
||||||
S->Flags |= SF_OFFSET;
|
S->Flags |= SF_OFFSET;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CFGTOK_OPTIONAL:
|
||||||
|
FlagAttr (&S->Attr, SA_OPTIONAL, "OPTIONAL");
|
||||||
|
CfgBoolToken ();
|
||||||
|
if (CfgTok == CFGTOK_TRUE) {
|
||||||
|
S->Flags |= SF_OPTIONAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CFGTOK_RUN:
|
||||||
|
FlagAttr (&S->Attr, SA_RUN, "RUN");
|
||||||
|
S->Run = CfgGetMemory (CfgSVal);
|
||||||
|
break;
|
||||||
|
|
||||||
case CFGTOK_START:
|
case CFGTOK_START:
|
||||||
CfgAssureInt ();
|
CfgAssureInt ();
|
||||||
FlagAttr (&S->Attr, SA_START, "START");
|
FlagAttr (&S->Attr, SA_START, "START");
|
||||||
CfgRangeCheck (1, 0x1000000);
|
CfgRangeCheck (1, 0x1000000);
|
||||||
S->Addr = CfgIVal;
|
S->Addr = CfgIVal;
|
||||||
S->Flags |= SF_START;
|
S->Flags |= SF_START;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case CFGTOK_TYPE:
|
||||||
|
FlagAttr (&S->Attr, SA_TYPE, "TYPE");
|
||||||
|
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
||||||
|
switch (CfgTok) {
|
||||||
|
case CFGTOK_RO: S->Flags |= SF_RO; break;
|
||||||
|
case CFGTOK_RW: /* Default */ break;
|
||||||
|
case CFGTOK_BSS: S->Flags |= SF_BSS; break;
|
||||||
|
case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break;
|
||||||
|
case CFGTOK_WPROT: S->Flags |= (SF_RO | SF_WPROT); break;
|
||||||
|
default: Internal ("Unexpected token: %d", CfgTok);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
FAIL ("Unexpected attribute token");
|
FAIL ("Unexpected attribute token");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -744,7 +753,7 @@ static void ParseSegments (void)
|
||||||
*/
|
*/
|
||||||
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
|
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
|
||||||
Warning ("%s(%u): Segment with type `bss' contains initialized data",
|
Warning ("%s(%u): Segment with type `bss' contains initialized data",
|
||||||
CfgGetName (), CfgErrorLine);
|
CfgGetName (), CfgErrorLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the segment is marked as BSS style, it may not have separate
|
/* If the segment is marked as BSS style, it may not have separate
|
||||||
|
@ -758,23 +767,23 @@ static void ParseSegments (void)
|
||||||
/* Don't allow read/write data to be put into a readonly area */
|
/* Don't allow read/write data to be put into a readonly area */
|
||||||
if ((S->Flags & SF_RO) == 0) {
|
if ((S->Flags & SF_RO) == 0) {
|
||||||
if (S->Run->Flags & MF_RO) {
|
if (S->Run->Flags & MF_RO) {
|
||||||
CfgError ("Cannot put r/w segment `%s' in r/o memory area `%s'",
|
CfgError ("Cannot put r/w segment `%s' in r/o memory area `%s'",
|
||||||
S->Name, S->Run->Name);
|
S->Name, S->Run->Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only one of ALIGN, START and OFFSET may be used */
|
/* Only one of ALIGN, START and OFFSET may be used */
|
||||||
Count = ((S->Flags & SF_ALIGN) != 0) +
|
Count = ((S->Flags & SF_ALIGN) != 0) +
|
||||||
((S->Flags & SF_OFFSET) != 0) +
|
((S->Flags & SF_OFFSET) != 0) +
|
||||||
((S->Flags & SF_START) != 0);
|
((S->Flags & SF_START) != 0);
|
||||||
if (Count > 1) {
|
if (Count > 1) {
|
||||||
CfgError ("Only one of ALIGN, START, OFFSET may be used");
|
CfgError ("Only one of ALIGN, START, OFFSET may be used");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this segment does exist in any of the object files, insert the
|
/* If this segment does exist in any of the object files, insert the
|
||||||
* descriptor into the list of segment descriptors. Otherwise discard
|
* descriptor into the list of segment descriptors. Otherwise print a
|
||||||
* it silently, because the segment pointer in the descriptor is
|
* warning and discard it, because the segment pointer in the
|
||||||
* invalid.
|
* descriptor is invalid.
|
||||||
*/
|
*/
|
||||||
if (S->Seg != 0) {
|
if (S->Seg != 0) {
|
||||||
/* Insert the descriptor into the list of all descriptors */
|
/* Insert the descriptor into the list of all descriptors */
|
||||||
|
@ -782,11 +791,15 @@ static void ParseSegments (void)
|
||||||
/* Insert the segment into the memory area list */
|
/* Insert the segment into the memory area list */
|
||||||
MemoryInsert (S->Run, S);
|
MemoryInsert (S->Run, S);
|
||||||
if ((S->Flags & SF_LOAD_AND_RUN) != 0) {
|
if ((S->Flags & SF_LOAD_AND_RUN) != 0) {
|
||||||
/* We have a separate RUN area given */
|
/* We have a separate RUN area given */
|
||||||
MemoryInsert (S->Load, S);
|
MemoryInsert (S->Load, S);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Segment does not exist, discard the descriptor */
|
/* Print a warning if the segment is not optional */
|
||||||
|
if ((S->Flags & SF_OPTIONAL) == 0) {
|
||||||
|
CfgWarning ("Segment `%s' does not exist", S->Name);
|
||||||
|
}
|
||||||
|
/* Discard the descriptor */
|
||||||
FreeSegDesc (S);
|
FreeSegDesc (S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* 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 */
|
||||||
|
@ -107,14 +107,15 @@ extern unsigned SegDescCount; /* Number of entries in list */
|
||||||
#define MF_RO 0x0004 /* Read only memory area */
|
#define MF_RO 0x0004 /* Read only memory area */
|
||||||
|
|
||||||
/* Segment flags */
|
/* Segment flags */
|
||||||
#define SF_RO 0x0001 /* Read only segment */
|
#define SF_RO 0x0001 /* Read only segment */
|
||||||
#define SF_BSS 0x0002 /* Segment is BSS style segment */
|
#define SF_BSS 0x0002 /* Segment is BSS style segment */
|
||||||
#define SF_ZP 0x0004 /* Zeropage segment (o65 only) */
|
#define SF_ZP 0x0004 /* Zeropage segment (o65 only) */
|
||||||
#define SF_WPROT 0x0008 /* Write protected segment */
|
#define SF_WPROT 0x0008 /* Write protected segment */
|
||||||
#define SF_DEFINE 0x0010 /* Define start and size */
|
#define SF_DEFINE 0x0010 /* Define start and size */
|
||||||
#define SF_ALIGN 0x0020 /* Align the segment */
|
#define SF_ALIGN 0x0020 /* Align the segment */
|
||||||
#define SF_OFFSET 0x0040 /* Segment has offset in memory */
|
#define SF_OFFSET 0x0040 /* Segment has offset in memory */
|
||||||
#define SF_START 0x0080 /* Segment has fixed start address */
|
#define SF_START 0x0080 /* Segment has fixed start address */
|
||||||
|
#define SF_OPTIONAL 0x0100 /* Segment is optional (must not exist) */
|
||||||
#define SF_LOAD_AND_RUN 0x1000 /* LOAD and RUN given */
|
#define SF_LOAD_AND_RUN 0x1000 /* LOAD and RUN given */
|
||||||
#define SF_RUN_DEF 0x2000 /* RUN symbols already defined */
|
#define SF_RUN_DEF 0x2000 /* RUN symbols already defined */
|
||||||
#define SF_LOAD_DEF 0x4000 /* LOAD symbols already defined */
|
#define SF_LOAD_DEF 0x4000 /* LOAD symbols already defined */
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* 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 */
|
||||||
|
@ -85,6 +85,7 @@ typedef enum {
|
||||||
CFGTOK_RUN,
|
CFGTOK_RUN,
|
||||||
CFGTOK_ALIGN,
|
CFGTOK_ALIGN,
|
||||||
CFGTOK_OFFSET,
|
CFGTOK_OFFSET,
|
||||||
|
CFGTOK_OPTIONAL,
|
||||||
|
|
||||||
CFGTOK_RO,
|
CFGTOK_RO,
|
||||||
CFGTOK_RW,
|
CFGTOK_RW,
|
||||||
|
|
Loading…
Add table
Reference in a new issue