Merge branch 'master' into macexpand

This commit is contained in:
Bob Andrews
2025-07-03 23:16:28 +02:00
committed by GitHub
582 changed files with 19953 additions and 3048 deletions

View File

@@ -394,6 +394,16 @@ void DoConditionals (void)
CalcOverallIfCond ();
break;
case TOK_IFP02X:
D = AllocIf (".IFP02X", 1);
NextTok ();
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_6502X);
}
ExpectSep ();
CalcOverallIfCond ();
break;
case TOK_IFP4510:
D = AllocIf (".IFP4510", 1);
NextTok ();
@@ -404,6 +414,26 @@ void DoConditionals (void)
CalcOverallIfCond ();
break;
case TOK_IFP45GS02:
D = AllocIf (".IFP45GS02", 1);
NextTok ();
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_45GS02);
}
ExpectSep ();
CalcOverallIfCond ();
break;
case TOK_IFP6280:
D = AllocIf (".IFP6280", 1);
NextTok ();
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_HUC6280);
}
ExpectSep ();
CalcOverallIfCond ();
break;
case TOK_IFP816:
D = AllocIf (".IFP816", 1);
NextTok ();
@@ -424,6 +454,16 @@ void DoConditionals (void)
CalcOverallIfCond ();
break;
case TOK_IFPCE02:
D = AllocIf (".IFPCE02", 1);
NextTok ();
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_65CE02);
}
ExpectSep ();
CalcOverallIfCond ();
break;
case TOK_IFPDTV:
D = AllocIf (".IFPDTV", 1);
NextTok ();
@@ -434,6 +474,16 @@ void DoConditionals (void)
CalcOverallIfCond ();
break;
case TOK_IFPM740:
D = AllocIf (".IFPM740", 1);
NextTok ();
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_M740);
}
ExpectSep ();
CalcOverallIfCond ();
break;
case TOK_IFPSC02:
D = AllocIf (".IFPSC02", 1);
NextTok ();
@@ -444,6 +494,26 @@ void DoConditionals (void)
CalcOverallIfCond ();
break;
case TOK_IFPSWEET16:
D = AllocIf (".IFPSWEET16", 1);
NextTok ();
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_SWEET16);
}
ExpectSep ();
CalcOverallIfCond ();
break;
case TOK_IFPWC02:
D = AllocIf (".IFPWC02", 1);
NextTok ();
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_W65C02);
}
ExpectSep ();
CalcOverallIfCond ();
break;
case TOK_IFREF:
D = AllocIf (".IFREF", 1);
NextTok ();
@@ -485,11 +555,18 @@ int CheckConditionals (void)
case TOK_IFNDEF:
case TOK_IFNREF:
case TOK_IFP02:
case TOK_IFP02X:
case TOK_IFP4510:
case TOK_IFP45GS02:
case TOK_IFP6280:
case TOK_IFP816:
case TOK_IFPC02:
case TOK_IFPCE02:
case TOK_IFPDTV:
case TOK_IFPM740:
case TOK_IFPSC02:
case TOK_IFPSWEET16:
case TOK_IFPWC02:
case TOK_IFREF:
DoConditionals ();
return 1;

View File

@@ -101,6 +101,9 @@ void GetEA (EffAddr* A)
if (TokIsSep (CurTok.Tok)) {
A->AddrModeSet = AM65_IMPLICIT;
if (GetCPU () == CPU_45GS02) {
A->AddrModeSet |= AM65_Q;
}
} else if (CurTok.Tok == TOK_HASH) {
@@ -114,6 +117,11 @@ void GetEA (EffAddr* A)
NextTok ();
A->AddrModeSet = AM65_ACCU;
} else if (CurTok.Tok == TOK_Q) {
NextTok ();
A->AddrModeSet = AM65_Q;
} else if (CurTok.Tok == IndirectEnter) {
/* One of the indirect modes */
@@ -160,8 +168,19 @@ void GetEA (EffAddr* A)
}
} else {
/* (adr) */
A->AddrModeSet = (CPU == CPU_4510) ? AM65_ABS_IND
: AM65_ABS_IND | AM65_ABS_IND_LONG | AM65_DIR_IND;
switch (CPU) {
case CPU_4510:
A->AddrModeSet = AM65_ABS_IND;
break;
case CPU_45GS02:
A->AddrModeSet = AM65_ABS_IND | AM65_DIR_IND;
break;
default:
A->AddrModeSet = AM65_ABS_IND | AM65_ABS_IND_LONG | AM65_DIR_IND;
break;
}
}
}
@@ -175,8 +194,14 @@ void GetEA (EffAddr* A)
if (CurTok.Tok == TOK_COMMA) {
/* [dir],y */
NextTok ();
Consume (TOK_Y, "'Y' expected");
A->AddrModeSet = AM65_DIR_IND_LONG_Y;
if (GetCPU () == CPU_45GS02) {
Consume (TOK_Z, "'Z' expected");
A->AddrModeSet = AM65_32BIT_BASE_IND_Z;
}
else {
Consume (TOK_Y, "'Y' expected");
A->AddrModeSet = AM65_DIR_IND_LONG_Y;
}
} else {
/* [dir] */
A->AddrModeSet = AM65_DIR_IND_LONG | AM65_ABS_IND_LONG;
@@ -186,10 +211,11 @@ void GetEA (EffAddr* A)
/* Remaining stuff:
**
** adr
** adr,x
** adr,y
** adr,s
** addr
** addr, x
** addr, y
** addr, s
** addr, relative addr
*/
A->Expr = Expression ();
@@ -214,7 +240,9 @@ void GetEA (EffAddr* A)
break;
default:
Error ("Syntax error");
/* FIXME: syntax error if not zp, ind */
A->AddrModeSet = AM65_ZP_REL;
break;
}

