Various 020+ fixes. In brief, this commit fixes the following:
authorggn <ggn.dbug@gmail.com>
Thu, 20 Jul 2017 09:21:20 +0000 (12:21 +0300)
committerShamus Hammons <jlhamm@acm.org>
Thu, 20 Jul 2017 12:52:45 +0000 (07:52 -0500)
- Fix warning for \! inside string - we might be evaluating a macro so it's legal.
- Handle (Dn[.w][*scale],label[.l]) ea case.
- Enable scale value in ea to be expression (evaluated) besides constant.
- Fix for ([address[.wl]]). It seems that undefined symbols were not stored properly in eagen0.s (it used aNexpr instead of aNbexpr when storing base displacement).
- Fixes for fmove freg,freg (no size suffix) and ftst freg (no size suffix).
- fmovem now defaults to .x
- Fixed muls.l

68ktab
amode.h
eagen.c
eagen0.c
mach.c
parmode.h

diff --git a/68ktab b/68ktab
index e250bf75b64b4013625ed358d6b0b9bfe28bc785..f8ba190d1e4987c55c3e78147eced4b518b56557 100644 (file)
--- a/68ktab
+++ b/68ktab
@@ -402,7 +402,7 @@ fmod   NBWLSQXP C_ALL030     M_FREG          %1111001000eeeeee   m_fmod   +
 -      NX       M_FREG       M_AM_NONE       %1111001000eeeeee   m_fmod
 fmove  NBWLSQXP C_ALL030     M_FREG          %1111001000eeeeee   m_fmove +
 -      NBWLSQXP M_FREG       C_ALL030        %1111001000eeeeee   m_fmove +
 -      NX       M_FREG       M_AM_NONE       %1111001000eeeeee   m_fmod
 fmove  NBWLSQXP C_ALL030     M_FREG          %1111001000eeeeee   m_fmove +
 -      NBWLSQXP M_FREG       C_ALL030        %1111001000eeeeee   m_fmove +
--      NBWLSQXP M_FREG       M_FREG          %1111001000eeeeee   m_fmove +
+-      NX       M_FREG       M_FREG          %1111001000eeeeee   m_fmove +
 -      NL       M_FPSCR      C_ALL030        %1111001000eeeeee   m_fmovescr +
 -      NL       C_ALL030     M_FPSCR         %1111001000eeeeee   m_fmovescr +
 fsmove NBWLSQXP C_ALL030     M_FREG          %1111001000eeeeee   m_fsmove
 -      NL       M_FPSCR      C_ALL030        %1111001000eeeeee   m_fmovescr +
 -      NL       C_ALL030     M_FPSCR         %1111001000eeeeee   m_fmovescr +
 fsmove NBWLSQXP C_ALL030     M_FREG          %1111001000eeeeee   m_fsmove
@@ -502,7 +502,7 @@ ftentox NBWLSQXP C_ALL030    M_FREG          %1111001000eeeeee   m_ftentox   +
 -       NX       M_FREG      M_FREG          %1111001000eeeeee   m_ftentox   +
 -       NX       M_FREG      M_AM_NONE       %1111001000eeeeee   m_ftentox
 ftst  NBWLSQXP C_ALL030      M_AM_NONE       %1111001000eeeeee   m_ftst +
 -       NX       M_FREG      M_FREG          %1111001000eeeeee   m_ftentox   +
 -       NX       M_FREG      M_AM_NONE       %1111001000eeeeee   m_ftentox
 ftst  NBWLSQXP C_ALL030      M_AM_NONE       %1111001000eeeeee   m_ftst +
--      X          M_FREG      M_AM_NONE       %1111001000eeeeee  m_ftst
+-     NX         M_FREG      M_AM_NONE       %1111001000eeeeee   m_ftst
 ftwotox NBWLSQXP C_ALL030    M_FREG          %1111001000eeeeee   m_ftwotox   +
 -       NX       M_FREG      M_FREG          %1111001000eeeeee   m_ftwotox   +
 -       NX       M_FREG      M_AM_NONE       %1111001000eeeeee   m_ftwotox
 ftwotox NBWLSQXP C_ALL030    M_FREG          %1111001000eeeeee   m_ftwotox   +
 -       NX       M_FREG      M_FREG          %1111001000eeeeee   m_ftwotox   +
 -       NX       M_FREG      M_AM_NONE       %1111001000eeeeee   m_ftwotox
