+ // Check for scale
+ if (*tok == '*') // ([bd,An/PC],Xn*...)
+ { // scale: *1, *2, *4, *8
+ tok++;
+
+ if (*tok == SYMBOL)
+ {
+ if (expr(scaleexpr, &scaleval, &scaleattr, &scaleesym) != OK)
+ return error("scale factor expression must evaluate");
+
+ switch (scaleval)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
+ }
+ else if (*tok++ != CONST)
+ goto badmode;
+ else
+ {
+ switch ((int)*tok++)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ AnEXTEN |= 1 << 9;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ AnEXTEN |= 2 << 9;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ AnEXTEN |= 3 << 9;
+ break;
+ default:
+ goto badmode;
+ }
+
+ tok++; // Take into account that constants are 64-bit
+ }
+ }
+
+ // Check for ]
+ if (*tok != ']')
+ return error("Expected closing bracket ]");
+ tok++; // Eat the bracket
+
+ // Check for od
+ if (*tok == ')') // ([bd,An/PC,Xn]...
+ {
+ // od is non existent, get out of jail free card
+ AMn = MEMPRE + ea_PC; // let's say it's ([bd,An,Xn],od) with od suppressed then
+ AnEXTEN |= EXT_IISPREN; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+ else if (*tok++ != ',')
+ return error("comma expected after ]");
+
+ if (*tok == SYMBOL || *tok == CONST)
+ {
+ if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ goto badmode;
+
+ if (CHECK_OPTS(OPT_020_DISP) && (AnEXVAL == 0) && (AnEXATTR & DEFINED))
+ {
+ // od=0 so optimise it out
+ AMn = MEMPRE + ea_PC; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN |= EXT_IISPRE0; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+ }
+
+ // ([bd,An/PC,Xn],od)
+ if (*tok == DOTL)
+ {
+ // expr.L
+ AMn = MEMPRE + ea_PC;
+ tok++;
+ AnEXTEN |= EXT_IISPREL;
+ }
+ else
+ {
+ // expr.[W]
+ AMn = MEMPRE + ea_PC;
+ int expr_size = EXT_IISPREW; // Assume we have a .w value
+
+ if ((AnEXVAL + 0x8000) > 0x10000)
+ {
+ // Long value, so mark it as such for now
+ expr_size = EXT_IISPREL;
+
+ // Defined, absolute values from $FFFF8000..$00007FFF
+ // get optimized to absolute short
+ if (CHECK_OPTS(OPT_020_DISP)
+ && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
+ && (((uint32_t)AnEXVAL + 0x8000) < 0x10000))
+ {
+ expr_size = EXT_IISPREW;
+
+ if (optim_warn_flag)
+ warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
+ }
+ }
+
+ AnEXTEN |= expr_size; // Assume we have a .w value
+
+ // Is .W forced here?
+ if (*tok == DOTW)
+ {
+ tok++;
+
+ if (expr_size == EXT_IISPREL)
+ return error("outer displacement value does not fit in .w size");
+ }
+ }
+
+ // Check for final closing parenthesis
+ if (*tok == ')')
+ {
+ tok++;
+ goto AnOK;
+ }
+ else
+ return error("Closing parenthesis missing on addressing mode");
+ }
+ else
+ goto badmode;