diff --git a/src/ca65/ea65.c b/src/ca65/ea65.c index a1bda2d7b..d030f47b4 100644 --- a/src/ca65/ea65.c +++ b/src/ca65/ea65.c @@ -90,7 +90,7 @@ void GetEA (EffAddr* A) /* #val */ NextTok (); A->Expr = Expression (); - A->AddrModeSet = AM65_IMM; + A->AddrModeSet = AM65_ALL_IMM; } else if (CurTok.Tok == TOK_A) { @@ -203,4 +203,4 @@ void GetEA (EffAddr* A) - + diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 2cebfecff..c4d756a5d 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -945,17 +945,29 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A) A->Expr = SimplifyExpr (A->Expr, &ED); if (ED.AddrSize == ADDR_SIZE_DEFAULT) { - /* If we don't know how big the expression is, assume the - * default address size for data. If this default address - * size is unequal to zero page addressing, but zero page - * addressing is allowed by the instruction, mark all symbols - * in the expression tree. This mark will be checked at end - * of assembly, and a warning is issued, if a zero page symbol - * was guessed wrong here. + /* We don't know how big the expression is. If the instruction + * allows just one addressing mode, assume this as address size + * for the expression. Otherwise assume the default address size + * for data. */ - ED.AddrSize = DataAddrSize; - if (ED.AddrSize > ADDR_SIZE_ZP && (A->AddrModeSet & AM65_SET_ZP)) { - ExprGuessedAddrSize (A->Expr, ADDR_SIZE_ZP); + if ((A->AddrModeSet & ~AM65_ALL_ZP) == 0) { + ED.AddrSize = ADDR_SIZE_ZP; + } else if ((A->AddrModeSet & ~AM65_ALL_ABS) == 0) { + ED.AddrSize = ADDR_SIZE_ABS; + } else if ((A->AddrModeSet & ~AM65_ALL_FAR) == 0) { + ED.AddrSize = ADDR_SIZE_FAR; + } else { + ED.AddrSize = DataAddrSize; + /* If the default address size of the data segment is unequal + * to zero page addressing, but zero page addressing is + * allowed by the instruction, mark all symbols in the + * expression tree. This mark will be checked at end of + * assembly, and a warning is issued, if a zero page symbol + * was guessed wrong here. + */ + if (ED.AddrSize > ADDR_SIZE_ZP && (A->AddrModeSet & AM65_SET_ZP)) { + ExprGuessedAddrSize (A->Expr, ADDR_SIZE_ZP); + } } } @@ -989,7 +1001,7 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A) * emit a warning. This warning protects against a typo, where the '#' * for the immediate operand is omitted. */ - if (A->Expr && (Ins->AddrMode & AM65_IMM) && + if (A->Expr && (Ins->AddrMode & AM65_ALL_IMM) && (A->AddrModeSet & (AM65_DIR | AM65_ABS | AM65_ABS_LONG)) && ExtBytes[A->AddrMode] == 1) { diff --git a/src/ca65/instr.h b/src/ca65/instr.h index aa0a43236..7d39dbeaf 100644 --- a/src/ca65/instr.h +++ b/src/ca65/instr.h @@ -82,7 +82,6 @@ #define AM65_IMM_ACCU 0x00200000UL #define AM65_IMM_INDEX 0x00400000UL #define AM65_IMM_IMPLICIT 0x00800000UL -#define AM65_IMM (AM65_IMM_ACCU | AM65_IMM_INDEX | AM65_IMM_IMPLICIT) #define AM65_BLOCKMOVE 0x01000000UL #define AM65_BLOCKXFER 0x02000000UL @@ -90,7 +89,19 @@ #define AM65_SET_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND) /* Bitmask for all ABS operations that have correspondent FAR ops */ -#define AM65_SET_ABS (AM65_ABS | AM65_ABS_X) +#define AM65_SET_ABS (AM65_ABS | AM65_ABS_X) + +/* Bitmask for all ZP operations */ +#define AM65_ALL_ZP (AM65_DIR | AM65_DIR_X | AM65_DIR_Y | AM65_DIR_IND | AM65_DIR_X_IND) + +/* Bitmask for all ABS operations */ +#define AM65_ALL_ABS (AM65_ABS | AM65_ABS_X | AM65_ABS_Y | AM65_ABS_IND | AM65_ABS_X_IND) + +/* Bitmask for all FAR operations */ +#define AM65_ALL_FAR (AM65_ABS_LONG | AM65_ABS_LONG_X) + +/* Bitmask for all immediate operations */ +#define AM65_ALL_IMM (AM65_IMM_ACCU | AM65_IMM_INDEX | AM65_IMM_IMPLICIT) /* Bit numbers and count */ #define AM65I_IMM_ACCU 21