@@ -583,7 +583,8 @@ illegal N    M_AM_NONE       M_AM_NONE       %0100101011111100   m_self
 jmp   N      C_CTRL          M_AM_NONE       %0100111011eee000   m_ea     +
 -     N      C_CTRL030       M_AM_NONE       %0100111011eee000   m_ea030
 
 jmp   N      C_CTRL          M_AM_NONE       %0100111011eee000   m_ea     +
 -     N      C_CTRL030       M_AM_NONE       %0100111011eee000   m_ea030
 
-jsr   N      C_CTRL          M_AM_NONE       %0100111010eee000   m_ea
+jsr   N      C_CTRL          M_AM_NONE       %0100111010eee000   m_ea     +
+-     N      C_CTRL030       M_AM_NONE       %0100111010eee000   m_ea030
 
 lea   NL     C_CTRL          M_AREG          %0100rrr111eR1000   m_lea
 
 
 lea   NL     C_CTRL          M_AREG          %0100rrr111eR1000   m_lea
 
diff --git a/amode.h b/amode.h
index f785b875e524389ce0f6425c72e21237dd1e116b..818c7113bacef34f3232737bd74d1f5459569593 100644 (file)
--- a/amode.h
+++ b/amode.h
@@ -15,6 +15,8 @@
 #define DREG         000                       // Dn
 #define AREG         010                       // An
 #define AIND         020                       // (An)
 #define DREG         000                       // Dn
 #define AREG         010                       // An
 #define AIND         020                       // (An)
+#define DINDW        0112                      // (Dn.w)
+#define DINDL        0113                      // (Dn.l)
 #define APOSTINC     030                       // (An)+
 #define APREDEC      040                       // -(An)
 #define ADISP        050                       // (d16,An) d16(An)
 #define APOSTINC     030                       // (An)+
 #define APREDEC      040                       // -(An)
 #define ADISP        050                       // (d16,An) d16(An)
diff --git a/eagen.c b/eagen.c
index bf1f67ac88d84a1170098f339236090b7016891f..de1ecb426fb2699981f7fb31719aeeacf69e6c42 100644 (file)
--- a/eagen.c
+++ b/eagen.c
@@ -24,6 +24,7 @@
 #define aNixsiz   a0ixsiz
 #define AnESYM    a0esym
 #define aNexten   a0extension
 #define aNixsiz   a0ixsiz
 #define AnESYM    a0esym
 #define aNexten   a0extension
+#define aNbexpr   a0bexpr
 #define aNbdexval a0bexval
 #define aNbdexattr a0bexattr
 #include "eagen0.c"
 #define aNbdexval a0bexval
 #define aNbdexattr a0bexattr
 #include "eagen0.c"
@@ -37,6 +38,7 @@
 #define aNixsiz   a1ixsiz
 #define AnESYM    a1esym
 #define aNexten   a1extension
 #define aNixsiz   a1ixsiz
 #define AnESYM    a1esym
 #define aNexten   a1extension
+#define aNbexpr   a1bexpr
 #define aNbdexval a1bexval
 #define aNbdexattr a1bexattr
 #include "eagen0.c"
 #define aNbdexval a1bexval
 #define aNbdexattr a1bexattr
 #include "eagen0.c"
index 7fe382a115c5c692a04aed6e19c321cdb6e3e5a4..f01b989a7454812538d397cdca29881e0fa2545d 100644 (file)
--- a/eagen0.c
+++ b/eagen0.c
@@ -251,6 +251,12 @@ int eaNgen(WORD siz)
                        D_long(0);
                }
 
                        D_long(0);
                }
 
+               break;
+       case DINDW:
+               D_word(0x190|(aNixreg<<12));
+               break;
+       case DINDL:
+               D_word(0x990|(aNixreg<<12));
                break;
        case ABASE:
        case MEMPOST:
                break;
        case ABASE:
        case MEMPOST:
@@ -281,7 +287,7 @@ int eaNgen(WORD siz)
                        else
                        {
                                // Arrange for fixup later on
                        else
                        {
                                // Arrange for fixup later on
-                               AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+                               AddFixup(FU_WORD|FU_SEXT, sloc, aNbexpr);
                                D_word(0);
                        }
                }
                                D_word(0);
                        }
                }
