//
-// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
+// RMAC - Renamed Macro Assembler for all Atari computers
// AMODE.C - Addressing Modes
-// Copyright (C) 199x Landon Dyer, 2011 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
//
#define DEF_MN
#include "mntab.h"
+extern char unsupport[];
// Address-mode information
int nmodes; // Number of addr'ing modes found
int am0; // Addressing mode
int a0reg; // Register
TOKEN a0expr[EXPRSIZE]; // Expression
-VALUE a0exval; // Expression's value
+uint64_t a0exval; // Expression's value
WORD a0exattr; // Expression's attribute
int a0ixreg; // Index register
int a0ixsiz; // Index register size (and scale)
-TOKEN a0oexpr[EXPRSIZE]; // Outer displacement expression
-VALUE a0oexval; // Outer displacement value
-WORD a0oexattr; // Outer displacement attribute
SYM * a0esym; // External symbol involved in expr
TOKEN a0bexpr[EXPRSIZE]; // Base displacement expression
-VALUE a0bexval; // Base displacement value
+uint64_t a0bexval; // Base displacement value
WORD a0bexattr; // Base displacement attribute
WORD a0bsize; // Base displacement size
WORD a0extension; // 020+ extension address word
int am1; // Addressing mode
int a1reg; // Register
TOKEN a1expr[EXPRSIZE]; // Expression
-VALUE a1exval; // Expression's value
+uint64_t a1exval; // Expression's value
WORD a1exattr; // Expression's attribute
int a1ixreg; // Index register
int a1ixsiz; // Index register size (and scale)
-TOKEN a1oexpr[EXPRSIZE]; // Outer displacement expression
-VALUE a1oexval; // Outer displacement value
-WORD a1oexattr; // Outer displacement attribute
SYM * a1esym; // External symbol involved in expr
TOKEN a1bexpr[EXPRSIZE]; // Base displacement expression
-VALUE a1bexval; // Base displacement value
+uint64_t a1bexval; // Base displacement value
WORD a1bexattr; // Base displacement attribute
WORD a1bsize; // Base displacement size
WORD a1extension; // 020+ extension address word
WORD am1_030; // ea bits for 020+ addressing modes
int a2reg; // Register for div.l (68020+)
-WORD mulmode; // To distinguish between 32 and 64 bit multiplications (68020+)
-int bfparam1; // bfxxx instruction parameter 1
-int bfparam2; // bfxxx instruction parameter 2
+int bfparam1; // bfxxx / fmove instruction parameter 1
+int bfparam2; // bfxxx / fmove instruction parameter 2
+int bfval1; // bfxxx / fmove value 1
+int bfval2; // bfxxx / fmove value 2
TOKEN bf0expr[EXPRSIZE]; // Expression
-VALUE bf0exval; // Expression's value
+uint64_t bf0exval; // Expression's value
WORD bf0exattr; // Expression's attribute
SYM * bf0esym; // External symbol involved in expr
// Function prototypes
-int check030bf(void);
+int Check030Bitfield(void);
//
// Initialize global return values
nmodes = a0reg = a1reg = 0;
am0 = am1 = AM_NONE;
- a0expr[0] = a0oexpr[0] = a1expr[0] = a1oexpr[0] = ENDEXPR;
- a0exattr = a0oexattr = a1exattr = a1oexattr = 0;
+ a0expr[0] = a1expr[0] = ENDEXPR;
+ a0exattr = a1exattr = 0;
a0esym = a1esym = NULL;
a0bexpr[0] = a1bexpr[0] = ENDEXPR;
- a0bexval = a0bsize = a0extension = a1bexval = a1bsize = a1extension = 0;
+ a0bexval = a1bexval = 0;
+ a0bsize = a0extension = a1bsize = a1extension = 0;
am0_030 = am1_030 = 0;
bfparam1 = bfparam2 = 0;
bf0expr[0] = ENDEXPR;
#define AnEXPR a0expr
#define AnEXVAL a0exval
#define AnEXATTR a0exattr
- #define AnOEXPR a0oexpr
- #define AnOEXVAL a0oexval
- #define AnOEXATTR a0oexattr
#define AnESYM a0esym
#define AMn_IX0 am0_ix0
#define AMn_IXN am0_ixn
// it's a bitfield instruction--check the parameters inside the {} block
// for validity
- if ((*tok == '{') && (check030bf() == ERROR))
- return ERROR;
+ if (*tok == '{')
+ if (Check030Bitfield() == ERROR)
+ return ERROR;
if ((acount == 0) || (*tok != ','))
return 1;
#define AnEXPR a1expr
#define AnEXVAL a1exval
#define AnEXATTR a1exattr
- #define AnOEXPR a1oexpr
- #define AnOEXVAL a1oexval
- #define AnOEXATTR a1oexattr
#define AnESYM a1esym
#define AMn_IX0 am1_ix0
#define AMn_IXN am1_ixn
// It's a bitfield instruction--check the parameters inside the {} block
// for validity
- if ((*tok == '{') && (check030bf() == ERROR))
+ if (*tok == '{')
+ if (Check030Bitfield() == ERROR)
return ERROR;
// At this point, it is legal for 020+ to have a ':'. For example divu.l
tok++; //eat the colon
if ((*tok >= KW_D0) && (*tok <= KW_D7))
- {
- a2reg = (*tok - KW_D0);
- mulmode = 1 << 10;
- }
+ a2reg = (*tok++) & 7;
else if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
- {
- a2reg = (*tok - KW_FP0);
- mulmode = 1 << 10;
- }
+ a2reg = (*tok++) & 7;
else
return error("a data or FPU register must follow a :");
-
- *tok++;
}
else
{
// If no ':' is present then maybe we have something like divs.l d0,d1
// which sould translate to divs.l d0,d1:d1
a2reg = a1reg;
- mulmode = 0;
}
nmodes = 2;
// Error messages:
badmode:
return error("addressing mode syntax");
-
- //unmode:
- //return error("unimplemented addressing mode");
}
else
cnt = 0;
+ r = 0;
+
while (cnt-- >= 0)
rmask |= msktab_minus[r++];
int fpu_reglist_right(WORD * a_rmask)
{
static WORD msktab_plus[] = {
- 0x0001, 0x0002, 0x0004, 0x0008,
- 0x0010, 0x0020, 0x0040, 0x0080
+ 0x0080, 0x0040, 0x0020, 0x0010,
+ 0x0008, 0x0004, 0x0002, 0x0001
};
WORD rmask = 0;
// bfxxx <ea>{param1,param2}
// param1/2 are either data registers or immediate values
//
-int check030bf(void)
+int Check030Bitfield(void)
{
- WARNING(Add more strict checks as well as checks for non defined (yet) labels)
-
- if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
- return error(unsupport);
-
+ PTR tp;
+ CHECK00;
tok++;
if (*tok == CONST)
{
- tok++;
- bfparam1 = *(int *)tok;
-
- if ((bfparam1 > 31) || (bfparam1 < 0))
- return error("bfxxx offset: immediate value must be between 0 and 31");
+ tp.u32 = tok + 1;
+ bfval1 = (int)*tp.u64++;
+ tok = tp.u32;
// Do=0, offset=immediate - shift it to place
- bfparam1 = (bfparam1 << 6) | (0 << 11);
- tok++;
+ bfparam1 = (0 << 11);
}
else if (*tok == SYMBOL)
{
if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
return ERROR;
- bfparam1 = bf0exval;
+ if (!(bf0exattr & DEFINED))
+ return error("bfxxx offset: immediate value must evaluate");
- if ((bfparam1 > 31) || (bfparam1 < 0))
- return error("bfxxx offset: immediate value must be between 0 and 31");
+ bfval1 = (int)bf0exval;
// Do=0, offset=immediate - shift it to place
- bfparam1 = (bfparam1 << 6) | (0 << 11);
+ bfparam1 = (0 << 11);
}
else if ((*tok >= KW_D0) && (*tok <= KW_D7))
{
// Do=1, offset=data register - shift it to place
- bfparam1 = ((*(int *)tok - 128) << 6) | (1 << 11);
+ bfparam1 = (1 << 11);
+ bfval1 = (*(int *)tok - 128);
tok++;
}
else
return ERROR;
- if (*tok==':')
- tok++; //eat the ':'
+ // Eat the ':', if any
+ if (*tok == ':')
+ tok++;
if (*tok == '}' && tok[1] == EOL)
{
if (*tok == CONST)
{
- tok++;
- bfparam2 = *(int *)tok;
-
- if (bfparam2 > 31 || bfparam2 < 0)
- return error("bfxxx width: immediate value must be between 0 and 31");
+ tp.u32 = tok + 1;
+ bfval2 = (int)*tp.u64++;
+ tok = tp.u32;
// Do=0, offset=immediate - shift it to place
- bfparam2 = (bfparam2 << 0) | (0 << 5);
- tok++;
+ bfparam2 = (0 << 5);
}
else if (*tok == SYMBOL)
{
if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
return ERROR;
- bfparam2 = bf0exval;
+ bfval2 = (int)bf0exval;
- if (bfparam2 > 31 || bfparam2 < 0)
- return error("bfxxx width: immediate value must be between 0 and 31");
+ if (!(bf0exattr & DEFINED))
+ return error("bfxxx width: immediate value must evaluate");
// Do=0, offset=immediate - shift it to place
- bfparam2 = (bfparam2 << 0) | (0 << 5);
+ bfparam2 = (0 << 5);
}
else if ((*tok >= KW_D0) && (*tok <= KW_D7))
{
// Do=1, offset=data register - shift it to place
- bfparam2 = ((*(int *)tok - 128) << 0) | (1 << 5);
+ bfval2 = (*(int *)tok - 128);
+ bfparam2 = (1 << 5);
tok++;
}
else