]> Shamusworld >> Repos - rmac/blobdiff - dsp56k_amode.c
Version bump for last commit. :-)
[rmac] / dsp56k_amode.c
index 7937b106b87c54623bdaffdb17d665d4679b980a..664c533f84eef8a51345d1a639964f11de1274f1 100644 (file)
@@ -1,7 +1,7 @@
 //
-// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
+// RMAC - Renamed Macro Assembler for the Atari Jaguar Console System
 // AMODE.C - DSP 56001 Addressing Modes
-// Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2021 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 #include "sect.h"
 #include "math.h"
 
-#define DEF_KW
-#include "kwtab.h"
 #define DEF_MN
 #include "mntab.h"
+#define DEF_REG56
+#include "56kregs.h"
 
 // Address-mode information
-//int nmodes;                                          // Number of addr'ing modes found
 int dsp_am0;                                   // Addressing mode
 int dsp_a0reg;                                 // Register
 TOKEN dsp_a0expr[EXPRSIZE];            // Expression
@@ -62,16 +61,17 @@ uint64_t dspaaEXVAL;                        // Expression's value
 WORD  dspaaEXATTR;                             // Expression's attribute
 SYM * dspaaESYM;                               // External symbol involved in expr
 
-LONG dsp_a0perspace;                      // Peripheral space (X, Y - used in movep)
-LONG dsp_a1perspace;                      // Peripheral space (X, Y - used in movep)
+LONG dsp_a0perspace;                   // Peripheral space (X, Y - used in movep)
+LONG dsp_a1perspace;                   // Peripheral space (X, Y - used in movep)
 
-int dsp_k;                          // Multiplications sign
+int dsp_k;                                             // Multiplications sign
 
 static inline LONG checkea(const uint32_t termchar, const int strings);
 
-// ea checking error strings put into a table because I'm not sure there's an easy way to do otherwise
-// (the messages start getting differerent in many places so it will get awkward to code those in)
-// (I'd rather burn some RAM in order to have more helpful error messages than the other way round)
+// ea checking error strings put into a table because I'm not sure there's an
+// easy way to do otherwise (the messages start getting differerent in many
+// places so it will get awkward to code those in) (I'd rather burn some RAM
+// in order to have more helpful error messages than the other way round)
 
 #define X_ERRORS 0
 #define Y_ERRORS 1
@@ -148,12 +148,13 @@ enum
        NUM_FORCE_SHORT = 2
 };
 