@@ -299,7 +305,7 @@ int eaNgen(WORD siz)
                        else
                        {
                                // Arrange for fixup later on
                        else
                        {
                                // Arrange for fixup later on
-                               AddFixup(FU_LONG|FU_SEXT, sloc, aNexpr);
+                               AddFixup(FU_LONG, sloc, aNbexpr);
                                D_long(0);
                        }
                }
                                D_long(0);
                        }
                }
@@ -369,6 +375,7 @@ int eaNgen(WORD siz)
 #undef aNixreg
 #undef aNixsiz
 #undef aNexten
 #undef aNixreg
 #undef aNixsiz
 #undef aNexten
+#undef aNbexpr
 #undef aNbdexval
 #undef aNbdexattr
 #undef AnESYM
 #undef aNbdexval
 #undef aNbdexattr
 #undef AnESYM
diff --git a/mach.c b/mach.c
index 12abcc218ddcae1fe32d046989e6aadcdc349fd5..ac800eb665bdf0e77366c5adfbdd55faa3addb85 100644 (file)
--- a/mach.c
+++ b/mach.c
@@ -1391,7 +1391,7 @@ int m_cas(WORD inst, WORD siz)
        // Reject invalud ea modes
        amsk = amsktab[am0];
 
        // Reject invalud ea modes
        amsk = amsktab[am0];
 
-       if (amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE) == 0)
+       if ((amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE)) == 0)
                return error("unsupported addressing mode");
 
        inst |= am0 | a0reg;
                return error("unsupported addressing mode");
 
        inst |= am0 | a0reg;
@@ -1409,7 +1409,6 @@ int m_cas(WORD inst, WORD siz)
 int m_cas2(WORD inst, WORD siz)
 {
        WORD inst2, inst3;
 int m_cas2(WORD inst, WORD siz)
 {
        WORD inst2, inst3;
-       LONG amsk;
 
        if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
                return error(unsupport);
 
        if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
                return error(unsupport);
@@ -1614,7 +1613,6 @@ int m_cpbr(WORD inst, WORD siz)
                        {
                                inst |= (1 << 6);
                                D_word(inst);
                        {
                                inst |= (1 << 6);
                                D_word(inst);
-                               WARNING(check what s "optional coprocessor-defined extension words!")
                                D_long(v);
                                return OK;
                        }
                                D_long(v);
                                return OK;
                        }
@@ -1625,7 +1623,6 @@ int m_cpbr(WORD inst, WORD siz)
                                return error(range_error);
 
                        D_word(inst);
                                return error(range_error);
 
                        D_word(inst);
-                       WARNING(check what s "optional coprocessor-defined extension words!")
                        D_word(v);
                }
 
                        D_word(v);
                }
 
@@ -1753,6 +1750,11 @@ int m_muls(WORD inst, WORD siz)
                inst |= am1 | a1reg;                    // Get ea1 into instr
                D_word(inst);                                   // Deposit instr
 
                inst |= am1 | a1reg;                    // Get ea1 into instr
                D_word(inst);                                   // Deposit instr
 
+                                                                               // Extension word
+               inst = a1reg + (a2reg << 12) + (1 << 11);
+               inst |= mulmode;  // add size bit
+               D_word(inst);
+
                // Generate ea0 if requested
                if (flg & 2)
                        ea0gen(siz);
                // Generate ea0 if requested
                if (flg & 2)
                        ea0gen(siz);
@@ -1764,6 +1766,11 @@ int m_muls(WORD inst, WORD siz)
                // Use am0
                inst |= am0 | a0reg;                    // Get ea0 into instr
                D_word(inst);                                   // Deposit instr
                // Use am0
                inst |= am0 | a0reg;                    // Get ea0 into instr
                D_word(inst);                                   // Deposit instr
+                                                                               // Extension word
+               inst = a1reg + (a2reg << 12) + (1 << 11);
+               inst |= mulmode;  // add size bit
+               D_word(inst);
+
                ea0gen(siz);                                    // Generate ea0
 
                // Generate ea1 if requested
                ea0gen(siz);                                    // Generate ea0
 
                // Generate ea1 if requested
@@ -1771,9 +1778,8 @@ int m_muls(WORD inst, WORD siz)
                        ea1gen(siz);
        }
 
                        ea1gen(siz);
        }
 
-       inst = a1reg + (a2reg << 12) + (1 << 11);
-       inst |= mulmode;  // add size bit
-       D_word(inst);
+       //D_word(inst);
+       //ea0gen(siz);
 
        return OK;
 }
 
        return OK;
 }
