+
+ // 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;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
+
+ tok++; // Take into account that constants are 64-bit
+ }
+ }
+
+ // Check for od
+ if (*tok == ')') // ([bd,An/PC],Xn)
+ {
+ // od is non existent, get out of jail free card
+ AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN |= EXT_IISPOSN; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+ else if (*tok != ',')
+ return error("comma expected");
+ else
+ tok++; // eat the comma
+
+CHECKODn:
+ if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ goto badmode;
+
+ if (CHECK_OPTS(OPT_BASE_DISP) && (AnEXATTR & DEFINED) && (AnEXVAL == 0))
+ {
+ // od=0 so optimise it out
+ AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN |= EXT_IISPOSN; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+
+ // ([bd,An/PC],Xn,od)
+ if (*tok == DOTL)
+ {
+ // expr.L
+ if (!(AnEXTEN & EXT_BS))
+ AnEXTEN |= EXT_IISPOSL; // Long outer displacement
+ else
+ {
+ // bd is suppressed, so sticking the od size in bd
+ AnEXTEN |= EXT_BDSIZEL;
+ // And of course the expression has to be copied to
+ // AnBEXPR instead of AnEXPR. Yay. :-/
+ int i = 0;
+
+ do
+ {
+ AnBEXPR[i] = AnEXPR[i];
+ i++;
+ }
+ while (AnEXPR[i] != 'E');
+
+ AnBEXPR[i] = 'E';
+ }
+
+ AMn = MEMPOST;
+ tok++;
+
+ // Defined, absolute values from $FFFF8000..$00007FFF get
+ // optimized to absolute short
+ if (CHECK_OPTS(OPT_ABS_SHORT)
+ && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
+ && (((uint32_t)AnEXVAL + 0x8000) < 0x10000))
+ {
+ AnEXTEN |= EXT_IISPOSW; // Word outer displacement
+ AMn = MEMPOST;
+ warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
+ }
+
+ }
+ else
+ {
+ // expr[.W]
+ AnEXTEN |= EXT_IISPOSW; // Word outer displacement
+ AMn = MEMPOST;
+
+ // Is .W forced here?
+ if (*tok == DOTW)
+ tok++;
+ }
+
+ // Check for final closing parenthesis
+ if (*tok == ')')
+ {
+ tok++;
+ goto AnOK;
+ }
+ else
+ return error("Closing parenthesis missing on addressing mode");
+
+IS_SUPPRESSEDn:
+
+ // Check for od
+ if (*tok == ')') // ([bd,An/PC],Xn)
+ {
+ // od is non existent, get out of jail free card
+ AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN |= EXT_IISNOIN; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+ else if (*tok!=',')
+ return error("comma expected");
+ else
+ tok++; // eat the comma
+
+ if ((*tok != CONST) && (*tok != SYMBOL))
+ goto badmode;
+
+ expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM);
+
+ if (CHECK_OPTS(OPT_BASE_DISP) && (AnEXVAL == 0))
+ {
+ // od=0 so optimise it out
+ AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
+ AnEXTEN |= EXT_IISNOIN; // No outer displacement
+ tok++;
+ goto AnOK;
+ }
+
+ // ([bd,An/PC],Xn,od)
+ if (*tok == DOTL)
+ {
+ // expr.L
+ tok++;
+ AMn = MEMPOST;
+ AnEXTEN |= EXT_IISNOIL; // Long outer displacement with IS suppressed
+ }
+ else
+ {
+ // expr[.W][]
+ AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed
+ AMn = MEMPRE;
+
+ if (*tok == DOTW)
+ {
+ //AnEXTEN|=EXT_IISNOIW; // Word outer displacement
+ AMn = MEMPOST;
+ tok++;
+ }
+ // Defined, absolute values from $FFFF8000..$00007FFF get
+ // optimized to absolute short
+ else if (CHECK_OPTS(OPT_BASE_DISP)
+ && ((AnEXATTR & (TDB | DEFINED)) == DEFINED)
+ && (((uint32_t)AnEXVAL + 0x8000) < 0x10000))
+ {
+ //AnEXTEN|=EXT_IISNOIW; // Word outer displacement with IS suppressed
+ warn("outer displacement absolute value from $FFFF8000..$00007FFF optimised to absolute short");
+ }
+ }
+
+ // Check for final closing parenthesis
+ if (*tok == ')')
+ {
+ tok++;
+ goto AnOK;
+ }
+ else
+ return error("Closing parenthesis missing on addressing mode");