//
-// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
+// RMAC - Reboot's Macro Assembler for all Atari computers
// PARMODE.C - Addressing Modes Parser Include
-// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends
// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
// Source utilised with the kind permission of Landon Dyer
//
else if (*tok == 'L')
{
// TODO: does DINDL gets used at all?
- //AMn=DINDL; // (Dn.l)
- //AnEXTEN = 1 << 1; // Long index size
- //tok++;
+ AMn=DINDL; // (Dn.l)
+ AnEXTEN = 1 << 1; // Long index size
+ tok++;
}
else if (*tok == 'W') // (Dn.w)
{
// TODO: does DINDW gets used at all?
- //AMn=DINDW;
- //AnEXTEN = 1 << 1; // Word index size
- //tok++;
+ AMn=DINDW;
+ AnEXTEN = 1 << 1; // Word index size
+ tok++;
}
else if (*tok == ',')
{
goto CHECKODn;
}
else
+ {
return error("(Dn) error");
+ }
+
+ if (*tok == '*')
+ { // scale: *1, *2, *4, *8
+ tok++;
+
+ if (*tok == SYMBOL)
+ {
+ if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ return error("scale factor expression must evaluate");
+ switch (AnEXVAL)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
+ }
+ else if (*tok++ != CONST || *tok > 8)
+ goto badmode;
+ else
+ {
+ switch ((int)*tok++)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
+ }
+ }
if (*tok == ')')
{
AMn = MEMPOST;
goto AnOK;
}
+ else if (*tok==',')
+ {
+ tok++; // eat the comma
+ // It might be (Dn[.wl][*scale],od)
+ // Maybe this is wrong and we have to write some code here
+ // instead of reusing that path...
+ goto CHECKODn;
+ }
else
return error("unhandled so far");
}
}
if (*tok == '*')
- { // scale: *1, *2, *4, *8
+ { // scale: *1, *2, *4, *8
tok++;
- if (*tok++ != CONST || *tok > 8)
- goto badmode;
-
- switch ((int)*tok++)
- {
- case 1:
- break;
- case 2:
- AnIXSIZ |= TIMES2;
- break;
- case 4:
- AnIXSIZ |= TIMES4;
- break;
- case 8:
- AnIXSIZ |= TIMES8;
- break;
- default:
+ if (*tok == SYMBOL)
+ {
+ if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ return error("scale factor expression must evaluate");
+ switch (AnEXVAL)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
+ }
+ else if (*tok++ != CONST || *tok > 8)
goto badmode;
+ else
+ {
+ switch ((int)*tok++)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
}
}
+ if (*tok == ',')
+ {
+ tok++;
+ goto CHECKODn;
+ }
if (*tok++ != ')') // final ")"
goto badmode;
// Check for scale
if (*tok == '*') // ([bd,An/PC],Xn*...)
- {
+ { // scale: *1, *2, *4, *8
tok++;
- if (*tok == CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
- tok++;
-
- switch ((int)*tok++)
+ if (*tok == SYMBOL)
{
- case 1:
- break;
- case 2:
- AnEXTEN |= EXT_TIMES2;
- break;
- case 4:
- AnEXTEN |= EXT_TIMES4;
- break;
- case 8:
- AnEXTEN |= EXT_TIMES8;
- break;
- default:
+ if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ return error("scale factor expression must evaluate");
+ switch (AnEXVAL)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
+ }
+ else if (*tok++ != CONST || *tok > 8)
goto badmode;
+ else
+ {
+ switch ((int)*tok++)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
}
}
-
if (*tok == ']') // ([bd,Dn]...
{
tok++;
if (*tok == ')')
{
//Xn and od are non existent, get out of jail free card
+ tok++;
AMn = MEMPRE; // ([bc,An,Xn],od) with no Xn and od
AnEXTEN |= EXT_IS | EXT_IISPREN; //Suppress Xn and od
- tok++;
goto AnOK;
}
else if (*tok != ',')
}
// Check for scale
- if (*tok == '*')
- {
- // ([bd,An/PC],Xn*...)
+ if (*tok == '*') // ([bd,An/PC],Xn*...)
+ { // scale: *1, *2, *4, *8
tok++;
- if (*tok == CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
- tok++;
-
- switch ((int)*tok++)
+ if (*tok == SYMBOL)
+ {
+ if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ return error("scale factor expression must evaluate");
+ switch (AnEXVAL)
{
case 1:
break;
case 2:
- AnEXTEN |= EXT_TIMES2;
+ AnIXSIZ |= TIMES2;
break;
case 4:
- AnEXTEN |= EXT_TIMES4;
+ AnIXSIZ |= TIMES4;
break;
case 8:
- AnEXTEN |= EXT_TIMES8;
+ AnIXSIZ |= TIMES8;
break;
default:
goto badmode;
+ }
+ }
+ else if (*tok++ != CONST || *tok > 8)
+ goto badmode;
+ else
+ {
+ switch ((int)*tok++)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
}
}
tok++; // eat the comma
CHECKODn:
-
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
goto badmode;
tok++;
goto AnOK;
}
-
// ([bd,An/PC],Xn,od)
if (*tok == DOTL)
{
// expr.L
AnEXTEN |= EXT_IISPOSL; // Long outer displacement
AMn = MEMPOST;
+ tok++;
// Defined, absolute values from $FFFF8000..$00007FFF get
// optimized to absolute short
// expr[.W][]
AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed
AMn = MEMPRE;
-
if (*tok == DOTW)
{
//AnEXTEN|=EXT_IISNOIW; // Word outer displacement
// Check for scale
if (*tok == '*') // ([bd,An/PC],Xn*...)
- {
+ { // scale: *1, *2, *4, *8
tok++;
- if (*tok == CONST) // TODO: I suppose the scale is stored as a CONST and nothing else? So prolly the if is not needed?
- tok++;
-
- switch ((int)*tok++)
+ if (*tok == SYMBOL)
{
- case 1:
- break;
- case 2:
- AnEXTEN |= EXT_TIMES2;
- break;
- case 4:
- AnEXTEN |= EXT_TIMES4;
- break;
- case 8:
- AnEXTEN |= EXT_TIMES8;
- break;
- default:
+ if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
+ return error("scale factor expression must evaluate");
+ switch (AnEXVAL)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
+ }
+ else if (*tok++ != CONST || *tok > 8)
goto badmode;
+ else
+ {
+ switch ((int)*tok++)
+ {
+ case 1:
+ break;
+ case 2:
+ AnIXSIZ |= TIMES2;
+ break;
+ case 4:
+ AnIXSIZ |= TIMES4;
+ break;
+ case 8:
+ AnIXSIZ |= TIMES8;
+ break;
+ default:
+ goto badmode;
+ }
}
}
//Check for ]
if (*tok != ']')
return error("Expected closing bracket ]");
-
tok++; // Eat the bracket
//Check for od
// After a cache keyword only a comma or EOL is allowed
if ((*tok != ',') && (*tok != EOL))
return ERROR;
-
goto AnOK;
}
else if ((*tok >= KW_SFC) && (*tok <= KW_CRP))