1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-25 11:30:06 +00:00

New .FEATURE org_per_seg. If enabled, .org/.reloc do only influence the

current segment. Idea by Peter Wendrich <pwsoft@syntiac.com>.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3794 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2007-08-23 19:48:43 +00:00
parent 5eadec958c
commit a7358314a0
11 changed files with 131 additions and 50 deletions

View File

@ -2273,6 +2273,13 @@ Here's a list of all control commands and a description, what they do:
<bf/Note:/ This does not work in conjunction with <tt/.FEATURE <bf/Note:/ This does not work in conjunction with <tt/.FEATURE
loose_string_term/, since in this case the input would be ambiguous. loose_string_term/, since in this case the input would be ambiguous.
<tag><tt>org_per_seg</tt><label id="org_per_seg"></tag>
This feature makes relocatable/absolute mode local to the current segment.
Using <tt><ref id=".ORG" name=".ORG"></tt> when <tt/org_per_seg/ is in
effect will only enable absolute mode for the current segment. Dito for
<tt><ref id=".RELOC" name=".RELOC"></tt>.
<tag><tt>pc_assignment</tt></tag> <tag><tt>pc_assignment</tt></tag>
Allow assignments to the PC symbol (`*' or `&dollar;' if <tt/dollar_is_pc/ Allow assignments to the PC symbol (`*' or `&dollar;' if <tt/dollar_is_pc/
@ -2798,12 +2805,14 @@ Here's a list of all control commands and a description, what they do:
assembled. Use <tt><ref id=".RELOC" name=".RELOC"></tt> to switch back to assembled. Use <tt><ref id=".RELOC" name=".RELOC"></tt> to switch back to
relocatable code. relocatable code.
Please note that you <em/do not need/ this command in most cases. Placing By default, absolute/relocatable mode is global (valid even when switching
segments). Using <tt>.FEATURE <ref id="org_per_seg" name="org_per_seg"></tt>
it can be made segment local.
Please note that you <em/do not need/ <tt/.ORG/ in most cases. Placing
code at a specific address is the job of the linker, not the assembler, so code at a specific address is the job of the linker, not the assembler, so
there is usually no reason to assemble code to a specific address. there is usually no reason to assemble code to a specific address.
You may not switch segments while inside a section of absolute code.
Example: Example:
<tscreen><verb> <tscreen><verb>

View File

@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2006 Ullrich von Bassewitz */ /* (C) 1998-2007 Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@ -1482,7 +1482,7 @@ ExprNode* GenCurrentPC (void)
{ {
ExprNode* Root; ExprNode* Root;
if (RelocMode) { if (GetRelocMode ()) {
/* Create SegmentBase + Offset */ /* Create SegmentBase + Offset */
Root = GenAddExpr (GenSectionExpr (GetCurrentSegNum ()), Root = GenAddExpr (GenSectionExpr (GetCurrentSegNum ()),
GenLiteralExpr (GetPC ())); GenLiteralExpr (GetPC ()));
@ -1531,7 +1531,7 @@ ExprNode* GenBranchExpr (unsigned Offs)
* (Val - PC - Offs) - Seg * (Val - PC - Offs) - Seg
*/ */
Root = GenLiteralExpr (Val - GetPC () - Offs); Root = GenLiteralExpr (Val - GetPC () - Offs);
if (RelocMode) { if (GetRelocMode ()) {
N = Root; N = Root;
Root = NewExprNode (EXPR_MINUS); Root = NewExprNode (EXPR_MINUS);
Root->Left = N; Root->Left = N;
@ -1549,7 +1549,7 @@ ExprNode* GenBranchExpr (unsigned Offs)
Root = NewExprNode (EXPR_MINUS); Root = NewExprNode (EXPR_MINUS);
Root->Left = N; Root->Left = N;
Root->Right = GenLiteralExpr (GetPC () + Offs); Root->Right = GenLiteralExpr (GetPC () + Offs);
if (RelocMode) { if (GetRelocMode ()) {
N = Root; N = Root;
Root = NewExprNode (EXPR_MINUS); Root = NewExprNode (EXPR_MINUS);
Root->Left = N; Root->Left = N;

View File

@ -56,6 +56,7 @@ static const char* FeatureKeys[FEAT_COUNT] = {
"at_in_identifiers", "at_in_identifiers",
"dollar_in_identifiers", "dollar_in_identifiers",
"leading_dot_in_identifiers", "leading_dot_in_identifiers",
"org_per_seg",
"pc_assignment", "pc_assignment",
"missing_char_term", "missing_char_term",
"ubiquitous_idents", "ubiquitous_idents",
@ -108,10 +109,11 @@ feature_t SetFeature (const char* Key)
case FEAT_AT_IN_IDENTIFIERS: AtInIdents = 1; break; case FEAT_AT_IN_IDENTIFIERS: AtInIdents = 1; break;
case FEAT_DOLLAR_IN_IDENTIFIERS: DollarInIdents = 1; break; case FEAT_DOLLAR_IN_IDENTIFIERS: DollarInIdents = 1; break;
case FEAT_LEADING_DOT_IN_IDENTIFIERS: LeadingDotInIdents= 1; break; case FEAT_LEADING_DOT_IN_IDENTIFIERS: LeadingDotInIdents= 1; break;
case FEAT_ORG_PER_SEG: OrgPerSeg = 1; break;
case FEAT_PC_ASSIGNMENT: PCAssignment = 1; break; case FEAT_PC_ASSIGNMENT: PCAssignment = 1; break;
case FEAT_MISSING_CHAR_TERM: MissingCharTerm = 1; break; case FEAT_MISSING_CHAR_TERM: MissingCharTerm = 1; break;
case FEAT_UBIQUITOUS_IDENTS: UbiquitousIdents = 1; break; case FEAT_UBIQUITOUS_IDENTS: UbiquitousIdents = 1; break;
default: /* Keep gcc silent */ break; default: /* Keep gcc silent */ break;
} }
/* Return the value found */ /* Return the value found */

View File

@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2003 Ullrich von Bassewitz */ /* (C) 2000-2007 Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@ -45,7 +45,7 @@
typedef enum { typedef enum {
FEAT_UNKNOWN = -1, FEAT_UNKNOWN = -1,
FEAT_DOLLAR_IS_PC, FEAT_DOLLAR_IS_PC,
FEAT_LABELS_WITHOUT_COLONS, FEAT_LABELS_WITHOUT_COLONS,
FEAT_LOOSE_STRING_TERM, FEAT_LOOSE_STRING_TERM,
@ -53,6 +53,7 @@ typedef enum {
FEAT_AT_IN_IDENTIFIERS, FEAT_AT_IN_IDENTIFIERS,
FEAT_DOLLAR_IN_IDENTIFIERS, FEAT_DOLLAR_IN_IDENTIFIERS,
FEAT_LEADING_DOT_IN_IDENTIFIERS, FEAT_LEADING_DOT_IN_IDENTIFIERS,
FEAT_ORG_PER_SEG,
FEAT_PC_ASSIGNMENT, FEAT_PC_ASSIGNMENT,
FEAT_MISSING_CHAR_TERM, FEAT_MISSING_CHAR_TERM,
FEAT_UBIQUITOUS_IDENTS, FEAT_UBIQUITOUS_IDENTS,

View File

@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2004 Ullrich von Bassewitz */ /* (C) 1998-2007 Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@ -65,7 +65,7 @@ unsigned char DbgSyms = 0; /* Add debug symbols */
unsigned char Listing = 0; /* Create listing file */ unsigned char Listing = 0; /* Create listing file */
unsigned char LineCont = 0; /* Allow line continuation */ unsigned char LineCont = 0; /* Allow line continuation */
/* Emulation features */ /* Emulation features */
unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */ unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */
unsigned char NoColonLabels = 0; /* Allow labels without a colon */ unsigned char NoColonLabels = 0; /* Allow labels without a colon */
unsigned char LooseStringTerm = 0; /* Allow ' as string terminator */ unsigned char LooseStringTerm = 0; /* Allow ' as string terminator */
@ -76,6 +76,7 @@ unsigned char LeadingDotInIdents = 0; /* Allow '.' to start an identifier */
unsigned char PCAssignment = 0; /* Allow "* = $XXX" or "$ = $XXX" */ unsigned char PCAssignment = 0; /* Allow "* = $XXX" or "$ = $XXX" */
unsigned char MissingCharTerm = 0; /* Allow lda #'a (no closing term) */ unsigned char MissingCharTerm = 0; /* Allow lda #'a (no closing term) */
unsigned char UbiquitousIdents = 0; /* Allow ubiquitous identifiers */ unsigned char UbiquitousIdents = 0; /* Allow ubiquitous identifiers */
unsigned char OrgPerSeg = 0; /* Make .org local to current seg */
/* Misc stuff */ /* Misc stuff */
const char Copyright[] = "(C) Copyright 1998-2005 Ullrich von Bassewitz"; const char Copyright[] = "(C) Copyright 1998-2005 Ullrich von Bassewitz";

View File

@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2004 Ullrich von Bassewitz */ /* (C) 1998-2007 Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@ -73,6 +73,7 @@ extern unsigned char LeadingDotInIdents; /* Allow '.' to start an identifier
extern unsigned char PCAssignment; /* Allow "* = $XXX" or "$ = $XXX" */ extern unsigned char PCAssignment; /* Allow "* = $XXX" or "$ = $XXX" */
extern unsigned char MissingCharTerm; /* Allow lda #'a (no closing term) */ extern unsigned char MissingCharTerm; /* Allow lda #'a (no closing term) */
extern unsigned char UbiquitousIdents; /* Allow ubiquitous identifiers */ extern unsigned char UbiquitousIdents; /* Allow ubiquitous identifiers */
extern unsigned char OrgPerSeg; /* Make .org local to current seg */
/* Misc stuff */ /* Misc stuff */
extern const char Copyright[]; /* Copyright string */ extern const char Copyright[]; /* Copyright string */

View File

@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2003 Ullrich von Bassewitz */ /* (C) 2000-2007 Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@ -105,7 +105,7 @@ void NewListingLine (const char* Line, unsigned char File, unsigned char Depth)
L->FragList = 0; L->FragList = 0;
L->FragLast = 0; L->FragLast = 0;
L->PC = GetPC (); L->PC = GetPC ();
L->Reloc = RelocMode; L->Reloc = GetRelocMode ();
L->File = File; L->File = File;
L->Depth = Depth; L->Depth = Depth;
L->Output = (ListingEnabled > 0); L->Output = (ListingEnabled > 0);
@ -181,7 +181,7 @@ void InitListingLine (void)
/* Set the values for this line */ /* Set the values for this line */
CHECK (L != 0); CHECK (L != 0);
L->PC = GetPC (); L->PC = GetPC ();
L->Reloc = RelocMode; L->Reloc = GetRelocMode ();
L->Output = (ListingEnabled > 0); L->Output = (ListingEnabled > 0);
L->ListBytes = (unsigned char) ListBytes; L->ListBytes = (unsigned char) ListBytes;
} while (L->Next != LineLast); } while (L->Next != LineLast);
@ -191,7 +191,7 @@ void InitListingLine (void)
/* Set the values for this line */ /* Set the values for this line */
CHECK (LineCur != 0); CHECK (LineCur != 0);
LineCur->PC = GetPC (); LineCur->PC = GetPC ();
LineCur->Reloc = RelocMode; LineCur->Reloc = GetRelocMode ();
LineCur->Output = (ListingEnabled > 0); LineCur->Output = (ListingEnabled > 0);
LineCur->ListBytes = (unsigned char) ListBytes; LineCur->ListBytes = (unsigned char) ListBytes;
} }

View File

@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2005, Ullrich von Bassewitz */ /* (C) 1998-2007, Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@ -511,7 +511,7 @@ static void DoPCAssign (void)
if (PC < 0 || PC > 0xFFFFFF) { if (PC < 0 || PC > 0xFFFFFF) {
Error ("Range error"); Error ("Range error");
} else { } else {
SetAbsPC (PC); EnterAbsoluteMode (PC);
} }
} }

View File

@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2005, Ullrich von Bassewitz */ /* (C) 1998-2007, Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@ -1248,7 +1248,7 @@ static void DoOrg (void)
Error ("Range error"); Error ("Range error");
return; return;
} }
SetAbsPC (PC); EnterAbsoluteMode (PC);
} }
@ -1391,7 +1391,7 @@ static void DoPushSeg (void)
static void DoReloc (void) static void DoReloc (void)
/* Enter relocatable mode */ /* Enter relocatable mode */
{ {
RelocMode = 1; EnterRelocMode ();
} }

View File

@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2007 Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@ -63,13 +63,15 @@
/* Are we in absolute mode or in relocatable mode? */ /* If OrgPerSeg is false, all segments share the RelocMode flag and a PC
int RelocMode = 1; * used when in absolute mode. OrgPerSeg may be set by .feature org_per_seg
unsigned long AbsPC = 0; /* PC if in absolute mode */ */
static int RelocMode = 1;
static unsigned long AbsPC = 0; /* PC if in absolute mode */
/* Segment initializer macro */ /* Segment initializer macro */
#define SEG(segdef, num, prev) \ #define SEG(segdef, num, prev) \
{ prev, 0, 0, 0, num, 0, 0, segdef } { 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);
@ -130,7 +132,9 @@ static Segment* NewSegment (const char* Name, unsigned char AddrSize)
S->FragCount = 0; S->FragCount = 0;
S->Num = SegmentCount++; S->Num = SegmentCount++;
S->Align = 0; S->Align = 0;
S->RelocMode = 1;
S->PC = 0; S->PC = 0;
S->AbsPC = 0;
S->Def = NewSegDef (Name, AddrSize); S->Def = NewSegDef (Name, AddrSize);
/* Insert it into the segment list */ /* Insert it into the segment list */
@ -170,8 +174,16 @@ Fragment* GenFragment (unsigned char Type, unsigned short Len)
/* Increment the program counter */ /* Increment the program counter */
ActiveSeg->PC += F->Len; ActiveSeg->PC += F->Len;
if (!RelocMode) { if (OrgPerSeg) {
AbsPC += F->Len; /* Relocatable mode is switched per segment */
if (!ActiveSeg->RelocMode) {
ActiveSeg->AbsPC += F->Len;
}
} else {
/* Relocatable mode is switched globally */
if (!RelocMode) {
AbsPC += F->Len;
}
} }
/* Return the fragment */ /* Return the fragment */
@ -214,16 +226,61 @@ void UseSeg (const SegDef* D)
unsigned long GetPC (void) unsigned long GetPC (void)
/* Get the program counter of the current segment */ /* Get the program counter of the current segment */
{ {
return RelocMode? ActiveSeg->PC : AbsPC; if (OrgPerSeg) {
/* Relocatable mode is switched per segment */
return ActiveSeg->RelocMode? ActiveSeg->PC : ActiveSeg->AbsPC;
} else {
/* Relocatable mode is switched globally */
return RelocMode? ActiveSeg->PC : AbsPC;
}
} }
void SetAbsPC (unsigned long PC) void EnterAbsoluteMode (unsigned long PC)
/* Set the program counter in absolute mode */ /* Enter absolute (non relocatable mode). Depending on the OrgPerSeg flag,
* this will either switch the mode globally or for the current segment.
*/
{ {
RelocMode = 0; if (OrgPerSeg) {
AbsPC = PC; /* Relocatable mode is switched per segment */
ActiveSeg->RelocMode = 0;
ActiveSeg->AbsPC = PC;
} else {
/* Relocatable mode is switched globally */
RelocMode = 0;
AbsPC = PC;
}
}
int GetRelocMode (void)
/* Return true if we're currently in relocatable mode */
{
if (OrgPerSeg) {
/* Relocatable mode is switched per segment */
return ActiveSeg->RelocMode;
} else {
/* Relocatable mode is switched globally */
return RelocMode;
}
}
void EnterRelocMode (void)
/* Enter relocatable mode. Depending on the OrgPerSeg flag, this will either
* switch the mode globally or for the current segment.
*/
{
if (OrgPerSeg) {
/* Relocatable mode is switched per segment */
ActiveSeg->RelocMode = 1;
} else {
/* Relocatable mode is switched globally */
RelocMode = 1;
}
} }

View File

@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2007 Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@ -63,13 +63,13 @@ struct Segment {
unsigned long FragCount; /* Number of fragments */ unsigned long FragCount; /* Number of fragments */
unsigned Num; /* Segment number */ unsigned Num; /* Segment number */
unsigned Align; /* Segment alignment */ unsigned Align; /* Segment alignment */
unsigned long PC; int RelocMode; /* Relocatable mode if OrgPerSeg */
unsigned long PC; /* PC if in relocatable mode */
unsigned long AbsPC; /* PC if in local absolute mode */
/* (OrgPerSeg is true) */
SegDef* Def; /* Segment definition (name and type) */ SegDef* Def; /* Segment definition (name and type) */
}; };
/* Are we in absolute mode or in relocatable mode? */
extern int RelocMode;
/* Definitions for predefined segments */ /* Definitions for predefined segments */
extern SegDef NullSegDef; extern SegDef NullSegDef;
extern SegDef ZeropageSegDef; extern SegDef ZeropageSegDef;
@ -140,8 +140,18 @@ unsigned char GetSegAddrSize (unsigned SegNum);
unsigned long GetPC (void); unsigned long GetPC (void);
/* Get the program counter of the current segment */ /* Get the program counter of the current segment */
void SetAbsPC (unsigned long AbsPC); int GetRelocMode (void);
/* Set the program counter in absolute mode */ /* Return true if we're currently in relocatable mode */
void EnterAbsoluteMode (unsigned long AbsPC);
/* Enter absolute (non relocatable mode). Depending on the OrgPerSeg flag,
* this will either switch the mode globally or for the current segment.
*/
void EnterRelocMode (void);
/* Enter relocatable mode. Depending on the OrgPerSeg flag, this will either
* switch the mode globally or for the current segment.
*/
void SegCheck (void); void SegCheck (void);
/* Check the segments for range and other errors */ /* Check the segments for range and other errors */