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:
parent
5eadec958c
commit
a7358314a0
@ -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 `$' 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>
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
/* */
|
||||
@ -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";
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user