View File

@@ -148,7 +148,7 @@ static void AddNotifications (const Collection* LineInfos)
break;
case LI_TYPE_MACRO:
Msg = "Macro was defined here";
Msg = "Expanded from macro here";
break;
case LI_TYPE_MACPARAM:

View File

@@ -37,6 +37,7 @@
#include <time.h>
/* common */
#include "capability.h"
#include "check.h"
#include "cpu.h"
#include "exprdefs.h"
@@ -60,6 +61,7 @@
#include "studyexpr.h"
#include "symbol.h"
#include "symtab.h"
#include "target.h"
#include "toklist.h"
#include "ulabel.h"
#include "macro.h"
@@ -405,6 +407,66 @@ static ExprNode* FuncBlank (void)
static ExprNode* FuncCapability (void)
/* Handle the .CAPABILITY builtin function */
{
int Result = 1;
/* What follows is a comma separated list of identifiers. An empty list is
** not allowed.
*/
while (1) {
const char* Name;
capability_t Cap;
/* We must have an identifier */
if (CurTok.Tok != TOK_IDENT) {
Error ("Arguments to .CAPABILITY must be identifiers");
/* Skip tokens until closing paren or end of line */
while (CurTok.Tok != TOK_RPAREN && !TokIsSep (CurTok.Tok)) {
NextTok ();
}
return GenLiteral0 ();
}
/* Search for the capability that matches this identifier. Ignore case
** on the specified capabilities.
*/
UpcaseSVal ();
SB_Terminate (&CurTok.SVal);
Name = SB_GetConstBuf (&CurTok.SVal);
Cap = FindCapability (Name);
/* Check if the capability is supported */
if (Cap == CAP_INVALID) {
Error ("Not a valid capability name: %s", Name);
Result = 0;
} else {
/* The pseudo function result is the logical AND of all capabilities
** given.
*/
if (!CPUHasCap (Cap) && !TargetHasCap (Cap)) {
Result = 0;
}
}
/* Skip the capability name */
NextTok ();
/* Handle end of list or next capability */
if (CurTok.Tok != TOK_COMMA) {
break;
}
NextTok ();
}
/* Done */
return GenLiteralExpr (Result);
}
static ExprNode* FuncConst (void)
/* Handle the .CONST builtin function */
{
@@ -484,9 +546,10 @@ static ExprNode* FuncIsMnemonic (void)
if (FindMacro (&CurTok.SVal) == 0) {
Instr = FindInstruction (&CurTok.SVal);
}
}
else {
/* Macros and symbols may NOT use the names of instructions, so just check for the instruction */
} else {
/* Macros and symbols may NOT use the names of instructions, so
** just check for the instruction.
*/
Instr = FindInstruction (&CurTok.SVal);
}
}
@@ -532,7 +595,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
token_t Term = GetTokListTerm (TOK_COMMA);
while (CurTok.Tok != Term) {
/* We may not end-of-line of end-of-file here */
/* We may not end-of-line or end-of-file here */
if (TokIsSep (CurTok.Tok)) {
Error ("Unexpected end of line");
return GenLiteral0 ();
@@ -570,7 +633,7 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
Node = Root;
while (CurTok.Tok != Term) {
/* We may not end-of-line of end-of-file here */
/* We may not end-of-line or end-of-file here */
if (TokIsSep (CurTok.Tok)) {
Error ("Unexpected end of line");
return GenLiteral0 ();
@@ -1129,6 +1192,10 @@ static ExprNode* Factor (void)
N = Function (FuncBlank);
break;
case TOK_CAP:
N = Function (FuncCapability);
break;
case TOK_CONST:
N = Function (FuncConst);
break;

File diff suppressed because it is too large Load Diff

View File

@@ -58,34 +58,38 @@
** When assembling for the 6502 or 65C02, all addressing modes that are not
** available on these CPUs are removed before doing any checks.
*/
#define AM65_IMPLICIT 0x00000003UL
#define AM65_ACCU 0x00000002UL
#define AM65_DIR 0x00000004UL
#define AM65_ABS 0x00000008UL
#define AM65_ABS_LONG 0x00000010UL
#define AM65_DIR_X 0x00000020UL
#define AM65_ABS_X 0x00000040UL
#define AM65_ABS_LONG_X 0x00000080UL
#define AM65_DIR_Y 0x00000100UL
#define AM65_ABS_Y 0x00000200UL
#define AM65_DIR_IND 0x00000400UL
#define AM65_ABS_IND 0x00000800UL
#define AM65_DIR_IND_LONG 0x00001000UL
#define AM65_DIR_IND_Y 0x00002000UL
#define AM65_DIR_IND_LONG_Y 0x00004000UL
#define AM65_DIR_X_IND 0x00008000UL
#define AM65_ABS_X_IND 0x00010000UL
#define AM65_REL 0x00020000UL
#define AM65_REL_LONG 0x00040000UL
#define AM65_STACK_REL 0x00080000UL
#define AM65_STACK_REL_IND_Y 0x00100000UL
#define AM65_IMPLICIT 0x00000003UL /* IMP */
#define AM65_ACCU 0x00000002UL /* A */
#define AM65_DIR 0x00000004UL /* ZP */
#define AM65_ABS 0x00000008UL /* ABS */
#define AM65_ABS_LONG 0x00000010UL /* adr */
#define AM65_DIR_X 0x00000020UL /* ZP,X */
#define AM65_ABS_X 0x00000040UL /* ABS, X */
#define AM65_ABS_LONG_X 0x00000080UL /* adr,x */
#define AM65_DIR_Y 0x00000100UL /* ZP, Y */
#define AM65_ABS_Y 0x00000200UL /* ABS, Y */
#define AM65_DIR_IND 0x00000400UL /* (ZP) or (ZP),z (4510 / 45GS02) */
#define AM65_ABS_IND 0x00000800UL /* (ABS) */
#define AM65_DIR_IND_LONG 0x00001000UL /* [ABS] (65816) */
#define AM65_DIR_IND_Y 0x00002000UL /* (ZP),y */
#define AM65_DIR_IND_LONG_Y 0x00004000UL /* [adr],y (not 45GS02) */
#define AM65_DIR_X_IND 0x00008000UL /* (ZP,x) */
#define AM65_ABS_X_IND 0x00010000UL /* (ABS,x) */
#define AM65_REL 0x00020000UL /* REL */
#define AM65_REL_LONG 0x00040000UL /* LONGREL */
#define AM65_STACK_REL 0x00080000UL /* adr,s */
#define AM65_STACK_REL_IND_Y 0x00100000UL /* (rel,s),y */
#define AM65_IMM_ACCU 0x00200000UL
#define AM65_IMM_INDEX 0x00400000UL
#define AM65_IMM_IMPLICIT 0x00800000UL
#define AM65_IMM_IMPLICIT 0x00800000UL /* IMM */
#define AM65_BLOCKMOVE 0x01000000UL
#define AM65_BLOCKXFER 0x02000000UL
#define AM65_ABS_IND_LONG 0x04000000UL
#define AM65_ABS_IND_LONG 0x04000000UL /* (adr) [dir] */
#define AM65_IMM_IMPLICIT_WORD 0x08000000UL /* PHW #$1234 (4510 only) */
#define AM65_ZP_REL 0x10000000UL /* ZP, REL (m740) */
#define AM65_SPECIAL_PAGE 0x20000000UL /* $FFxx (m740) */
#define AM65_32BIT_BASE_IND_Z 0x40000000UL /* LDA [$nn],Z (45GS02 only) */
#define AM65_Q 0x80000000UL /* Q (45GS02 only) */
/* Bitmask for all ZP operations that have correspondent ABS ops */
#define AM65_SET_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND)
@@ -106,11 +110,39 @@
#define AM65_ALL_IMM (AM65_IMM_ACCU | AM65_IMM_INDEX | AM65_IMM_IMPLICIT | AM65_IMM_IMPLICIT_WORD)
/* Bit numbers and count */
#define AM65I_IMM_ACCU 21
#define AM65I_IMM_INDEX 22
#define AM65I_IMM_IMPLICIT 23
#define AM65I_IMM_IMPLICIT_WORD 27
#define AM65I_COUNT 28
#define AM65I_IMPLICIT 0
#define AM65I_ACCU 1
#define AM65I_DIR 2
#define AM65I_ABS 3
#define AM65I_ABS_LONG 4
#define AM65I_DIR_X 5
#define AM65I_ABS_X 6
#define AM65I_ABS_LONG_X 7
#define AM65I_DIR_Y 8
#define AM65I_ABS_Y 9
#define AM65I_DIR_IND 10
#define AM65I_ABS_IND 11
#define AM65I_DIR_IND_LONG 12
#define AM65I_DIR_IND_Y 13
#define AM65I_DIR_IND_LONG_Y 14
#define AM65I_DIR_X_IND 15
#define AM65I_ABS_X_IND 16
#define AM65I_REL 17
#define AM65I_REL_LONG 18
#define AM65I_STACK_REL 19
#define AM65I_STACK_REL_IND_Y 20
#define AM65I_IMM_ACCU 21
#define AM65I_IMM_INDEX 22
#define AM65I_IMM_IMPLICIT 23
#define AM65I_BLOCKMOVE 24
#define AM65I_BLOCKXFER 25
#define AM65I_ABS_IND_LONG 26
#define AM65I_IMM_IMPLICIT_WORD 27
#define AM65I_ZP_REL 28
#define AM65I_SPECIAL_PAGE 29
#define AM65I_32BIT_BASE_IND_Z 30
#define AM65I_Q 31
#define AM65I_COUNT 32

View File

@@ -194,6 +194,45 @@ static void CBMSystem (const char* Sys)
static void DefineCpuSymbols (void)
/* Define all the symbols to evaluate .cpu. These were previously in cpu.mac. */
{
NewSymbol ("CPU_ISET_NONE", CPU_ISET_NONE);
NewSymbol ("CPU_ISET_6502", CPU_ISET_6502);
NewSymbol ("CPU_ISET_6502X", CPU_ISET_6502X);
NewSymbol ("CPU_ISET_6502DTV", CPU_ISET_6502DTV);
NewSymbol ("CPU_ISET_65SC02", CPU_ISET_65SC02);
NewSymbol ("CPU_ISET_65C02", CPU_ISET_65C02);
NewSymbol ("CPU_ISET_65816", CPU_ISET_65816);
NewSymbol ("CPU_ISET_SWEET16", CPU_ISET_SWEET16);
NewSymbol ("CPU_ISET_HUC6280", CPU_ISET_HUC6280);
NewSymbol ("CPU_ISET_M740", CPU_ISET_M740);
NewSymbol ("CPU_ISET_4510", CPU_ISET_4510);
NewSymbol ("CPU_ISET_45GS02", CPU_ISET_45GS02);
NewSymbol ("CPU_ISET_W65C02", CPU_ISET_W65C02);
NewSymbol ("CPU_ISET_65CE02", CPU_ISET_65CE02);
/* Additional ones from cpu.mac. Not sure how useful they are after the
** changes from #2751.
*/
NewSymbol ("CPU_NONE", CPUIsets[CPU_NONE]);
NewSymbol ("CPU_6502", CPUIsets[CPU_6502]);
NewSymbol ("CPU_6502X", CPUIsets[CPU_6502X]);
NewSymbol ("CPU_6502DTV", CPUIsets[CPU_6502DTV]);
NewSymbol ("CPU_65SC02", CPUIsets[CPU_65SC02]);
NewSymbol ("CPU_65C02", CPUIsets[CPU_65C02]);
NewSymbol ("CPU_65816", CPUIsets[CPU_65816]);
NewSymbol ("CPU_SWEET16", CPUIsets[CPU_SWEET16]);
NewSymbol ("CPU_HUC6280", CPUIsets[CPU_HUC6280]);
NewSymbol ("CPU_M740", CPUIsets[CPU_M740]);
NewSymbol ("CPU_4510", CPUIsets[CPU_4510]);
NewSymbol ("CPU_45GS02", CPUIsets[CPU_45GS02]);
NewSymbol ("CPU_W65C02", CPUIsets[CPU_W65C02]);
NewSymbol ("CPU_65CE02", CPUIsets[CPU_65CE02]);
}
static void SetSys (const char* Sys)
/* Define a target system */
{
@@ -344,6 +383,10 @@ static void SetSys (const char* Sys)
NewSymbol ("__SYM1__", 1);
break;
case TGT_MEGA65:
CBMSystem ("__MEGA65__");
break;
case TGT_KIM1:
NewSymbol ("__KIM1__", 1);
break;
@@ -352,11 +395,18 @@ static void SetSys (const char* Sys)
NewSymbol ("__RP6502__", 1);
break;
case TGT_AGAT:
NewSymbol ("__AGAT__", 1);
break;
default:
AbEnd ("Invalid target name: '%s'", Sys);
}
/* Define the symbols for evaluating .cpu */
DefineCpuSymbols ();
/* Initialize the translation tables for the target system */
TgtTranslateInit ();
}

View File

@@ -1562,6 +1562,14 @@ static void DoP02 (void)
static void DoP02X (void)
/* Switch to 6502X CPU */
{
SetCPU (CPU_6502X);
}
static void DoPC02 (void)
/* Switch to 65C02 CPU */
{
@@ -1570,10 +1578,18 @@ static void DoPC02 (void)
static void DoP816 (void)
/* Switch to 65816 CPU */
static void DoPWC02 (void)
/* Switch to W65C02 CPU */
{
SetCPU (CPU_65816);
SetCPU (CPU_W65C02);
}
static void DoPCE02 (void)
/* Switch to 65CE02 CPU */
{
SetCPU (CPU_65CE02);
}
@@ -1586,6 +1602,30 @@ static void DoP4510 (void)
static void DoP45GS02 (void)
/* Switch to 45GS02 CPU */
{
SetCPU (CPU_45GS02);
}
static void DoP6280 (void)
/* Switch to HuC6280 CPU */
{
SetCPU (CPU_HUC6280);
}
static void DoP816 (void)
/* Switch to 65816 CPU */
{
SetCPU (CPU_65816);
}
static void DoPDTV (void)
/* Switch to C64DTV CPU */
{
@@ -1594,6 +1634,14 @@ static void DoPDTV (void)
static void DoPM740 (void)
/* Switch to M740 CPU */
{
SetCPU (CPU_M740);
}
static void DoPageLength (void)
/* Set the page length for the listing */
{
@@ -1704,6 +1752,14 @@ static void DoPSC02 (void)
static void DoPSweet16 (void)
/* Switch to Sweet16 CPU */
{
SetCPU (CPU_SWEET16);
}
static void DoPushCharmap (void)
/* Save the current charmap */
{
@@ -2057,70 +2113,74 @@ struct CtrlDesc {
void (*Handler) (void); /* Command handler */
};
/* NOTE: .AND, .BITAND, .BITNOT, .BITOR, .BITXOR, .MOD, .NOT, .OR, .SHL, .SHR
** and .XOR do NOT go into this table.
*/
#define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0]))
static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoA16 },
{ ccNone, DoA8 },
{ ccNone, DoA16 }, /* .A16 */
{ ccNone, DoA8 }, /* .A8 */
{ ccNone, DoAddr }, /* .ADDR */
{ ccNone, DoUnexpected }, /* .ADDRSIZE */
{ ccNone, DoAlign },
{ ccNone, DoASCIIZ },
{ ccNone, DoAlign }, /* .ALIGN */
{ ccNone, DoASCIIZ }, /* .ASCIIZ */
{ ccNone, DoUnexpected }, /* .ASIZE */
{ ccNone, DoAssert },
{ ccNone, DoAutoImport },
{ ccNone, DoAssert }, /* .ASSERT */
{ ccNone, DoAutoImport }, /* .AUTOIMPORT */
{ ccNone, DoUnexpected }, /* .BANK */
{ ccNone, DoUnexpected }, /* .BANKBYTE */
{ ccNone, DoBankBytes },
{ ccNone, DoBankBytes }, /* .BANKBYTES */
{ ccNone, DoUnexpected }, /* .BLANK */
{ ccNone, DoBss },
{ ccNone, DoByte },
{ ccNone, DoCase },
{ ccNone, DoCharMap },
{ ccNone, DoCode },
{ ccNone, DoBss }, /* .BSS */
{ ccNone, DoByte }, /* .BYT, .BYTE */
{ ccNone, DoUnexpected }, /* .CAP */
{ ccNone, DoCase }, /* .CASE */
{ ccNone, DoCharMap }, /* .CHARMAP */
{ ccNone, DoCode }, /* .CODE */
{ ccNone, DoUnexpected, }, /* .CONCAT */
{ ccNone, DoConDes },
{ ccNone, DoConDes }, /* .CONDES */
{ ccNone, DoUnexpected }, /* .CONST */
{ ccNone, DoConstructor },
{ ccNone, DoConstructor }, /* .CONSTRUCTOR */
{ ccNone, DoUnexpected }, /* .CPU */
{ ccNone, DoData },
{ ccNone, DoDbg, },
{ ccNone, DoDByt },
{ ccNone, DoDebugInfo },
{ ccKeepToken, DoDefine },
{ ccNone, DoData }, /* .DATA */
{ ccNone, DoDbg, }, /* .DBG */
{ ccNone, DoDByt }, /* .DBYT */
{ ccNone, DoDebugInfo }, /* .DEBUGINFO */
{ ccKeepToken, DoDefine }, /* .DEF, .DEFINE */
{ ccNone, DoUnexpected }, /* .DEFINED */
{ ccNone, DoUnexpected }, /* .DEFINEDMACRO */
{ ccNone, DoDelMac },
{ ccNone, DoDestructor },
{ ccNone, DoDWord },
{ ccNone, DoDelMac }, /* .DELMAC, .DELMACRO */
{ ccNone, DoDestructor }, /* .DESTRUCTOR */
{ ccNone, DoDWord }, /* .DWORD */
{ ccKeepToken, DoConditionals }, /* .ELSE */
{ ccKeepToken, DoConditionals }, /* .ELSEIF */
{ ccKeepToken, DoEnd },
{ ccKeepToken, DoEnd }, /* .END */
{ ccNone, DoUnexpected }, /* .ENDENUM */
{ ccKeepToken, DoConditionals }, /* .ENDIF */
{ ccNone, DoUnexpected }, /* .ENDMACRO */
{ ccNone, DoEndProc },
{ ccNone, DoUnexpected }, /* .ENDREPEAT */
{ ccNone, DoEndScope },
{ ccNone, DoUnexpected }, /* .ENDMAC, .ENDMACRO */
{ ccNone, DoEndProc }, /* .ENDPROC */
{ ccNone, DoUnexpected }, /* .ENDREP, .ENDREPEAT */
{ ccNone, DoEndScope }, /* .ENDSCOPE */
{ ccNone, DoUnexpected }, /* .ENDSTRUCT */
{ ccNone, DoUnexpected }, /* .ENDUNION */
{ ccNone, DoEnum },
{ ccNone, DoError },
{ ccNone, DoExitMacro },
{ ccNone, DoExport },
{ ccNone, DoExportZP },
{ ccNone, DoFarAddr },
{ ccNone, DoFatal },
{ ccNone, DoFeature },
{ ccNone, DoFileOpt },
{ ccNone, DoForceImport },
{ ccNone, DoEnum }, /* .ENUM */
{ ccNone, DoError }, /* .ERROR */
{ ccNone, DoExitMacro }, /* .EXITMAC, .EXITMACRO */
{ ccNone, DoExport }, /* .EXPORT */
{ ccNone, DoExportZP }, /* .EXPORTZP */
{ ccNone, DoFarAddr }, /* .FARADDR */
{ ccNone, DoFatal }, /* .FATAL */
{ ccNone, DoFeature }, /* .FEATURE */
{ ccNone, DoFileOpt }, /* .FOPT, .FILEOPT */
{ ccNone, DoForceImport }, /* .FORCEIMPORT */
{ ccNone, DoUnexpected }, /* .FORCEWORD */
{ ccNone, DoGlobal },
{ ccNone, DoGlobalZP },
{ ccNone, DoGlobal }, /* .GLOBAL */
{ ccNone, DoGlobalZP }, /* .GLOBALZP */
{ ccNone, DoUnexpected }, /* .HIBYTE */
{ ccNone, DoHiBytes },
{ ccNone, DoHiBytes }, /* .HIBYTES */
{ ccNone, DoUnexpected }, /* .HIWORD */
{ ccNone, DoI16 },
{ ccNone, DoI8 },
{ ccNone, DoI16 }, /* .I16 */
{ ccNone, DoI8 }, /* .I8 */
{ ccNone, DoUnexpected }, /* .IDENT */
{ ccKeepToken, DoConditionals }, /* .IF */
{ ccKeepToken, DoConditionals }, /* .IFBLANK */
@@ -2131,81 +2191,95 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccKeepToken, DoConditionals }, /* .IFNDEF */
{ ccKeepToken, DoConditionals }, /* .IFNREF */
{ ccKeepToken, DoConditionals }, /* .IFP02 */
{ ccKeepToken, DoConditionals }, /* .IFP02X */
{ ccKeepToken, DoConditionals }, /* .IFP4510 */
{ ccKeepToken, DoConditionals }, /* .IFP45GS02 */
{ ccKeepToken, DoConditionals }, /* .IFP6280 */
{ ccKeepToken, DoConditionals }, /* .IFP816 */
{ ccKeepToken, DoConditionals }, /* .IFPC02 */
{ ccKeepToken, DoConditionals }, /* .IFPCE02 */
{ ccKeepToken, DoConditionals }, /* .IFPDTV */
{ ccKeepToken, DoConditionals }, /* .IFPM740 */
{ ccKeepToken, DoConditionals }, /* .IFPSC02 */
{ ccKeepToken, DoConditionals }, /* .IFPSWEET16 */
{ ccKeepToken, DoConditionals }, /* .IFPWC02 */
{ ccKeepToken, DoConditionals }, /* .IFREF */
{ ccNone, DoImport },
{ ccNone, DoImportZP },
{ ccNone, DoIncBin },
{ ccNone, DoInclude },
{ ccNone, DoInterruptor },
{ ccNone, DoImport }, /* .IMPORT */
{ ccNone, DoImportZP }, /* .IMPORTZP */
{ ccNone, DoIncBin }, /* .INCBIN */
{ ccNone, DoInclude }, /* .INCLUDE */
{ ccNone, DoInterruptor }, /* .INTERRUPTPOR */
{ ccNone, DoUnexpected }, /* .ISIZE */
{ ccNone, DoUnexpected }, /* .ISMNEMONIC */
{ ccNone, DoInvalid }, /* .LEFT */
{ ccNone, DoLineCont },
{ ccNone, DoList },
{ ccNone, DoListBytes },
{ ccNone, DoLiteral },
{ ccNone, DoLineCont }, /* .LINECONT */
{ ccNone, DoList }, /* .LIST */
{ ccNone, DoListBytes }, /* .LISTBYTES */
{ ccNone, DoLiteral }, /* .LITERAL */
{ ccNone, DoUnexpected }, /* .LOBYTE */
{ ccNone, DoLoBytes },
{ ccNone, DoLoBytes }, /* .LOBYTES */
{ ccNone, DoUnexpected }, /* .LOCAL */
{ ccNone, DoLocalChar },
{ ccNone, DoLocalChar }, /* .LOCALCHAR */
{ ccNone, DoUnexpected }, /* .LOWORD */
{ ccNone, DoMacPack },
{ ccNone, DoMacro },
{ ccNone, DoMacPack }, /* .MACPACK */
{ ccNone, DoMacro }, /* .MAC, .MACRO */
{ ccNone, DoUnexpected }, /* .MATCH */
{ ccNone, DoUnexpected }, /* .MAX */
{ ccNone, DoInvalid }, /* .MID */
{ ccNone, DoUnexpected }, /* .MIN */
{ ccNone, DoNull },
{ ccNone, DoOrg },
{ ccNone, DoOut },
{ ccNone, DoP02 },
{ ccNone, DoP4510 },
{ ccNone, DoP816 },
{ ccNone, DoPageLength },
{ ccNone, DoNull }, /* .NULL */
{ ccNone, DoOrg }, /* .ORG */
{ ccNone, DoOut }, /* .OUT */
{ ccNone, DoP02 }, /* .P02 */
{ ccNone, DoP02X }, /* .P02X */
{ ccNone, DoP4510 }, /* .P4510 */
{ ccNone, DoP45GS02 }, /* .P45GS02 */
{ ccNone, DoP6280 }, /* .P6280 */
{ ccNone, DoP816 }, /* .P816 */
{ ccNone, DoPageLength }, /* .PAGELEN, .PAGELENGTH */
{ ccNone, DoUnexpected }, /* .PARAMCOUNT */
{ ccNone, DoPC02 },
{ ccNone, DoPDTV },
{ ccNone, DoPopCharmap },
{ ccNone, DoPopCPU },
{ ccNone, DoPopSeg },
{ ccNone, DoProc },
{ ccNone, DoPSC02 },
{ ccNone, DoPushCharmap },
{ ccNone, DoPushCPU },
{ ccNone, DoPushSeg },
{ ccNone, DoUnexpected }, /* .REFERENCED */
{ ccNone, DoReferTo }, /* .REFERTO */
{ ccNone, DoReloc },
{ ccNone, DoRepeat },
{ ccNone, DoRes },
{ ccNone, DoPC02 }, /* .PC02 */
{ ccNone, DoPCE02 }, /* .PCE02 */
{ ccNone, DoPDTV }, /* .PDTV */
{ ccNone, DoPM740 }, /* .PM740 */
{ ccNone, DoPopCharmap }, /* .POPCHARMAP */
{ ccNone, DoPopCPU }, /* .POPCPU */
{ ccNone, DoPopSeg }, /* .POPSEG */
{ ccNone, DoProc }, /* .PROC */
{ ccNone, DoPSC02 }, /* .PSC02 */
{ ccNone, DoPSweet16 }, /* .PSWEET16 */
{ ccNone, DoPushCharmap }, /* .PUSHCHARMAP */
{ ccNone, DoPushCPU }, /* .PUSHCPU */
{ ccNone, DoPushSeg }, /* .PUSHSEG */
{ ccNone, DoPWC02 }, /* .PWC02 */
{ ccNone, DoUnexpected }, /* .REF, .REFERENCED */
{ ccNone, DoReferTo }, /* .REFTO, .REFERTO */
{ ccNone, DoReloc }, /* .RELOC */
{ ccNone, DoRepeat }, /* .REPEAT */
{ ccNone, DoRes }, /* .RES */
{ ccNone, DoInvalid }, /* .RIGHT */
{ ccNone, DoROData },
{ ccNone, DoScope },
{ ccNone, DoSegment },
{ ccNone, DoROData }, /* .RODATA */
{ ccNone, DoScope }, /* .SCOPE */
{ ccNone, DoSegment }, /* .SEGMENT */
{ ccNone, DoUnexpected }, /* .SET */
{ ccNone, DoSetCPU },
{ ccNone, DoSetCPU }, /* .SETCPU */
{ ccNone, DoUnexpected }, /* .SIZEOF */
{ ccNone, DoSmart },
{ ccNone, DoSmart }, /* .SMART */
{ ccNone, DoUnexpected }, /* .SPRINTF */
{ ccNone, DoUnexpected }, /* .STRAT */
{ ccNone, DoUnexpected }, /* .STRING */
{ ccNone, DoUnexpected }, /* .STRLEN */
{ ccNone, DoStruct },
{ ccNone, DoTag },
{ ccNone, DoStruct }, /* .STRUCT */
{ ccNone, DoTag }, /* .TAG */
{ ccNone, DoUnexpected }, /* .TCOUNT */
{ ccNone, DoUnexpected }, /* .TIME */
{ ccKeepToken, DoUnDef },
{ ccNone, DoUnion },
{ ccKeepToken, DoUnDef }, /* .UNDEF, .UNDEFINE */
{ ccNone, DoUnion }, /* .UNION */
{ ccNone, DoUnexpected }, /* .VERSION */
{ ccNone, DoWarning },
{ ccNone, DoWord },
{ ccNone, DoWarning }, /* .WARNING */
{ ccNone, DoWord }, /* .WORD */
{ ccNone, DoUnexpected }, /* .XMATCH */
{ ccNone, DoZeropage },
{ ccNone, DoZeropage }, /* .ZEROPAGE */
};

View File

@@ -136,6 +136,7 @@ struct DotKeyword {
const char* Key; /* MUST be first field */
token_t Tok;
} DotKeywords [] = {
/* BEGIN SORTED.SH */
{ ".A16", TOK_A16 },
{ ".A8", TOK_A8 },
{ ".ADDR", TOK_ADDR },
@@ -157,6 +158,8 @@ struct DotKeyword {
{ ".BSS", TOK_BSS },
{ ".BYT", TOK_BYTE },
{ ".BYTE", TOK_BYTE },
{ ".CAP", TOK_CAP },
{ ".CAPABILITY", TOK_CAP },
{ ".CASE", TOK_CASE },
{ ".CHARMAP", TOK_CHARMAP },
{ ".CODE", TOK_CODE },
@@ -220,11 +223,18 @@ struct DotKeyword {
{ ".IFNDEF", TOK_IFNDEF },
{ ".IFNREF", TOK_IFNREF },
{ ".IFP02", TOK_IFP02 },
{ ".IFP02X", TOK_IFP02X },
{ ".IFP4510", TOK_IFP4510 },
{ ".IFP45GS02", TOK_IFP45GS02 },
{ ".IFP6280", TOK_IFP6280 },
{ ".IFP816", TOK_IFP816 },
{ ".IFPC02", TOK_IFPC02 },
{ ".IFPCE02", TOK_IFPCE02 },
{ ".IFPDTV", TOK_IFPDTV },
{ ".IFPM740", TOK_IFPM740 },
{ ".IFPSC02", TOK_IFPSC02 },
{ ".IFPSWEET16", TOK_IFPSWEET16 },
{ ".IFPWC02", TOK_IFPWC02 },
{ ".IFREF", TOK_IFREF },
{ ".IMPORT", TOK_IMPORT },
{ ".IMPORTZP", TOK_IMPORTZP },
@@ -258,21 +268,28 @@ struct DotKeyword {
{ ".ORG", TOK_ORG },
{ ".OUT", TOK_OUT },
{ ".P02", TOK_P02 },
{ ".P02X", TOK_P02X },
{ ".P4510", TOK_P4510 },
{ ".P45GS02", TOK_P45GS02 },
{ ".P6280", TOK_P6280 },
{ ".P816", TOK_P816 },
{ ".PAGELEN", TOK_PAGELENGTH },
{ ".PAGELENGTH", TOK_PAGELENGTH },
{ ".PARAMCOUNT", TOK_PARAMCOUNT },
{ ".PC02", TOK_PC02 },
{ ".PCE02", TOK_PCE02 },
{ ".PDTV", TOK_PDTV },
{ ".PM740", TOK_PM740 },
{ ".POPCHARMAP", TOK_POPCHARMAP },
{ ".POPCPU", TOK_POPCPU },
{ ".POPSEG", TOK_POPSEG },
{ ".PROC", TOK_PROC },
{ ".PSC02", TOK_PSC02 },
{ ".PSWEET16", TOK_PSWEET16 },
{ ".PUSHCHARMAP", TOK_PUSHCHARMAP },
{ ".PUSHCPU", TOK_PUSHCPU },
{ ".PUSHSEG", TOK_PUSHSEG },
{ ".PWC02", TOK_PWC02 },
{ ".REF", TOK_REFERENCED },
{ ".REFERENCED", TOK_REFERENCED },
{ ".REFERTO", TOK_REFERTO },
@@ -307,6 +324,7 @@ struct DotKeyword {
{ ".XMATCH", TOK_XMATCH },
{ ".XOR", TOK_BOOLXOR },
{ ".ZEROPAGE", TOK_ZEROPAGE },
/* END SORTED.SH */
};
@@ -1284,12 +1302,19 @@ Again:
break;
case 'S':
if ((CPU == CPU_4510) || (CPU == CPU_65816)) {
if ((CPU == CPU_65CE02) || (CPU == CPU_4510) || (CPU == CPU_45GS02) || (CPU == CPU_65816)) {
CurTok.Tok = TOK_S;
return;
}
break;
case 'Q':
if (CPU == CPU_45GS02) {
CurTok.Tok = TOK_Q;
return;
}
break;
case 'X':
CurTok.Tok = TOK_X;
return;
@@ -1304,7 +1329,7 @@ Again:
CurTok.Tok = TOK_OVERRIDE_ZP;
return;
} else {
if (CPU == CPU_4510) {
if ((CPU == CPU_65CE02) || (CPU == CPU_4510) || (CPU == CPU_45GS02)) {
CurTok.Tok = TOK_Z;
return;
}
@@ -1316,7 +1341,8 @@ Again:
}
break;
case 2:
if ((CPU == CPU_4510) &&
/* FIXME: make sure we only alias "sp" to "s" when its really needed */
if (((CPU == CPU_65CE02) || (CPU == CPU_4510) || (CPU == CPU_45GS02)) &&
(toupper (SB_AtUnchecked (&CurTok.SVal, 0)) == 'S') &&
(toupper (SB_AtUnchecked (&CurTok.SVal, 1)) == 'P')) {

View File

@@ -610,12 +610,13 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
DumpExpr (Expr, SymResolve);
}
/* If the symbol has an explicit address size, use it. This may
** lead to range errors later (maybe even in the linker stage), if
** the user lied about the address size, but for now we trust him.
/* If the symbol has an explicit address size that is smaller than
** the one found, use it. This may lead to range errors later
** (maybe even in the linker stage) if the user lied about the
** address size, but for now we trust him.
*/
AddrSize = GetSymAddrSize (Sym);
if (AddrSize != ADDR_SIZE_DEFAULT) {
if (AddrSize != ADDR_SIZE_DEFAULT && AddrSize < D->AddrSize) {
D->AddrSize = AddrSize;
}
}

View File

@@ -211,6 +211,8 @@ static void SymReplaceExprRefs (SymEntry* S)
void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags)
/* Define a new symbol */
{
int Redef = 0; /* Flag for symbol redefinition */
if (S->Flags & SF_IMPORT) {
/* Defined symbol is marked as imported external symbol */
Error ("Symbol '%m%p' is already an import", GetSymName (S));
@@ -238,6 +240,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
*/
FreeExpr (S->Expr);
S->Expr = 0;
Redef = 1;
}
}
@@ -291,8 +294,10 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
}
}
/* If this is not a local symbol, remember it as the last global one */
if ((S->Flags & SF_LOCAL) == 0) {
/* If this is not a local symbol and not a redefinition for a variable
** symbol, remember it as the last global one.
*/
if ((S->Flags & SF_LOCAL) == 0 && !Redef) {
SymLast = S;
}
}

View File

@@ -68,6 +68,7 @@ typedef enum token_t {
TOK_Y, /* Y register */
TOK_Z, /* Z register */
TOK_S, /* S register */
TOK_Q, /* Q pseudo register */
TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */
TOK_ASSIGN, /* := */
@@ -136,6 +137,7 @@ typedef enum token_t {
TOK_BLANK,
TOK_BSS,
TOK_BYTE,
TOK_CAP,
TOK_CASE,
TOK_CHARMAP,
TOK_CODE,
@@ -193,11 +195,18 @@ typedef enum token_t {
TOK_IFNDEF,
TOK_IFNREF,
TOK_IFP02,
TOK_IFP02X,
TOK_IFP4510,
TOK_IFP45GS02,
TOK_IFP6280,
TOK_IFP816,
TOK_IFPC02,
TOK_IFPCE02,
TOK_IFPDTV,
TOK_IFPM740,
TOK_IFPSC02,
TOK_IFPSWEET16,
TOK_IFPWC02,
TOK_IFREF,
TOK_IMPORT,
TOK_IMPORTZP,
@@ -226,20 +235,27 @@ typedef enum token_t {
TOK_ORG,
TOK_OUT,
TOK_P02,
TOK_P02X,
TOK_P4510,
TOK_P45GS02,
TOK_P6280,
TOK_P816,
TOK_PAGELENGTH,
TOK_PARAMCOUNT,
TOK_PC02,
TOK_PCE02,
TOK_PDTV,
TOK_PM740,
TOK_POPCHARMAP,
TOK_POPCPU,
TOK_POPSEG,
TOK_PROC,
TOK_PSC02,
TOK_PSWEET16,
TOK_PUSHCHARMAP,
TOK_PUSHCPU,
TOK_PUSHSEG,
TOK_PWC02,
TOK_REFERENCED,
TOK_REFERTO,
TOK_RELOC,