+
 //
 // Parse a single addressing mode
 //
 static inline int dsp_parmode(int *am, int *areg, TOKEN * AnEXPR, uint64_t * AnEXVAL, WORD * AnEXATTR, SYM ** AnESYM, LONG *memspace, LONG *perspace, const int operand)
 {
-       if (*tok == KW_A || *tok == KW_B)
+       if (*tok == REG56_A || *tok == REG56_B)
        {
                *am = M_ACC56;
                *areg = *tok++;
@@ -221,13 +222,13 @@ static inline int dsp_parmode(int *am, int *areg, TOKEN * AnEXPR, uint64_t * AnE
 
                return OK;
        }
-       else if (*tok >= KW_X0 && *tok <= KW_Y1)
+       else if (*tok >= REG56_X0 && *tok <= REG56_Y1)
        {
                *am = M_ALU24;
                *areg = *tok++;
                return OK;
        }
-       else if (*tok == KW_X && *(tok + 1) == ':')
+       else if (*tok == REG56_X && *(tok + 1) == ':')
        {
                tok = tok + 2;
 
@@ -358,7 +359,7 @@ static inline int dsp_parmode(int *am, int *areg, TOKEN * AnEXPR, uint64_t * AnE
                        *am = M_DSPPP;
                        *memspace = 0 << 6;          // Mark we're on X memory space
                        *perspace = 0 << 16;         // Mark we're on X peripheral space
-                       *areg = *AnEXVAL & 0x3f;     // Since this is only going to get used in dsp_ea_imm5...
+                       *areg = *AnEXVAL & 0x3F;     // Since this is only going to get used in dsp_ea_imm5...
                        return OK;
                }
 
@@ -372,7 +373,7 @@ static inline int dsp_parmode(int *am, int *areg, TOKEN * AnEXPR, uint64_t * AnE
                else
                        return ERROR;
        }
-       else if (*tok == KW_Y && *(tok + 1) == ':')
+       else if (*tok == REG56_Y && *(tok + 1) == ':')
        {
                tok = tok + 2;
 
@@ -437,11 +438,20 @@ static inline int dsp_parmode(int *am, int *areg, TOKEN * AnEXPR, uint64_t * AnE
                        {
                                if (*AnEXVAL > 0x3F)
                                {
-                                       warn("short addressing mode forced but address is bigger than $3F - switching to long");
-                                       *am = M_DSPEA;
-                                       *memspace = 1 << 6;     // Mark we're on Y memory space
-                                       *areg = DSP_EA_ABS;
-                                       return OK;
+                                       if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+                                       {
+                                               if (optim_warn_flag)
+                                                       warn("o11: short addressing mode forced but address is bigger than $3F - switching to long");
+
+                                               *am = M_DSPEA;
+                                               *memspace = 1 << 6;     // Mark we're on Y memory space
+                                               *areg = DSP_EA_ABS;
+                                               return OK;
+                                       }
+                                       else
+                                       {
+                                               return error("short addressing mode forced but address is bigger than $3F - turn opt switch o11 on to bypass");
+                                       }
                                }
                        }
                        else
@@ -521,44 +531,44 @@ static inline int dsp_parmode(int *am, int *areg, TOKEN * AnEXPR, uint64_t * AnE
                        return ERROR;
                // TODO: add absolute address checks
        }
-       else if ((*tok >= KW_X) && (*tok <= KW_Y))
+       else if ((*tok >= REG56_X) && (*tok <= REG56_Y))
        {
                *am = M_INP48;
                *areg = *tok++;
                return OK;
        }
-       else if ((*tok >= KW_M0) && (*tok <= KW_M7))
+       else if ((*tok >= REG56_M0) && (*tok <= REG56_M7))
        {
                *am = M_DSPM;
                *areg = (*tok++) & 7;
                return OK;
        }
-       else if ((*tok >= KW_R0) && (*tok <= KW_R7))
+       else if ((*tok >= REG56_R0) && (*tok <= REG56_R7))
        {
                *am = M_DSPR;
-               *areg = (*tok++) - KW_R0;
+               *areg = (*tok++) - REG56_R0;
                return OK;
        }
-       else if ((*tok >= KW_N0) && (*tok <= KW_N7))
+       else if ((*tok >= REG56_N0) && (*tok <= REG56_N7))
        {
                *am = M_DSPN;
                *areg = (*tok++) & 7;
                return OK;
        }
-       else if ((*tok == KW_A0) || (*tok == KW_A1) || (*tok == KW_B0)
-               || (*tok == KW_B1))
+       else if ((*tok == REG56_A0) || (*tok == REG56_A1) || (*tok == REG56_B0)
+               || (*tok == REG56_B1))
        {
                *am = M_ACC24;
                *areg = *tok++;
                return OK;
        }
-       else if ((*tok == KW_A2) || (*tok == KW_B2))
+       else if ((*tok == REG56_A2) || (*tok == REG56_B2))
        {
                *am = M_ACC8;
                *areg = *tok++;
                return OK;
        }
-       else if ((*tok == '-') && (*(tok + 1) == KW_X0 || *(tok + 1) == KW_X1 || *(tok + 1) == KW_Y0 || *(tok + 1) == KW_Y1))
+       else if ((*tok == '-') && (*(tok + 1) == REG56_X0 || *(tok + 1) == REG56_X1 || *(tok + 1) == REG56_Y0 || *(tok + 1) == REG56_Y1))
        {
                // '-X0', '-Y0', '-X1' or '-Y1', used in multiplications
                tok++;
@@ -572,7 +582,7 @@ static inline int dsp_parmode(int *am, int *areg, TOKEN * AnEXPR, uint64_t * AnE
                dsp_k = 1 << 2;
                return OK;
        }
-       else if (*tok == '+' && (*(tok + 1) == KW_X0 || *(tok + 1) == KW_X1 || *(tok + 1) == KW_Y0 || *(tok + 1) == KW_Y1))
+       else if (*tok == '+' && (*(tok + 1) == REG56_X0 || *(tok + 1) == REG56_X1 || *(tok + 1) == REG56_Y0 || *(tok + 1) == REG56_Y1))
        {
                // '+X0', '+Y0', '+X1' or '+Y1', used in multiplications
                tok++;
@@ -611,7 +621,7 @@ static inline int dsp_parmode(int *am, int *areg, TOKEN * AnEXPR, uint64_t * AnE
                // TODO: add absolute address checks
                return error("internal assembler error: parmode checking for '(' and '-' does not have absolute address checks yet!");
        }
-       else if (*tok == KW_P && *(tok + 1) == ':')
+       else if (*tok == REG56_P && *(tok + 1) == ':')
        {
                tok = tok + 2;
 
@@ -731,7 +741,7 @@ static inline int dsp_parmode(int *am, int *areg, TOKEN * AnEXPR, uint64_t * AnE
                *areg = DSP_EA_ABS;
                return OK;
        }
-       else if (*tok == KW_PC || *tok == KW_CCR || *tok == KW_SR || *tok == KW_SP || (*tok >= KW_MR&&*tok <= KW_SS))
+       else if (*tok == REG56_PC || *tok == REG56_CCR || *tok == REG56_SR || *tok == REG56_SP || (*tok >= REG56_MR&&*tok <= REG56_SS))
        {
                *areg = *tok++;
                *am = M_DSPPCU;
@@ -876,12 +886,12 @@ int dsp_amode(int maxea)
 //
 static inline int SDreg(int reg)
 {
-       if (reg >= KW_X0 && reg <= KW_N7)
+       if (reg >= REG56_X0 && reg <= REG56_N7)
                return reg & 0xFF;
-       else if (reg >= KW_A0&&reg <= KW_A2)
+       else if (reg >= REG56_A0&&reg <= REG56_A2)
                return (8 >> (reg & 7)) | 8;
-       else //if (reg>=KW_R0&&reg<=KW_R7)
-               return reg - KW_R0 + 16;
+       else //if (reg>=REG56_R0&&reg<=REG56_R7)
+               return reg - REG56_R0 + 16;
        // Handy map for the above:
        // (values are of course taken from keytab)
        // Register | Value | Return value
@@ -944,10 +954,10 @@ static inline LONG check_x_y(LONG ea1, LONG S1)
                        // Check for D1
                        switch (K_D1 = *tok++)
                        {
-                       case KW_X0: D1 = 0 << 10; break;
-                       case KW_X1: D1 = 1 << 10; break;
-                       case KW_A:  D1 = 2 << 10; break;
-                       case KW_B:  D1 = 3 << 10; break;
+                       case REG56_X0: D1 = 0 << 10; break;
+                       case REG56_X1: D1 = 1 << 10; break;
+                       case REG56_A:  D1 = 2 << 10; break;
+                       case REG56_B:  D1 = 3 << 10; break;
                        default:    return error("unrecognised X:Y: parallel move syntax: expected x0, x1, a or b after 'X:eax,'");
                        }
                }
@@ -966,7 +976,7 @@ static inline LONG check_x_y(LONG ea1, LONG S1)
                        }
                }
 
-               if (*tok == KW_Y)
+               if (*tok == REG56_Y)
                {
                        tok++;
                        // 'X:eax,D1 Y:eay,D2' 'S1,X:eax Y:eay,D2'
@@ -975,9 +985,9 @@ static inline LONG check_x_y(LONG ea1, LONG S1)
 
                        if (*tok++ == '(')
                        {
-                               if (*tok >= KW_R0 && *tok <= KW_R7)
+                               if (*tok >= REG56_R0 && *tok <= REG56_R7)
                                {
-                                       ea2 = (*tok++ - KW_R0);
+                                       ea2 = (*tok++ - REG56_R0);
 
                                        if (((ea1 & 7) < 4 && ea2 < 4) || ((ea1 & 7) >= 4 && ea2 > 4))
                                                return error("unrecognised X:Y: parallel move syntax: eax and eay register banks must be different in 'X:ea,D1/S1,X:ea Y:eay,D2'");
@@ -1002,7 +1012,7 @@ static inline LONG check_x_y(LONG ea1, LONG S1)
                                                ea2 = 3 << 12;
                                                tok++;
                                        }
-                                       else if (*tok >= KW_N0 && *tok <= KW_N7)
+                                       else if (*tok >= REG56_N0 && *tok <= REG56_N7)
                                        {
                                                // (Rn)+Nn
                                                if ((*tok++ & 7) != ea2)
@@ -1038,10 +1048,10 @@ static inline LONG check_x_y(LONG ea1, LONG S1)
 
                                switch (K_D2 = *tok++)
                                {
-                               case KW_Y0: D2 = 0 << 8; break;
-                               case KW_Y1: D2 = 1 << 8; break;
-                               case KW_A:  D2 = 2 << 8; break;
-                               case KW_B:  D2 = 3 << 8; break;
+                               case REG56_Y0: D2 = 0 << 8; break;
+                               case REG56_Y1: D2 = 1 << 8; break;
+                               case REG56_A:  D2 = 2 << 8; break;
+                               case REG56_B:  D2 = 3 << 8; break;
                                default:    return error("unrecognised X:Y: parallel move syntax: expected y0, y1, a or b after 'X:ea,D1/S1,X:ea Y:eay,'");
                                }
 
@@ -1052,29 +1062,29 @@ static inline LONG check_x_y(LONG ea1, LONG S1)
                                        if (K_D1 == K_D2)
                                                return error("unrecognised X:Y: parallel move syntax: D1 and D2 cannot be the same in 'X:ea,D1 Y:eay,D2'");
 
-                               inst = B16(11000000, 00000000) | w;
+                               inst = 0b1100000000000000 | w;
                                inst |= ea1 | D1 | ea2 | D2;
                                return inst;
                        }
                        else
                                return error("unrecognised X:Y: parallel move syntax: expected '(Rn)', '(Rn)+', '(Rn)-', '(Rn)+Nn' after 'X:ea,D1/S1,X:ea Y:'");
                }
-               else if (*tok == KW_Y0 || *tok == KW_Y1 || *tok == KW_A || *tok == KW_B)
+               else if (*tok == REG56_Y0 || *tok == REG56_Y1 || *tok == REG56_A || *tok == REG56_B)
                {
                        // 'X:eax,D1 S2,Y:eay' 'S1,X:eax1 S2,Y:eay'
                        switch (*tok++)
                        {
-                       case KW_Y0: S2 = 0 << 8; break;
-                       case KW_Y1: S2 = 1 << 8; break;
-                       case KW_A:  S2 = 2 << 8; break;
-                       case KW_B:  S2 = 3 << 8; break;
+                       case REG56_Y0: S2 = 0 << 8; break;
+                       case REG56_Y1: S2 = 1 << 8; break;
+                       case REG56_A:  S2 = 2 << 8; break;
+                       case REG56_B:  S2 = 3 << 8; break;
                        default: return error("unrecognised X:Y: parallel move syntax: expected y0, y1, a or b after 'X:ea,D1/S1,X:ea Y:eay,'");
                        }
 
                        if (*tok++ != ',')
                                return error("unrecognised X:Y: parallel move syntax: expected ',' after 'X:ea,D1/S1,X:ea S2'");
 
-                       if (*tok++ == KW_Y)
+                       if (*tok++ == REG56_Y)
                        {
                                // 'X:eax,D1 Y:eay,D2' 'S1,X:eax Y:eay,D2'
                                if (*tok++ != ':')
@@ -1082,9 +1092,9 @@ static inline LONG check_x_y(LONG ea1, LONG S1)
 
                                if (*tok++ == '(')
                                {
-                                       if (*tok >= KW_R0 && *tok <= KW_R7)
+                                       if (*tok >= REG56_R0 && *tok <= REG56_R7)
                                        {
-                                               ea2 = (*tok++ - KW_R0);
+                                               ea2 = (*tok++ - REG56_R0);
 
                                                if (((ea1 & 7) < 4 && ea2 < 4) || ((ea1 & 7) >= 4 && ea2 > 4))
                                                        return error("unrecognised X:Y: parallel move syntax: eax and eay register banks must be different in 'X:ea,D1/S1,X:ea S2,Y:eay'");
@@ -1105,7 +1115,7 @@ static inline LONG check_x_y(LONG ea1, LONG S1)
                                                if (*tok == EOL)
                                                        // (Rn)+
                                                        ea2 = 3 << 12;
-                                               else if (*tok >= KW_N0 && *tok <= KW_N7)
+                                               else if (*tok >= REG56_N0 && *tok <= REG56_N7)
                                                {
                                                        // (Rn)+Nn
                                                        if ((*tok++ & 7) != ea2)
@@ -1138,7 +1148,7 @@ static inline LONG check_x_y(LONG ea1, LONG S1)
 
                                        ea2 |= eay_temp; //OR eay back from temp
 
-                                       inst = B16(10000000, 00000000) | w;
+                                       inst = 0b1000000000000000 | w;
                                        inst |= (ea1 & 0x1f) | D1 | S2 | ea2;
                                        return inst;
                                }
@@ -1188,7 +1198,7 @@ static inline LONG parse_x(const int W, LONG inst, const LONG S1, const int chec
                                {
 x_checkea_right:
                                        // 'S1,X:ea S2,D2', 'A,X:ea X0,A', 'B,X:ea X0,B', 'S1,X:eax Y:eay,D2', 'S1,X:eax S2,Y:eay'
-                                       if (*tok == KW_X0 && tok[1] == ',' && tok[2] == KW_A)
+                                       if (*tok == REG56_X0 && tok[1] == ',' && tok[2] == REG56_A)
                                        {
                                                // 'A,X:ea X0,A'
                                                if (ea1 == DSP_EA_ABS)
@@ -1200,13 +1210,13 @@ x_checkea_right:
                                                if (ea1 == -1)
                                                        return error("unrecognised X:R parallel move syntax: absolute address not allowed in 'a,X:ea x0,a'");
 
-                                               if (ea1 == B8(00110100))
+                                               if (ea1 == 0b00110100)
                                                        return error("unrecognised X:R parallel move syntax: immediate data not allowed in 'a,X:ea x0,a'");
 
-                                               inst = B16(00001000, 00000000) | ea1 | (0 << 8);
+                                               inst = 0b0000100000000000 | ea1 | (0 << 8);
                                                return inst;
                                        }
-                                       else if (*tok == KW_X0 && tok[1] == ',' && tok[2] == KW_B)
+                                       else if (*tok == REG56_X0 && tok[1] == ',' && tok[2] == REG56_B)
                                        {
                                                // 'B,X:ea X0,B'
                                                if (ea1 == DSP_EA_ABS)
@@ -1218,13 +1228,13 @@ x_checkea_right:
                                                if (ea1 == -1)
                                                        return error("unrecognised X:R parallel move syntax: absolute address not allowed in 'b,X:ea x0,b'");
 
-                                               if (ea1 == B8(00110100))
+                                               if (ea1 == 0b00110100)
                                                        return error("unrecognised X:R parallel move syntax: immediate data not allowed in 'b,X:ea x0,b'");
 
-                                               inst = B16(00001001, 00000000) | ea1 | (1 << 8);
+                                               inst = 0b0000100100000000 | ea1 | (1 << 8);
                                                return inst;
                                        }
-                                       else if (*tok == KW_A || *tok == KW_B)
+                                       else if (*tok == REG56_A || *tok == REG56_B)
                                        {
                                                // 'S1,X:ea S2,D2', 'S1,X:eax S2,Y:eay'
                                                switch (S1)
@@ -1236,7 +1246,7 @@ x_checkea_right:
                                                default: return error("unrecognised X:R parallel move syntax: S1 can only be x0, x1, a or b in 'S1,X:ea S2,D2'");
                                                }
 
-                                               if (tok[1] == ',' && tok[2] == KW_Y)
+                                               if (tok[1] == ',' && tok[2] == REG56_Y)
                                                {
                                                        // 'S1,X:eax S2,Y:eay'
                                                        return check_x_y(ea1, S1);
@@ -1248,17 +1258,17 @@ x_checkea_right:
 
                                                switch (*tok++)
                                                {
-                                               case KW_A: S2 = 0 << 9; break;
-                                               case KW_B: S2 = 1 << 9; break;
+                                               case REG56_A: S2 = 0 << 9; break;
+                                               case REG56_B: S2 = 1 << 9; break;
                                                default:   return error("unrecognised X:R parallel move syntax: expected a or b after 'S1,X:eax'");
                                                }
 
                                                if (*tok++ != ',')
                                                        return error("unrecognised X:R parallel move syntax: expected ',' after 'S1,X:eax S2'");
 
-                                               if (*tok == KW_Y0 || *tok == KW_Y1)
+                                               if (*tok == REG56_Y0 || *tok == REG56_Y1)
                                                {
-                                                       if (*tok++ == KW_Y0)
+                                                       if (*tok++ == REG56_Y0)
                                                                D2 = 0 << 8;
                                                        else
                                                                D2 = 1 << 8;
@@ -1266,19 +1276,19 @@ x_checkea_right:
                                                        if (*tok != EOL)
                                                                return error("unrecognised X:R parallel move syntax: unexpected text after 'X:eax,D1 S2,S2'");
 
-                                                       inst = B16(00010000, 00000000) | (0 << 7);
+                                                       inst = 0b0001000000000000 | (0 << 7);
                                                        inst |= ea1 | D1 | S2 | D2;
                                                        return inst;
                                                }
                                                else
                                                        return error("unrecognised X:R parallel move syntax: expected y0 or y1 after 'X:eax,D1 S2,'");
                                        }
-                                       else if (*tok == KW_Y)
+                                       else if (*tok == REG56_Y)
                                        {
                                                // 'S1,X:eax Y:eay,D2'
                                                return check_x_y(ea1, S1);
                                        }
-                                       else if (*tok == KW_Y0 || *tok == KW_Y1)
+                                       else if (*tok == REG56_Y0 || *tok == REG56_Y1)
                                        {
                                                // 'S1,X:eax S2,Y:eay'
                                                return check_x_y(ea1, S1);
@@ -1307,7 +1317,7 @@ x_check_immed:
                                                                // It might be X:aa but we're not 100% sure yet.
                                                                // If it is, the only possible syntax here is 'X:aa,D'.
                                                                // So check ahead to see if EOL follows D, then we're good to go.
-                                                               if (*tok == ',' && ((*(tok + 1) >= KW_X0 && *(tok + 1) <= KW_N7) || (*(tok + 1) >= KW_R0 && *(tok + 1) <= KW_R7) || (*(tok + 1) >= KW_A0 && *(tok + 1) <= KW_A2)) && *(tok + 2) == EOL)
+                                                               if (*tok == ',' && ((*(tok + 1) >= REG56_X0 && *(tok + 1) <= REG56_N7) || (*(tok + 1) >= REG56_R0 && *(tok + 1) <= REG56_R7) || (*(tok + 1) >= REG56_A0 && *(tok + 1) <= REG56_A2)) && *(tok + 2) == EOL)
                                                                {
                                                                        // Yup, we're good to go - 'X:aa,D' it is
                                                                        tok++;
@@ -1346,14 +1356,14 @@ x_check_immed:
                                                if (*tok++ != ',')
                                                        return error("unrecognised X: parallel move syntax: expected ',' after 'X:ea'");
 
-                                               if ((*tok >= KW_X0 && *tok <= KW_N7) || (*tok >= KW_R0 && *tok <= KW_R7) || (*tok >= KW_A0 && *tok <= KW_A2))
+                                               if ((*tok >= REG56_X0 && *tok <= REG56_N7) || (*tok >= REG56_R0 && *tok <= REG56_R7) || (*tok >= REG56_A0 && *tok <= REG56_A2))
                                                {
                                                        D1 = SDreg(*tok++);
 
                                                        if (*tok == EOL)
                                                        {
                                                                // 'X:ea,D'
-                                                               inst = inst | B8(01000000) | (1 << 7);
+                                                               inst = inst | 0b01000000 | (1 << 7);
                                                                inst |= ((D1 & 0x18) << (12 - 3)) + ((D1 & 7) << 8);
                                                                inst |= ea1;
 
@@ -1365,21 +1375,21 @@ x_check_immed:
                                                        else
                                                        {
                                                                // 'X:ea,D1 S2,D2'
-                                                               if (*tok == KW_A || *tok == KW_B)
+                                                               if (*tok == REG56_A || *tok == REG56_B)
                                                                {
                                                                        S2 = SDreg(*tok++);
 
                                                                        if (*tok++ != ',')
                                                                                return error("unrecognised X:R parallel move syntax: expected comma after X:ea,D1 S2");
 
-                                                                       if (*tok == KW_Y0 || *tok == KW_Y1)
+                                                                       if (*tok == REG56_Y0 || *tok == REG56_Y1)
                                                                        {
                                                                                D2 = SDreg(*tok++);
 
                                                                                if (*tok != EOL)
                                                                                        return error("unrecognised X:R parallel move syntax: expected EOL after X:ea,D1 S2,D2");
 
-                                                                               inst = B16(00010000, 00000000) | (1 << 7);
+                                                                               inst = 0b0001000000000000 | (1 << 7);
                                                                                inst |= ((D1 & 0x8) << (12 - 4)) + ((D1 & 1) << 10);
                                                                                inst |= (S2 & 1) << 9;
                                                                                inst |= (D2 & 1) << 8;
@@ -1401,7 +1411,7 @@ x_check_immed:
                                                if (*tok == EOL)
                                                {
                                                        // 'S,X:ea'
-                                                       inst = inst | B8(01000000) | (0 << 7);
+                                                       inst = inst | 0b01000000 | (0 << 7);
                                                        inst |= ((S1 & 0x18) << (12 - 3)) + ((S1 & 7) << 8);
                                                        inst |= ea1;
 
@@ -1470,12 +1480,12 @@ x_gotea1:
                        // It might be 'X:(Rn..)..,D' but we're not 100% sure yet.
                        // If it is, the only possible syntax here is 'X:ea,D'.
                        // So check ahead to see if EOL follows D, then we're good to go.
-                       if (((*tok >= KW_X0 && *tok <= KW_N7) || (*tok >= KW_R0 && *tok <= KW_R7) || (*tok >= KW_A0 && *tok <= KW_A2)) && *(tok + 1) == EOL)
+                       if (((*tok >= REG56_X0 && *tok <= REG56_N7) || (*tok >= REG56_R0 && *tok <= REG56_R7) || (*tok >= REG56_A0 && *tok <= REG56_A2)) && *(tok + 1) == EOL)
                        {
                                //'X:ea,D'
                                D1 = SDreg(*tok++);
 
-                               inst = inst | B8(01000000) | (1 << 7);
+                               inst = inst | 0b01000000 | (1 << 7);
                                inst |= ea1;
                                inst |= ((D1 & 0x18) << (12 - 3)) + ((D1 & 7) << 8);
                                return inst;
@@ -1486,7 +1496,7 @@ x_gotea1:
                        if (*tok == EOL)
                        {
                                //'S,X:ea'
-                               inst = inst | B8(01000000) | (0 << 7);
+                               inst = inst | 0b01000000 | (0 << 7);
                                inst |= ea1;
                                inst |= ((S1 & 0x18) << (12 - 3)) + ((S1 & 7) << 8);
                                return inst;
@@ -1499,32 +1509,32 @@ x_gotea1:
 
                // 'X:eax,D1 Y:eay,D2', 'X:eax,D1 S2,Y:eay' or 'X:ea,D1 S2,D2'
                // Check ahead for S2,D2 - if that's true then we have 'X:ea,D1 S2,D2'
-               if ((*tok == KW_X0 || *tok == KW_X1 || *tok == KW_A || *tok == KW_B) && (*(tok + 1) == KW_A || *(tok + 1) == KW_B) && (*(tok + 2) == ',') && (*(tok + 3) == KW_Y0 || (*(tok + 3) == KW_Y1)))
+               if ((*tok == REG56_X0 || *tok == REG56_X1 || *tok == REG56_A || *tok == REG56_B) && (*(tok + 1) == REG56_A || *(tok + 1) == REG56_B) && (*(tok + 2) == ',') && (*(tok + 3) == REG56_Y0 || (*(tok + 3) == REG56_Y1)))
                {
                        // 'X:ea,D1 S2,D2'
                        // Check if D1 is x0, x1, a or b
                        switch (*tok++)
                        {
-                       case KW_X0: D1 = 0 << 10; break;
-                       case KW_X1: D1 = 1 << 10; break;
-                       case KW_A:  D1 = 2 << 10; break;
-                       case KW_B:  D1 = 3 << 10; break;
+                       case REG56_X0: D1 = 0 << 10; break;
+                       case REG56_X1: D1 = 1 << 10; break;
+                       case REG56_A:  D1 = 2 << 10; break;
+                       case REG56_B:  D1 = 3 << 10; break;
                        default:    return error("unrecognised X:R parallel move syntax: expected x0, x1, a or b after 'X:eax,'");
                        }
 
                        switch (*tok++)
                        {
-                       case KW_A: S2 = 0 << 9; break;
-                       case KW_B: S2 = 1 << 9; break;
+                       case REG56_A: S2 = 0 << 9; break;
+                       case REG56_B: S2 = 1 << 9; break;
                        default:   return error("unrecognised X:R parallel move syntax: expected a or b after 'X:eax,D1 '");
                        }
 
                        if (*tok++ != ',')
                                return error("unrecognised X:R parallel move syntax: expected ',' after 'X:eax,D1 S2'");
 
-                       if (*tok == KW_Y0 || *tok == KW_Y1)
+                       if (*tok == REG56_Y0 || *tok == REG56_Y1)
                        {
-                               if (*tok++ == KW_Y0)
+                               if (*tok++ == REG56_Y0)
                                        D2 = 0 << 8;
                                else
                                        D2 = 1 << 8;
@@ -1532,7 +1542,7 @@ x_gotea1:
                                if (*tok != EOL)
                                        return error("unrecognised X:R parallel move syntax: unexpected text after 'X:eax,D1 S2,S2'");
 
-                               inst = B16(00010000, 00000000) | (W << 7);
+                               inst = 0b0001000000000000 | (W << 7);
                                inst |= ea1 | D1 | S2 | D2;
                                return inst;
                        }
@@ -1585,9 +1595,8 @@ x_gotea1:
                if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
                        return ERROR;
 
-               if (dspImmedEXATTR & DEFINED)
-                       if (dspImmedEXVAL > 0xffffff)
-                               return error("long address is bigger than $ffffff");
+               if ((dspImmedEXATTR & DEFINED) && (dspImmedEXVAL > 0xFFFFFF))
+                       return error("long address is bigger than $FFFFFF");
 
                deposit_extra_ea = DEPOSIT_EXTRA_WORD;
 
@@ -1609,10 +1618,19 @@ x_gotea1:
                {
                        if (dspImmedEXVAL > 0x3F)
                        {
-                               warn("short addressing mode forced but address is bigger than $3F - switching to long");
-                               force_imm = NUM_FORCE_LONG;
-                               deposit_extra_ea = DEPOSIT_EXTRA_WORD;
-                               ea1 = DSP_EA_ABS;
+                               if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+                               {
+                                       if (optim_warn_flag)
+                                               warn("o11: short addressing mode forced but address is bigger than $3F - switching to long");
+
+                                       force_imm = NUM_FORCE_LONG;
+                                       deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+                                       ea1 = DSP_EA_ABS;
+                               }
+                               else
+                               {
+                                       return error("short addressing mode forced but address is bigger than $3F - turn opt switch o11 on to bypass");
+                               }
                        }
                }
                else
@@ -1673,12 +1691,13 @@ static inline LONG parse_y(LONG inst, LONG S1, LONG D1, LONG S2)
                                                if (*tok == EOL && S1 != 0)
                                                {
                                                        // 'S,Y:aa'
-                                                       inst = B16(01001000, 00000000);
+                                                       inst = 0b0100100000000000;
                                                        inst |= dspImmedEXVAL;
                                                        inst |= ((S1 & 0x18) << (12 - 3)) + ((S1 & 7) << 8);
                                                        return inst;
                                                }
-                                               if (*tok == ',' && ((*(tok + 1) >= KW_X0 && *(tok + 1) <= KW_N7) || (*(tok + 1) >= KW_R0 && *(tok + 1) <= KW_R7) || (*(tok + 1) >= KW_A0 && *(tok + 1) <= KW_A2)) && *(tok + 2) == EOL)
+
+                                               if (*tok == ',' && ((*(tok + 1) >= REG56_X0 && *(tok + 1) <= REG56_N7) || (*(tok + 1) >= REG56_R0 && *(tok + 1) <= REG56_R7) || (*(tok + 1) >= REG56_A0 && *(tok + 1) <= REG56_A2)) && *(tok + 2) == EOL)
                                                {
                                                        // Yup, we're good to go - 'Y:aa,D' it is
                                                        tok++;
@@ -1693,24 +1712,28 @@ static inline LONG parse_y(LONG inst, LONG S1, LONG D1, LONG S2)
                                if (*tok == EOL && S1 != 0)
                                {
                                        // 'S,Y:ea'
-                                       inst = B16(01001000, 01110000);
+                                       inst = 0b0100100001110000;
                                        inst |= ea1;
                                        inst |= ((S1 & 0x18) << (12 - 3)) + ((S1 & 7) << 8);
                                        if (ea1 == DSP_EA_ABS)
                                                deposit_extra_ea = DEPOSIT_EXTRA_WORD;
                                        return inst;
                                }
+
                                if (*tok++ != ',')
                                        return error("unrecognised Y: parallel move syntax: expected ',' after 'Y:ea'");
+
                                if (D1 == 0 && S1 == 0)
                                {
                                        // 'Y:ea,D'
-                                       if ((*tok >= KW_X0 && *tok <= KW_N7) || (*tok >= KW_R0 && *tok <= KW_R7) || (*tok >= KW_A0 && *tok <= KW_A2))
+                                       if ((*tok >= REG56_X0 && *tok <= REG56_N7) || (*tok >= REG56_R0 && *tok <= REG56_R7) || (*tok >= REG56_A0 && *tok <= REG56_A2))
                                        {
                                                D1 = SDreg(*tok++);
+
                                                if (*tok != EOL)
                                                        return error("unrecognised Y: parallel move syntax: expected EOL after 'Y:ea,D'");
-                                               inst |= B16(00000000, 01110000);
+
+                                               inst |= 0b0000000001110000;
                                                inst |= ea1;
                                                inst |= ((D1 & 0x18) << (12 - 3)) + ((D1 & 7) << 8);
                                                if (ea1 == DSP_EA_ABS)
@@ -1723,7 +1746,7 @@ static inline LONG parse_y(LONG inst, LONG S1, LONG D1, LONG S2)
                                else
                                {
                                        // 'S1,D1 Y:ea,D2'
-                                       if (*tok == KW_A || *tok == KW_B || *tok == KW_Y0 || *tok == KW_Y1)
+                                       if (*tok == REG56_A || *tok == REG56_B || *tok == REG56_Y0 || *tok == REG56_Y1)
                                        {
                                                D2 = SDreg(*tok++);
                                                inst |= ea1;
@@ -1741,696 +1764,762 @@ static inline LONG parse_y(LONG inst, LONG S1, LONG D1, LONG S2)
                        else
                                return ERROR;
                }
-        else
-        {
-            // It's not an immediate, check for '-(Rn)'
-            ea1 = checkea(',', Y_ERRORS);
-
-            if (ea1 == ERROR)
-                return ERROR;
+               else
+               {
+                       // It's not an immediate, check for '-(Rn)'
+                       ea1 = checkea(',', Y_ERRORS);
 
-            goto y_gotea1;
+                       if (ea1 == ERROR)
+                               return ERROR;
 
-        }
-    }
-    else if (*tok == '#')
-    {
-        tok++;
-        if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-            return ERROR;
-        // Okay so we have immediate data - mark it down
-        ea1 = DSP_EA_IMM;
-        // Now, proceed to the main code for this branch
-        goto y_gotea1;
-    }
-    else if (*tok == '(')
-    {
-        // Maybe we got an expression here, check for it
-        if (tok[1] == CONST || tok[1] == FCONST || tok[1] == SUNARY || tok[1] == SYMBOL || tok[1] == STRING)
-        {
-            // Evaluate the expression and go to immediate code path
-            expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM);
-            goto y_check_immed;
-        }
+                       goto y_gotea1;
 
-        // Nope, let's check for ea then
-        if (S1 == 0 || (S1 != 0 && D1 != 0))
-            ea1 = checkea(',', Y_ERRORS);
-        else
-            ea1 = checkea(EOL, Y_ERRORS);
+               }
+       }
+       else if (*tok == '#')
+       {
+               tok++;
 
-        if (ea1 == ERROR)
-            return ERROR;
+               if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                       return ERROR;
 
-    y_gotea1:
-        if (S1 != 0 && *tok == EOL)
-        {
-            // 'S,Y:ea'
-            inst = B16(01001000, 01000000);
-            inst |= ea1;
-            inst |= ((S1 & 0x18) << (12 - 3)) + ((S1 & 7) << 8);
-            return inst;
-        }
-        else if (S1 != 0 && D1 != 0 && S2 == 0)
-        {
-            // 'S1,D1 Y:ea,D2'
-            switch (S1)
-            {
-            case 14: S1 = 0 << 11; break; // A
-            case 15: S1 = 1 << 11; break; // B
-            default: return error("unrecognised R:Y parallel move syntax: S1 can only be A or B in 'S1,D1 Y:ea,D2'"); break;
-            }
-            switch (D1)
-            {
-            case 4: D1 = 0 << 10; break; // X0
-            case 5: D1 = 1 << 10; break; // X1
-            default: return error("unrecognised R:Y parallel move syntax: D1 can only be x0 or x1 in 'S1,D1 Y:ea,D2'");break;
-            }
-            if (*tok++ != ',')
-                return error("unrecognised R:Y parallel move syntax: expected ',' after 'S1,D1 Y:ea'");
-            switch (*tok++)
-            {
-            case KW_Y0: D2 = 0 << 8; break;
-            case KW_Y1: D2 = 1 << 8; break;
-            case KW_A:  D2 = 2 << 8; break;
-            case KW_B:  D2 = 3 << 8; break;
-            default: return error("unrecognised R:Y parallel move syntax: D2 can only be y0, y1, a or b after 'S1,D1 Y:ea'");
-            }
-            inst = B16(00010000, 11000000);
-            inst |= S1 | D1 | D2;
-            inst |= ea1;
-            return inst;
-        }
-        if (*tok++ != ',')
-            return error("Comma expected after 'Y:(Rn)')");
-        // It might be 'Y:(Rn..)..,D' but we're not 100% sure yet.
-        // If it is, the only possible syntax here is 'Y:ea,D'.
-        // So check ahead to see if EOL follows D, then we're good to go.
-        if (((*tok >= KW_X0 && *tok <= KW_N7) || (*tok >= KW_R0 && *tok <= KW_R7) || (*tok >= KW_A0 && *tok <= KW_A2)) && *(tok + 1) == EOL)
-        {
-            //'Y:ea,D'
-            D1 = SDreg(*tok++);
-            inst |= B16(00000000, 01000000);
-            inst |= ea1;
-            inst |= ((D1 & 0x18) << (12 - 3)) + ((D1 & 7) << 8);
-            return inst;
-        }
-    }
-    else if (*tok == CONST || *tok == FCONST || *tok == SYMBOL)
-    {
-        // Check for immediate address
-        if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-            return ERROR;
-
-        // Yes, we have an expression, so we now check for
-        // 'Y:ea,D' or 'Y:aa,D'
-        ea1 = DSP_EA_ABS; // Reluctant - but it's probably correct
-        if (!(dspImmedEXATTR&DEFINED))
-        {
-            force_imm = NUM_FORCE_LONG;
-            deposit_extra_ea = DEPOSIT_EXTRA_WORD;
-        }
+               // Okay so we have immediate data - mark it down
+               ea1 = DSP_EA_IMM;
+               // Now, proceed to the main code for this branch
+               goto y_gotea1;
+       }
+       else if (*tok == '(')
+       {
+               // Maybe we got an expression here, check for it
+               if (tok[1] == CONST || tok[1] == FCONST || tok[1] == SUNARY || tok[1] == SYMBOL || tok[1] == STRING)
+               {
+                       // Evaluate the expression and go to immediate code path
+                       expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM);
+                       goto y_check_immed;
+               }
 
-        goto y_check_immed;
-    }
-    else if (*tok == '>')
-    {
-        // Check for immediate address forced long
-        tok++;
-        if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-            return ERROR;
-        if (dspImmedEXATTR & DEFINED)
-            if (dspImmedEXVAL > 0xffffff)
-                return error("long address is bigger than $ffffff");
-
-        deposit_extra_ea = DEPOSIT_EXTRA_WORD;
-
-        force_imm = NUM_FORCE_LONG;
-        ea1 = DSP_EA_ABS;
-        goto y_check_immed;
-    }
-    else if (*tok == '<')
-    {
-        tok++;
-        if (S1 != 0 && D1 != 0)
-        {
-            // We're in 'S1,D1 Y:ea,D2' or 'S1,D1 S1,Y:ea'
-            // there's no Y:aa mode here, so we'll force long
-            warn("forced short addressing in R:Y mode is not allowed - switching to long");
+               // Nope, let's check for ea then
+               if (S1 == 0 || (S1 != 0 && D1 != 0))
+                       ea1 = checkea(',', Y_ERRORS);
+               else
+                       ea1 = checkea(EOL, Y_ERRORS);
 
-            if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-                return ERROR;
+               if (ea1 == ERROR)
+                       return ERROR;
 
-            ea1 = DSP_EA_ABS;
+       y_gotea1:
+               if (S1 != 0 && *tok == EOL)
+               {
+                       // 'S,Y:ea'
+                       inst = 0b0100100001000000;
+                       inst |= ea1;
+                       inst |= ((S1 & 0x18) << (12 - 3)) + ((S1 & 7) << 8);
+                       return inst;
+               }
+               else if (S1 != 0 && D1 != 0 && S2 == 0)
+               {
+                       // 'S1,D1 Y:ea,D2'
+                       switch (S1)
+                       {
+                       case 14: S1 = 0 << 11; break; // A
+                       case 15: S1 = 1 << 11; break; // B
+                       default: return error("unrecognised R:Y parallel move syntax: S1 can only be A or B in 'S1,D1 Y:ea,D2'"); break;
+                       }
 
-            force_imm = NUM_FORCE_LONG;
-            deposit_extra_ea = DEPOSIT_EXTRA_WORD;
-            goto y_check_immed;
-        }
-        else
-        {
-            // Check for immediate address forced short
-            ea1 = DSP_EA_ABS; // Reluctant - but it's probably correct
-
-            if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-                return ERROR;
-            force_imm = NUM_FORCE_SHORT;
-            if (dspImmedEXATTR & DEFINED)
-            {
-                if (dspImmedEXVAL > 0xfff)
-                {
-                    warn("short addressing mode forced but address is bigger than $fff - switching to long");
-                    ea1 = DSP_EA_ABS;
-                    force_imm = NUM_FORCE_LONG;
-                    deposit_extra_ea = DEPOSIT_EXTRA_WORD;
-                }
-            }
-            else
-            {
-                // This might end up as something like 'move Y:<adr,register'
-                // so let's mark it as an extra aa fixup here.
-                // Note: we are branching to y_check_immed without a
-                // defined dspImmed so it's going to be 0. It probably
-                // doesn't harm anything.
-                deposit_extra_ea = DEPOSIT_EXTRA_FIXUP;
-            }
+                       switch (D1)
+                       {
+                       case 4: D1 = 0 << 10; break; // X0
+                       case 5: D1 = 1 << 10; break; // X1
+                       default: return error("unrecognised R:Y parallel move syntax: D1 can only be x0 or x1 in 'S1,D1 Y:ea,D2'");break;
+                       }
 
-            goto y_check_immed;
-        }
-    }
+                       if (*tok++ != ',')
+                               return error("unrecognised R:Y parallel move syntax: expected ',' after 'S1,D1 Y:ea'");
 
-    return error("unrecognised Y: parallel move syntax");
-}
+                       switch (*tok++)
+                       {
+                       case REG56_Y0: D2 = 0 << 8; break;
+                       case REG56_Y1: D2 = 1 << 8; break;
+                       case REG56_A:  D2 = 2 << 8; break;
+                       case REG56_B:  D2 = 3 << 8; break;
+                       default: return error("unrecognised R:Y parallel move syntax: D2 can only be y0, y1, a or b after 'S1,D1 Y:ea'");
+                       }
 
+                       inst = 0b0001000011000000;
+                       inst |= S1 | D1 | D2;
+                       inst |= ea1;
+                       return inst;
+               }
 
-//
-// Parse L: addressing space parallel moves
-//
-static inline LONG parse_l(const int W, LONG inst, LONG S1)
-{
-    int immreg;                                        // Immediate register destination
-    LONG D1;                                   // Source and Destinations
-    LONG ea1;                                  // ea bitfields
-    int force_imm = NUM_NORMAL;        // Holds forced immediate value (i.e. '<' or '>')
-    if (*tok == '-')
-    {
-        if (*tok == CONST || tok[1] == FCONST)
-        {
-            tok++;
-            dspImmedEXVAL = *tok++;
-            goto l_check_immed;
-        }
-        // This could be either -(Rn), -aa or -ea. Check for immediate first
-        // Maybe we got an expression here, check for it
-        if (*tok == SYMBOL || tok[1] == SYMBOL)
-        {
-            // Evaluate the expression and go to immediate code path
-            if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) == OK)
-            {
-                // Only check for aa if we have a defined number in our hands or we've
-                // been asked to use a short number format. The former case we'll just test
-                // it to see if it's small enough. The later - it's the programmer's call
-                // so he'd better have a small address or the fixups will bite him/her in the arse!
-                if (dspImmedEXATTR&DEFINED || force_imm == NUM_FORCE_SHORT)
-                {
-                    // It's an immediate, so ea is probably an absolute address
-                    // (unless it's aa if the immediate is small enough)
-                    // 'L:ea,D' or 'L:aa,D'
-                l_check_immed:
-                    // Check for aa (which is 6 bits zero extended)
-                    if (*tok == EOL)
-                    {
-                        // 'S,L:aa'
-                        if (dspImmedEXVAL < 0x40 && force_imm != NUM_FORCE_LONG)
-                        {
-                            // 'S,L:aa'
-                            if (S1 == KW_A)
-                                S1 = 4;
-                            else if (S1 == KW_B)
-                                S1 = 5;
-                            else
-                                S1 &= 7;
-
-                            inst = B16(01000000, 00000000);
-                            inst |= dspImmedEXVAL;
-                            inst |= ((S1 & 0x4) << (11 - 2)) + ((S1 & 3) << 8);
-                            return inst;
-                        }
-                        else
-                        {
-                            // 'S,L:ea'
-                            if (S1 == KW_A)
-                                S1 = 4;
-                            else if (S1 == KW_B)
-                                S1 = 5;
-                            else
-                                S1 &= 7;
-
-                            if (ea1 == DSP_EA_ABS)
-                                deposit_extra_ea = DEPOSIT_EXTRA_WORD;
-
-                            inst |= B16(01000000, 01110000);
-                            inst |= ((S1 & 0x4) << (11 - 2)) + ((S1 & 3) << 8);
-                            inst |= ea1;
-                            return inst;
-                        }
-
-                    }
-                    if (*tok++ != ',')
-                        return error("unrecognised L: parallel move syntax: expected ',' after 'L:ea/L:aa'");
-                    // Check for allowed registers for D (a0, b0, x, y, a, b, ab or ba)
-                    if (!((*tok >= KW_A10 && *(tok + 1) <= KW_BA) || (*tok >= KW_A && *tok <= KW_B)))
-                        return error("unrecognised L: parallel move syntax: expected a0, b0, x, y, a, b, ab or ba after 'L:ea/L:aa'");
-
-                    if (dspImmedEXVAL < (1 << 6) && (dspImmedEXATTR&DEFINED))
-                    {
-                        // 'L:aa,D'
-                        l_aa:
-                        immreg = *tok++;
-                        if (immreg == KW_A)
-                            immreg = 4;
-                        else if (immreg == KW_B)
-                            immreg = 5;
-                        else
-                            immreg &= 7;
-
-                        if (*tok != EOL)
-                            return error("unrecognised L: parallel move syntax: expected End-Of-Line after L:aa,D");
-
-                        inst &= B16(11111111, 10111111);
-                        inst |= dspImmedEXVAL;
-                        inst |= ((immreg & 0x4) << (11 - 2)) + ((immreg & 3) << 8);
-                        return inst;
-                    }
-                }
-
-                if (deposit_extra_ea == DEPOSIT_EXTRA_FIXUP)
-                {
-                    // Hang on, we've got a L:<aa here, let's do that instead
-                    goto l_aa;
-                }
-
-                // Well, that settles it - we do have a ea in our hands
-                // 'L:ea,D'
-                D1 = *tok++;
-                if (D1 == KW_A)
-                    D1 = 4;
-                else if (D1 == KW_B)
-                    D1 = 5;
-                else
-                    D1 &= 7;
-
-                if (*tok != EOL)
-                    return error("unrecognised L: parallel move syntax: expected End-Of-Line after L:ea,D");
-
-                inst |= B16(00000000, 00110000);
-                inst |= ((D1 & 0x4) << (11 - 2)) + ((D1 & 3) << 8);
-                return inst;
-            }
-        }
-        else
-        {
-            //It's not an immediate, check for '-(Rn)'
-            ea1 = checkea(',', L_ERRORS);
+               if (*tok++ != ',')
+            return error("Comma expected after 'Y:(Rn)')");
 
-            if (ea1 == ERROR)
-                return ERROR;
+               // It might be 'Y:(Rn..)..,D' but we're not 100% sure yet.
+               // If it is, the only possible syntax here is 'Y:ea,D'.
+               // So check ahead to see if EOL follows D, then we're good to go.
+               if (((*tok >= REG56_X0 && *tok <= REG56_N7) || (*tok >= REG56_R0 && *tok <= REG56_R7) || (*tok >= REG56_A0 && *tok <= REG56_A2)) && *(tok + 1) == EOL)
+               {
+                       //'Y:ea,D'
+                       D1 = SDreg(*tok++);
+                       inst |= 0b0000000001000000;
+                       inst |= ea1;
+                       inst |= ((D1 & 0x18) << (12 - 3)) + ((D1 & 7) << 8);
+                       return inst;
+               }
+       }
+       else if (*tok == CONST || *tok == FCONST || *tok == SYMBOL)
+       {
+               // Check for immediate address
+               if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                       return ERROR;
 
-            goto l_gotea1;
+               // Yes, we have an expression, so we now check for
+               // 'Y:ea,D' or 'Y:aa,D'
+               ea1 = DSP_EA_ABS; // Reluctant - but it's probably correct
 
-        }
-    }
-    else if (*tok == '(')
-    {
-        // Maybe we got an expression here, check for it
-        if (tok[1] == CONST || tok[1] == FCONST || tok[1] == SUNARY || tok[1] == SYMBOL || tok[1] == STRING)
-        {
-            // Evaluate the expression and go to immediate code path
-            expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM);
-            goto l_check_immed;
-        }
+               if (!(dspImmedEXATTR&DEFINED))
+               {
+                       force_imm = NUM_FORCE_LONG;
+                       deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+               }
 
-        //Nope, let's check for ea then
-        if (S1 == 0)
-            ea1 = checkea(',', L_ERRORS);
-        else
-            ea1 = checkea(EOL, L_ERRORS);
+               goto y_check_immed;
+       }
+       else if (*tok == '>')
+       {
+               // Check for immediate address forced long
+               tok++;
 
-        if (ea1 == ERROR)
-            return ERROR;
+               if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                       return ERROR;
 
-    l_gotea1:
-        if (*tok == EOL)
-        {
-            // 'S,L:ea'
-            inst = B16(01000000, 01000000);
-            if (S1 == KW_A)
-                S1 = 4;
-            else if (S1 == KW_B)
-                S1 = 5;
-            else
-                S1 &= 7;
-
-            inst |= ea1;
-            inst |= ((S1 & 0x4) << (11 - 2)) + ((S1 & 3) << 8);
-            return inst;
-        }
-        else if (*tok++ != ',')
-            return error("Comma expected after 'L:(Rn)')");
+               if ((dspImmedEXATTR & DEFINED) && (dspImmedEXVAL > 0xFFFFFF))
+                       return error("long address is bigger than $FFFFFF");
 
-        // It might be 'L:(Rn..)..,D' but we're not 100% sure yet.
-        // If it is, the only possible syntax here is 'L:ea,D'.
-        // So check ahead to see if EOL follows D, then we're good to go.
-        if (((*tok >= KW_A10 && *tok <= KW_BA) || (*tok >= KW_A && *tok <= KW_B)) && *(tok + 1) == EOL)
-        {
-            //'L:ea,D'
-            D1 = *tok++;
-            if (D1 == KW_A)
-                D1 = 4;
-            else if (D1 == KW_B)
-                D1 = 5;
-            else
-                D1 &= 7;
-
-            inst |= ea1;
-            inst |= ((D1 & 0x4) << (11 - 2)) + ((D1 & 3) << 8);
-            return inst;
-        }
-    }
-    else if (*tok == CONST || *tok == FCONST || *tok == SYMBOL)
-    {
-        // Check for immediate address
-        if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-            return ERROR;
-
-        // We set ea1 here - if it's aa instead of ea
-        // then it won't be used anyway
-        ea1 = DSP_EA_ABS;
-        if (!(dspImmedEXATTR & DEFINED))
-        {
-            force_imm = NUM_FORCE_LONG;
-            deposit_extra_ea = DEPOSIT_EXTRA_WORD;
-        }
-               else if (dspImmedEXVAL > 0x3f)
-               {
-                       // Definitely no aa material, so it's going to be a long
-                       // Mark that we need to deposit an extra word
-                       deposit_extra_ea = DEPOSIT_EXTRA_WORD;
-               }
+               deposit_extra_ea = DEPOSIT_EXTRA_WORD;
 
-        // Yes, we have an expression, so we now check for
-        // 'L:ea,D' or 'L:aa,D'
-        goto l_check_immed;
-    }
-    else if (*tok == '>')
-    {
-        // Check for immediate address forced long
-        tok++;
-        if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-            return ERROR;
-        if (dspImmedEXATTR & DEFINED)
-            if (dspImmedEXVAL > 0xffffff)
-                return error("long address is bigger than $ffffff");
-
-        deposit_extra_ea = DEPOSIT_EXTRA_WORD;
-
-        force_imm = NUM_FORCE_LONG;
-        goto l_check_immed;
-    }
-    else if (*tok == '<')
-    {
-        // Check for immediate address forced short
-        tok++;
-        if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-            return ERROR;
-        if (dspImmedEXATTR & DEFINED)
-        {
-            if (dspImmedEXVAL > 0xfff)
-                return error("short addressing mode forced but address is bigger than $fff");
-        }
-        else
-        {
-            // This might end up as something like 'move Y:<adr,register'
-            // so let's mark it as an extra aa fixup here.
-            // Note: we are branching to l_check_immed without a
-            // defined dspImmed so it's going to be 0. It probably
-            // doesn't harm anything.
-            deposit_extra_ea = DEPOSIT_EXTRA_FIXUP;
-        }
+               force_imm = NUM_FORCE_LONG;
+               ea1 = DSP_EA_ABS;
+               goto y_check_immed;
+       }
+       else if (*tok == '<')
+       {
+               tok++;
 
-        force_imm = NUM_FORCE_SHORT;
-        goto l_check_immed;
-    }
+               if (S1 != 0 && D1 != 0)
+               {
+                       // We're in 'S1,D1 Y:ea,D2' or 'S1,D1 S1,Y:ea'
+                       // there's no Y:aa mode here, so we'll force long
+                       if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+                       {
+                               if (optim_warn_flag)
+                                       warn("forced short addressing in R:Y mode is not allowed - switching to long");
 
-    return error("internal assembler error: Please report this error message: 'reached the end of parse_l' with the line of code that caused it. Thanks, and sorry for the inconvenience");
-}
+                               if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                                       return ERROR;
 
+                               ea1 = DSP_EA_ABS;
 
-//
-// Checks for all ea cases where indexed addressing is concenred
-//
-static inline LONG checkea(const uint32_t termchar, const int strings)
-{
-    LONG ea;
-    if (*tok == '-')
-    {
-        // -(Rn)
-        tok++;
-        if (*tok++ != '(')
-            return error(ea_errors[strings][0]);
-        if (*tok >= KW_R0 && *tok <= KW_R7)
-        {
-            // We got '-(Rn' so mark it down
-            ea = DSP_EA_PREDEC1 | (*tok++ - KW_R0);
-            if (*tok++ != ')')
-                return error(ea_errors[strings][1]);
-            // Now, proceed to the main code for this branch
-            return ea;
-        }
-        else
-            return error(ea_errors[strings][2]);
-    }
-    else if (*tok == '(')
-    {
-        // Checking for ea of type (Rn)
-        tok++;
-        if (*tok >= KW_R0 && *tok <= KW_R7)
-        {
-            // We're in 'X:(Rn..)..,D', 'X:(Rn..)..,D1 Y:eay,D2', 'X:(Rn..)..,D1 S2,Y:eay'
-            ea = *tok++ - KW_R0;
-            if (*tok == '+')
-            {
-                // '(Rn+Nn)'
-                tok++;
-                if (*tok < KW_N0 || *tok > KW_N7)
-                    return error(ea_errors[strings][3]);
-                if ((*tok++ & 7) != ea)
-                    return error(ea_errors[strings][4]);
-                ea |= DSP_EA_INDEX;
-                if (*tok++ != ')')
-                    return error(ea_errors[strings][5]);
-                return ea;
-            }
-            else if (*tok == ')')
-            {
-                // Check to see if we have '(Rn)+', '(Rn)-', '(Rn)-Nn', '(Rn)+Nn' or '(Rn)'
-                tok++;
-                if (*tok == '+')
-                {
-                    tok++;
-                    if (termchar == ',')
-                    {
-                        if (*tok == ',')
-                        {
-                            // (Rn)+
-                            ea |= DSP_EA_POSTINC1;
-                            return ea;
-                        }
-                        else if (*tok >= KW_N0 && *tok <= KW_N7)
-                        {
-                            // (Rn)+Nn
-                            if ((*tok++ & 7) != ea)
-                                return error(ea_errors[strings][6]);
-                            ea |= DSP_EA_POSTINC;
-                            return ea;
-                        }
-                        else
-                            return error(ea_errors[strings][7]);
-                    }
-                    else
-                    {
-                        if (*tok >= KW_N0 && *tok <= KW_N7)
-                        {
-                            // (Rn)+Nn
-                            if ((*tok++ & 7) != ea)
-                                return error(ea_errors[strings][6]);
-                            ea |= DSP_EA_POSTINC;
-                            return ea;
-                        }
-                        else
-                        {
-                            // (Rn)+
-                            ea |= DSP_EA_POSTINC1;
-                            return ea;
-                        }
-                    }
-                }
-                else if (*tok == '-')
-                {
-                    tok++;
-                    if (termchar == ',')
-                    {
-                        if (*tok == ',')
-                        {
-                            // (Rn)-
-                            ea |= DSP_EA_POSTDEC1;
-                            return ea;
-                        }
-                        else if (*tok >= KW_N0 && *tok <= KW_N7)
-                        {
-                            // (Rn)-Nn
-                            if ((*tok++ & 7) != ea)
-                                return error(ea_errors[strings][8]);
-                            ea |= DSP_EA_POSTDEC;
-                            return ea;
-                        }
-                        else
-                            return error(ea_errors[strings][9]);
-                    }
-                    else
-                    {
-                        if (*tok >= KW_N0 && *tok <= KW_N7)
-                        {
-                            // (Rn)-Nn
-                            if ((*tok++ & 7) != ea)
-                                return error(ea_errors[strings][8]);
-                            ea |= DSP_EA_POSTDEC;
-                            return ea;
-                        }
-                        else
-                        {
-                            // (Rn)-
-                            ea |= DSP_EA_POSTDEC1;
-                            return ea;
-                        }
-                    }
-                }
-                else if (termchar == ',')
-                {
-                    if (*tok == ',')
-                    {
-                        // (Rn)
-                        ea |= DSP_EA_NOUPD;
-                        return ea;
-                    }
-                    else
-                        return error(ea_errors[strings][10]);
-                }
-                else
-                {
-                    // (Rn)
-                    ea |= DSP_EA_NOUPD;
-                    return ea;
-                }
-            }
-            else
-                return error(ea_errors[strings][11]);
-        }
-    }
-    return error("internal assembler error: Please report this error message: 'reached the end of checkea' with the line of code that caused it. Thanks, and sorry for the inconvenience");
-}
+                               force_imm = NUM_FORCE_LONG;
+                               deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+                               goto y_check_immed;
+                       }
+                       else
+                       {
+                               return error("forced short addressing in R:Y mode is not allowed - turn opt switch o11 on to bypass");
+                       }
+               }
+               else
+               {
+                       // Check for immediate address forced short
+                       ea1 = DSP_EA_ABS; // Reluctant - but it's probably correct
 
+                       if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                               return ERROR;
 
-//
-// Checks for all ea cases, i.e. all addressing modes that checkea handles
-// plus immediate addresses included forced short/long ones.
-// In other words this is a superset of checkea (and in fact calls checkea).
-//
-LONG checkea_full(const uint32_t termchar, const int strings)
-{
-    LONG ea1;
+                       force_imm = NUM_FORCE_SHORT;
 
-    if (*tok == CONST || *tok == FCONST || *tok == SYMBOL)
-    {
-        // Check for immediate address
-        if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-            return ERROR;
+                       if (dspImmedEXATTR & DEFINED)
+                       {
+                               if (dspImmedEXVAL > 0xFFF)
+                               {
+                                       if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+                                       {
+                                               if (optim_warn_flag)
+                                                       warn("short addressing mode forced but address is bigger than $FFF - switching to long");
 
-        deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+                                               ea1 = DSP_EA_ABS;
+                                               force_imm = NUM_FORCE_LONG;
+                                               deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+                                       }
+                                       else
+                                       {
+                                               return error("short addressing mode forced but address is bigger than $FFF - turn opt switch o11 on to bypass");
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               // This might end up as something like 'move Y:<adr,register'
+                               // so let's mark it as an extra aa fixup here.
+                               // Note: we are branching to y_check_immed without a
+                               // defined dspImmed so it's going to be 0. It probably
+                               // doesn't harm anything.
+                               deposit_extra_ea = DEPOSIT_EXTRA_FIXUP;
+                       }
 
-        // Yes, we have an expression
-        return DSP_EA_ABS;
-    }
-    else if (*tok == '>')
-    {
-        // Check for immediate address forced long
-        tok++;
-        if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-            return ERROR;
-        if (dspImmedEXATTR & DEFINED)
-            if (dspImmedEXVAL > 0xffffff)
-                return error("long address is bigger than $ffffff");
-
-        deposit_extra_ea = DEPOSIT_EXTRA_WORD;
-
-        // Yes, we have an expression
-        return DSP_EA_ABS;
-    }
-    else if (*tok == '<')
-    {
-        // Check for immediate address forced short
-        tok++;
-        if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
-            return ERROR;
-        if (dspImmedEXATTR & DEFINED)
-            if (dspImmedEXVAL > 0xfff)
-                return error("short addressing mode forced but address is bigger than $fff");
-
-        // Yes, we have an expression
-        return DSP_EA_ABS;
-    }
-    else
-    {
-        ea1 = checkea(termchar, strings);
-        if (ea1 == ERROR)
-            return ERROR;
-        else
-            return ea1;
-    }
+                       goto y_check_immed;
+               }
+       }
 
+       return error("unrecognised Y: parallel move syntax");
 }
 
 
 //
-// Main routine to check parallel move modes.
-// It's quite complex so it's split into a few procedures (in fact most of the
-// above ones). A big effort was made so this can be managable and not too
-// hacky, however one look at the 56001 manual regarding parallel moves and
-// you'll know that this is not an easy // problem to deal with!
-// dest=destination register from the main opcode. This must not be the same
-// as D1 or D2 and that even goes for stuff like dest=A, D1=A0/1/2!!!
+// Parse L: addressing space parallel moves
 //
-LONG parmoves(WORD dest)
+static inline LONG parse_l(const int W, LONG inst, LONG S1)
 {
-       int force_imm;          // Addressing mode force operator
-       int immreg;             // Immediate register destination
-       LONG inst;              // 16 bit bitfield that has the parallel move opcode
-       LONG S1, S2, D1, D2;    // Source and Destinations
-       LONG ea1;                               // ea bitfields
-
-       if (*tok == EOL)
-       {
-               // No parallel move
-               return B16(00100000, 00000000);
-       }
+       int immreg;                                     // Immediate register destination
+       LONG D1;                                        // Source and Destinations
+       LONG ea1;                                       // ea bitfields
+       int force_imm = NUM_NORMAL;     // Holds forced immediate value (i.e. '<' or '>')
 
-       if (*tok == '#')
+       if (*tok == '-')
        {
-               // '#xxxxxx,D', '#xx,D'
-               tok++;
-               force_imm = NUM_NORMAL;
-
-               if (*tok == '>')
+               if (*tok == CONST || tok[1] == FCONST)
+               {
+                       tok++;
+                       dspImmedEXVAL = *tok++;
+                       goto l_check_immed;
+               }
+
+               // This could be either -(Rn), -aa or -ea. Check for immediate first
+               // Maybe we got an expression here, check for it
+               if (*tok == SYMBOL || tok[1] == SYMBOL)
+               {
+                       // Evaluate the expression and go to immediate code path
+                       if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) == OK)
+                       {
+                               // Only check for aa if we have a defined number in our hands
+                               // or we've been asked to use a short number format. The
+                               // former case we'll just test it to see if it's small enough.
+                               // The later - it's the programmer's call so he'd better have
+                               // a small address or the fixups will bite him/her in the arse!
+                               if (dspImmedEXATTR&DEFINED || force_imm == NUM_FORCE_SHORT)
+                               {
+                                       // It's an immediate, so ea is probably an absolute address
+                                       // (unless it's aa if the immediate is small enough)
+                                       // 'L:ea,D' or 'L:aa,D'
+                               l_check_immed:
+                                       // Check for aa (which is 6 bits zero extended)
+                                       if (*tok == EOL)
+                                       {
+                                               // 'S,L:aa'
+                                               if (dspImmedEXVAL < 0x40 && force_imm != NUM_FORCE_LONG)
+                                               {
+                                                       // 'S,L:aa'
+                                                       if (S1 == REG56_A)
+                                                               S1 = 4;
+                                                       else if (S1 == REG56_B)
+                                                               S1 = 5;
+                                                       else
+                                                               S1 &= 7;
+
+                                                       inst = 0b0100000000000000;
+                                                       inst |= dspImmedEXVAL;
+                                                       inst |= ((S1 & 0x4) << (11 - 2)) + ((S1 & 3) << 8);
+                                                       return inst;
+                                               }
+                                               else
+                                               {
+                                                       // 'S,L:ea'
+                                                       if (S1 == REG56_A)
+                                                               S1 = 4;
+                                                       else if (S1 == REG56_B)
+                                                               S1 = 5;
+                                                       else
+                                                               S1 &= 7;
+
+                                                       if (ea1 == DSP_EA_ABS)
+                                                               deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+
+                                                       inst |= 0b0100000001110000;
+                                                       inst |= ((S1 & 0x4) << (11 - 2)) + ((S1 & 3) << 8);
+                                                       inst |= ea1;
+                                                       return inst;
+                                               }
+
+                                       }
+
+                                       if (*tok++ != ',')
+                                               return error("unrecognised L: parallel move syntax: expected ',' after 'L:ea/L:aa'");
+
+                                       // Check for allowed registers for D (a0, b0, x, y, a, b, ab or ba)
+                                       if (!((*tok >= REG56_A10 && *(tok + 1) <= REG56_BA) || (*tok >= REG56_A && *tok <= REG56_B)))
+                                               return error("unrecognised L: parallel move syntax: expected a0, b0, x, y, a, b, ab or ba after 'L:ea/L:aa'");
+
+                                       if (dspImmedEXVAL < (1 << 6) && (dspImmedEXATTR&DEFINED))
+                                       {
+                                               // 'L:aa,D'
+                                               l_aa:
+                                               immreg = *tok++;
+
+                                               if (immreg == REG56_A)
+                                                       immreg = 4;
+                                               else if (immreg == REG56_B)
+                                                       immreg = 5;
+                                               else
+                                                       immreg &= 7;
+
+                                               if (*tok != EOL)
+                                                       return error("unrecognised L: parallel move syntax: expected End-Of-Line after L:aa,D");
+
+                                               inst &= 0b1111111110111111;
+                                               inst |= dspImmedEXVAL;
+                                               inst |= ((immreg & 0x4) << (11 - 2)) + ((immreg & 3) << 8);
+                                               return inst;
+                                       }
+                               }
+
+                               if (deposit_extra_ea == DEPOSIT_EXTRA_FIXUP)
+                               {
+                                       // Hang on, we've got a L:<aa here, let's do that instead
+                                       goto l_aa;
+                               }
+
+                               // Well, that settles it - we do have a ea in our hands
+                               // 'L:ea,D'
+                               D1 = *tok++;
+
+                               if (D1 == REG56_A)
+                                       D1 = 4;
+                               else if (D1 == REG56_B)
+                                       D1 = 5;
+                               else
+                                       D1 &= 7;
+
+                               if (*tok != EOL)
+                                       return error("unrecognised L: parallel move syntax: expected End-Of-Line after L:ea,D");
+
+                               inst |= 0b0000000000110000;
+                               inst |= ((D1 & 0x4) << (11 - 2)) + ((D1 & 3) << 8);
+                               return inst;
+                       }
+               }
+               else
+               {
+                       //It's not an immediate, check for '-(Rn)'
+                       ea1 = checkea(',', L_ERRORS);
+
+                       if (ea1 == ERROR)
+                               return ERROR;
+
+                       goto l_gotea1;
+
+               }
+       }
+       else if (*tok == '(')
+       {
+               // Maybe we got an expression here, check for it
+               if (tok[1] == CONST || tok[1] == FCONST || tok[1] == SUNARY || tok[1] == SYMBOL || tok[1] == STRING)
+               {
+                       // Evaluate the expression and go to immediate code path
+                       expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM);
+                       goto l_check_immed;
+               }
+
+               //Nope, let's check for ea then
+               if (S1 == 0)
+                       ea1 = checkea(',', L_ERRORS);
+               else
+                       ea1 = checkea(EOL, L_ERRORS);
+
+               if (ea1 == ERROR)
+                       return ERROR;
+
+       l_gotea1:
+               if (*tok == EOL)
+               {
+                       // 'S,L:ea'
+                       inst = 0b0100000001000000;
+
+                       if (S1 == REG56_A)
+                               S1 = 4;
+                       else if (S1 == REG56_B)
+                               S1 = 5;
+                       else
+                               S1 &= 7;
+
+                       inst |= ea1;
+                       inst |= ((S1 & 0x4) << (11 - 2)) + ((S1 & 3) << 8);
+                       return inst;
+               }
+               else if (*tok++ != ',')
+                       return error("Comma expected after 'L:(Rn)')");
+
+               // It might be 'L:(Rn..)..,D' but we're not 100% sure yet.
+               // If it is, the only possible syntax here is 'L:ea,D'.
+               // So check ahead to see if EOL follows D, then we're good to go.
+               if (((*tok >= REG56_A10 && *tok <= REG56_BA) || (*tok >= REG56_A && *tok <= REG56_B)) && *(tok + 1) == EOL)
+               {
+                       //'L:ea,D'
+                       D1 = *tok++;
+
+                       if (D1 == REG56_A)
+                               D1 = 4;
+                       else if (D1 == REG56_B)
+                               D1 = 5;
+                       else
+                               D1 &= 7;
+
+                       inst |= ea1;
+                       inst |= ((D1 & 0x4) << (11 - 2)) + ((D1 & 3) << 8);
+                       return inst;
+               }
+       }
+       else if (*tok == CONST || *tok == FCONST || *tok == SYMBOL)
+       {
+               // Check for immediate address
+               if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                       return ERROR;
+
+               // We set ea1 here - if it's aa instead of ea
+               // then it won't be used anyway
+               ea1 = DSP_EA_ABS;
+
+               if (!(dspImmedEXATTR & DEFINED))
+               {
+                       force_imm = NUM_FORCE_LONG;
+                       deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+               }
+               else if (dspImmedEXVAL > 0x3f)
+               {
+                       // Definitely no aa material, so it's going to be a long
+                       // Mark that we need to deposit an extra word
+                       deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+               }
+
+               // Yes, we have an expression, so we now check for
+               // 'L:ea,D' or 'L:aa,D'
+               goto l_check_immed;
+       }
+       else if (*tok == '>')
+       {
+               // Check for immediate address forced long
+               tok++;
+
+               if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                       return ERROR;
+
+               if ((dspImmedEXATTR & DEFINED) && (dspImmedEXVAL > 0xFFFFFF))
+                       return error("long address is bigger than $FFFFFF");
+
+               deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+
+               force_imm = NUM_FORCE_LONG;
+               goto l_check_immed;
+       }
+       else if (*tok == '<')
+       {
+               // Check for immediate address forced short
+               tok++;
+
+               if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                       return ERROR;
+
+               if (dspImmedEXATTR & DEFINED)
+               {
+                       if (dspImmedEXVAL > 0xFFF)
+                               return error("short addressing mode forced but address is bigger than $FFF");
+               }
+               else
+               {
+                       // This might end up as something like 'move Y:<adr,register'
+                       // so let's mark it as an extra aa fixup here.
+                       // Note: we are branching to l_check_immed without a
+                       // defined dspImmed so it's going to be 0. It probably
+                       // doesn't harm anything.
+                       deposit_extra_ea = DEPOSIT_EXTRA_FIXUP;
+               }
+
+               force_imm = NUM_FORCE_SHORT;
+               goto l_check_immed;
+       }
+
+       return error("internal assembler error: Please report this error message: 'reached the end of parse_l' with the line of code that caused it. Thanks, and sorry for the inconvenience");
+}
+
+
+//
+// Checks for all ea cases where indexed addressing is concenred
+//
+static inline LONG checkea(const uint32_t termchar, const int strings)
+{
+       LONG ea;
+
+       if (*tok == '-')
+       {
+               // -(Rn)
+               tok++;
+
+               if (*tok++ != '(')
+                       return error(ea_errors[strings][0]);
+
+               if (*tok >= REG56_R0 && *tok <= REG56_R7)
+               {
+                       // We got '-(Rn' so mark it down
+                       ea = DSP_EA_PREDEC1 | (*tok++ - REG56_R0);
+
+                       if (*tok++ != ')')
+                               return error(ea_errors[strings][1]);
+
+                       // Now, proceed to the main code for this branch
+                       return ea;
+               }
+               else
+                       return error(ea_errors[strings][2]);
+       }
+       else if (*tok == '(')
+       {
+               // Checking for ea of type (Rn)
+               tok++;
+
+               if (*tok >= REG56_R0 && *tok <= REG56_R7)
+               {
+                       // We're in 'X:(Rn..)..,D', 'X:(Rn..)..,D1 Y:eay,D2', 'X:(Rn..)..,D1 S2,Y:eay'
+                       ea = *tok++ - REG56_R0;
+
+                       if (*tok == '+')
+                       {
+                               // '(Rn+Nn)'
+                               tok++;
+
+                               if (*tok < REG56_N0 || *tok > REG56_N7)
+                                       return error(ea_errors[strings][3]);
+
+                               if ((*tok++ & 7) != ea)
+                                       return error(ea_errors[strings][4]);
+
+                               ea |= DSP_EA_INDEX;
+
+                               if (*tok++ != ')')
+                                       return error(ea_errors[strings][5]);
+
+                               return ea;
+                       }
+                       else if (*tok == ')')
+                       {
+                               // Check to see if we have '(Rn)+', '(Rn)-', '(Rn)-Nn', '(Rn)+Nn' or '(Rn)'
+                               tok++;
+
+                               if (*tok == '+')
+                               {
+                                       tok++;
+
+                                       if (termchar == ',')
+                                       {
+                                               if (*tok == ',')
+                                               {
+                                                       // (Rn)+
+                                                       ea |= DSP_EA_POSTINC1;
+                                                       return ea;
+                                               }
+                                               else if (*tok >= REG56_N0 && *tok <= REG56_N7)
+                                               {
+                                                       // (Rn)+Nn
+                                                       if ((*tok++ & 7) != ea)
+                                                               return error(ea_errors[strings][6]);
+
+                                                       ea |= DSP_EA_POSTINC;
+                                                       return ea;
+                                               }
+                                               else
+                                                       return error(ea_errors[strings][7]);
+                                       }
+                                       else
+                                       {
+                                               if (*tok >= REG56_N0 && *tok <= REG56_N7)
+                                               {
+                                                       // (Rn)+Nn
+                                                       if ((*tok++ & 7) != ea)
+                                                               return error(ea_errors[strings][6]);
+
+                                                       ea |= DSP_EA_POSTINC;
+                                                       return ea;
+                                               }
+                                               else
+                                               {
+                                                       // (Rn)+
+                                                       ea |= DSP_EA_POSTINC1;
+                                                       return ea;
+                                               }
+                                       }
+                               }
+                               else if (*tok == '-')
+                               {
+                                       tok++;
+
+                                       if (termchar == ',')
+                                       {
+                                               if (*tok == ',')
+                                               {
+                                                       // (Rn)-
+                                                       ea |= DSP_EA_POSTDEC1;
+                                                       return ea;
+                                               }
+                                               else if (*tok >= REG56_N0 && *tok <= REG56_N7)
+                                               {
+                                                       // (Rn)-Nn
+                                                       if ((*tok++ & 7) != ea)
+                                                               return error(ea_errors[strings][8]);
+
+                                                       ea |= DSP_EA_POSTDEC;
+                                                       return ea;
+                                               }
+                                               else
+                                                       return error(ea_errors[strings][9]);
+                                       }
+                                       else
+                                       {
+                                               if (*tok >= REG56_N0 && *tok <= REG56_N7)
+                                               {
+                                                       // (Rn)-Nn
+                                                       if ((*tok++ & 7) != ea)
+                                                               return error(ea_errors[strings][8]);
+
+                                                       ea |= DSP_EA_POSTDEC;
+                                                       return ea;
+                                               }
+                                               else
+                                               {
+                                                       // (Rn)-
+                                                       ea |= DSP_EA_POSTDEC1;
+                                                       return ea;
+                                               }
+                                       }
+                               }
+                               else if (termchar == ',')
+                               {
+                                       if (*tok == ',')
+                                       {
+                                               // (Rn)
+                                               ea |= DSP_EA_NOUPD;
+                                               return ea;
+                                       }
+                                       else
+                                               return error(ea_errors[strings][10]);
+                               }
+                               else
+                               {
+                                       // (Rn)
+                                       ea |= DSP_EA_NOUPD;
+                                       return ea;
+                               }
+                       }
+                       else
+                               return error(ea_errors[strings][11]);
+               }
+       }
+
+       return error("internal assembler error: Please report this error message: 'reached the end of checkea' with the line of code that caused it. Thanks, and sorry for the inconvenience");
+}
+
+
+//
+// Checks for all ea cases, i.e. all addressing modes that checkea handles
+// plus immediate addresses included forced short/long ones.
+// In other words this is a superset of checkea (and in fact calls checkea).
+//
+LONG checkea_full(const uint32_t termchar, const int strings)
+{
+       LONG ea1;
+
+       if (*tok == CONST || *tok == FCONST || *tok == SYMBOL)
+       {
+               // Check for immediate address
+               if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                       return ERROR;
+
+               deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+
+               // Yes, we have an expression
+               return DSP_EA_ABS;
+       }
+       else if (*tok == '>')
+       {
+               // Check for immediate address forced long
+               tok++;
+
+               if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                       return ERROR;
+
+               if ((dspImmedEXATTR & DEFINED) && (dspImmedEXVAL > 0xFFFFFF))
+                       return error("long address is bigger than $FFFFFF");
+
+               deposit_extra_ea = DEPOSIT_EXTRA_WORD;
+
+               // Yes, we have an expression
+               return DSP_EA_ABS;
+       }
+       else if (*tok == '<')
+       {
+               // Check for immediate address forced short
+               tok++;
+
+               if (expr(dspImmedEXPR, &dspImmedEXVAL, &dspImmedEXATTR, &dspImmedESYM) != OK)
+                       return ERROR;
+
+               if ((dspImmedEXATTR & DEFINED) && (dspImmedEXVAL > 0xFFF))
+                       return error("short addressing mode forced but address is bigger than $FFF");
+
+               // Yes, we have an expression
+               return DSP_EA_ABS;
+       }
+       else
+       {
+               ea1 = checkea(termchar, strings);
+
+               if (ea1 == ERROR)
+                       return ERROR;
+               else
+                       return ea1;
+       }
+
+}
+
+
+//
+// Main routine to check parallel move modes.
+// It's quite complex so it's split into a few procedures (in fact most of the
+// above ones). A big effort was made so this can be managable and not too
+// hacky, however one look at the 56001 manual regarding parallel moves and
+// you'll know that this is not an easy // problem to deal with!
+// dest=destination register from the main opcode. This must not be the same
+// as D1 or D2 and that even goes for stuff like dest=A, D1=A0/1/2!!!
+//
+LONG parmoves(WORD dest)
+{
+       int force_imm;          // Addressing mode force operator
+       int immreg;             // Immediate register destination
+       LONG inst;              // 16 bit bitfield that has the parallel move opcode
+       LONG S1, S2, D1, D2;    // Source and Destinations
+       LONG ea1;                               // ea bitfields
+
+       if (*tok == EOL)
+       {
+               // No parallel move
+               return 0b0010000000000000;
+       }
+
+       if (*tok == '#')
+       {
+               // '#xxxxxx,D', '#xx,D'
+               tok++;
+               force_imm = NUM_NORMAL;
+
+               if (*tok == '>')
                {
                        force_imm = NUM_FORCE_LONG;
                        tok++;
@@ -2447,7 +2536,7 @@ LONG parmoves(WORD dest)
                if (*tok++ != ',')
                        return error("expected comma");
 
-               if (!((*tok >= KW_X0 && *tok <= KW_N7) || (*tok >= KW_R0 && *tok <= KW_R7) || (*tok >= KW_A0 && *tok <= KW_A2)))
+               if (!((*tok >= REG56_X0 && *tok <= REG56_N7) || (*tok >= REG56_R0 && *tok <= REG56_R7) || (*tok >= REG56_A0 && *tok <= REG56_A2)))
                        return error("expected x0,x1,y0,y1,a0,b0,a2,b2,a1,b1,a,b,r0-r7,n0-n7 after immediate");
 
                immreg = SDreg(*tok++);
@@ -2459,15 +2548,19 @@ LONG parmoves(WORD dest)
                                if (dspImmedEXATTR & DEFINED)
                                {
                                        // From I parallel move:
-                                       // "If the destination register D is X0, X1, Y0, Y1, A, or B, the 8-bit immediate short operand
-                                       // is interpreted as a signed fraction and is stored in the specified destination register.
-                                       // That is, the 8 - bit data is stored in the eight MS bits of the destination operand, and the
-                                       // remaining bits of the destination operand D are zeroed."
-                                       // The funny bit is that Motorola assembler can parse something like 'move #$FF0000,b' into an
-                                       // I (immediate short move) - so let's do that as well then...
+                                       // "If the destination register D is X0, X1, Y0, Y1, A, or
+                                       // B, the 8-bit immediate short operand is interpreted as
+                                       // a signed fraction and is stored in the specified
+                                       // destination register. That is, the 8 - bit data is
+                                       // stored in the eight MS bits of the destination operand,
+                                       // and the remaining bits of the destination operand D are
+                                       // zeroed."
+                                       // The funny bit is that Motorola assembler can parse
+                                       // something like 'move #$FF0000,b' into an I (immediate
+                                       // short move) - so let's do that as well then...
                                        if (((immreg >= 4 && immreg <= 7) || immreg == 14 || immreg == 15) && force_imm != NUM_FORCE_LONG)
                                        {
-                                               if ((dspImmedEXVAL & 0xffff) == 0)
+                                               if ((dspImmedEXVAL & 0xFFFF) == 0)
                                                {
                                                        dspImmedEXVAL >>= 16;
                                                }
@@ -2479,13 +2572,21 @@ LONG parmoves(WORD dest)
                                                {
                                                        // '#xx,D'
                                                        // value fits in 8 bits - immediate move
-                                                       inst = B16(00100000, 00000000) + (immreg << 8) + (uint32_t)dspImmedEXVAL;
+                                                       inst = 0b0010000000000000 + (immreg << 8) + (uint32_t)dspImmedEXVAL;
                                                        return inst;
                                                }
                                                else
                                                {
-                                                       warn("forced short immediate value doesn't fit in 8 bits - switching to long");
-                                                       force_imm = NUM_FORCE_LONG;
+                                                       if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+                                                       {
+                                                               if (optim_warn_flag)
+                                                                       warn("forced short immediate value doesn't fit in 8 bits - switching to long");
+                                                               force_imm = NUM_FORCE_LONG;
+                                                       }
+                                                       else
+                                                       {
+                                                               return error("forced short immediate value doesn't fit in 8 bits - turn opt switch o11 on to bypass");
+                                                       }
                                                }
                                        }
 
@@ -2496,7 +2597,7 @@ LONG parmoves(WORD dest)
                                                // X or Y Data move. I don't think it matters much
                                                // which of the two it will be, so let's use X.
 deposit_immediate_long_with_register:
-                                               inst = B16(01000000, 11110100);
+                                               inst = 0b0100000011110100;
                                                inst |= ((immreg & 0x18) << (12 - 3)) + ((immreg & 7) << 8);
                                                deposit_extra_ea = DEPOSIT_EXTRA_WORD;
                                                return inst;
@@ -2506,7 +2607,7 @@ deposit_immediate_long_with_register:
                                        {
                                                // value fits in 8 bits - immediate move
 deposit_immediate_short_with_register:
-                                               inst = B16(00100000, 00000000) + (immreg << 8) + (uint32_t)dspImmedEXVAL;
+                                               inst = 0b0010000000000000 + (immreg << 8) + (uint32_t)dspImmedEXVAL;
                                                return inst;
                                        }
                                        else
@@ -2531,7 +2632,7 @@ deposit_immediate_short_with_register:
                                                // '#xx,D' - I mode
                                                // No visibility of the number so let's add a fixup for this
                                                AddFixup(FU_DSPIMM8, sloc, dspImmedEXPR);
-                                               inst = B16(00100000, 00000000);
+                                               inst = 0b0010000000000000;
                                                inst |= ((immreg & 0x18) << (11 - 3)) + ((immreg & 7) << 8);
                                                return inst;
                                        }
@@ -2544,7 +2645,7 @@ deposit_immediate_short_with_register:
                                {
                                        double f = *(double *)&dspImmedEXVAL;
                                        // Check direct.c for ossom comments regarding conversion!
-//N.B.: This is bogus, we need to fix this so it does this the right way... !!! FIX !!!
+                                       //N.B.: This is bogus, we need to fix this so it does this the right way... !!! FIX !!!
                                        dspImmedEXVAL = ((uint32_t)(int32_t)round(f * (1 << 23))) & 0xFFFFFF;
                                        double g;
                                        g = f * (1 << 23);
@@ -2552,19 +2653,38 @@ deposit_immediate_short_with_register:
 
                                        if ((dspImmedEXVAL & 0xFFFF) == 0)
                                        {
-                                               // Value's 16 lower bits are not set so the value can fit in a single byte
-                                               // (check parallel I move quoted above)
-                                               warn("Immediate value fits inside 8 bits, so using instruction short format");
-                                               dspImmedEXVAL >>= 16;
-                                               goto deposit_immediate_short_with_register;
+                                               if (CHECK_OPTS(OPT_56K_SHORT))
+                                               {
+                                                       // Value's 16 lower bits are not set so the value can
+                                                       // fit in a single byte (check parallel I move quoted
+                                                       // above)
+                                                       if (optim_warn_flag)
+                                                               warn("o10: Immediate value fits inside 8 bits, so using instruction short format");
+
+                                                       dspImmedEXVAL >>= 16;
+                                                       goto deposit_immediate_short_with_register;
+                                               }
+                                               else
+                                               {
+                                                       return error("Immediate value fits inside 8 bits, so using instruction short format - turn opt switch o10 on to bypass");
+                                               }
                                        }
 
                                        if (force_imm == NUM_FORCE_SHORT)
                                        {
                                                if ((dspImmedEXVAL & 0xFFFF) != 0)
                                                {
-                                                       warn("Immediate value short format forced but value does not fit inside 8 bits - switching to long format");
-                                                       goto deposit_immediate_long_with_register;
+                                                       if (CHECK_OPTS(OPT_56K_AUTO_LONG))
+                                                       {
+                                                               if (optim_warn_flag)
+                                                                       warn("o11: Immediate value short format forced but value does not fit inside 8 bits - switching to long format");
+
+                                                               goto deposit_immediate_long_with_register;
+                                                       }
+                                                       else
+                                                       {
+                                                               return error("Immediate value short format forced but value does not fit inside 8 bits - turn opt switch o11 on to bypass");
+                                                       }
                                                }
 
                                                return error("internal assembler error: we haven't implemented floating point constants in parallel mode parser yet!");
@@ -2583,7 +2703,7 @@ deposit_immediate_short_with_register:
                                        {
                                                // Just deposit a float fixup
                                                AddFixup(FU_DSPIMMFL8, sloc, dspImmedEXPR);
-                                               inst = B16(00100000, 00000000);
+                                               inst = 0b0010000000000000;
                                                inst |= ((immreg & 0x18) << (12 - 3)) + ((immreg & 7) << 8);
                                                return inst;
                                        }
@@ -2604,8 +2724,8 @@ deposit_immediate_short_with_register:
 
                        switch (*tok++)
                        {
-                       case KW_A: S2 = 0 << 9; break;
-                       case KW_B: S2 = 1 << 9; break;
+                       case REG56_A: S2 = 0 << 9; break;
+                       case REG56_B: S2 = 1 << 9; break;
                        default: return error("unrecognised X:R parallel move syntax: S2 can only be A or B in '#xxxxxx,D1 S2,D2'"); break;
                        }
 
@@ -2614,20 +2734,20 @@ deposit_immediate_short_with_register:
 
                        switch (*tok++)
                        {
-                       case KW_Y0: D2 = 0 << 8; break;
-                       case KW_Y1: D2 = 1 << 8; break;
+                       case REG56_Y0: D2 = 0 << 8; break;
+                       case REG56_Y1: D2 = 1 << 8; break;
                        default: return error("unrecognised X:R parallel move syntax: D2 can only be Y0 or Y1 in '#xxxxxx,D1 S2,D2'"); break;
                        }
 
                        if (*tok != EOL)
                                return error("unrecognised X:R parallel move syntax: expected end-of-line after '#xxxxxx,D1 S2,D2'");
 
-                       inst = B16(00010000, 10110100) | D1 | S2 | D2;
+                       inst = 0b0001000010110100 | D1 | S2 | D2;
                        deposit_extra_ea = DEPOSIT_EXTRA_WORD;
                        return inst;
                }
        }
-       else if (*tok == KW_X)
+       else if (*tok == REG56_X)
        {
                if (tok[1] == ',')
                        // Hey look, it's just the register X and not the addressing mode - fall through to general case
@@ -2639,9 +2759,9 @@ deposit_immediate_short_with_register:
                        return error("expected ':' after 'X' in parallel move (i.e. X:)");
 
                // 'X:ea,D' or 'X:aa,D' or 'X:ea,D1 S2,D2' or 'X:eax,D1 Y:eay,D2' or 'X:eax,D1 S2,Y:eay'
-               return parse_x(1, B16(01000000, 00000000), 0, 1);
+               return parse_x(1, 0b0100000000000000, 0, 1);
        }
-       else if (*tok == KW_Y)
+       else if (*tok == REG56_Y)
        {
                if (tok[1] == ',')
                        // Hey look, it's just the register y and not the addressing mode - fall through to general case
@@ -2653,18 +2773,18 @@ deposit_immediate_short_with_register:
                        return error("expected ':' after 'Y' in parallel move (i.e. Y:)");
 
                // 'Y:ea,D' or 'Y:aa,D'
-               return parse_y(B16(01001000, 10000000), 0, 0, 0);
+               return parse_y(0b0100100010000000, 0, 0, 0);
        }
-       else if (*tok == KW_L)
+       else if (*tok == REG56_L)
        {
                // 'L:ea,D' or 'L:aa,D'
                tok++;
                if (*tok++ != ':')
                        return error("expected ':' after 'L' in parallel move (i.e. L:)");
 
-               return parse_l(1, B16(01000000, 11000000), 0);
+               return parse_l(1, 0b0100000011000000, 0);
        }
-       else if ((*tok >= KW_X0 && *tok <= KW_N7) || (*tok >= KW_R0 && *tok <= KW_R7) || (*tok >= KW_A0 && *tok <= KW_A2) || (*tok >= KW_A10 && *tok <= KW_BA))
+       else if ((*tok >= REG56_X0 && *tok <= REG56_N7) || (*tok >= REG56_R0 && *tok <= REG56_R7) || (*tok >= REG56_A0 && *tok <= REG56_A2) || (*tok >= REG56_A10 && *tok <= REG56_BA))
        {
                // Everything else - brace for impact!
                // R:   'S,D'
@@ -2681,7 +2801,7 @@ parse_everything_else:
                if (*tok++ != ',')
                        return error("Comma expected after 'S')");
 
-               if (*tok == KW_X)
+               if (*tok == REG56_X)
                {
                        // 'S,X:ea' 'S,X:aa' 'S,X:ea S2,D2' 'S1,X:eax Y:eay,D2' 'S1,X:eax S2,Y:eay'
                        // 'A,X:ea X0,A' 'B,X:ea X0,B'
@@ -2690,9 +2810,9 @@ parse_everything_else:
                        if (*tok++ != ':')
                                return error("unrecognised X: parallel move syntax: expected ':' after 'S,X'");
 
-                       return parse_x(0, B16(01000000, 00000000), S1, 1);
+                       return parse_x(0, 0b0100000000000000, S1, 1);
                }
-               else if (*tok == KW_Y)
+               else if (*tok == REG56_Y)
                {
                        // 'S,Y:ea' 'S,Y:aa'
                        tok++;
@@ -2700,9 +2820,9 @@ parse_everything_else:
                        if (*tok++ != ':')
                                return error("unrecognised Y: parallel move syntax: expected ':' after 'S,Y'");
 
-                       return parse_y(B16(0000000, 00000000), S1, 0, 0);
+                       return parse_y(0b000000000000000, S1, 0, 0);
                }
-               else if (*tok == KW_L)
+               else if (*tok == REG56_L)
                {
                        // 'S,L:ea' 'S,L:aa'
                        tok++;
@@ -2710,9 +2830,9 @@ parse_everything_else:
                        if (*tok++ != ':')
                                return error("unrecognised L: parallel move syntax: expected ':' after 'S,L'");
 
-                       return parse_l(1, B16(00000000, 00000000), L_S1);
+                       return parse_l(1, 0b0000000000000000, L_S1);
                }
-               else if ((*tok >= KW_X0 && *tok <= KW_N7) || (*tok >= KW_R0 && *tok <= KW_R7) || (*tok >= KW_A0 && *tok <= KW_A2))
+               else if ((*tok >= REG56_X0 && *tok <= REG56_N7) || (*tok >= REG56_R0 && *tok <= REG56_R7) || (*tok >= REG56_A0 && *tok <= REG56_A2))
                {
                        // 'S,D'
                        // 'S1,D1 Y:ea,D2' 'S1,D1 S2,Y:ea' 'S1,D1 #xxxxxx,D2'
@@ -2722,20 +2842,20 @@ parse_everything_else:
                        if (*tok == EOL)
                        {
                                // R 'S,D'
-                               inst = B16(00100000, 00000000);
+                               inst = 0b0010000000000000;
                                inst |= (S1 << 5) | (D1);
                                return inst;
                        }
-                       else if (*tok == KW_Y)
+                       else if (*tok == REG56_Y)
                        {
                                // 'S1,D1 Y:ea,D2'
                                tok++;
                                if (*tok++ != ':')
                                        return error("expected ':' after 'Y' in parallel move (i.e. Y:)");
-                               return parse_y(B16(00010000, 01000000), S1, D1, 0);
+                               return parse_y(0b0001000001000000, S1, D1, 0);
 
                        }
-                       else if (*tok == KW_A || *tok == KW_B || *tok == KW_Y0 || *tok == KW_Y1)
+                       else if (*tok == REG56_A || *tok == REG56_B || *tok == REG56_Y0 || *tok == REG56_Y1)
                        {
                                // 'Y0,A A,Y:ea' 'Y0,B B,Y:ea' 'S1,D1 S2,Y:ea'
                                S2 = SDreg(*tok++);
@@ -2746,7 +2866,7 @@ parse_everything_else:
                                        if (*tok++ != ',')
                                                return error("unrecognised Y: parallel move syntax: expected ',' after Y0,A A");
 
-                                       if (*tok++ != KW_Y)
+                                       if (*tok++ != REG56_Y)
                                                return error("unrecognised Y: parallel move syntax: expected 'Y' after Y0,A A,");
 
                                        if (*tok++ != ':')
@@ -2757,7 +2877,7 @@ parse_everything_else:
                                        if (ea1 == ERROR)
                                                return ERROR;
 
-                                       inst = B16(00001000, 10000000);
+                                       inst = 0b0000100010000000;
                                        inst |= 0 << 8;
                                        inst |= ea1;
                                        return inst;
@@ -2768,7 +2888,7 @@ parse_everything_else:
                                        if (*tok++ != ',')
                                                return error("unrecognised Y: parallel move syntax: expected ',' after Y0,B B");
 
-                                       if (*tok++ != KW_Y)
+                                       if (*tok++ != REG56_Y)
                                                return error("unrecognised Y: parallel move syntax: expected 'Y' after Y0,B B,");
 
                                        if (*tok++ != ':')
@@ -2779,7 +2899,7 @@ parse_everything_else:
                                        if (ea1 == ERROR)
                                                return ERROR;
 
-                                       inst = B16(00001000, 10000000);
+                                       inst = 0b0000100010000000;
                                        inst |= 1 << 8;
                                        inst |= ea1;
                                        return inst;
@@ -2790,7 +2910,7 @@ parse_everything_else:
                                        if (*tok++ != ',')
                                                return error("unrecognised Y: parallel move syntax: expected ',' after S1,D1 S2");
 
-                                       if (*tok++ != KW_Y)
+                                       if (*tok++ != REG56_Y)
                                                return error("unrecognised Y: parallel move syntax: expected 'Y' after S1,D1 S2,");
 
                                        if (*tok++ != ':')
@@ -2801,7 +2921,7 @@ parse_everything_else:
                                        if (ea1 == ERROR)
                                                return ERROR;
 
-                                       inst = B16(00010000, 01000000);
+                                       inst = 0b0001000001000000;
                                        inst |= (S1 & 1) << 11;
                                        inst |= (D1 & 1) << 10;
                                        inst |= ((S2 & 8) << (10 - 4)) | ((S2 & 1) << 8);
@@ -2828,9 +2948,8 @@ parse_everything_else:
                                if (expr(dspaaEXPR, &dspaaEXVAL, &dspaaEXATTR, &dspaaESYM) != OK)
                                        return ERROR;
 
-                               if (dspImmedEXATTR & DEFINED)
-                                       if (dspImmedEXVAL > 0xffffff)
-                                               return error("immediate is bigger than $ffffff");
+                               if ((dspImmedEXATTR & DEFINED) && (dspImmedEXVAL > 0xFFFFFF))
+                                       return error("immediate is bigger than $FFFFFF");
 
                                deposit_extra_ea = DEPOSIT_EXTRA_WORD;
 
@@ -2840,10 +2959,10 @@ parse_everything_else:
                                // S1 is a or b, D1 is x0 or x1 and d2 is y0, y1, a or b
                                switch (*tok++)
                                {
-                               case KW_Y0: D2 = 0 << 8; break;
-                               case KW_Y1: D2 = 1 << 8; break;
-                               case KW_A:  D2 = 2 << 8; break;
-                               case KW_B:  D2 = 3 << 8; break;
+                               case REG56_Y0: D2 = 0 << 8; break;
+                               case REG56_Y1: D2 = 1 << 8; break;
+                               case REG56_A:  D2 = 2 << 8; break;
+                               case REG56_B:  D2 = 3 << 8; break;
                                default:    return error("unrecognised R:Y: parallel move syntax: D2 must be y0, y1, a or b in 'S1,D1 #xxxxxx,D2'");
                                }
 
@@ -2851,7 +2970,7 @@ parse_everything_else:
                                {
                                        if (D1 == 4 || D1 == 5)
                                        {
-                                               inst = B16(00010000, 11110100);
+                                               inst = 0b0001000011110100;
                                                inst |= (S1 & 1) << 11;
                                                inst |= (D1 & 1) << 10;
                                                inst |= D2;
@@ -2876,9 +2995,9 @@ parse_everything_else:
                // U 'ea' can only be '(Rn)-Nn', '(Rn)+Nn', '(Rn)-' or '(Rn)+'
                tok++;
 
-               if (*tok >= KW_R0 && *tok <= KW_R7)
+               if (*tok >= REG56_R0 && *tok <= REG56_R7)
                {
-                       ea1 = (*tok++ - KW_R0);
+                       ea1 = (*tok++ - REG56_R0);
                }
                else
                        return error("unrecognised U parallel move syntax: expected 'Rn' after '('");
@@ -2893,7 +3012,7 @@ parse_everything_else:
                        if (*tok == EOL)
                                // (Rn)+
                                ea1 |= 3 << 3;
-                       else if (*tok >= KW_N0 && *tok <= KW_N7)
+                       else if (*tok >= REG56_N0 && *tok <= REG56_N7)
                        {
                                // (Rn)+Nn
                                if ((*tok++ & 7) != ea1)
@@ -2917,7 +3036,7 @@ parse_everything_else:
                                ea1 |= 2 << 3;
                                tok++;
                        }
-                       else if (*tok >= KW_N0 && *tok <= KW_N7)
+                       else if (*tok >= REG56_N0 && *tok <= REG56_N7)
                        {
                                // (Rn)-Nn
                                if ((*tok++ & 7) != ea1)
@@ -2930,7 +3049,7 @@ parse_everything_else:
                        }
                }
 
-               inst = B16(00100000, 01000000);
+               inst = 0b0010000001000000;
                inst |= ea1;
                return inst;
        }