1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-10 19:29:45 +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
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>
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
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
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:
<tscreen><verb>

View File

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

View File

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

View File

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

View File

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

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 1998-2007 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* 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 MissingCharTerm; /* Allow lda #'a (no closing term) */
extern unsigned char UbiquitousIdents; /* Allow ubiquitous identifiers */
extern unsigned char OrgPerSeg; /* Make .org local to current seg */
/* Misc stuff */
extern const char Copyright[]; /* Copyright string */

View File

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

View File

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

View File

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

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 1998-2007 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -63,13 +63,15 @@
/* Are we in absolute mode or in relocatable mode? */
int RelocMode = 1;
unsigned long AbsPC = 0; /* PC if in absolute mode */
/* If OrgPerSeg is false, all segments share the RelocMode flag and a PC
* used when in absolute mode. OrgPerSeg may be set by .feature org_per_seg
*/
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, 0, segdef }
{ prev, 0, 0, 0, num, 0, 1, 0, 0, segdef }
/* Definitions for predefined segments */
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->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 */
@ -170,8 +174,16 @@ Fragment* GenFragment (unsigned char Type, unsigned short Len)
/* Increment the program counter */
ActiveSeg->PC += F->Len;
if (!RelocMode) {
AbsPC += F->Len;
if (OrgPerSeg) {
/* 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 */
@ -214,16 +226,61 @@ void UseSeg (const SegDef* D)
unsigned long GetPC (void)
/* 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)
/* Set the program counter in absolute mode */
void EnterAbsoluteMode (unsigned long PC)
/* Enter absolute (non relocatable mode). Depending on the OrgPerSeg flag,
* this will either switch the mode globally or for the current segment.
*/
{
RelocMode = 0;
AbsPC = PC;
if (OrgPerSeg) {
/* 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 */
/* Römerstraße 52 */
/* (C) 1998-2007 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -63,13 +63,13 @@ struct Segment {
unsigned long FragCount; /* Number of fragments */
unsigned Num; /* Segment number */
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) */
};
/* Are we in absolute mode or in relocatable mode? */
extern int RelocMode;
/* Definitions for predefined segments */
extern SegDef NullSegDef;
extern SegDef ZeropageSegDef;
@ -140,8 +140,18 @@ unsigned char GetSegAddrSize (unsigned SegNum);
unsigned long GetPC (void);
/* Get the program counter of the current segment */
void SetAbsPC (unsigned long AbsPC);
/* Set the program counter in absolute mode */
int GetRelocMode (void);
/* 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);
/* Check the segments for range and other errors */