1
0
mirror of https://github.com/cc65/cc65.git synced 2024-07-05 21:29:03 +00:00

Merge pull request #155 from Movax12/exp

Added function .ADDRSIZE to ca65
This commit is contained in:
Oliver Schmidt 2015-04-22 13:20:32 +02:00
commit 88fe6b615b
9 changed files with 144 additions and 0 deletions

View File

@ -1279,6 +1279,35 @@ Pseudo functions expect their arguments in parenthesis, and they have a result,
either a string or an expression.
<sect1><tt>.ADDRSIZE</tt><label id=".ADDRSIZE"><p>
The <tt/.ADDRSIZE/ function is used to return the interal address size
associated with a symbol. This can be helpful in macros when knowing the address
size of symbol can help with custom instructions.
Example:
<tscreen><verb>
.macro myLDA foo
.if .ADDRSIZE(foo) = 1
;do custom command based on zeropage addressing:
.byte 0A5h, foo
.elseif .ADDRSIZE(foo) = 2
;do custom command based on absolute addressing:
.byte 0ADh
.word foo
.elseif .ADDRSIZE(foo) = 0
; no address size defined for this symbol:
.out .sprintf("Error, address size unknown for symbol %s", .string(foo))
.endif
.endmacro
</verb></tscreen>
This command is new and must be enabled with the <tt/.FEATURE addrsize/ command.
See: <tt><ref id=".FEATURE" name=".FEATURE"></tt>
<sect1><tt>.BANK</tt><label id=".BANK"><p>
The <tt/.BANK/ function is used to support systems with banked memory. The
@ -2596,6 +2625,12 @@ Here's a list of all control commands and a description, what they do:
<descrip>
<tag><tt>addrsize</tt><label id="addrsize"></tag>
Enables the .ADDRSIZE pseudo function. This function is experimental and not enabled by default.
See also: <tt><ref id=".ADDRSIZE" name=".ADDRSIZE"></tt>
<tag><tt>at_in_identifiers</tt><label id="at_in_identifiers"></tag>
Accept the at character (`@') as a valid character in identifiers. The

View File

@ -629,6 +629,85 @@ static ExprNode* FuncReferenced (void)
static ExprNode* FuncAddrSize (void)
/* Handle the .ADDRSIZE function */
{
StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
StrBuf Name = STATIC_STRBUF_INITIALIZER;
SymEntry* Sym;
int AddrSize;
int NoScope;
/* Assume we don't know the size */
AddrSize = 0;
/* Check for a cheap local which needs special handling */
if (CurTok.Tok == TOK_LOCAL_IDENT) {
/* Cheap local symbol */
Sym = SymFindLocal (SymLast, &CurTok.SVal, SYM_FIND_EXISTING);
if (Sym == 0) {
Error ("Unknown symbol or scope: `%m%p'", &CurTok.SVal);
} else {
AddrSize = Sym->AddrSize;
}
/* Remember and skip SVal, terminate ScopeName so it is empty */
SB_Copy (&Name, &CurTok.SVal);
NextTok ();
SB_Terminate (&ScopeName);
} else {
/* Parse the scope and the name */
SymTable* ParentScope = ParseScopedIdent (&Name, &ScopeName);
/* Check if the parent scope is valid */
if (ParentScope == 0) {
/* No such scope */
SB_Done (&ScopeName);
SB_Done (&Name);
return GenLiteral0 ();
}
/* If ScopeName is empty, no explicit scope was specified. We have to
** search upper scope levels in this case.
*/
NoScope = SB_IsEmpty (&ScopeName);
/* If we did find a scope with the name, read the symbol defining the
** size, otherwise search for a symbol entry with the name and scope.
*/
if (NoScope) {
Sym = SymFindAny (ParentScope, &Name);
} else {
Sym = SymFind (ParentScope, &Name, SYM_FIND_EXISTING);
}
/* If we found the symbol retrieve the size, otherwise complain */
if (Sym) {
AddrSize = Sym->AddrSize;
} else {
Error ("Unknown symbol or scope: `%m%p%m%p'", &ScopeName, &Name);
}
}
if (AddrSize == 0) {
Warning (1, "Unknown address size: `%m%p%m%p'", &ScopeName, &Name);
}
/* Free the string buffers */
SB_Done (&ScopeName);
SB_Done (&Name);
/* Return the size. */
return GenLiteralExpr (AddrSize);
}
static ExprNode* FuncSizeOf (void)
/* Handle the .SIZEOF function */
{
@ -965,6 +1044,10 @@ static ExprNode* Factor (void)
N = Function (FuncBankByte);
break;
case TOK_ADDRSIZE:
N = Function (FuncAddrSize);
break;
case TOK_BLANK:
N = Function (FuncBlank);
break;

View File

@ -63,6 +63,7 @@ static const char* FeatureKeys[FEAT_COUNT] = {
"c_comments",
"force_range",
"underline_in_numbers",
"addrsize",
};
@ -119,6 +120,7 @@ feature_t SetFeature (const StrBuf* Key)
case FEAT_C_COMMENTS: CComments = 1; break;
case FEAT_FORCE_RANGE: ForceRange = 1; break;
case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break;
case FEAT_ADDRSIZE: AddrSize = 1; break;
default: /* Keep gcc silent */ break;
}

