- // 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;
- }
+ 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 (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 = 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)')");
+
+ // 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;
+ }