X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=dsp56k_amode.c;h=70a69cf3a5ce5b2be497e337d673bdb37e7ac5bd;hp=7937b106b87c54623bdaffdb17d665d4679b980a;hb=HEAD;hpb=e6faa71fc77a1b7ed35b9fec6274d9de44bd2e3f diff --git a/dsp56k_amode.c b/dsp56k_amode.c index 7937b10..664c533 100644 --- a/dsp56k_amode.c +++ b/dsp56k_amode.c @@ -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 // @@ -15,13 +15,12 @@ #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&® <= KW_A2) + else if (reg >= REG56_A0&® <= REG56_A2) return (8 >> (reg & 7)) | 8; - else //if (reg>=KW_R0&®<=KW_R7) - return reg - KW_R0 + 16; + else //if (reg>=REG56_R0&®<=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:') - 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:= 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:= 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:') - { - // 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:= 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:= 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; }