diff --git a/src/ca65/expr.c b/src/ca65/expr.c index cb77d0e1d..e0d15a6fc 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -291,6 +291,23 @@ static ExprNode* BankByte (ExprNode* Operand) 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) @@ -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) /* Handle the .MATCH and .XMATCH builtin functions */ @@ -1287,6 +1309,10 @@ static ExprNode* Factor (void) NextTok (); break; + case TOK_TOPBYTE: + N = Function (FuncTopByte); + break; + case TOK_VERSION: N = GenLiteralExpr (GetVersionAsNumber ()); NextTok (); diff --git a/src/ca65/main.c b/src/ca65/main.c index c9bb11eb9..01c80fcf0 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -1275,6 +1275,8 @@ int main (int argc, char* argv []) /* Define the default options */ SetOptions (); + CreateDefaultSegments (); + /* Assemble the input */ Assemble (); diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 88f609e25..e430ff887 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -377,7 +377,11 @@ static void DoAddr (void) /* Do a range check */ Expr = GenWordExpr (Expr); } - EmitWord (Expr); + if (GetCPU () == CPU_65C032) { + EmitDWord( Expr ); + } else { + EmitWord (Expr); + } if (CurTok.Tok != TOK_COMMA) { break; } else { @@ -2254,6 +2258,7 @@ static CtrlDesc CtrlCmdTab [] = { { ccNone, DoTag }, /* .TAG */ { ccNone, DoUnexpected }, /* .TCOUNT */ { ccNone, DoUnexpected }, /* .TIME */ + { ccNone, DoUnexpected }, /* .TOPBYTE */ { ccKeepToken, DoUnDef }, /* .UNDEF, .UNDEFINE */ { ccNone, DoUnion }, /* .UNION */ { ccNone, DoUnexpected }, /* .VERSION */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index ce90388d4..121d2a1e6 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -316,6 +316,7 @@ struct DotKeyword { { ".TAG", TOK_TAG }, { ".TCOUNT", TOK_TCOUNT }, { ".TIME", TOK_TIME }, + { ".TOPBYTE", TOK_TOPBYTE }, { ".UNDEF", TOK_UNDEF }, { ".UNDEFINE", TOK_UNDEF }, { ".UNION", TOK_UNION }, diff --git a/src/ca65/segment.c b/src/ca65/segment.c index d5073895d..bf49fb1b5 100644 --- a/src/ca65/segment.c +++ b/src/ca65/segment.c @@ -58,6 +58,7 @@ #include "spool.h" #include "studyexpr.h" #include "symtab.h" +#include "cpu.h" @@ -93,7 +94,22 @@ Segment* ActiveSeg; /* 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) /* Create a new segment from a segment definition. Used only internally, no diff --git a/src/ca65/segment.h b/src/ca65/segment.h index 35430739b..6ee0d2fca 100644 --- a/src/ca65/segment.h +++ b/src/ca65/segment.h @@ -90,6 +90,8 @@ extern Segment* ActiveSeg; /* Code */ /*****************************************************************************/ +void CreateDefaultSegments (void); +/* Create the default segments, based on the current CPU */ Fragment* GenFragment (unsigned char Type, unsigned short Len); diff --git a/src/ca65/struct.c b/src/ca65/struct.c index d755aa4bf..6d93a7af8 100644 --- a/src/ca65/struct.c +++ b/src/ca65/struct.c @@ -48,6 +48,7 @@ #include "symbol.h" #include "symtab.h" #include "struct.h" +#include "cpu.h" @@ -175,7 +176,14 @@ static long DoStructInternal (long Offs, unsigned Type) case TOK_WORD: case TOK_ADDR: NextTok (); - MemberSize = Member (2); + switch (CPU) { + case CPU_65C032: + MemberSize = Member (4); + break; + default: + MemberSize = Member (2); + break; + } break; case TOK_FARADDR: diff --git a/src/ca65/token.c b/src/ca65/token.c index 48ffdff80..7251b4c60 100644 --- a/src/ca65/token.c +++ b/src/ca65/token.c @@ -274,6 +274,7 @@ static const TokDescEntry TokDesc[] = { { ".TAG" }, { ".TCOUNT" }, { ".TIME" }, + { ".TOPBYTE" }, { ".UNDEF" }, { ".UNION" }, { ".VERSION" }, diff --git a/src/ca65/token.h b/src/ca65/token.h index 34706fad5..534d5be27 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -280,6 +280,7 @@ typedef enum token_t { TOK_TAG, TOK_TCOUNT, TOK_TIME, + TOK_TOPBYTE, TOK_UNDEF, TOK_UNION, TOK_VERSION, diff --git a/src/common/alignment.h b/src/common/alignment.h index 8a798facd..fd1a181c4 100644 --- a/src/common/alignment.h +++ b/src/common/alignment.h @@ -47,7 +47,7 @@ /* Maximum possible alignment. Beware: To increase the possible alignment it ** 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 ** a warning if not suppressed. diff --git a/src/common/cpu.c b/src/common/cpu.c index 30d8e5787..f1e842748 100644 --- a/src/common/cpu.c +++ b/src/common/cpu.c @@ -217,7 +217,7 @@ int ValidAddrSizeForCPU (unsigned char AddrSize) case ADDR_SIZE_LONG: /* "none" supports all sizes */ - return (CPU == CPU_NONE); + return (CPU == CPU_65C032); default: FAIL ("Invalid address size"); diff --git a/src/ld65/config.c b/src/ld65/config.c index 9536d5c26..6bebba791 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -731,7 +731,7 @@ static void ParseSegments (void) case CFGTOK_OFFSET: FlagAttr (&S->Attr, SA_OFFSET, "OFFSET"); - S->Addr = CfgCheckedConstExpr (0, 0x1000000); + S->Addr = CfgCheckedConstExpr (0, 0x100000000); S->Flags |= SF_OFFSET; break; @@ -752,7 +752,7 @@ static void ParseSegments (void) case CFGTOK_START: FlagAttr (&S->Attr, SA_START, "START"); - S->Addr = CfgCheckedConstExpr (0, 0x1000000); + S->Addr = CfgCheckedConstExpr (0, 0x100000000); S->Flags |= SF_START; break; @@ -1959,11 +1959,11 @@ unsigned CfgProcess (void) GetString (M->Name)); } M->Size = GetExprVal (M->SizeExpr); - if (M->Size >= 0x80000000) { - PError (GetSourcePos (M->LI), - "Size of memory area `%s' is negative: %ld", - GetString (M->Name), (long)M->Size); - } + // if (M->Size >= 0x80000000) { + // PError (GetSourcePos (M->LI), + // "Size of memory area `%s' is negative: %ld", + // GetString (M->Name), (long)M->Size); + // } /* Walk through the segments in this memory area */ for (J = 0; J < CollCount (&M->SegList); ++J) { diff --git a/test/asm/opcodes/65c032-opcodes.ref b/test/asm/opcodes/65c032-opcodes.ref index e69de29bb..3f7016f5c 100644 Binary files a/test/asm/opcodes/65c032-opcodes.ref and b/test/asm/opcodes/65c032-opcodes.ref differ