- NX M_FREG M_AM_NONE %1111001000eeeeee m_fmod
fmove NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fmove +
- NBWLSQXP M_FREG C_ALL030 %1111001000eeeeee m_fmove +
-- NBWLSQXP M_FREG M_FREG %1111001000eeeeee m_fmove +
+- NX M_FREG M_FREG %1111001000eeeeee m_fmove +
- NL M_FPSCR C_ALL030 %1111001000eeeeee m_fmovescr +
- NL C_ALL030 M_FPSCR %1111001000eeeeee m_fmovescr +
fsmove NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_fsmove
- NX M_FREG M_FREG %1111001000eeeeee m_ftentox +
- NX M_FREG M_AM_NONE %1111001000eeeeee m_ftentox
ftst NBWLSQXP C_ALL030 M_AM_NONE %1111001000eeeeee m_ftst +
-- X M_FREG M_AM_NONE %1111001000eeeeee m_ftst
+- NX M_FREG M_AM_NONE %1111001000eeeeee m_ftst
ftwotox NBWLSQXP C_ALL030 M_FREG %1111001000eeeeee m_ftwotox +
- NX M_FREG M_FREG %1111001000eeeeee m_ftwotox +
- NX M_FREG M_AM_NONE %1111001000eeeeee m_ftwotox
jmp N C_CTRL M_AM_NONE %0100111011eee000 m_ea +
- N C_CTRL030 M_AM_NONE %0100111011eee000 m_ea030
-jsr N C_CTRL M_AM_NONE %0100111010eee000 m_ea
+jsr N C_CTRL M_AM_NONE %0100111010eee000 m_ea +
+- N C_CTRL030 M_AM_NONE %0100111010eee000 m_ea030
lea NL C_CTRL M_AREG %0100rrr111eR1000 m_lea
// Reject invalud ea modes
amsk = amsktab[am0];
- if (amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE) == 0)
+ if ((amsk & (M_AIND | M_APOSTINC | M_APREDEC | M_ADISP | M_AINDEXED | M_ABSW | M_ABSL | M_ABASE | M_MEMPOST | M_MEMPRE)) == 0)
return error("unsupported addressing mode");
inst |= am0 | a0reg;
int m_cas2(WORD inst, WORD siz)
{
WORD inst2, inst3;
- LONG amsk;
if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
return error(unsupport);
{
inst |= (1 << 6);
D_word(inst);
- WARNING(check what s "optional coprocessor-defined extension words!")
D_long(v);
return OK;
}
return error(range_error);
D_word(inst);
- WARNING(check what s "optional coprocessor-defined extension words!")
D_word(v);
}
inst |= am1 | a1reg; // Get ea1 into instr
D_word(inst); // Deposit instr
+ // Extension word
+ inst = a1reg + (a2reg << 12) + (1 << 11);
+ inst |= mulmode; // add size bit
+ D_word(inst);
+
// Generate ea0 if requested
if (flg & 2)
ea0gen(siz);
// Use am0
inst |= am0 | a0reg; // Get ea0 into instr
D_word(inst); // Deposit instr
+ // Extension word
+ inst = a1reg + (a2reg << 12) + (1 << 11);
+ inst |= mulmode; // add size bit
+ D_word(inst);
+
ea0gen(siz); // Generate ea0
// Generate ea1 if requested
ea1gen(siz);
}
- inst = a1reg + (a2reg << 12) + (1 << 11);
- inst |= mulmode; // add size bit
- D_word(inst);
+ //D_word(inst);
+ //ea0gen(siz);
return OK;
}
}
D_word(B16(10100000, 00000000));
+ return OK;
}
// EA to register
if ((am0 == FREG) && (am1 < AM_USP))
{
+ //fpx->ea
// EA
inst |= am1 | a1reg;
D_word(inst);
}
else if ((am0 < AM_USP) && (am1 == FREG))
{
+ //ea->fpx
+
// EA
inst |= am0 | a0reg;
D_word(inst);
}
else if ((am0 == FREG) && (am1 == FREG))
{
+ // register-to-register
+ // Essentially ea to register with R/0=0
+
// EA
D_word(inst);
WORD regmask;
WORD datareg;
- if (siz == SIZX)
+ if (siz == SIZX || siz==SIZN)
{
if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
{
- // fmovem.x <rlist>,ea
+ //fmovem.x <rlist>,ea
if (fpu_reglist_left(®mask) < 0)
return OK;
}
}
}
- else if ((siz == SIZL) || (siz==SIZN))
+ else if (siz == SIZL)
{
if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
{
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))