@@ -2419,6 +2425,7 @@ int m_pflushr(WORD inst, WORD siz)
        }
 
        D_word(B16(10100000, 00000000));
        }
 
        D_word(B16(10100000, 00000000));
+       return OK;
 }
 
 
 }
 
 
@@ -2934,6 +2941,7 @@ int m_fmove(WORD inst, WORD siz)
        // EA to register
        if ((am0 == FREG) && (am1 < AM_USP))
        {
        // EA to register
        if ((am0 == FREG) && (am1 < AM_USP))
        {
+               //fpx->ea
                // EA
                inst |= am1 | a1reg;
                D_word(inst);
                // EA
                inst |= am1 | a1reg;
                D_word(inst);
@@ -2982,6 +2990,8 @@ int m_fmove(WORD inst, WORD siz)
        }
        else if ((am0 < AM_USP) && (am1 == FREG))
        {
        }
        else if ((am0 < AM_USP) && (am1 == FREG))
        {
+               //ea->fpx
+
                // EA
                inst |= am0 | a0reg;
                D_word(inst);
                // EA
                inst |= am0 | a0reg;
                D_word(inst);
@@ -3016,6 +3026,9 @@ int m_fmove(WORD inst, WORD siz)
        }
        else if ((am0 == FREG) && (am1 == FREG))
        {
        }
        else if ((am0 == FREG) && (am1 == FREG))
        {
+               // register-to-register
+               // Essentially ea to register with R/0=0
+
                // EA
                D_word(inst);
 
                // EA
                D_word(inst);
 
@@ -3128,11 +3141,11 @@ int m_fmovem(WORD inst, WORD siz)
        WORD regmask;
        WORD datareg;
 
        WORD regmask;
        WORD datareg;
 
-       if (siz == SIZX)
+       if (siz == SIZX || siz==SIZN)
        {
                if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
                {
        {
                if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
                {
-                       // fmovem.x <rlist>,ea
+                       //fmovem.x <rlist>,ea
                        if (fpu_reglist_left(&regmask) < 0)
                                return OK;
 
                        if (fpu_reglist_left(&regmask) < 0)
                                return OK;
 
@@ -3210,7 +3223,7 @@ int m_fmovem(WORD inst, WORD siz)
                        }
                }
        }
                        }
                }
        }
-       else if ((siz == SIZL) || (siz==SIZN))
+       else if (siz == SIZL)
        {
                if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
                {
        {
                if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
                {
index 5ad5da90e1240e21bcd37da69a889228af048082..e623084b252fb9928d33d7dd9170fc8a3c4b22ea 100644 (file)
--- a/parmode.h
+++ b/parmode.h
                        else if (*tok == 'L')
                        {
                                // TODO: does DINDL gets used at all?
                        else if (*tok == 'L')
                        {
                                // TODO: does DINDL gets used at all?
-                               //AMn=DINDL;                                     // (Dn.l)
-                               //AnEXTEN = 1 << 1;   // Long index size
-                               //tok++;
+                               AMn=DINDL;                                     // (Dn.l)
+                               AnEXTEN = 1 << 1;   // Long index size
+                               tok++;
                        }
                        else if (*tok == 'W')                                // (Dn.w)
                        {
                                // TODO: does DINDW gets used at all?
                        }
                        else if (*tok == 'W')                                // (Dn.w)
                        {
                                // TODO: does DINDW gets used at all?
-                               //AMn=DINDW;
-                               //AnEXTEN = 1 << 1;   // Word index size
-                               //tok++;
+                               AMn=DINDW;
+                               AnEXTEN = 1 << 1;   // Word index size
+                               tok++;
                        }
                        else if (*tok == ',')
                        {
                        }
                        else if (*tok == ',')
                        {
                                goto CHECKODn;
                        }
                        else
                                goto CHECKODn;
                        }
                        else
+                       {
                                return error("(Dn) error");
                                return error("(Dn) error");
+                       }
+
+                       if (*tok == '*')
+                       {                        // scale: *1, *2, *4, *8
+                               tok++;
+
+                               if (*tok == SYMBOL)
+                               {
+                                       if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+                                               return error("scale factor expression must evaluate");
+                                       switch (AnEXVAL)
+                                       {
+                                       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 || *tok > 8)
+                                       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;
+                                       }
+                               }
+                       }
 
                        if (*tok == ')')
                        {
 
                        if (*tok == ')')
                        {
                                AMn = MEMPOST;
                                goto AnOK;
                        }
                                AMn = MEMPOST;
                                goto AnOK;
                        }
+                       else if (*tok==',')
+                       {
+                               tok++;  // eat the comma
+                               // It might be (Dn[.wl][*scale],od)
+                               // Maybe this is wrong and we have to write some code here
+                               // instead of reusing that path...
+                               goto CHECKODn;
+                       }
                        else
                                return error("unhandled so far");
                }
                        else
                                return error("unhandled so far");
                }
                        }
 
                        if (*tok == '*')
                        }
 
                        if (*tok == '*')