View File

@ -65,6 +65,7 @@ typedef enum {
FEAT_C_COMMENTS,
FEAT_FORCE_RANGE,
FEAT_UNDERLINE_IN_NUMBERS,
FEAT_ADDRSIZE,
/* Special value: Number of features available */
FEAT_COUNT

View File

@ -82,3 +82,4 @@ unsigned char OrgPerSeg = 0; /* Make .org local to current seg */
unsigned char CComments = 0; /* Allow C like comments */
unsigned char ForceRange = 0; /* Force values into expected range */
unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */
unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */

View File

@ -84,6 +84,8 @@ extern unsigned char OrgPerSeg; /* Make .org local to current seg */
extern unsigned char CComments; /* Allow C like comments */
extern unsigned char ForceRange; /* Force values into expected range */
extern unsigned char UnderlineInNumbers; /* Allow underlines in numbers */
extern unsigned char AddrSize; /* Allow .ADDRSIZE function */

View File

@ -1964,6 +1964,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoA16 },
{ ccNone, DoA8 },
{ ccNone, DoAddr }, /* .ADDR */
{ ccNone, DoUnexpected }, /* .ADDRSIZE */
{ ccNone, DoAlign },
{ ccNone, DoASCIIZ },
{ ccNone, DoAssert },

View File

@ -135,6 +135,7 @@ struct DotKeyword {
{ ".A16", TOK_A16 },
{ ".A8", TOK_A8 },
{ ".ADDR", TOK_ADDR },
{ ".ADDRSIZE", TOK_ADDRSIZE },
{ ".ALIGN", TOK_ALIGN },
{ ".AND", TOK_BOOLAND },
{ ".ASCIIZ", TOK_ASCIIZ },
@ -723,7 +724,24 @@ static token_t FindDotKeyword (void)
R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
sizeof (DotKeywords [0]), CmpDotKeyword);
if (R != 0) {
/* By default, disable any somewhat experiemental DotKeyword. */
switch (R->Tok) {
case TOK_ADDRSIZE:
/* Disallow .ADDRSIZE function by default */
if (AddrSize == 0) {
return TOK_NONE;
}
break;
default:
break;
}
return R->Tok;
} else {
return TOK_NONE;
}

View File

@ -123,6 +123,7 @@ typedef enum token_t {
TOK_A16 = TOK_FIRSTPSEUDO,
TOK_A8,
TOK_ADDR,
TOK_ADDRSIZE,
TOK_ALIGN,
TOK_ASCIIZ,
TOK_ASSERT,