Allow 32 bit segments, add .TOPBYTE pseduo instruction
This commit is contained in:
@@ -291,6 +291,23 @@ static ExprNode* BankByte (ExprNode* Operand)
|
|||||||
return Expr;
|
return Expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ExprNode* TopByte (ExprNode* Operand)
|
||||||
|
/* Return the top byte of the given expression */
|
||||||
|
{
|
||||||
|
ExprNode* Expr;
|
||||||
|
long Val;
|
||||||
|
|
||||||
|
/* Special handling for const expressions */
|
||||||
|
if (IsEasyConst (Operand, &Val)) {
|
||||||
|
FreeExpr (Operand);
|
||||||
|
Expr = GenLiteralExpr ((Val >> 24) & 0xFF);
|
||||||
|
} else {
|
||||||
|
/* Extract byte #2 */
|
||||||
|
Expr = NewExprNode (EXPR_BYTE3);
|
||||||
|
Expr->Left = Operand;
|
||||||
|
}
|
||||||
|
return Expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ExprNode* LoWord (ExprNode* Operand)
|
static ExprNode* LoWord (ExprNode* Operand)
|
||||||
@@ -579,6 +596,11 @@ static ExprNode* FuncLoWord (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExprNode* FuncTopByte (void)
|
||||||
|
/* Handle the .TOPBYTE builtin function */
|
||||||
|
{
|
||||||
|
return TopByte (Expression ());
|
||||||
|
}
|
||||||
|
|
||||||
static ExprNode* DoMatch (enum TC EqualityLevel)
|
static ExprNode* DoMatch (enum TC EqualityLevel)
|
||||||
/* Handle the .MATCH and .XMATCH builtin functions */
|
/* Handle the .MATCH and .XMATCH builtin functions */
|
||||||
@@ -1287,6 +1309,10 @@ static ExprNode* Factor (void)
|
|||||||
NextTok ();
|
NextTok ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOK_TOPBYTE:
|
||||||
|
N = Function (FuncTopByte);
|
||||||
|
break;
|
||||||
|
|
||||||
case TOK_VERSION:
|
case TOK_VERSION:
|
||||||
N = GenLiteralExpr (GetVersionAsNumber ());
|
N = GenLiteralExpr (GetVersionAsNumber ());
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|||||||
@@ -1275,6 +1275,8 @@ int main (int argc, char* argv [])
|
|||||||
/* Define the default options */
|
/* Define the default options */
|
||||||
SetOptions ();
|
SetOptions ();
|
||||||
|
|
||||||
|
CreateDefaultSegments ();
|
||||||
|
|
||||||
/* Assemble the input */
|
/* Assemble the input */
|
||||||
Assemble ();
|
Assemble ();
|
||||||
|
|
||||||
|
|||||||
@@ -377,7 +377,11 @@ static void DoAddr (void)
|
|||||||
/* Do a range check */
|
/* Do a range check */
|
||||||
Expr = GenWordExpr (Expr);
|
Expr = GenWordExpr (Expr);
|
||||||
}
|
}
|
||||||
|
if (GetCPU () == CPU_65C032) {
|
||||||
|
EmitDWord( Expr );
|
||||||
|
} else {
|
||||||
EmitWord (Expr);
|
EmitWord (Expr);
|
||||||
|
}
|
||||||
if (CurTok.Tok != TOK_COMMA) {
|
if (CurTok.Tok != TOK_COMMA) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@@ -2254,6 +2258,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
|||||||
{ ccNone, DoTag }, /* .TAG */
|
{ ccNone, DoTag }, /* .TAG */
|
||||||
{ ccNone, DoUnexpected }, /* .TCOUNT */
|
{ ccNone, DoUnexpected }, /* .TCOUNT */
|
||||||
{ ccNone, DoUnexpected }, /* .TIME */
|
{ ccNone, DoUnexpected }, /* .TIME */
|
||||||
|
{ ccNone, DoUnexpected }, /* .TOPBYTE */
|
||||||
{ ccKeepToken, DoUnDef }, /* .UNDEF, .UNDEFINE */
|
{ ccKeepToken, DoUnDef }, /* .UNDEF, .UNDEFINE */
|
||||||
{ ccNone, DoUnion }, /* .UNION */
|
{ ccNone, DoUnion }, /* .UNION */
|
||||||
{ ccNone, DoUnexpected }, /* .VERSION */
|
{ ccNone, DoUnexpected }, /* .VERSION */
|
||||||
|
|||||||
@@ -316,6 +316,7 @@ struct DotKeyword {
|
|||||||
{ ".TAG", TOK_TAG },
|
{ ".TAG", TOK_TAG },
|
||||||
{ ".TCOUNT", TOK_TCOUNT },
|
{ ".TCOUNT", TOK_TCOUNT },
|
||||||
{ ".TIME", TOK_TIME },
|
{ ".TIME", TOK_TIME },
|
||||||
|
{ ".TOPBYTE", TOK_TOPBYTE },
|
||||||
{ ".UNDEF", TOK_UNDEF },
|
{ ".UNDEF", TOK_UNDEF },
|
||||||
{ ".UNDEFINE", TOK_UNDEF },
|
{ ".UNDEFINE", TOK_UNDEF },
|
||||||
{ ".UNION", TOK_UNION },
|
{ ".UNION", TOK_UNION },
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
#include "spool.h"
|
#include "spool.h"
|
||||||
#include "studyexpr.h"
|
#include "studyexpr.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -93,7 +94,22 @@ Segment* ActiveSeg;
|
|||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void CreateDefaultSegments(void) {
|
||||||
|
int AddrSizeAbs;
|
||||||
|
|
||||||
|
if (CPU == CPU_65C032) {
|
||||||
|
AddrSizeAbs = 4;
|
||||||
|
} else {
|
||||||
|
AddrSizeAbs = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
NullSegDef.AddrSize = AddrSizeAbs;
|
||||||
|
ZeropageSegDef.AddrSize = ADDR_SIZE_ZP;
|
||||||
|
DataSegDef.AddrSize = AddrSizeAbs;
|
||||||
|
BssSegDef.AddrSize = AddrSizeAbs;
|
||||||
|
RODataSegDef.AddrSize = AddrSizeAbs;
|
||||||
|
CodeSegDef.AddrSize = AddrSizeAbs;
|
||||||
|
}
|
||||||
|
|
||||||
static Segment* NewSegFromDef (SegDef* Def)
|
static Segment* NewSegFromDef (SegDef* Def)
|
||||||
/* Create a new segment from a segment definition. Used only internally, no
|
/* Create a new segment from a segment definition. Used only internally, no
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ extern Segment* ActiveSeg;
|
|||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void CreateDefaultSegments (void);
|
||||||
|
/* Create the default segments, based on the current CPU */
|
||||||
|
|
||||||
|
|
||||||
Fragment* GenFragment (unsigned char Type, unsigned short Len);
|
Fragment* GenFragment (unsigned char Type, unsigned short Len);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "struct.h"
|
#include "struct.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -175,8 +176,15 @@ static long DoStructInternal (long Offs, unsigned Type)
|
|||||||
case TOK_WORD:
|
case TOK_WORD:
|
||||||
case TOK_ADDR:
|
case TOK_ADDR:
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
switch (CPU) {
|
||||||
|
case CPU_65C032:
|
||||||
|
MemberSize = Member (4);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
MemberSize = Member (2);
|
MemberSize = Member (2);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case TOK_FARADDR:
|
case TOK_FARADDR:
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|||||||
@@ -274,6 +274,7 @@ static const TokDescEntry TokDesc[] = {
|
|||||||
{ ".TAG" },
|
{ ".TAG" },
|
||||||
{ ".TCOUNT" },
|
{ ".TCOUNT" },
|
||||||
{ ".TIME" },
|
{ ".TIME" },
|
||||||
|
{ ".TOPBYTE" },
|
||||||
{ ".UNDEF" },
|
{ ".UNDEF" },
|
||||||
{ ".UNION" },
|
{ ".UNION" },
|
||||||
{ ".VERSION" },
|
{ ".VERSION" },
|
||||||
|
|||||||
@@ -280,6 +280,7 @@ typedef enum token_t {
|
|||||||
TOK_TAG,
|
TOK_TAG,
|
||||||
TOK_TCOUNT,
|
TOK_TCOUNT,
|
||||||
TOK_TIME,
|
TOK_TIME,
|
||||||
|
TOK_TOPBYTE,
|
||||||
TOK_UNDEF,
|
TOK_UNDEF,
|
||||||
TOK_UNION,
|
TOK_UNION,
|
||||||
TOK_VERSION,
|
TOK_VERSION,
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
/* Maximum possible alignment. Beware: To increase the possible alignment it
|
/* Maximum possible alignment. Beware: To increase the possible alignment it
|
||||||
** is not enough to bump this value. Check the code inside.
|
** is not enough to bump this value. Check the code inside.
|
||||||
*/
|
*/
|
||||||
#define MAX_ALIGNMENT 0x10000UL
|
#define MAX_ALIGNMENT 0x100000000UL
|
||||||
|
|
||||||
/* The following value marks what is considered a "large alignment" and worth
|
/* The following value marks what is considered a "large alignment" and worth
|
||||||
** a warning if not suppressed.
|
** a warning if not suppressed.
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ int ValidAddrSizeForCPU (unsigned char AddrSize)
|
|||||||
|
|
||||||
case ADDR_SIZE_LONG:
|
case ADDR_SIZE_LONG:
|
||||||
/* "none" supports all sizes */
|
/* "none" supports all sizes */
|
||||||
return (CPU == CPU_NONE);
|
return (CPU == CPU_65C032);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FAIL ("Invalid address size");
|
FAIL ("Invalid address size");
|
||||||
|
|||||||
@@ -731,7 +731,7 @@ static void ParseSegments (void)
|
|||||||
|
|
||||||
case CFGTOK_OFFSET:
|
case CFGTOK_OFFSET:
|
||||||
FlagAttr (&S->Attr, SA_OFFSET, "OFFSET");
|
FlagAttr (&S->Attr, SA_OFFSET, "OFFSET");
|
||||||
S->Addr = CfgCheckedConstExpr (0, 0x1000000);
|
S->Addr = CfgCheckedConstExpr (0, 0x100000000);
|
||||||
S->Flags |= SF_OFFSET;
|
S->Flags |= SF_OFFSET;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -752,7 +752,7 @@ static void ParseSegments (void)
|
|||||||
|
|
||||||
case CFGTOK_START:
|
case CFGTOK_START:
|
||||||
FlagAttr (&S->Attr, SA_START, "START");
|
FlagAttr (&S->Attr, SA_START, "START");
|
||||||
S->Addr = CfgCheckedConstExpr (0, 0x1000000);
|
S->Addr = CfgCheckedConstExpr (0, 0x100000000);
|
||||||
S->Flags |= SF_START;
|
S->Flags |= SF_START;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1959,11 +1959,11 @@ unsigned CfgProcess (void)
|
|||||||
GetString (M->Name));
|
GetString (M->Name));
|
||||||
}
|
}
|
||||||
M->Size = GetExprVal (M->SizeExpr);
|
M->Size = GetExprVal (M->SizeExpr);
|
||||||
if (M->Size >= 0x80000000) {
|
// if (M->Size >= 0x80000000) {
|
||||||
PError (GetSourcePos (M->LI),
|
// PError (GetSourcePos (M->LI),
|
||||||
"Size of memory area `%s' is negative: %ld",
|
// "Size of memory area `%s' is negative: %ld",
|
||||||
GetString (M->Name), (long)M->Size);
|
// GetString (M->Name), (long)M->Size);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/* Walk through the segments in this memory area */
|
/* Walk through the segments in this memory area */
|
||||||
for (J = 0; J < CollCount (&M->SegList); ++J) {
|
for (J = 0; J < CollCount (&M->SegList); ++J) {
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user