-                       {                        // scale: *1, *2, *4, *8
+                       {                                  // scale: *1, *2, *4, *8
                                tok++;
 
                                tok++;
 
-                               if (*tok++ != CONST || *tok > 8)
-                                       goto badmode;
-
-                               switch ((int)*tok++)
-                               {
-                               case 1:
-                                       break;
-                               case 2:
-                                       AnIXSIZ |= TIMES2;
-                                       break;
-                               case 4:
-                                       AnIXSIZ |= TIMES4;
-                                       break;
-                               case 8:
-                                       AnIXSIZ |= TIMES8;
-                                       break;
-                               default:
+                               if (*tok == SYMBOL)
+                               {
+                                       if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+                                               return error("scale factor expression must evaluate");
+                                       switch (AnEXVAL)
+                                       {
+                                       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 || *tok > 8)
                                        goto badmode;
                                        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;
+                                       }
                                }
                        }
 
                                }
                        }
 
+                       if (*tok == ',')
+                       {
+                               tok++;
+                               goto CHECKODn;
+                       }
                        if (*tok++ != ')')         // final ")"
                                goto badmode;
 
                        if (*tok++ != ')')         // final ")"
                                goto badmode;
 
 
                                // Check for scale
                                if (*tok == '*')                        // ([bd,An/PC],Xn*...)
 
                                // Check for scale
                                if (*tok == '*')                        // ([bd,An/PC],Xn*...)
-                               {
+                               {                           // scale: *1, *2, *4, *8
                                        tok++;
 
                                        tok++;
 
-                                       if (*tok == CONST)      // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
-                                               tok++;
-
-                                       switch ((int)*tok++)
+                                       if (*tok == SYMBOL)
                                        {
                                        {
-                                       case 1:
-                                               break;
-                                       case 2:
-                                               AnEXTEN |= EXT_TIMES2;
-                                               break;
-                                       case 4:
-                                               AnEXTEN |= EXT_TIMES4;
-                                               break;
-                                       case 8:
-                                               AnEXTEN |= EXT_TIMES8;
-                                               break;
-                                       default:
+                                               if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+                                                       return error("scale factor expression must evaluate");
+                                               switch (AnEXVAL)
+                                               {
+                                               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 || *tok > 8)
                                                goto badmode;
                                                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;
+                                               }
                                        }
                                }
                                        }
                                }
-
                                if (*tok == ']')  // ([bd,Dn]...
                                {
                                        tok++;
                                if (*tok == ']')  // ([bd,Dn]...
                                {
                                        tok++;
                                if (*tok == ')')
                                {
                                        //Xn and od are non existent, get out of jail free card
                                if (*tok == ')')
                                {
                                        //Xn and od are non existent, get out of jail free card
+                                       tok++;
                                        AMn = MEMPRE;                   // ([bc,An,Xn],od) with no Xn and od
                                        AnEXTEN |= EXT_IS | EXT_IISPREN;        //Suppress Xn and od
                                        AMn = MEMPRE;                   // ([bc,An,Xn],od) with no Xn and od
                                        AnEXTEN |= EXT_IS | EXT_IISPREN;        //Suppress Xn and od
-                                       tok++;
                                        goto AnOK;
                                }
                                else if (*tok != ',')
                                        goto AnOK;
                                }
                                else if (*tok != ',')
                                }
 
                                // Check for scale
                                }
 
                                // Check for scale
-                               if (*tok == '*')
-                               {
-                                       // ([bd,An/PC],Xn*...)
+                               if (*tok == '*')                   // ([bd,An/PC],Xn*...)
+                               {                                  // scale: *1, *2, *4, *8
                                        tok++;
 
                                        tok++;
 
-                                       if (*tok == CONST)      // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
-                                               tok++;
-
-                                       switch ((int)*tok++)
+                                       if (*tok == SYMBOL)
+                                       {
+                                               if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+                                                       return error("scale factor expression must evaluate");
+                                               switch (AnEXVAL)
                                        {
                                        case 1:
                                                break;
                                        case 2:
                                        {
                                        case 1:
                                                break;
                                        case 2:
-                                               AnEXTEN |= EXT_TIMES2;
+                                                       AnIXSIZ |= TIMES2;
                                                break;
                                        case 4:
                                                break;
                                        case 4:
-                                               AnEXTEN |= EXT_TIMES4;
+                                                       AnIXSIZ |= TIMES4;
                                                break;
                                        case 8:
                                                break;
                                        case 8:
-                                               AnEXTEN |= EXT_TIMES8;
+                                                       AnIXSIZ |= TIMES8;
                                                break;
                                        default:
                                                goto badmode;
                                                break;
                                        default:
                                                goto badmode;
+                                               }
+                                       }
+                                       else if (*tok++ != CONST || *tok > 8)
+                                               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++;  // eat the comma
 
                                CHECKODn:
                                        tok++;  // eat the comma
 
                                CHECKODn:
-
                                if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
                                        goto badmode;
 
                                if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
                                        goto badmode;
 
                                        tok++;
                                        goto AnOK;
                                }
                                        tok++;
                                        goto AnOK;
                                }
-
                                // ([bd,An/PC],Xn,od)
                                if (*tok == DOTL)
                                {
                                        // expr.L
                                        AnEXTEN |= EXT_IISPOSL; // Long outer displacement
                                        AMn = MEMPOST;
                                // ([bd,An/PC],Xn,od)
                                if (*tok == DOTL)
                                {
                                        // expr.L
                                        AnEXTEN |= EXT_IISPOSL; // Long outer displacement
                                        AMn = MEMPOST;
+                                       tok++;
 
                                        // Defined, absolute values from $FFFF8000..$00007FFF get
                                        // optimized to absolute short
 
                                        // Defined, absolute values from $FFFF8000..$00007FFF get
                                        // optimized to absolute short
                                        // expr[.W][]
                                        AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed
                                        AMn = MEMPRE;
                                        // expr[.W][]
                                        AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed
                                        AMn = MEMPRE;
-
                                        if (*tok == DOTW)
                                        {
                                                //AnEXTEN|=EXT_IISNOIW; // Word outer displacement
                                        if (*tok == DOTW)
                                        {
                                                //AnEXTEN|=EXT_IISNOIW; // Word outer displacement
 
                                // Check for scale
                                if (*tok == '*')                        // ([bd,An/PC],Xn*...)
 
                                // Check for scale
                                if (*tok == '*')                        // ([bd,An/PC],Xn*...)
-                               {
+                               {                           // scale: *1, *2, *4, *8
                                        tok++;
 
                                        tok++;
 
-                                       if (*tok == CONST)      // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
-                                               tok++;
-
-                                       switch ((int)*tok++)
+                                       if (*tok == SYMBOL)
                                        {
                                        {
-                                       case 1:
-                                               break;
-                                       case 2:
-                                               AnEXTEN |= EXT_TIMES2;
-                                               break;
-                                       case 4:
-                                               AnEXTEN |= EXT_TIMES4;
-                                               break;
-                                       case 8:
-                                               AnEXTEN |= EXT_TIMES8;
-                                               break;
-                                       default:
+                                               if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+                                                       return error("scale factor expression must evaluate");
+                                               switch (AnEXVAL)
+                                               {
+                                               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 || *tok > 8)
                                                goto badmode;
                                                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;
+                                               }
                                        }
                                }
 
                                //Check for ]
                                if (*tok != ']')
                                        return error("Expected closing bracket ]");
                                        }
                                }
 
                                //Check for ]
                                if (*tok != ']')
                                        return error("Expected closing bracket ]");
-
                                tok++;                  // Eat the bracket
 
                                //Check for od
                                tok++;                  // Eat the bracket
 
                                //Check for od
                // After a cache keyword only a comma or EOL is allowed
                if ((*tok != ',') && (*tok != EOL))
                        return ERROR;
                // After a cache keyword only a comma or EOL is allowed
                if ((*tok != ',') && (*tok != EOL))
                        return ERROR;
-
                goto AnOK;
        }
        else if ((*tok >= KW_SFC) && (*tok <= KW_CRP))
                goto AnOK;
        }
        else if ((*tok >= KW_SFC) && (*tok <= KW_CRP))