Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* code68k.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator 680x0-Familie                                               */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "bpemu.h"
  17. #include "be_le.h"
  18. #include "ieeefloat.h"
  19. #include "strutil.h"
  20. #include "asmdef.h"
  21. #include "asmsub.h"
  22. #include "asmpars.h"
  23. #include "asmallg.h"
  24. #include "onoff_common.h"
  25. #include "asmcode.h"
  26. #include "motpseudo.h"
  27. #include "asmitree.h"
  28. #include "codevars.h"
  29. #include "errmsg.h"
  30. #include "codepseudo.h"
  31.  
  32. #include "code68k.h"
  33.  
  34. typedef enum
  35. {
  36.   e68KGen1a, /* 68008/68000 */
  37.   e68KGen1b, /* 68010/68012 */
  38.   eColdfire,
  39.   eCPU32,
  40.   e68KGen2,  /* 68020/68030 */
  41.   e68KGen3   /* 68040 */
  42. } tFamily;
  43.  
  44. typedef enum
  45. {
  46.   eCfISA_None,
  47.   eCfISA_A,
  48.   eCfISA_APlus,
  49.   eCfISA_B,
  50.   eCfISA_C
  51. } tCfISA;
  52.  
  53. typedef enum
  54. {
  55.   eFlagNone = 0,
  56.   eFlagLogCCR = 1 << 0,
  57.   eFlagIdxScaling = 1 << 1,
  58.   eFlagCALLM_RTM = 1 << 2,
  59.   eFlagIntFPU = 1 << 3,
  60.   eFlagExtFPU = 1 << 4,
  61.   eFlagIntPMMU = 1 << 5,
  62.   eFlagBranch32 = 1 << 6,
  63.   eFlagMAC = 1 << 7,
  64.   eFlagEMAC = 1 << 8
  65. } tSuppFlags;
  66.  
  67. #define eSymbolSizeShiftCnt ((tSymbolSize)8)
  68.  
  69. #ifdef __cplusplus
  70. # include "code68k.hpp"
  71. #endif
  72.  
  73. enum
  74. {
  75.   Std_Variant = 0,
  76.   I_Variant = 4,
  77.   A_Variant = 8,
  78.   VariantMask = 12
  79. };
  80.  
  81. typedef struct
  82. {
  83.   const char *Name;
  84.   Word Code;
  85. } tCtReg;
  86.  
  87. #define MAX_CTREGS_GROUPS 4
  88.  
  89. typedef struct
  90. {
  91.   const char *pName;
  92.   LongWord AddrSpaceMask;
  93.   tFamily Family;
  94.   tCfISA CfISA;
  95.   tSuppFlags SuppFlags;
  96.   const tCtReg *pCtRegs[MAX_CTREGS_GROUPS];
  97. } tCPUProps;
  98.  
  99. typedef struct
  100. {
  101.   Word Code;
  102.   Boolean MustSup;
  103.   Word FamilyMask;
  104. } FixedOrder;
  105.  
  106. typedef struct
  107. {
  108.   Byte Code;
  109.   Boolean Dya;
  110.   tSuppFlags NeedsSuppFlags;
  111. } FPUOp;
  112.  
  113. typedef struct
  114. {
  115.   const char *pName;
  116.   tSymbolSize Size;
  117.   Word Code;
  118. } PMMUReg;
  119.  
  120. #define EMACAvailName  "HASEMAC"
  121.  
  122. #define REG_SP 15
  123. #define REG_FPCTRL 8
  124. #define REG_FPCR 4
  125. #define REG_FPSR 2
  126. #define REG_FPIAR 1
  127.  
  128. typedef enum
  129. {
  130.   ModNone = 0,
  131.   ModData = 1,
  132.   ModAdr = 2,
  133.   ModAdrI = 3,
  134.   ModPost = 4,
  135.   ModPre = 5,
  136.   ModDAdrI = 6,
  137.   ModAIX = 7,
  138.   ModPC = 8,
  139.   ModPCIdx = 9,
  140.   ModAbs = 10,
  141.   ModImm = 11,
  142.   ModFPn = 12,
  143.   ModFPCR = 13
  144. } adrmode_t;
  145.  
  146. enum
  147. {
  148.   MModData = 1 << (ModData - 1),
  149.   MModAdr = 1 << (ModAdr - 1),
  150.   MModAdrI = 1 << (ModAdrI - 1),
  151.   MModPost = 1 << (ModPost - 1),
  152.   MModPre = 1 << (ModPre - 1),
  153.   MModDAdrI = 1 << (ModDAdrI - 1),
  154.   MModAIX = 1 << (ModAIX - 1),
  155.   MModPC = 1 << (ModPC - 1),
  156.   MModPCIdx = 1 << (ModPCIdx - 1),
  157.   MModAbs = 1 << (ModAbs - 1),
  158.   MModImm = 1 << (ModImm - 1),
  159.   MModFPn = 1 << (ModFPn - 1),
  160.   MModFPCR = 1 << (ModFPCR - 1)
  161. };
  162.  
  163. typedef struct
  164. {
  165.   adrmode_t AdrMode;
  166.   Word AdrPart;
  167.   Word Vals[10];
  168.   tSymbolFlags ImmSymFlags;
  169.   int Cnt;
  170. } tAdrResult;
  171.  
  172. static tSymbolSize OpSize;
  173. static ShortInt RelPos;
  174. static Boolean FullPMMU;                /* voller PMMU-Befehlssatz? */
  175.  
  176. static FixedOrder *FixedOrders;
  177. static FPUOp *FPUOps;
  178. static PMMUReg *PMMURegs;
  179.  
  180. static const tCPUProps *pCurrCPUProps;
  181. static tSymbolSize NativeFloatSize;
  182.  
  183. static const Byte FSizeCodes[10] =
  184. {
  185.   6, 4, 0, 7, 0, 1, 5, 2, 0, 3
  186. };
  187.  
  188. /*-------------------------------------------------------------------------*/
  189. /* Unterroutinen */
  190.  
  191. #define CopyAdrVals(Dest, pAdrResult) memcpy(Dest, (pAdrResult)->Vals, (pAdrResult)->Cnt)
  192.  
  193. static Boolean CheckFamilyCore(unsigned FamilyMask)
  194. {
  195.   return !!((FamilyMask >> pCurrCPUProps->Family) & 1);
  196. }
  197.  
  198. static Boolean CheckFamily(unsigned FamilyMask)
  199. {
  200.   if (CheckFamilyCore(FamilyMask))
  201.     return True;
  202.   WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  203.   CodeLen = 0;
  204.   return False;
  205. }
  206.  
  207. static Boolean CheckISA(unsigned ISAMask)
  208. {
  209.   if ((ISAMask >> pCurrCPUProps->CfISA) & 1)
  210.     return True;
  211.   WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  212.   CodeLen = 0;
  213.   return False;
  214. }
  215.  
  216. static Boolean CheckNoFamily(unsigned FamilyMask)
  217. {
  218.   if (!CheckFamilyCore(FamilyMask))
  219.     return True;
  220.   WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  221.   CodeLen = 0;
  222.   return False;
  223. }
  224.  
  225. static void CheckSup(void)
  226. {
  227.   if (!SupAllowed)
  228.     WrStrErrorPos(ErrNum_PrivOrder, &OpPart);
  229. }
  230.  
  231. static Boolean CheckColdSize(void)
  232. {
  233.   if ((OpSize > eSymbolSize32Bit) || ((pCurrCPUProps->Family == eColdfire) && (OpSize < eSymbolSize32Bit)))
  234.   {
  235.     WrError(ErrNum_InvOpSize);
  236.     return False;
  237.   }
  238.   else
  239.     return True;
  240. }
  241.  
  242. static Boolean CheckFloatSize(void)
  243. {
  244.   if (!*AttrPart.str.p_str)
  245.     OpSize = NativeFloatSize;
  246.  
  247.   switch (OpSize)
  248.   {
  249.     case eSymbolSize8Bit:
  250.     case eSymbolSize16Bit:
  251.     case eSymbolSize32Bit:
  252.     case eSymbolSizeFloat32Bit:
  253.     case eSymbolSizeFloat64Bit:
  254.       return True;
  255.     case eSymbolSizeFloat96Bit:
  256.     case eSymbolSizeFloatDec96Bit:
  257.       if (pCurrCPUProps->Family != eColdfire)
  258.         return True;
  259.       /* else fall-through */
  260.     default:
  261.       WrError(ErrNum_InvOpSize);
  262.       return False;
  263.   }
  264. }
  265.  
  266. static Boolean FloatOpSizeFitsDataReg(tSymbolSize OpSize)
  267. {
  268.   return (OpSize <= eSymbolSize32Bit) || (OpSize == eSymbolSizeFloat32Bit);
  269. }
  270.  
  271. static Boolean ValReg(char Ch)
  272. {
  273.   return ((Ch >= '0') && (Ch <= '7'));
  274. }
  275.  
  276. /*-------------------------------------------------------------------------*/
  277. /* Register Symbols */
  278.  
  279. /*!------------------------------------------------------------------------
  280.  * \fn     DecodeRegCore(const char *pArg, Word *pResult)
  281.  * \brief  check whether argument is a CPU register
  282.  * \param  pArg argument to check
  283.  * \param  pResult numeric register value if yes
  284.  * \return True if yes
  285.  * ------------------------------------------------------------------------ */
  286.  
  287. static Boolean DecodeRegCore(const char *pArg, Word *pResult)
  288. {
  289.   if (!as_strcasecmp(pArg, "SP"))
  290.   {
  291.     *pResult = REG_SP | REGSYM_FLAG_ALIAS;
  292.     return True;
  293.   }
  294.  
  295.   if (strlen(pArg) != 2)
  296.     return False;
  297.   if ((*pResult = pArg[1] - '0') > 7)
  298.     return False;
  299.  
  300.   switch (as_toupper(*pArg))
  301.   {
  302.     case 'D':
  303.       return True;
  304.     case 'A':
  305.       *pResult |= 8;
  306.       return True;
  307.     default:
  308.       return False;
  309.   }
  310. }
  311.  
  312. /*!------------------------------------------------------------------------
  313.  * \fn     DecodeFPRegCore(const char *pArg, Word *pResult)
  314.  * \brief  check whether argument is an FPU register
  315.  * \param  pArg argument to check
  316.  * \param  pResult numeric register value if yes
  317.  * \return True if yes
  318.  * ------------------------------------------------------------------------ */
  319.  
  320. static Boolean DecodeFPRegCore(const char *pArg, Word *pResult)
  321. {
  322.   if (!as_strcasecmp(pArg, "FPCR"))
  323.   {
  324.     *pResult = REG_FPCTRL | REG_FPCR;
  325.     return True;
  326.   }
  327.   if (!as_strcasecmp(pArg, "FPSR"))
  328.   {
  329.     *pResult = REG_FPCTRL | REG_FPSR;
  330.     return True;
  331.   }
  332.   if (!as_strcasecmp(pArg, "FPIAR"))
  333.   {
  334.     *pResult = REG_FPCTRL | REG_FPIAR;
  335.     return True;
  336.   }
  337.  
  338.   if (strlen(pArg) != 3)
  339.     return False;
  340.   if (as_strncasecmp(pArg, "FP", 2))
  341.     return False;
  342.   if ((*pResult = pArg[2] - '0') > 7)
  343.     return False;
  344.   return True;
  345. }
  346.  
  347. /*!------------------------------------------------------------------------
  348.  * \fn     DissectReg_68K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  349.  * \brief  dissect register symbols - 68K variant
  350.  * \param  pDest destination buffer
  351.  * \param  DestSize destination buffer size
  352.  * \param  Value numeric register value
  353.  * \param  InpSize register size
  354.  * ------------------------------------------------------------------------ */
  355.  
  356. static void DissectReg_68K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  357. {
  358.   if (InpSize == NativeFloatSize)
  359.   {
  360.     switch (Value)
  361.     {
  362.       case REG_FPCTRL | REG_FPCR:
  363.         as_snprintf(pDest, DestSize, "FPCR");
  364.         break;
  365.       case REG_FPCTRL | REG_FPSR:
  366.         as_snprintf(pDest, DestSize, "FPSR");
  367.         break;
  368.       case REG_FPCTRL | REG_FPIAR:
  369.         as_snprintf(pDest, DestSize, "FPIAR");
  370.         break;
  371.       default:
  372.         as_snprintf(pDest, DestSize, "FP%u", (unsigned)Value);
  373.     }
  374.   }
  375.   else if (InpSize == eSymbolSize32Bit)
  376.   {
  377.     switch (Value)
  378.     {
  379.       case REGSYM_FLAG_ALIAS | REG_SP:
  380.         as_snprintf(pDest, DestSize, "SP");
  381.         break;
  382.       default:
  383.         as_snprintf(pDest, DestSize, "%c%u", Value & 8 ? 'A' : 'D', (unsigned)(Value & 7));
  384.     }
  385.   }
  386.   else
  387.     as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  388. }
  389.  
  390. /*!------------------------------------------------------------------------
  391.  * \fn     compare_reg_68k(tRegInt reg1_num, tSymbolSize reg1_size, tRegInt reg2_num, tRegInt reg2_size)
  392.  * \brief  compare two register symbols
  393.  * \param  reg1_num 1st register's number
  394.  * \param  reg1_size 1st register's data size
  395.  * \param  reg2_num 2nd register's number
  396.  * \param  reg2_size 2nd register's data size
  397.  * \return 0, -1, 1, -2
  398.  * ------------------------------------------------------------------------ */
  399.  
  400. static int compare_reg_68k(tRegInt reg1_num, tSymbolSize reg1_size, tRegInt reg2_num, tSymbolSize reg2_size)
  401. {
  402.   /* FP and Integer registers in different register files: */
  403.  
  404.   if (reg1_size != reg2_size)
  405.     return -2;
  406.  
  407.   if (reg1_size == NativeFloatSize)
  408.   {
  409.     /* only FP data registers have an ordering: */
  410.  
  411.     if ((reg1_num & REG_FPCTRL) || (reg2_num & REG_FPCTRL))
  412.       return (reg1_num == reg2_num) ? 0 : -2;
  413.   }
  414.   else if (reg1_size == eSymbolSize32Bit)
  415.   {
  416.     reg1_num &= ~REGSYM_FLAG_ALIAS;
  417.     reg2_num &= ~REGSYM_FLAG_ALIAS;
  418.   }
  419.  
  420.   if (reg1_num < reg2_num)
  421.     return -1;
  422.   else if (reg1_num > reg2_num)
  423.     return 1;
  424.   else
  425.     return 0;
  426. }
  427.  
  428. /*-------------------------------------------------------------------------*/
  429. /* Adressparser */
  430.  
  431. typedef enum
  432. {
  433.   PC, AReg, Index, indir, Disp, None
  434. } CompType;
  435.  
  436. /* static const char *CompNames[] = { "PC", "AReg", "Index", "indir", "Disp", "None" }; */
  437.  
  438. typedef struct
  439. {
  440.   tStrComp Comp;
  441.   CompType Art;
  442.   Word ANummer, INummer;
  443.   Boolean Long;
  444.   Word Scale;
  445.   ShortInt Size;
  446.   LongInt Wert;
  447. } AdrComp;
  448.  
  449. static void ClrAdrVals(tAdrResult *pResult)
  450. {
  451.   pResult->AdrMode = ModNone;
  452.   pResult->Cnt = 0;
  453. }
  454.  
  455. static Boolean ACheckFamily(unsigned FamilyMask, const tStrComp *pAdrComp, tAdrResult *pResult)
  456. {
  457.   if (CheckFamilyCore(FamilyMask))
  458.     return True;
  459.   WrStrErrorPos(ErrNum_AddrModeNotSupported, pAdrComp);
  460.   ClrAdrVals(pResult);
  461.   return False;
  462. }
  463.  
  464. /*!------------------------------------------------------------------------
  465.  * \fn     DecodeReg(const tStrComp *pArg, Word *pErg, Boolean MustBeReg)
  466.  * \brief  check whether argument is a CPU register or register alias
  467.  * \param  pArg argument to check
  468.  * \param  pResult numeric register value if yes
  469.  * \param  MustBeReg argument is expected to be a register
  470.  * \return RegEvalResult
  471.  * ------------------------------------------------------------------------ */
  472.  
  473. static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pResult, Boolean MustBeReg)
  474. {
  475.   tRegDescr RegDescr;
  476.   tEvalResult EvalResult;
  477.   tRegEvalResult RegEvalResult;
  478.  
  479.   if (DecodeRegCore(pArg->str.p_str, pResult))
  480.   {
  481.     *pResult &= ~REGSYM_FLAG_ALIAS;
  482.     return eIsReg;
  483.   }
  484.  
  485.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize32Bit, MustBeReg);
  486.   *pResult = RegDescr.Reg & ~REGSYM_FLAG_ALIAS;
  487.   return RegEvalResult;
  488. }
  489.  
  490. /*!------------------------------------------------------------------------
  491.  * \fn     DecodeFPReg(const tStrComp *pArg, Word *pResult, Boolean MustBeReg)
  492.  * \brief  check whether argument is a FPU register or register alias
  493.  * \param  pArg argument to check
  494.  * \param  pResult numeric register value if yes
  495.  * \param  MustBeReg argument is expected to be a register
  496.  * \return RegEvalResult
  497.  * ------------------------------------------------------------------------ */
  498.  
  499. static tRegEvalResult DecodeFPReg(const tStrComp *pArg, Word *pResult, Boolean MustBeReg)
  500. {
  501.   tRegDescr RegDescr;
  502.   tEvalResult EvalResult;
  503.   tRegEvalResult RegEvalResult;
  504.  
  505.   if (DecodeFPRegCore(pArg->str.p_str, pResult))
  506.   {
  507.     *pResult &= ~REGSYM_FLAG_ALIAS;
  508.     return eIsReg;
  509.   }
  510.  
  511.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, NativeFloatSize, MustBeReg);
  512.   *pResult = RegDescr.Reg;
  513.   return RegEvalResult;
  514. }
  515.  
  516. /*!------------------------------------------------------------------------
  517.  * \fn     DecodeRegOrFPReg(const tStrComp *pArg, Word *pErg, tSymbolSize *pSize, Boolean MustBeReg)
  518.  * \brief  check whether argument is an CPU/FPU register or register alias
  519.  * \param  pArg argument to check
  520.  * \param  pResult numeric register value if yes
  521.  * \param  pSize size of register if yes
  522.  * \param  MustBeReg argument is expected to be a register
  523.  * \return RegEvalResult
  524.  * ------------------------------------------------------------------------ */
  525.  
  526. static tRegEvalResult DecodeRegOrFPReg(const tStrComp *pArg, Word *pResult, tSymbolSize *pSize, Boolean MustBeReg)
  527. {
  528.   tRegDescr RegDescr;
  529.   tEvalResult EvalResult;
  530.   tRegEvalResult RegEvalResult;
  531.  
  532.   if (DecodeRegCore(pArg->str.p_str, pResult))
  533.   {
  534.     *pResult &= ~REGSYM_FLAG_ALIAS;
  535.     *pSize = eSymbolSize32Bit;
  536.     return eIsReg;
  537.   }
  538.   if (DecodeFPRegCore(pArg->str.p_str, pResult))
  539.   {
  540.     *pSize = NativeFloatSize;
  541.     return eIsReg;
  542.   }
  543.  
  544.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
  545.   *pResult = RegDescr.Reg & ~REGSYM_FLAG_ALIAS;
  546.   *pSize = EvalResult.DataSize;
  547.   return RegEvalResult;
  548. }
  549.  
  550. static Boolean DecodeRegPair(tStrComp *pArg, Word *Erg1, Word *Erg2)
  551. {
  552.   char *pSep = strchr(pArg->str.p_str, ':');
  553.   tStrComp Left, Right;
  554.  
  555.   if (!pSep)
  556.     return False;
  557.   StrCompSplitRef(&Left, &Right, pArg, pSep);
  558.   return (DecodeReg(&Left, Erg1, False) == eIsReg)
  559.       && (*Erg1 <= 7)
  560.       && (DecodeReg(&Right, Erg2, False) == eIsReg)
  561.       && (*Erg2 <= 7);
  562. }
  563.  
  564. static Boolean CodeIndRegPair(tStrComp *pArg, Word *Erg1, Word *Erg2)
  565. {
  566.   char *pSep = strchr(pArg->str.p_str, ':');
  567.   tStrComp Left, Right;
  568.  
  569.   if (!pSep)
  570.     return False;
  571.   StrCompSplitRef(&Left, &Right, pArg, pSep);
  572.  
  573.   if (!IsIndirect(Left.str.p_str) || !IsIndirect(Right.str.p_str))
  574.     return False;
  575.   StrCompShorten(&Left, 1);
  576.   StrCompIncRefLeft(&Left, 1);
  577.   StrCompShorten(&Right, 1);
  578.   StrCompIncRefLeft(&Right, 1);
  579.  
  580.   return (DecodeReg(&Left, Erg1, False) == eIsReg)
  581.       && (DecodeReg(&Right, Erg2, False) == eIsReg);
  582. }
  583.  
  584. static Boolean CodeCache(char *Asc, Word *Erg)
  585. {
  586.    if (!as_strcasecmp(Asc, "IC"))
  587.      *Erg = 2;
  588.    else if (!as_strcasecmp(Asc, "DC"))
  589.      *Erg = 1;
  590.    else if (!as_strcasecmp(Asc, "IC/DC"))
  591.      *Erg = 3;
  592.    else if (!as_strcasecmp(Asc, "DC/IC"))
  593.      *Erg = 3;
  594.    else
  595.      return False;
  596.    return True;
  597. }
  598.  
  599. static Boolean DecodeCtrlReg(char *Asc, Word *Erg)
  600. {
  601.   int Grp;
  602.   String Asc_N;
  603.   const tCtReg *pReg;
  604.  
  605.   strmaxcpy(Asc_N, Asc, STRINGSIZE);
  606.   NLS_UpString(Asc_N);
  607.   Asc = Asc_N;
  608.  
  609.   for (Grp = 0; Grp < MAX_CTREGS_GROUPS; Grp++)
  610.   {
  611.     pReg = pCurrCPUProps->pCtRegs[Grp];
  612.     if (!pReg)
  613.       return False;
  614.     for (; pReg->Name; pReg++)
  615.       if (!strcmp(pReg->Name, Asc))
  616.       {
  617.         *Erg = pReg->Code;
  618.         return True;
  619.       }
  620.   }
  621.   return False;
  622. }
  623.  
  624. static Boolean OneField(const tStrComp *pArg, Word *Erg, Boolean Ab1)
  625. {
  626.   switch (DecodeReg(pArg, Erg, False))
  627.   {
  628.     case eIsReg:
  629.       if (*Erg > 7)
  630.         return False;
  631.       *Erg |= 0x20;
  632.       return True;
  633.     case eIsNoReg:
  634.     {
  635.       Boolean ValOK;
  636.  
  637.       *Erg = EvalStrIntExpression(pArg, Int8, &ValOK);
  638.       if (Ab1 && (*Erg == 32))
  639.         *Erg = 0;
  640.       return (ValOK && (*Erg < 32));
  641.     }
  642.     default:
  643.       return False;
  644.   }
  645. }
  646.  
  647. static Boolean SplitBitField(tStrComp *pArg, Word *Erg)
  648. {
  649.   char *p;
  650.   Word OfsVal;
  651.   tStrComp FieldArg, OffsArg, WidthArg;
  652.  
  653.   p = strchr(pArg->str.p_str, '{');
  654.   if (!p)
  655.     return False;
  656.   StrCompSplitRef(pArg, &FieldArg, pArg, p);
  657.   if ((!*FieldArg.str.p_str) || (FieldArg.str.p_str[strlen(FieldArg.str.p_str) - 1] != '}'))
  658.     return False;
  659.   StrCompShorten(&FieldArg, 1);
  660.  
  661.   p = strchr(FieldArg.str.p_str, ':');
  662.   if (!p)
  663.     return False;
  664.   StrCompSplitRef(&OffsArg, &WidthArg, &FieldArg, p);
  665.   if (!OneField(&OffsArg, &OfsVal, False))
  666.     return False;
  667.   if (!OneField(&WidthArg, Erg, True))
  668.     return False;
  669.   *Erg += OfsVal << 6;
  670.   return True;
  671. }
  672.  
  673. static Boolean SplitSize(tStrComp *pArg, ShortInt *DispLen, unsigned OpSizeMask)
  674. {
  675.   ShortInt NewLen = -1;
  676.   int ArgLen = strlen(pArg->str.p_str);
  677.  
  678.   if ((ArgLen > 2) && (pArg->str.p_str[ArgLen - 2] == '.'))
  679.   {
  680.     switch (as_toupper(pArg->str.p_str[ArgLen - 1]))
  681.     {
  682.       case 'B':
  683.         if (OpSizeMask & 1)
  684.           NewLen = 0;
  685.         else
  686.           goto wrong;
  687.         break;
  688.       case 'W':
  689.         if (OpSizeMask & 2)
  690.           NewLen = 1;
  691.         else
  692.           goto wrong;
  693.         break;
  694.       case 'L':
  695.         if (OpSizeMask & 2)
  696.           NewLen = 2;
  697.         else
  698.           goto wrong;
  699.         break;
  700.       default:
  701.       wrong:
  702.         WrError(ErrNum_InvOpSize);
  703.         return False;
  704.     }
  705.     if ((*DispLen != -1) && (*DispLen != NewLen))
  706.     {
  707.       WrError(ErrNum_ConfOpSizes);
  708.       return False;
  709.     }
  710.     *DispLen = NewLen;
  711.     StrCompShorten(pArg, 2);
  712.   }
  713.  
  714.   return True;
  715. }
  716.  
  717. static Boolean ClassComp(AdrComp *C)
  718. {
  719.   int comp_len = strlen(C->Comp.str.p_str), reg_len;
  720.   char save, c_scale, c_size;
  721.  
  722.   C->Art = None;
  723.   C->ANummer = C->INummer = 0;
  724.   C->Long = False;
  725.   C->Scale = 0;
  726.   C->Size = -1;
  727.   C->Wert = 0;
  728.  
  729.   if ((*C->Comp.str.p_str == '[') && (C->Comp.str.p_str[comp_len - 1] == ']'))
  730.   {
  731.     C->Art = indir;
  732.     return True;
  733.   }
  734.  
  735.   if (!as_strcasecmp(C->Comp.str.p_str, "PC"))
  736.   {
  737.     C->Art = PC;
  738.     return True;
  739.   }
  740.  
  741.   /* assume register, splitting off scale & size first: */
  742.  
  743.   reg_len = comp_len;
  744.   c_scale = c_size = '\0';
  745.   if ((reg_len > 2) && (C->Comp.str.p_str[reg_len - 2] == '*'))
  746.   {
  747.     c_scale = C->Comp.str.p_str[reg_len - 1];
  748.     reg_len -= 2;
  749.   }
  750.   if ((reg_len > 2) && (C->Comp.str.p_str[reg_len - 2] == '.'))
  751.   {
  752.     c_size = C->Comp.str.p_str[reg_len - 1];
  753.     reg_len -= 2;
  754.   }
  755.   save = C->Comp.str.p_str[reg_len];
  756.   C->Comp.str.p_str[reg_len] = '\0';
  757.   switch (DecodeReg(&C->Comp, &C->ANummer, False))
  758.   {
  759.     case eRegAbort:
  760.       return False;
  761.     case eIsReg:
  762.       C->Comp.str.p_str[reg_len] = save;
  763.       break;
  764.     default: /* eIsNoReg */
  765.       C->Comp.str.p_str[reg_len] = save;
  766.       goto is_disp;
  767.   }
  768.  
  769.   /* OK, we know it's a register, with optional scale & size: */
  770.  
  771.   if ((C->ANummer > 7) && !c_scale && !c_size)
  772.   {
  773.     C->Art = AReg;
  774.     C->ANummer -= 8;
  775.     return True;
  776.   }
  777.  
  778.   if (c_size)
  779.   {
  780.     switch (as_toupper(c_size))
  781.     {
  782.       case 'L':
  783.         C->Long = True;
  784.         break;
  785.       case 'W':
  786.         C->Long = False;
  787.         break;
  788.       default:
  789.         return False;
  790.     }
  791.   }
  792.   else
  793.     C->Long = (pCurrCPUProps->Family == eColdfire);
  794.  
  795.   if (c_scale)
  796.   {
  797.     switch (c_scale)
  798.     {
  799.       case '1':
  800.         C->Scale = 0;
  801.         break;
  802.       case '2':
  803.         C->Scale = 1;
  804.         break;
  805.       case '4':
  806.         C->Scale = 2;
  807.         break;
  808.       case '8':
  809.         if (pCurrCPUProps->Family == eColdfire)
  810.           return False;
  811.         C->Scale = 3;
  812.         break;
  813.       default:
  814.         return False;
  815.     }
  816.   }
  817.   else
  818.     C->Scale = 0;
  819.   C->INummer = C->ANummer;
  820.   C->Art = Index;
  821.   return True;
  822.  
  823. is_disp:
  824.   C->Art = Disp;
  825.   if ((comp_len >= 2) && (C->Comp.str.p_str[comp_len - 2] == '.'))
  826.   {
  827.     switch (as_toupper(C->Comp.str.p_str[comp_len - 1]))
  828.     {
  829.       case 'L':
  830.         C->Size = 2;
  831.         break;
  832.       case 'W':
  833.         C->Size = 1;
  834.         break;
  835.       default:
  836.         return False;
  837.     }
  838.     StrCompShorten(&C->Comp, 2);
  839.   }
  840.   else
  841.     C->Size = -1;
  842.   C->Art = Disp;
  843.   return True;
  844. }
  845.  
  846. static void SwapAdrComps(AdrComp *pComp1, AdrComp *pComp2)
  847. {
  848.   AdrComp Tmp;
  849.  
  850.   Tmp = *pComp1;
  851.   *pComp1 = *pComp2;
  852.   *pComp2 = Tmp;
  853. }
  854.  
  855. static void AdrCompToIndex(AdrComp *pComp)
  856. {
  857.   pComp->Art = Index;
  858.   pComp->INummer = pComp->ANummer + 8;
  859.   pComp->Long = False;
  860.   pComp->Scale = 0;
  861. }
  862.  
  863. static Boolean IsShortAdr(LongInt Addr)
  864. {
  865.   LongWord OrigAddr = (LongWord)Addr, ExtAddr;
  866.  
  867.   /* Assuming we would code this address as short address... */
  868.  
  869.   ExtAddr = OrigAddr & 0xffff;
  870.   if (ExtAddr & 0x8000)
  871.     ExtAddr |= 0xffff0000ul;
  872.  
  873.   /* ...would this result in the same address on the bus? */
  874.  
  875.   return (ExtAddr & pCurrCPUProps->AddrSpaceMask) == (OrigAddr & pCurrCPUProps->AddrSpaceMask);
  876. }
  877.  
  878. static Boolean IsDisp8(LongInt Disp)
  879. {
  880.   return ((Disp >= -128) && (Disp <= 127));
  881. }
  882.  
  883. static Boolean IsDisp16(LongInt Disp)
  884. {
  885.   return ((Disp >= -32768) && (Disp <= 32767));
  886. }
  887.  
  888. ShortInt GetDispLen(LongInt Disp)
  889. {
  890.   if (IsDisp8(Disp))
  891.     return 0;
  892.   else if (IsDisp16(Disp))
  893.     return 1;
  894.   else
  895.     return 2;
  896. }
  897.  
  898. static void ChkEven(LongInt Adr)
  899. {
  900.   switch (pCurrCPUProps->Family)
  901.   {
  902.     case e68KGen1a:
  903.     case e68KGen1b:
  904.     case eColdfire:
  905.       if (Odd(Adr))
  906.         WrError(ErrNum_AddrNotAligned);
  907.       break;
  908.     default:
  909.       break;
  910.   }
  911. }
  912.  
  913. static void DecodeAbs(const tStrComp *pArg, ShortInt Size, tAdrResult *pResult)
  914. {
  915.   Boolean ValOK;
  916.   tSymbolFlags Flags;
  917.   LongInt HVal;
  918.   Integer HVal16;
  919.  
  920.   pResult->Cnt = 0;
  921.  
  922.   HVal = EvalStrIntExpressionWithFlags(pArg, Int32, &ValOK, &Flags);
  923.  
  924.   if (ValOK)
  925.   {
  926.     if (!mFirstPassUnknown(Flags) && (OpSize > eSymbolSize8Bit))
  927.       ChkEven(HVal);
  928.     HVal16 = HVal;
  929.  
  930.     if (Size == -1)
  931.       Size = (IsShortAdr(HVal)) ? 1 : 2;
  932.     pResult->AdrMode = ModAbs;
  933.  
  934.     if (Size == 1)
  935.     {
  936.       if (!IsShortAdr(HVal))
  937.       {
  938.         WrError(ErrNum_NoShortAddr);
  939.         pResult->AdrMode = ModNone;
  940.       }
  941.       else
  942.       {
  943.         pResult->AdrPart = 0x38;
  944.         pResult->Vals[0] = HVal16;
  945.         pResult->Cnt = 2;
  946.       }
  947.     }
  948.     else
  949.     {
  950.       pResult->AdrPart = 0x39;
  951.       pResult->Vals[0] = HVal >> 16;
  952.       pResult->Vals[1] = HVal & 0xffff;
  953.       pResult->Cnt = 4;
  954.     }
  955.   }
  956. }
  957.  
  958. static Byte DecodeAdr(const tStrComp *pArg, Word Erl, tAdrResult *pResult)
  959. {
  960.   Byte i;
  961.   int ArgLen;
  962.   char *p;
  963.   Word rerg;
  964.   Byte lklamm, rklamm, lastrklamm;
  965.   Boolean doklamm;
  966.  
  967.   AdrComp AdrComps[3], OneComp;
  968.   Byte CompCnt;
  969.   ShortInt OutDispLen = -1;
  970.   Boolean PreInd;
  971.  
  972.   LongInt HVal;
  973.   Integer HVal16;
  974.   ShortInt HVal8;
  975.   as_float_t DVal;
  976.   int ret;
  977.   Boolean ValOK;
  978.   tSymbolFlags Flags;
  979.   Word SwapField[6];
  980.   String ArgStr;
  981.   tStrComp Arg;
  982.   String CReg;
  983.   tStrComp CRegArg;
  984.   const unsigned ExtAddrFamilyMask = (1 << e68KGen3) | (1 << e68KGen2) | (1 << eCPU32);
  985.   IntType DispIntType;
  986.   tSymbolSize RegSize;
  987.  
  988.   /* some insns decode the same arg twice, so we must keep the original string intact. */
  989.  
  990.   StrCompMkTemp(&Arg, ArgStr, sizeof(ArgStr));
  991.   StrCompCopy(&Arg, pArg);
  992.   KillPrefBlanksStrComp(&Arg);
  993.   KillPostBlanksStrComp(&Arg);
  994.   ArgLen = strlen(Arg.str.p_str);
  995.   ClrAdrVals(pResult);
  996.  
  997.   StrCompMkTemp(&CRegArg, CReg, sizeof(CReg));
  998.  
  999.   /* immediate : */
  1000.  
  1001.   if (*Arg.str.p_str == '#')
  1002.   {
  1003.     tStrComp ImmArg;
  1004.  
  1005.     StrCompRefRight(&ImmArg, &Arg, 1);
  1006.     KillPrefBlanksStrComp(&ImmArg);
  1007.  
  1008.     pResult->AdrMode = ModImm;
  1009.     pResult->AdrPart = 0x3c;
  1010.     switch (OpSize)
  1011.     {
  1012.       case eSymbolSize8Bit:
  1013.         pResult->Cnt = 2;
  1014.         HVal8 = EvalStrIntExpressionWithFlags(&ImmArg, Int8, &ValOK, &pResult->ImmSymFlags);
  1015.         if (ValOK)
  1016.           pResult->Vals[0] = (Word)((Byte) HVal8);
  1017.         break;
  1018.       case eSymbolSize16Bit:
  1019.         pResult->Cnt = 2;
  1020.         HVal16 = EvalStrIntExpressionWithFlags(&ImmArg, Int16, &ValOK, &pResult->ImmSymFlags);
  1021.         if (ValOK)
  1022.           pResult->Vals[0] = (Word) HVal16;
  1023.         break;
  1024.       case eSymbolSize32Bit:
  1025.         pResult->Cnt = 4;
  1026.         HVal = EvalStrIntExpressionWithFlags(&ImmArg, Int32, &ValOK, &pResult->ImmSymFlags);
  1027.         if (ValOK)
  1028.         {
  1029.           pResult->Vals[0] = HVal >> 16;
  1030.           pResult->Vals[1] = HVal & 0xffff;
  1031.         }
  1032.         break;
  1033.       case eSymbolSize64Bit:
  1034.       {
  1035.         LargeInt QVal = EvalStrIntExpressionWithFlags(&ImmArg, LargeIntType, &ValOK, &pResult->ImmSymFlags);
  1036.         pResult->Cnt = 8;
  1037.         if (ValOK)
  1038.         {
  1039. #ifdef HAS64
  1040.           pResult->Vals[0] = (QVal >> 48) & 0xffff;
  1041.           pResult->Vals[1] = (QVal >> 32) & 0xffff;
  1042. #else
  1043.           pResult->Vals[0] =
  1044.           pResult->Vals[1] = (QVal & 0x80000000ul) ? 0xffff : 0x0000;
  1045. #endif
  1046.           pResult->Vals[2] = (QVal >> 16) & 0xffff;
  1047.           pResult->Vals[3] = (QVal      ) & 0xffff;
  1048.         }
  1049.         break;
  1050.       }
  1051.       case eSymbolSizeFloat32Bit:
  1052.         pResult->Cnt = 4;
  1053.         DVal = EvalStrFloatExpression(&ImmArg, &ValOK);
  1054.         if (ValOK)
  1055.         {
  1056.           if ((ret = as_float_2_ieee4(DVal, (Byte *) SwapField, HostBigEndian)) < 0)
  1057.           {
  1058.             asmerr_check_fp_dispose_result(ret, &ImmArg);
  1059.             ValOK = False;
  1060.           }
  1061.         }
  1062.         if (ValOK)
  1063.         {
  1064.           if (HostBigEndian)
  1065.             DWSwap((Byte *) SwapField, 4);
  1066.           pResult->Vals[0] = SwapField[1];
  1067.           pResult->Vals[1] = SwapField[0];
  1068.         }
  1069.         break;
  1070.       case eSymbolSizeFloat64Bit:
  1071.         pResult->Cnt = 8;
  1072.         DVal = EvalStrFloatExpression(&ImmArg, &ValOK);
  1073.         if (ValOK)
  1074.         {
  1075.           if ((ret = as_float_2_ieee8(DVal, (Byte *) SwapField, HostBigEndian)) < 0)
  1076.           {
  1077.             asmerr_check_fp_dispose_result(ret, &ImmArg);
  1078.             ValOK = False;
  1079.           }
  1080.         }
  1081.         if (ValOK)
  1082.         {
  1083.           if (HostBigEndian)
  1084.             QWSwap((Byte *) SwapField, 8);
  1085.           pResult->Vals[0] = SwapField[3];
  1086.           pResult->Vals[1] = SwapField[2];
  1087.           pResult->Vals[2] = SwapField[1];
  1088.           pResult->Vals[3] = SwapField[0];
  1089.         }
  1090.         break;
  1091.       case eSymbolSizeFloat96Bit:
  1092.         pResult->Cnt = 12;
  1093.         DVal = EvalStrFloatExpression(&ImmArg, &ValOK);
  1094.         if (ValOK)
  1095.         {
  1096.           if ((ret = as_float_2_ieee10(DVal, (Byte *) SwapField, False)) < 0)
  1097.           {
  1098.             asmerr_check_fp_dispose_result(ret, &ImmArg);
  1099.             ValOK = False;
  1100.           }
  1101.         }
  1102.         if (ValOK)
  1103.         {
  1104.           if (HostBigEndian)
  1105.             WSwap((Byte *) SwapField, 10);
  1106.           pResult->Vals[0] = SwapField[4];
  1107.           pResult->Vals[1] = 0;
  1108.           pResult->Vals[2] = SwapField[3];
  1109.           pResult->Vals[3] = SwapField[2];
  1110.           pResult->Vals[4] = SwapField[1];
  1111.           pResult->Vals[5] = SwapField[0];
  1112.         }
  1113.         break;
  1114.       case eSymbolSizeFloatDec96Bit:
  1115.         pResult->Cnt = 12;
  1116.         DVal = EvalStrFloatExpression(&ImmArg, &ValOK);
  1117.         if (ValOK)
  1118.         {
  1119.           ConvertMotoFloatDec(DVal, (Byte *) SwapField, False);
  1120.           pResult->Vals[0] = SwapField[5];
  1121.           pResult->Vals[1] = SwapField[4];
  1122.           pResult->Vals[2] = SwapField[3];
  1123.           pResult->Vals[3] = SwapField[2];
  1124.           pResult->Vals[4] = SwapField[1];
  1125.           pResult->Vals[5] = SwapField[0];
  1126.         }
  1127.         break;
  1128.       case eSymbolSizeShiftCnt: /* special arg 1..8 */
  1129.         pResult->Cnt = 2;
  1130.         HVal8 = EvalStrIntExpressionWithFlags(&ImmArg, UInt4, &ValOK, &pResult->ImmSymFlags);
  1131.         if (ValOK)
  1132.         {
  1133.           if (mFirstPassUnknown(pResult->ImmSymFlags))
  1134.            HVal8 = 1;
  1135.           ValOK = ChkRange(HVal8, 1, 8);
  1136.         }
  1137.         if (ValOK)
  1138.           pResult->Vals[0] = (Word)((Byte) HVal8);
  1139.         break;
  1140.       default:
  1141.         break;
  1142.     }
  1143.     goto chk;
  1144.   }
  1145.  
  1146.   /* CPU/FPU-Register direkt: */
  1147.  
  1148.   switch (DecodeRegOrFPReg(&Arg, &pResult->AdrPart, &RegSize, False))
  1149.   {
  1150.     case eIsReg:
  1151.       pResult->Cnt = 0;
  1152.       if (RegSize == NativeFloatSize)
  1153.       {
  1154.         pResult->AdrMode = (pResult->AdrPart > 7) ? ModFPCR : ModFPn;
  1155.         pResult->AdrPart &= 7;
  1156.       }
  1157.       else
  1158.         pResult->AdrMode = (pResult->AdrPart >> 3) ? ModAdr : ModData;
  1159.       /* fall-through */
  1160.     case eRegAbort:
  1161.       goto chk;
  1162.     default:
  1163.       break;
  1164.   }
  1165.  
  1166.   /* Adressregister indirekt mit Predekrement: */
  1167.  
  1168.   if ((ArgLen >= 4) && (*Arg.str.p_str == '-') && (Arg.str.p_str[1] == '(') && (Arg.str.p_str[ArgLen - 1] == ')'))
  1169.   {
  1170.     StrCompCopySub(&CRegArg, &Arg, 2, ArgLen - 3);
  1171.     if ((DecodeReg(&CRegArg, &rerg, False) == eIsReg) && (rerg > 7))
  1172.     {
  1173.       pResult->AdrPart = rerg + 24;
  1174.       pResult->Cnt = 0;
  1175.       pResult->AdrMode = ModPre;
  1176.       goto chk;
  1177.     }
  1178.   }
  1179.  
  1180.   /* Adressregister indirekt mit Postinkrement */
  1181.  
  1182.   if ((ArgLen >= 4) && (*Arg.str.p_str == '(') && (Arg.str.p_str[ArgLen - 2] == ')') && (Arg.str.p_str[ArgLen - 1] == '+'))
  1183.   {
  1184.     StrCompCopySub(&CRegArg, &Arg, 1, ArgLen - 3);
  1185.     if ((DecodeReg(&CRegArg, &rerg, False) == eIsReg) && (rerg > 7))
  1186.     {
  1187.       pResult->AdrPart = rerg + 16;
  1188.       pResult->Cnt = 0;
  1189.       pResult->AdrMode = ModPost;
  1190.       goto chk;
  1191.     }
  1192.   }
  1193.  
  1194.   /* Unterscheidung direkt<->indirekt: */
  1195.  
  1196.   lklamm = 0;
  1197.   rklamm = 0;
  1198.   lastrklamm = 0;
  1199.   doklamm = True;
  1200.   for (p = Arg.str.p_str; *p; p++)
  1201.   {
  1202.     if (*p == '[')
  1203.       doklamm = False;
  1204.     if (*p == ']')
  1205.       doklamm = True;
  1206.     if (doklamm)
  1207.     {
  1208.       if (*p == '(')
  1209.         lklamm++;
  1210.       else if (*p == ')')
  1211.       {
  1212.         rklamm++;
  1213.         lastrklamm = p - Arg.str.p_str;
  1214.       }
  1215.     }
  1216.   }
  1217.  
  1218.   if ((lklamm == 1) && (rklamm == 1) && (lastrklamm == ArgLen - 1))
  1219.   {
  1220.     tStrComp OutDisp, IndirComps, Remainder;
  1221.     char *pCompSplit;
  1222.  
  1223.     /* aeusseres Displacement abspalten, Klammern loeschen: */
  1224.  
  1225.     p = strchr(Arg.str.p_str, '(');
  1226.     *p = '\0';
  1227.     StrCompSplitRef(&OutDisp, &IndirComps, &Arg, p);
  1228.     OutDispLen = -1;
  1229.     if (!SplitSize(&OutDisp, &OutDispLen, 7))
  1230.       return ModNone;
  1231.     StrCompShorten(&IndirComps, 1);
  1232.  
  1233.     /* in Komponenten zerteilen: */
  1234.  
  1235.     CompCnt = 0;
  1236.     do
  1237.     {
  1238.       doklamm = True;
  1239.       pCompSplit = IndirComps.str.p_str;
  1240.       do
  1241.       {
  1242.         if (*pCompSplit == '[')
  1243.           doklamm = False;
  1244.         else if (*pCompSplit == ']')
  1245.           doklamm = True;
  1246.         pCompSplit++;
  1247.       }
  1248.       while (((!doklamm) || (*pCompSplit != ',')) && (*pCompSplit != '\0'));
  1249.  
  1250.       if (*pCompSplit == '\0')
  1251.       {
  1252.         AdrComps[CompCnt].Comp = IndirComps;
  1253.         pCompSplit = NULL;
  1254.       }
  1255.       else
  1256.       {
  1257.         StrCompSplitRef(&AdrComps[CompCnt].Comp, &Remainder, &IndirComps, pCompSplit);
  1258.         IndirComps = Remainder;
  1259.       }
  1260.  
  1261.       KillPrefBlanksStrCompRef(&AdrComps[CompCnt].Comp);
  1262.       KillPostBlanksStrComp(&AdrComps[CompCnt].Comp);
  1263.  
  1264.       /* ignore empty component */
  1265.  
  1266.       if (!AdrComps[CompCnt].Comp.str.p_str[0])
  1267.         continue;
  1268.       if (!ClassComp(&AdrComps[CompCnt]))
  1269.       {
  1270.         WrStrErrorPos(ErrNum_InvAddrMode, &AdrComps[CompCnt].Comp);
  1271.         return ModNone;
  1272.       }
  1273.  
  1274.       /* Base register position is already occupied and we get another one: */
  1275.  
  1276.       if ((CompCnt == 1) && ((AdrComps[CompCnt].Art == AReg) || (AdrComps[CompCnt].Art == PC)))
  1277.       {
  1278.         /* Index register at "base position": just swap comp 0 & 1, so we get (An,Xi) or (PC,Xi): */
  1279.  
  1280.         if (AdrComps[0].Art == Index)
  1281.           SwapAdrComps(&AdrComps[CompCnt], &AdrComps[0]);
  1282.  
  1283.         /* Address register at "base position" and we add PC: also swap and convert it to index so we get again (PC,Xi): */
  1284.  
  1285.         else if ((AdrComps[0].Art == AReg) && (AdrComps[CompCnt].Art == PC))
  1286.         {
  1287.           SwapAdrComps(&AdrComps[CompCnt], &AdrComps[0]);
  1288.           AdrCompToIndex(&AdrComps[CompCnt]);
  1289.         }
  1290.  
  1291.         /* Otherwise, convert address to general index register.  Result may require 68020++ modes: */
  1292.  
  1293.         else
  1294.           AdrCompToIndex(&AdrComps[CompCnt]);
  1295.  
  1296.         CompCnt++;
  1297.       }
  1298.  
  1299.       /* a displacement found inside (...), but outside [...].  Explicit
  1300.          sizes must be consistent, implicitly checked by SplitSize(). */
  1301.  
  1302.       else if (AdrComps[CompCnt].Art == Disp)
  1303.       {
  1304.         if (*OutDisp.str.p_str)
  1305.         {
  1306.           WrError(ErrNum_InvAddrMode);
  1307.           return ModNone;
  1308.         }
  1309.         OutDisp = AdrComps[CompCnt].Comp;
  1310.         OutDispLen = AdrComps[CompCnt].Size;
  1311.       }
  1312.  
  1313.       /* no second index */
  1314.  
  1315.       else if ((AdrComps[CompCnt].Art != Index) && (CompCnt != 0))
  1316.       {
  1317.         WrError(ErrNum_InvAddrMode);
  1318.         return ModNone;
  1319.       }
  1320.  
  1321.       else
  1322.         CompCnt++;
  1323.     }
  1324.     while (pCompSplit);
  1325.  
  1326.     if ((CompCnt > 2) || ((CompCnt > 1) && (AdrComps[0].Art == Index)))
  1327.     {
  1328.       WrError(ErrNum_InvAddrMode);
  1329.       return ModNone;
  1330.     }
  1331.  
  1332.     /* 0. Absolut in Klammern (d) */
  1333.  
  1334.     if (CompCnt == 0)
  1335.     {
  1336.       DecodeAbs(&OutDisp, OutDispLen, pResult);
  1337.     }
  1338.  
  1339.     /* 1. Variante (An....), d(An....) */
  1340.  
  1341.     else if (AdrComps[0].Art == AReg)
  1342.     {
  1343.  
  1344.       /* 1.1. Variante (An), d(An) */
  1345.  
  1346.       if (CompCnt == 1)
  1347.       {
  1348.         /* 1.1.1. Variante (An) */
  1349.  
  1350.         if ((*OutDisp.str.p_str == '\0') && ((MModAdrI & Erl) != 0))
  1351.         {
  1352.           pResult->AdrPart = 0x10 + AdrComps[0].ANummer;
  1353.           pResult->AdrMode = ModAdrI;
  1354.           pResult->Cnt = 0;
  1355.           goto chk;
  1356.         }
  1357.  
  1358.         /* 1.1.2. Variante d(An) */
  1359.  
  1360.         else
  1361.         {
  1362.           /* only try 32-bit displacement if explicitly requested, or 68020++ and no size given */
  1363.  
  1364.           if (OutDispLen < 0)
  1365.             DispIntType = CheckFamilyCore(ExtAddrFamilyMask) ? SInt32 : SInt16;
  1366.           else
  1367.             DispIntType = (OutDispLen >= 2) ? SInt32 : SInt16;
  1368.           HVal = EvalStrIntExpression(&OutDisp, DispIntType, &ValOK);
  1369.           if (!ValOK)
  1370.             return ModNone;
  1371.           if (ValOK && (HVal == 0) && ((MModAdrI & Erl) != 0) && (OutDispLen == -1))
  1372.           {
  1373.             pResult->AdrPart = 0x10 + AdrComps[0].ANummer;
  1374.             pResult->AdrMode = ModAdrI;
  1375.             pResult->Cnt = 0;
  1376.             goto chk;
  1377.           }
  1378.           if (OutDispLen == -1)
  1379.             OutDispLen = (IsDisp16(HVal)) ? 1 : 2;
  1380.           switch (OutDispLen)
  1381.           {
  1382.             case 1:                   /* d16(An) */
  1383.               pResult->AdrPart = 0x28 + AdrComps[0].ANummer;
  1384.               pResult->AdrMode = ModDAdrI;
  1385.               pResult->Cnt = 2;
  1386.               pResult->Vals[0] = HVal & 0xffff;
  1387.               goto chk;
  1388.             case 2:                   /* d32(An) */
  1389.               pResult->AdrPart = 0x30 + AdrComps[0].ANummer;
  1390.               pResult->AdrMode = ModAIX;
  1391.               pResult->Cnt = 6;
  1392.               pResult->Vals[0] = 0x0170;
  1393.               pResult->Vals[1] = (HVal >> 16) & 0xffff;
  1394.               pResult->Vals[2] = HVal & 0xffff;
  1395.               ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
  1396.               goto chk;
  1397.           }
  1398.         }
  1399.       }
  1400.  
  1401.       /* 1.2. Variante d(An,Xi) */
  1402.  
  1403.       else
  1404.       {
  1405.         pResult->Vals[0] = (AdrComps[1].INummer << 12) + (Ord(AdrComps[1].Long) << 11) + (AdrComps[1].Scale << 9);
  1406.         pResult->AdrPart = 0x30 + AdrComps[0].ANummer;
  1407.  
  1408.         /* only try 32-bit displacement if explicitly requested, or 68020++ and no size given */
  1409.  
  1410.         if (OutDispLen < 0)
  1411.           DispIntType = CheckFamilyCore(ExtAddrFamilyMask) ? SInt32 : SInt8;
  1412.         else
  1413.           DispIntType = (OutDispLen >= 2) ? SInt32 : (OutDispLen >= 1 ? SInt16 : SInt8);
  1414.         HVal = EvalStrIntExpression(&OutDisp, DispIntType, &ValOK);
  1415.         if (ValOK)
  1416.           switch (OutDispLen)
  1417.           {
  1418.             case eSymbolSize8Bit:
  1419.               if (!IsDisp8(HVal))
  1420.               {
  1421.                 WrError(ErrNum_OverRange);
  1422.                 ValOK = FALSE;
  1423.               }
  1424.               break;
  1425.             case eSymbolSize16Bit:
  1426.               if (!IsDisp16(HVal))
  1427.               {
  1428.                 WrError(ErrNum_OverRange);
  1429.                 ValOK = FALSE;
  1430.               }
  1431.               break;
  1432.           }
  1433.         if (ValOK)
  1434.         {
  1435.           if (OutDispLen == -1)
  1436.             OutDispLen = GetDispLen(HVal);
  1437.           switch (OutDispLen)
  1438.           {
  1439.             case 0:
  1440.               pResult->AdrMode = ModAIX;
  1441.               pResult->Cnt = 2;
  1442.               pResult->Vals[0] += (HVal & 0xff);
  1443.               if ((AdrComps[1].Scale != 0) && (!(pCurrCPUProps->SuppFlags & eFlagIdxScaling)))
  1444.               {
  1445.                 WrStrErrorPos(ErrNum_AddrModeNotSupported, &AdrComps[1].Comp);
  1446.                 ClrAdrVals(pResult);
  1447.               }
  1448.               goto chk;
  1449.             case 1:
  1450.               pResult->AdrMode = ModAIX;
  1451.               pResult->Cnt = 4;
  1452.               pResult->Vals[0] += 0x120;
  1453.               pResult->Vals[1] = HVal & 0xffff;
  1454.               ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
  1455.               goto chk;
  1456.             case 2:
  1457.               pResult->AdrMode = ModAIX;
  1458.               pResult->Cnt = 6;
  1459.               pResult->Vals[0] += 0x130;
  1460.               pResult->Vals[1] = HVal >> 16;
  1461.               pResult->Vals[2] = HVal & 0xffff;
  1462.               ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
  1463.               goto chk;
  1464.           }
  1465.         }
  1466.       }
  1467.     }
  1468.  
  1469.     /* 2. Variante d(PC....) */
  1470.  
  1471.     else if (AdrComps[0].Art == PC)
  1472.     {
  1473.       /* 2.1. Variante d(PC) */
  1474.  
  1475.       if (CompCnt == 1)
  1476.       {
  1477.         HVal = EvalStrIntExpressionWithFlags(&OutDisp, Int32, &ValOK, &Flags) - (EProgCounter() + RelPos);
  1478.         if (!ValOK)
  1479.           return ModNone;
  1480.         if (OutDispLen < 0)
  1481.         {
  1482.           if (mSymbolQuestionable(Flags) && !CheckFamilyCore(ExtAddrFamilyMask))
  1483.             HVal &= 0x7fff;
  1484.           OutDispLen = (IsDisp16(HVal)) ? 1 : 2;
  1485.         }
  1486.         switch (OutDispLen)
  1487.         {
  1488.           case 1:
  1489.             pResult->AdrPart = 0x3a;
  1490.             if (!mSymbolQuestionable(Flags) && !IsDisp16(HVal))
  1491.             {
  1492.               WrError(ErrNum_DistTooBig);
  1493.               return ModNone;
  1494.             }
  1495.             pResult->AdrMode = ModPC;
  1496.             pResult->Cnt = 2;
  1497.             pResult->Vals[0] = HVal & 0xffff;
  1498.             goto chk;
  1499.           case 2:
  1500.             pResult->AdrPart = 0x3b;
  1501.             pResult->AdrMode = ModPCIdx;
  1502.             pResult->Cnt = 6;
  1503.             pResult->Vals[0] = 0x170;
  1504.             pResult->Vals[1] = HVal >> 16;
  1505.             pResult->Vals[2] = HVal & 0xffff;
  1506.             ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
  1507.             goto chk;
  1508.         }
  1509.       }
  1510.  
  1511.       /* 2.2. Variante d(PC,Xi) */
  1512.  
  1513.       else
  1514.       {
  1515.         pResult->Vals[0] = (AdrComps[1].INummer << 12) + (Ord(AdrComps[1].Long) << 11) + (AdrComps[1].Scale << 9);
  1516.         HVal = EvalStrIntExpressionWithFlags(&OutDisp, Int32, &ValOK, &Flags) - (EProgCounter() + RelPos);
  1517.         if (!ValOK)
  1518.           return ModNone;
  1519.         if (OutDispLen < 0)
  1520.         {
  1521.           if (mSymbolQuestionable(Flags) && !CheckFamilyCore(ExtAddrFamilyMask))
  1522.             HVal &= 0x7f;
  1523.           OutDispLen = GetDispLen(HVal);
  1524.         }
  1525.         pResult->AdrPart = 0x3b;
  1526.         switch (OutDispLen)
  1527.         {
  1528.           case 0:
  1529.             if (!mSymbolQuestionable(Flags) && !IsDisp8(HVal))
  1530.             {
  1531.               WrError(ErrNum_DistTooBig);
  1532.               return ModNone;
  1533.             }
  1534.             pResult->Vals[0] += (HVal & 0xff);
  1535.             pResult->Cnt = 2;
  1536.             pResult->AdrMode = ModPCIdx;
  1537.             if ((AdrComps[1].Scale != 0) && (!(pCurrCPUProps->SuppFlags & eFlagIdxScaling)))
  1538.             {
  1539.               WrStrErrorPos(ErrNum_AddrModeNotSupported, &AdrComps[1].Comp);
  1540.               ClrAdrVals(pResult);
  1541.             }
  1542.             goto chk;
  1543.           case 1:
  1544.             if (!mSymbolQuestionable(Flags) && !IsDisp16(HVal))
  1545.             {
  1546.               WrError(ErrNum_DistTooBig);
  1547.               return ModNone;
  1548.             }
  1549.             pResult->Vals[0] += 0x120;
  1550.             pResult->Cnt = 4;
  1551.             pResult->AdrMode = ModPCIdx;
  1552.             pResult->Vals[1] = HVal & 0xffff;
  1553.             ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
  1554.             goto chk;
  1555.           case 2:
  1556.             pResult->Vals[0] += 0x130;
  1557.             pResult->Cnt = 6;
  1558.             pResult->AdrMode = ModPCIdx;
  1559.             pResult->Vals[1] = HVal >> 16;
  1560.             pResult->Vals[2] = HVal & 0xffff;
  1561.             ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
  1562.             goto chk;
  1563.         }
  1564.       }
  1565.     }
  1566.  
  1567.     /* 3. Variante (Xi), d(Xi) */
  1568.  
  1569.     else if (AdrComps[0].Art == Index)
  1570.     {
  1571.       pResult->Vals[0] = (AdrComps[0].INummer << 12) + (Ord(AdrComps[0].Long) << 11) + (AdrComps[0].Scale << 9) + 0x180;
  1572.       pResult->AdrPart = 0x30;
  1573.       if (*OutDisp.str.p_str == '\0')
  1574.       {
  1575.         pResult->Vals[0] = pResult->Vals[0] + 0x0010;
  1576.         pResult->Cnt = 2;
  1577.         pResult->AdrMode = ModAIX;
  1578.         ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
  1579.         goto chk;
  1580.       }
  1581.       else
  1582.       {
  1583.         HVal = EvalStrIntExpression(&OutDisp, (OutDispLen != 1) ? SInt32 : SInt16, &ValOK);
  1584.         if (ValOK)
  1585.         {
  1586.           if (OutDispLen == -1)
  1587.             OutDispLen = IsDisp16(HVal) ? 1 : 2;
  1588.           switch (OutDispLen)
  1589.           {
  1590.             case 0:
  1591.             case 1:
  1592.               pResult->Vals[0] = pResult->Vals[0] + 0x0020;
  1593.               pResult->Vals[1] = HVal & 0xffff;
  1594.               pResult->AdrMode = ModAIX;
  1595.               pResult->Cnt = 4;
  1596.               ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
  1597.               goto chk;
  1598.             case 2:
  1599.               pResult->Vals[0] = pResult->Vals[0] + 0x0030;
  1600.               pResult->AdrMode = ModAIX;
  1601.               pResult->Cnt = 6;
  1602.               pResult->Vals[1] = HVal >> 16;
  1603.               pResult->Vals[2] = HVal & 0xffff;
  1604.               ACheckFamily(ExtAddrFamilyMask, pArg, pResult);
  1605.               goto chk;
  1606.           }
  1607.         }
  1608.       }
  1609.     }
  1610.  
  1611.     /* 4. Variante indirekt: */
  1612.  
  1613.     else if (AdrComps[0].Art == indir)
  1614.     {
  1615.       /* erst ab 68020 erlaubt */
  1616.  
  1617.       if (!ACheckFamily((1 << e68KGen3) | (1 << e68KGen2), pArg, pResult))
  1618.         return ModNone;
  1619.  
  1620.       /* Unterscheidung Vor- <---> Nachindizierung: */
  1621.  
  1622.       if (CompCnt == 2)
  1623.       {
  1624.         PreInd = False;
  1625.         AdrComps[2] = AdrComps[1];
  1626.       }
  1627.       else
  1628.       {
  1629.         PreInd = True;
  1630.         AdrComps[2].Art = None;
  1631.       }
  1632.  
  1633.       /* indirektes Argument herauskopieren: */
  1634.  
  1635.       StrCompRefRight(&IndirComps, &AdrComps[0].Comp, 1);
  1636.       StrCompShorten(&IndirComps, 1);
  1637.  
  1638.       /* Felder loeschen: */
  1639.  
  1640.       for (i = 0; i < 2; AdrComps[i++].Art = None);
  1641.  
  1642.       /* indirekten Ausdruck auseinanderfieseln: */
  1643.  
  1644.       do
  1645.       {
  1646.         /* abschneiden & klassifizieren: */
  1647.  
  1648.         pCompSplit = strchr(IndirComps.str.p_str, ',');
  1649.         if (!pCompSplit)
  1650.           OneComp.Comp = IndirComps;
  1651.         else
  1652.         {
  1653.           StrCompSplitRef(&OneComp.Comp, &Remainder, &IndirComps, pCompSplit);
  1654.           IndirComps = Remainder;
  1655.         }
  1656.         KillPrefBlanksStrCompRef(&OneComp.Comp);
  1657.         KillPostBlanksStrComp(&OneComp.Comp);
  1658.         if (!ClassComp(&OneComp))
  1659.         {
  1660.           WrError(ErrNum_InvAddrMode);
  1661.           return ModNone;
  1662.         }
  1663.  
  1664.         /* passend einsortieren: */
  1665.  
  1666.         if ((AdrComps[1].Art != None) && (OneComp.Art == AReg))
  1667.         {
  1668.           OneComp.Art = Index;
  1669.           OneComp.INummer = OneComp.ANummer + 8;
  1670.           OneComp.Long = False;
  1671.           OneComp.Scale = 0;
  1672.         }
  1673.         switch (OneComp.Art)
  1674.         {
  1675.           case Disp:
  1676.             i = 0;
  1677.             break;
  1678.           case AReg:
  1679.           case PC:
  1680.             i = 1;
  1681.             break;
  1682.           case Index:
  1683.             i = 2;
  1684.             break;
  1685.           default:
  1686.             i = 3;
  1687.         }
  1688.         if ((i >= 3) || AdrComps[i].Art != None)
  1689.         {
  1690.           WrError(ErrNum_InvAddrMode);
  1691.           return ModNone;
  1692.         }
  1693.         else
  1694.           AdrComps[i] = OneComp;
  1695.       }
  1696.       while (pCompSplit);
  1697.  
  1698.       /* extension word: 68020 format */
  1699.  
  1700.       pResult->Vals[0] = 0x100;
  1701.  
  1702.       /* bit 2 = post-indexed. */
  1703.  
  1704.       if (!PreInd)
  1705.         pResult->Vals[0] |= 0x0004;
  1706.  
  1707.       /* Set post-indexed also for no index register for compatibility with older versions. */
  1708.  
  1709.       if (AdrComps[2].Art == None)
  1710.         pResult->Vals[0] |= 0x0040 | 0x0004;
  1711.       else
  1712.         pResult->Vals[0] |= (AdrComps[2].INummer << 12) + (Ord(AdrComps[2].Long) << 11) + (AdrComps[2].Scale << 9);
  1713.  
  1714.       /* 4.1 Variante d([...PC...]...) */
  1715.  
  1716.       if (AdrComps[1].Art == PC)
  1717.       {
  1718.         if (AdrComps[0].Art == None)
  1719.         {
  1720.           pResult->AdrPart = 0x3b;
  1721.           pResult->Vals[0] |= 0x10;
  1722.           pResult->AdrMode = ModAIX;
  1723.           pResult->Cnt = 2;
  1724.         }
  1725.         else
  1726.         {
  1727.           HVal = EvalStrIntExpression(&AdrComps[0].Comp, Int32, &ValOK);
  1728.           HVal -= EProgCounter() + RelPos;
  1729.           if (!ValOK)
  1730.             return ModNone;
  1731.           switch (AdrComps[0].Size)
  1732.           {
  1733.             case -1:
  1734.              if (IsDisp16(HVal))
  1735.                goto PCIs16;
  1736.              else
  1737.                goto PCIs32;
  1738.             case 1:
  1739.               if (!IsDisp16(HVal))
  1740.               {
  1741.                 WrError(ErrNum_DistTooBig);
  1742.                 return ModNone;
  1743.               }
  1744.             PCIs16:
  1745.               pResult->Vals[1] = HVal & 0xffff;
  1746.               pResult->AdrPart = 0x3b;
  1747.               pResult->Vals[0] += 0x20;
  1748.               pResult->AdrMode = ModAIX;
  1749.               pResult->Cnt = 4;
  1750.               break;
  1751.             case 2:
  1752.             PCIs32:
  1753.               pResult->Vals[1] = HVal >> 16;
  1754.               pResult->Vals[2] = HVal & 0xffff;
  1755.               pResult->AdrPart = 0x3b;
  1756.               pResult->Vals[0] += 0x30;
  1757.               pResult->AdrMode = ModAIX;
  1758.               pResult->Cnt = 6;
  1759.               break;
  1760.           }
  1761.         }
  1762.       }
  1763.  
  1764.       /* 4.2 Variante d([...An...]...) */
  1765.  
  1766.       else
  1767.       {
  1768.         if (AdrComps[1].Art == None)
  1769.         {
  1770.           pResult->AdrPart = 0x30;
  1771.           pResult->Vals[0] += 0x80;
  1772.         }
  1773.         else
  1774.           pResult->AdrPart = 0x30 + AdrComps[1].ANummer;
  1775.  
  1776.         if (AdrComps[0].Art == None)
  1777.         {
  1778.           pResult->AdrMode = ModAIX;
  1779.           pResult->Cnt = 2;
  1780.           pResult->Vals[0] += 0x10;
  1781.         }
  1782.         else
  1783.         {
  1784.           HVal = EvalStrIntExpression(&AdrComps[0].Comp, Int32, &ValOK);
  1785.           if (!ValOK)
  1786.             return ModNone;
  1787.           switch (AdrComps[0].Size)
  1788.           {
  1789.             case -1:
  1790.               if (IsDisp16(HVal))
  1791.                 goto AnIs16;
  1792.               else
  1793.                 goto AnIs32;
  1794.             case 1:
  1795.               if (!IsDisp16(HVal))
  1796.               {
  1797.                 WrError(ErrNum_DistTooBig);
  1798.                 return ModNone;
  1799.               }
  1800.             AnIs16:
  1801.               pResult->Vals[0] += 0x20;
  1802.               pResult->Vals[1] = HVal & 0xffff;
  1803.               pResult->AdrMode = ModAIX;
  1804.               pResult->Cnt = 4;
  1805.               break;
  1806.             case 2:
  1807.             AnIs32:
  1808.               pResult->Vals[0] += 0x30;
  1809.               pResult->Vals[1] = HVal >> 16;
  1810.               pResult->Vals[2] = HVal & 0xffff;
  1811.               pResult->AdrMode = ModAIX;
  1812.               pResult->Cnt = 6;
  1813.               break;
  1814.           }
  1815.         }
  1816.       }
  1817.  
  1818.       /* aeusseres Displacement: */
  1819.  
  1820.       if (OutDisp.str.p_str[0])
  1821.         HVal = EvalStrIntExpression(&OutDisp, (OutDispLen == 1) ? SInt16 : SInt32, &ValOK);
  1822.       else
  1823.       {
  1824.         HVal = 0;
  1825.         ValOK = True;
  1826.       }
  1827.       if (!ValOK)
  1828.       {
  1829.         pResult->AdrMode = ModNone;
  1830.         pResult->Cnt = 0;
  1831.         return ModNone;
  1832.       }
  1833.       if (OutDispLen == -1)
  1834.         OutDispLen = IsDisp16(HVal) ? 1 : 2;
  1835.       if (*OutDisp.str.p_str == '\0')
  1836.       {
  1837.         pResult->Vals[0]++;
  1838.         goto chk;
  1839.       }
  1840.       else
  1841.         switch (OutDispLen)
  1842.         {
  1843.           case 0:
  1844.           case 1:
  1845.             pResult->Vals[pResult->Cnt >> 1] = HVal & 0xffff;
  1846.             pResult->Cnt += 2;
  1847.             pResult->Vals[0] += 2;
  1848.             break;
  1849.           case 2:
  1850.             pResult->Vals[(pResult->Cnt >> 1)    ] = HVal >> 16;
  1851.             pResult->Vals[(pResult->Cnt >> 1) + 1] = HVal & 0xffff;
  1852.             pResult->Cnt += 4;
  1853.             pResult->Vals[0] += 3;
  1854.             break;
  1855.         }
  1856.  
  1857.       goto chk;
  1858.     }
  1859.  
  1860.   }
  1861.  
  1862.   /* absolut: */
  1863.  
  1864.   else
  1865.   {
  1866.     if (!SplitSize(&Arg, &OutDispLen, 6))
  1867.       return ModNone;
  1868.     DecodeAbs(&Arg, OutDispLen, pResult);
  1869.   }
  1870.  
  1871. chk:
  1872.   if ((pResult->AdrMode > 0) && (!(Erl & (1 << (pResult->AdrMode - 1)))))
  1873.   {
  1874.     WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  1875.     ClrAdrVals(pResult);
  1876.   }
  1877.   return pResult->AdrMode;
  1878. }
  1879.  
  1880. static Boolean DecodeMACACC(const char *pArg, Word *pResult)
  1881. {
  1882.   /* interprete ACC like ACC0, independent of MAC or EMAC: */
  1883.  
  1884.   if (!as_strcasecmp(pArg, "ACC"))
  1885.     *pResult = 0;
  1886.   else if (!as_strncasecmp(pArg, "ACC", 3) && (strlen(pArg) == 4) && (pArg[3] >= '0') && (pArg[3] <= '3'))
  1887.     *pResult = pArg[3] - '0';
  1888.   else
  1889.     return False;
  1890.  
  1891.   /* allow ACC1..3 only on EMAC: */
  1892.  
  1893.   if ((!(pCurrCPUProps->SuppFlags & eFlagEMAC)) && *pResult)
  1894.     return False;
  1895.   return True;
  1896. }
  1897.  
  1898. static Boolean DecodeMACReg(const char *pArg, Word *pResult)
  1899. {
  1900.   if (!as_strcasecmp(pArg, "MACSR"))
  1901.   {
  1902.     *pResult = 4;
  1903.     return True;
  1904.   }
  1905.   if (!as_strcasecmp(pArg, "MASK"))
  1906.   {
  1907.     *pResult = 6;
  1908.     return True;
  1909.   }
  1910.  
  1911.   /* ACCEXT01/23 only on EMAC: */
  1912.  
  1913.   if (pCurrCPUProps->SuppFlags & eFlagEMAC)
  1914.   {
  1915.     if (!as_strcasecmp(pArg, "ACCEXT01"))
  1916.     {
  1917.       *pResult = 5;
  1918.       return True;
  1919.     }
  1920.     if (!as_strcasecmp(pArg, "ACCEXT23"))
  1921.     {
  1922.       *pResult = 7;
  1923.       return True;
  1924.     }
  1925.   }
  1926.   return DecodeMACACC(pArg, pResult);
  1927. }
  1928.  
  1929. static Boolean DecodeRegList(const tStrComp *pArg, Word *Erg)
  1930. {
  1931.   Word h, h2;
  1932.   Byte z;
  1933.   char *p, *p2;
  1934.   String ArgStr;
  1935.   tStrComp Arg, Remainder, From, To;
  1936.  
  1937.   StrCompMkTemp(&Arg, ArgStr, sizeof(ArgStr));
  1938.   StrCompCopy(&Arg, pArg);
  1939.  
  1940.   *Erg = 0;
  1941.   do
  1942.   {
  1943.     p = strchr(Arg.str.p_str, '/');
  1944.     if (p)
  1945.       StrCompSplitRef(&Arg, &Remainder, &Arg, p);
  1946.     p2 = strchr(Arg.str.p_str, '-');
  1947.     if (!p2)
  1948.     {
  1949.       if (DecodeReg(&Arg, &h, False) != eIsReg)
  1950.         return False;
  1951.       *Erg |= 1 << h;
  1952.     }
  1953.     else
  1954.     {
  1955.       StrCompSplitRef(&From, &To, &Arg, p2);
  1956.       if (!*From.str.p_str || !*To.str.p_str)
  1957.         return False;
  1958.       if ((DecodeReg(&From, &h, False) != eIsReg)
  1959.        || (DecodeReg(&To, &h2, False) != eIsReg))
  1960.         return False;
  1961.       if (h <= h2)
  1962.       {
  1963.         for (z = h; z <= h2; z++)
  1964.           *Erg |= 1 << z;
  1965.       }
  1966.       else
  1967.       {
  1968.         for (z = h; z <= 15; z++)
  1969.           *Erg |= 1 << z;
  1970.         for (z = 0; z <= h2; z++)
  1971.           *Erg |= 1 << z;
  1972.       }
  1973.     }
  1974.     if (p)
  1975.       Arg = Remainder;
  1976.   }
  1977.   while (p);
  1978.   return True;
  1979. }
  1980.  
  1981. static Boolean DecodeMACScale(const tStrComp *pArg, Word *pResult)
  1982. {
  1983.   int l = strlen(pArg->str.p_str);
  1984.   tStrComp ShiftArg;
  1985.   Boolean Left = False, OK;
  1986.   Word ShiftCnt;
  1987.  
  1988.   /* allow empty argument */
  1989.  
  1990.   if (!l)
  1991.   {
  1992.     *pResult = 0;
  1993.     return True;
  1994.   }
  1995.   /* left or right? */
  1996.  
  1997.   if (l < 2)
  1998.     return False;
  1999.   if (!strncmp(pArg->str.p_str, "<<", 2))
  2000.     Left = True;
  2001.   else if (!strncmp(pArg->str.p_str, ">>", 2))
  2002.     Left = False;
  2003.   else
  2004.     return False;
  2005.  
  2006.   /* evaluate shift cnt - empty count counts as one */
  2007.  
  2008.   StrCompRefRight(&ShiftArg, pArg, 2);
  2009.   KillPrefBlanksStrCompRef(&ShiftArg);
  2010.   if (!*ShiftArg.str.p_str)
  2011.   {
  2012.     ShiftCnt = 1;
  2013.     OK = True;
  2014.   }
  2015.   else
  2016.     ShiftCnt = EvalStrIntExpression(&ShiftArg, UInt1, &OK);
  2017.   if (!OK)
  2018.     return False;
  2019.  
  2020.   /* codify */
  2021.  
  2022.   if (ShiftCnt)
  2023.     *pResult = Left ? 1 : 3;
  2024.   else
  2025.     *pResult = 0;
  2026.   return True;
  2027. }
  2028.  
  2029. static Boolean SplitMACUpperLower(Word *pResult, tStrComp *pArg)
  2030. {
  2031.   char *pSplit;
  2032.   tStrComp HalfComp;
  2033.  
  2034.   *pResult = 0;
  2035.   pSplit = strrchr(pArg->str.p_str, '.');
  2036.   if (!pSplit)
  2037.   {
  2038.     WrStrErrorPos(ErrNum_InvReg, pArg);
  2039.     return False;
  2040.   }
  2041.  
  2042.   StrCompSplitRef(pArg, &HalfComp, pArg, pSplit);
  2043.   KillPostBlanksStrComp(pArg);
  2044.   if (!as_strcasecmp(HalfComp.str.p_str, "L"))
  2045.     *pResult = 0;
  2046.   else if (!as_strcasecmp(HalfComp.str.p_str, "U"))
  2047.     *pResult = 1;
  2048.   else
  2049.   {
  2050.     WrStrErrorPos(ErrNum_InvReg, &HalfComp);
  2051.     return False;
  2052.   }
  2053.   return True;
  2054. }
  2055.  
  2056. static Boolean SplitMACANDMASK(Word *pResult, tStrComp *pArg)
  2057. {
  2058.   char *pSplit, Save;
  2059.   tStrComp MaskComp, AddrComp;
  2060.  
  2061.   *pResult = 0;
  2062.   pSplit = strrchr(pArg->str.p_str, '&');
  2063.   if (!pSplit)
  2064.     return True;
  2065.  
  2066.   Save = StrCompSplitRef(&AddrComp, &MaskComp, pArg, pSplit);
  2067.   KillPrefBlanksStrCompRef(&MaskComp);
  2068.  
  2069.   /* if no MASK argument, be sure to revert pArg to original state: */
  2070.  
  2071.   if (!strcmp(MaskComp.str.p_str, "") || !as_strcasecmp(MaskComp.str.p_str, "MASK"))
  2072.   {
  2073.     KillPostBlanksStrComp(&AddrComp);
  2074.     *pArg = AddrComp;
  2075.     *pResult = 1;
  2076.   }
  2077.   else
  2078.     *pSplit = Save;
  2079.   return True;
  2080. }
  2081.  
  2082. /*-------------------------------------------------------------------------*/
  2083. /* Dekodierroutinen: Integer-Einheit */
  2084.  
  2085. /* 0=MOVE 1=MOVEA */
  2086.  
  2087. static void DecodeMOVE(Word Index)
  2088. {
  2089.   Word MACReg;
  2090.   unsigned Variant = Index & VariantMask;
  2091.  
  2092.   if (!ChkArgCnt(2, 2));
  2093.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "USP"))
  2094.   {
  2095.     if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  2096.     else if ((pCurrCPUProps->Family != eColdfire) || CheckISA((1 << eCfISA_APlus) | (1 << eCfISA_B) | (1 << eCfISA_C)))
  2097.     {
  2098.       tAdrResult AdrResult;
  2099.  
  2100.       if (DecodeAdr(&ArgStr[2], MModAdr, &AdrResult))
  2101.       {
  2102.         CodeLen = 2;
  2103.         WAsmCode[0] = 0x4e68 | (AdrResult.AdrPart & 7);
  2104.         CheckSup();
  2105.       }
  2106.     }
  2107.   }
  2108.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "USP"))
  2109.   {
  2110.     if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  2111.     else if ((pCurrCPUProps->Family != eColdfire) || CheckISA((1 << eCfISA_APlus) | (1 << eCfISA_B) | (1 << eCfISA_C)))
  2112.     {
  2113.       tAdrResult AdrResult;
  2114.  
  2115.       if (DecodeAdr(&ArgStr[1], MModAdr, &AdrResult))
  2116.       {
  2117.         CodeLen = 2;
  2118.         WAsmCode[0] = 0x4e60 | (AdrResult.AdrPart & 7);
  2119.         CheckSup();
  2120.       }
  2121.     }
  2122.   }
  2123.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "SR"))
  2124.   {
  2125.     if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  2126.     else
  2127.     {
  2128.       tAdrResult AdrResult;
  2129.  
  2130.       if (DecodeAdr(&ArgStr[2], MModData | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs), &AdrResult))
  2131.       {
  2132.         CodeLen = 2 + AdrResult.Cnt;
  2133.         WAsmCode[0] = 0x40c0 | AdrResult.AdrPart;
  2134.         CopyAdrVals(WAsmCode + 1, &AdrResult);
  2135.         if (pCurrCPUProps->Family != e68KGen1a)
  2136.           CheckSup();
  2137.       }
  2138.     }
  2139.   }
  2140.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "CCR"))
  2141.   {
  2142.     if (*AttrPart.str.p_str && (OpSize > eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  2143.     else if (!CheckNoFamily(1 << e68KGen1a));
  2144.     else
  2145.     {
  2146.       tAdrResult AdrResult;
  2147.  
  2148.       OpSize = eSymbolSize8Bit;
  2149.       if (DecodeAdr(&ArgStr[2], MModData | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs), &AdrResult))
  2150.       {
  2151.         CodeLen = 2 + AdrResult.Cnt;
  2152.         WAsmCode[0] = 0x42c0 | AdrResult.AdrPart;
  2153.         CopyAdrVals(WAsmCode + 1, &AdrResult);
  2154.       }
  2155.     }
  2156.   }
  2157.   else if ((pCurrCPUProps->SuppFlags & eFlagMAC) && (DecodeMACReg(ArgStr[1].str.p_str, &MACReg)))
  2158.   {
  2159.     Word DestMACReg;
  2160.  
  2161.     if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  2162.     else if ((MACReg == 4) && (!as_strcasecmp(ArgStr[2].str.p_str, "CCR")))
  2163.     {
  2164.       WAsmCode[0] = 0xa9c0;
  2165.       CodeLen = 2;
  2166.     }
  2167.     else if ((MACReg < 4) && DecodeMACReg(ArgStr[2].str.p_str, &DestMACReg) && (DestMACReg < 4) && (pCurrCPUProps->SuppFlags & eFlagEMAC))
  2168.     {
  2169.       WAsmCode[0] = 0xa110 | (DestMACReg << 9) | (MACReg << 0);
  2170.       CodeLen = 2;
  2171.     }
  2172.     else
  2173.     {
  2174.       tAdrResult AdrResult;
  2175.  
  2176.       if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
  2177.       {
  2178.         CodeLen = 2;
  2179.         WAsmCode[0] = 0xa180 | (AdrResult.AdrPart & 15) | (MACReg << 9);
  2180.       }
  2181.     }
  2182.   }
  2183.   else if ((pCurrCPUProps->SuppFlags & eFlagMAC) && (DecodeMACReg(ArgStr[2].str.p_str, &MACReg)))
  2184.   {
  2185.     if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  2186.     else
  2187.     {
  2188.       tAdrResult AdrResult;
  2189.  
  2190.       if (DecodeAdr(&ArgStr[1], MModData | MModAdr | MModImm, &AdrResult))
  2191.       {
  2192.         CodeLen = 2 + AdrResult.Cnt;
  2193.         WAsmCode[0] = 0xa100 | (AdrResult.AdrPart) | (MACReg << 9);
  2194.         CopyAdrVals(WAsmCode + 1, &AdrResult);
  2195.       }
  2196.     }
  2197.   }
  2198.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "SR"))
  2199.   {
  2200.     if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  2201.     else
  2202.     {
  2203.       tAdrResult AdrResult;
  2204.  
  2205.       if (DecodeAdr(&ArgStr[1], MModData | MModImm | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs), &AdrResult))
  2206.       {
  2207.         CodeLen = 2 + AdrResult.Cnt;
  2208.         WAsmCode[0] = 0x46c0 | AdrResult.AdrPart;
  2209.         CopyAdrVals(WAsmCode + 1, &AdrResult);
  2210.         CheckSup();
  2211.       }
  2212.     }
  2213.   }
  2214.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "CCR"))
  2215.   {
  2216.     if (*AttrPart.str.p_str && (OpSize > eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  2217.     else
  2218.     {
  2219.       tAdrResult AdrResult;
  2220.  
  2221.       if (DecodeAdr(&ArgStr[1], MModData | MModImm | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs), &AdrResult))
  2222.       {
  2223.         CodeLen = 2 + AdrResult.Cnt;
  2224.         WAsmCode[0] = 0x44c0 | AdrResult.AdrPart;
  2225.         CopyAdrVals(WAsmCode + 1, &AdrResult);
  2226.       }
  2227.     }
  2228.   }
  2229.   else
  2230.   {
  2231.     if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  2232.     else
  2233.     {
  2234.       tAdrResult AdrResult;
  2235.  
  2236.       DecodeAdr(&ArgStr[1], ((Variant == I_Variant) ? 0 : MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs) | MModImm, &AdrResult);
  2237.  
  2238.       /* Is An as source in byte mode allowed for ColdFire? No corresponding footnote in CFPRM... */
  2239.  
  2240.       if ((AdrResult.AdrMode == ModAdr) && (OpSize == eSymbolSize8Bit) && (pCurrCPUProps->Family != eColdfire)) WrError(ErrNum_InvOpSize);
  2241.       else if (AdrResult.AdrMode != ModNone)
  2242.       {
  2243.         unsigned SrcAdrNum = AdrResult.AdrMode;
  2244.  
  2245.         CodeLen = 2 + AdrResult.Cnt;
  2246.         CopyAdrVals(WAsmCode + 1, &AdrResult);
  2247.         if (OpSize == eSymbolSize8Bit)
  2248.           WAsmCode[0] = 0x1000;
  2249.         else if (OpSize == eSymbolSize16Bit)
  2250.           WAsmCode[0] = 0x3000;
  2251.         else
  2252.           WAsmCode[0] = 0x2000;
  2253.         WAsmCode[0] |= AdrResult.AdrPart;
  2254.         DecodeAdr(&ArgStr[2], ((Variant == A_Variant) ? 0 : MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs) | MModAdr, &AdrResult);
  2255.         if ((AdrResult.AdrMode == ModAdr) && (OpSize == eSymbolSize8Bit))
  2256.         {
  2257.           CodeLen = 0;
  2258.           WrError(ErrNum_InvOpSize);
  2259.         }
  2260.         else if (AdrResult.AdrMode == ModNone)
  2261.           CodeLen = 0;
  2262.         else
  2263.         {
  2264.           Boolean CombinationOK;
  2265.  
  2266.           /* ColdFire does not allow all combinations of src+dest: */
  2267.  
  2268.           if (pCurrCPUProps->Family == eColdfire)
  2269.             switch (SrcAdrNum)
  2270.             {
  2271.               case ModData: /* Dn */
  2272.               case ModAdr: /* An */
  2273.               case ModAdrI: /* (An) */
  2274.               case ModPost: /* (An)+ */
  2275.               case ModPre: /* -(An) */
  2276.                 CombinationOK = True;
  2277.                 break;
  2278.               case ModDAdrI: /* (d16,An) */
  2279.               case ModPC: /* (d16,PC) */
  2280.                 CombinationOK = (AdrResult.AdrMode != ModAIX)   /* no (d8,An,Xi) */
  2281.                              && (AdrResult.AdrMode != ModAbs); /* no (xxx).W/L */
  2282.                 break;
  2283.               case ModAIX: /* (d8,An,Xi) */
  2284.               case ModPCIdx: /* (d8,PC,Xi) */
  2285.               case ModAbs: /* (xxx).W/L */
  2286.                 CombinationOK = (AdrResult.AdrMode != ModDAdrI)   /* no (d16,An) */
  2287.                              && (AdrResult.AdrMode != ModAIX)   /* no (d8,An,Xi) */
  2288.                              && (AdrResult.AdrMode != ModAbs); /* no (xxx).W/L */
  2289.                 break;
  2290.               case ModImm: /* #xxx */
  2291.                 if (AdrResult.AdrMode == ModDAdrI) /* (d16,An) OK for 8/16 bit starting with ISA B */
  2292.                   CombinationOK = (pCurrCPUProps->CfISA >= eCfISA_B) && (OpSize <= eSymbolSize16Bit);
  2293.                 else
  2294.                   CombinationOK = (AdrResult.AdrMode != ModAIX)   /* no (d8,An,Xi) */
  2295.                                && (AdrResult.AdrMode != ModAbs); /* no (xxx).W/L */
  2296.                 break;
  2297.               default: /* should not occur */
  2298.                 CombinationOK = False;
  2299.             }
  2300.           else
  2301.             CombinationOK = True;
  2302.           if (!CombinationOK)
  2303.           {
  2304.             WrError(ErrNum_InvAddrMode);
  2305.             CodeLen = 0;
  2306.           }
  2307.           else
  2308.           {
  2309.             AdrResult.AdrPart = ((AdrResult.AdrPart & 7) << 3) | (AdrResult.AdrPart >> 3);
  2310.             WAsmCode[0] |= AdrResult.AdrPart << 6;
  2311.             CopyAdrVals(WAsmCode + (CodeLen >> 1), &AdrResult);
  2312.             CodeLen += AdrResult.Cnt;
  2313.           }
  2314.         }
  2315.       }
  2316.     }
  2317.   }
  2318. }
  2319.  
  2320. static void DecodeLEA(Word Index)
  2321. {
  2322.   UNUSED(Index);
  2323.  
  2324.   if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  2325.   else if (!ChkArgCnt(2, 2));
  2326.   else
  2327.   {
  2328.     tAdrResult AdrResult;
  2329.  
  2330.     if (DecodeAdr(&ArgStr[2], MModAdr, &AdrResult))
  2331.     {
  2332.       OpSize = eSymbolSize8Bit;
  2333.       WAsmCode[0] = 0x41c0 | ((AdrResult.AdrPart & 7) << 9);
  2334.       if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
  2335.       {
  2336.         WAsmCode[0] |= AdrResult.AdrPart;
  2337.         CodeLen = 2 + AdrResult.Cnt;
  2338.         CopyAdrVals(WAsmCode + 1, &AdrResult);
  2339.       }
  2340.     }
  2341.   }
  2342. }
  2343.  
  2344. /* 0=ASR 1=ASL 2=LSR 3=LSL 4=ROXR 5=ROXL 6=ROR 7=ROL */
  2345.  
  2346. static void DecodeShift(Word Index)
  2347. {
  2348.   Boolean ValOK;
  2349.   Byte HVal8;
  2350.   Word LFlag = (Index >> 2), Op = Index & 3;
  2351.  
  2352.   if (!ChkArgCnt(1, 2));
  2353.   else if ((*OpPart.str.p_str == 'R') && (!CheckNoFamily(1 << eColdfire)));
  2354.   else
  2355.   {
  2356.     tAdrResult AdrResult;
  2357.  
  2358.     if (DecodeAdr(&ArgStr[ArgCnt], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult) == ModData)
  2359.     {
  2360.       if (CheckColdSize())
  2361.       {
  2362.         WAsmCode[0] = 0xe000 | AdrResult.AdrPart | (Op << 3) | (OpSize << 6) | (LFlag << 8);
  2363.         OpSize = eSymbolSizeShiftCnt;
  2364.         if (ArgCnt == 2)
  2365.           DecodeAdr(&ArgStr[1], MModData | MModImm, &AdrResult);
  2366.         else
  2367.         {
  2368.           AdrResult.AdrMode = ModImm;
  2369.           AdrResult.Vals[0] = 1;
  2370.         }
  2371.         if ((AdrResult.AdrMode == ModData) || ((AdrResult.AdrMode == ModImm) && (Lo(AdrResult.Vals[0]) >= 1) && (Lo(AdrResult.Vals[0]) <= 8)))
  2372.         {
  2373.           CodeLen = 2;
  2374.           WAsmCode[0] |= (AdrResult.AdrMode == ModData) ? 0x20 | (AdrResult.AdrPart << 9) : ((AdrResult.Vals[0] & 7) << 9);
  2375.         }
  2376.         else
  2377.           WrStrErrorPos(ErrNum_InvShiftArg, &ArgStr[1]);
  2378.       }
  2379.     }
  2380.     else if (AdrResult.AdrMode != ModNone)
  2381.     {
  2382.       if (pCurrCPUProps->Family == eColdfire) WrError(ErrNum_InvAddrMode);
  2383.       else
  2384.       {
  2385.         if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  2386.         else
  2387.         {
  2388.           WAsmCode[0] = 0xe0c0 | AdrResult.AdrPart | (Op << 9) | (LFlag << 8);
  2389.           CopyAdrVals(WAsmCode + 1, &AdrResult);
  2390.           if (2 == ArgCnt)
  2391.           {
  2392.             HVal8 = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), Int8, &ValOK);
  2393.           }
  2394.           else
  2395.           {
  2396.             HVal8 = 1;
  2397.             ValOK = True;
  2398.           }
  2399.           if ((ValOK) && (HVal8 == 1))
  2400.             CodeLen = 2 + AdrResult.Cnt;
  2401.           else
  2402.             WrStrErrorPos(ErrNum_Only1, &ArgStr[1]);
  2403.         }
  2404.       }
  2405.     }
  2406.   }
  2407. }
  2408.  
  2409. /*!------------------------------------------------------------------------
  2410.  * \fn     DecodeADDQSUBQ(Word Index)
  2411.  * \brief  Handle ADDQ/SUBQ Instructions
  2412.  * \param  Index ADDQ=0 SUBQ=1
  2413.  * ------------------------------------------------------------------------ */
  2414.  
  2415. static void DecodeADDQSUBQ(Word Index)
  2416. {
  2417.   LongWord ImmVal;
  2418.   Boolean ValOK;
  2419.   tSymbolFlags Flags;
  2420.   tAdrResult AdrResult;
  2421.  
  2422.   if (!CheckColdSize())
  2423.     return;
  2424.  
  2425.   if (!ChkArgCnt(2, 2))
  2426.     return;
  2427.  
  2428.   if (!DecodeAdr(&ArgStr[2], MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  2429.     return;
  2430.  
  2431.   if ((ModAdr == AdrResult.AdrMode) && (eSymbolSize8Bit == OpSize))
  2432.   {
  2433.     WrError(ErrNum_InvOpSize);
  2434.     return;
  2435.   }
  2436.  
  2437.   WAsmCode[0] = 0x5000 | AdrResult.AdrPart | (OpSize << 6) | (Index << 8);
  2438.   CopyAdrVals(WAsmCode + 1, &AdrResult);
  2439.   ImmVal = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), UInt32, &ValOK, &Flags);
  2440.   if (mFirstPassUnknownOrQuestionable(Flags))
  2441.     ImmVal = 1;
  2442.   if (ValOK && ((ImmVal < 1) || (ImmVal > 8)))
  2443.   {
  2444.     WrError(ErrNum_Range18);
  2445.     ValOK = False;
  2446.   }
  2447.   if (ValOK)
  2448.   {
  2449.     CodeLen = 2 + AdrResult.Cnt;
  2450.     WAsmCode[0] |= (ImmVal & 7) << 9;
  2451.   }
  2452. }
  2453.  
  2454. /* 0=SUBX 1=ADDX */
  2455.  
  2456. static void DecodeADDXSUBX(Word Index)
  2457. {
  2458.   if (CheckColdSize())
  2459.   {
  2460.     if (ChkArgCnt(2, 2))
  2461.     {
  2462.       tAdrResult AdrResult;
  2463.  
  2464.       if (DecodeAdr(&ArgStr[1], MModData | MModPre, &AdrResult))
  2465.       {
  2466.         WAsmCode[0] = 0x9100 | (OpSize << 6) | (AdrResult.AdrPart & 7) | (Index << 14);
  2467.         if (AdrResult.AdrMode == ModPre)
  2468.           WAsmCode[0] |= 8;
  2469.         if (DecodeAdr(&ArgStr[2], 1 << (AdrResult.AdrMode - 1), &AdrResult))
  2470.         {
  2471.           CodeLen = 2;
  2472.           WAsmCode[0] |= (AdrResult.AdrPart & 7) << 9;
  2473.         }
  2474.       }
  2475.     }
  2476.   }
  2477. }
  2478.  
  2479. static void DecodeCMPM(Word Index)
  2480. {
  2481.   UNUSED(Index);
  2482.  
  2483.   if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  2484.   else if (ChkArgCnt(2, 2)
  2485.         && CheckNoFamily(1 << eColdfire))
  2486.   {
  2487.     tAdrResult AdrResult;
  2488.  
  2489.     if (DecodeAdr(&ArgStr[1], MModPost, &AdrResult) == ModPost)
  2490.     {
  2491.       WAsmCode[0] = 0xb108 | (OpSize << 6) | (AdrResult.AdrPart & 7);
  2492.       if (DecodeAdr(&ArgStr[2], MModPost, &AdrResult) == ModPost)
  2493.       {
  2494.         WAsmCode[0] |= (AdrResult.AdrPart & 7) << 9;
  2495.         CodeLen = 2;
  2496.       }
  2497.     }
  2498.   }
  2499. }
  2500.  
  2501. /* 0=SUB 1=CMP 2=ADD +4=..I +8=..A */
  2502.  
  2503. static void DecodeADDSUBCMP(Word Index)
  2504. {
  2505.   Word Op = Index & 3, Reg;
  2506.   unsigned Variant = Index & VariantMask;
  2507.   Word DestMask, SrcMask;
  2508.   Boolean OpSizeOK;
  2509.  
  2510.   if (I_Variant == Variant)
  2511.     SrcMask = MModImm;
  2512.   else
  2513.     SrcMask = MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm;
  2514.  
  2515.   if (A_Variant == Variant)
  2516.     DestMask = MModAdr;
  2517.   else
  2518.   {
  2519.     DestMask = MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs;
  2520.  
  2521.     /* Since CMP only reads operands, PC-relative addressing is also
  2522.        allowed for the second operand on 68020++ */
  2523.  
  2524.     if ((as_toupper(*OpPart.str.p_str) == 'C')
  2525.      && (pCurrCPUProps->Family > e68KGen1b))
  2526.       DestMask |= MModPC | MModPCIdx;
  2527.   }
  2528.  
  2529.   /* ColdFire ISA B ff. allows 8/16 bit operand size of CMP: */
  2530.  
  2531.   if (OpSize > eSymbolSize32Bit)
  2532.     OpSizeOK = False;
  2533.   else if (OpSize == eSymbolSize32Bit)
  2534.     OpSizeOK = True;
  2535.   else
  2536.     OpSizeOK = (pCurrCPUProps->Family != eColdfire)
  2537.             || ((pCurrCPUProps->CfISA >= eCfISA_B) && (Op == 1));
  2538.  
  2539.   if (!OpSizeOK) WrError(ErrNum_InvOpSize);
  2540.   else
  2541.   {
  2542.     if (ChkArgCnt(2, 2))
  2543.     {
  2544.       tAdrResult AdrResult;
  2545.  
  2546.       switch (DecodeAdr(&ArgStr[2], DestMask, &AdrResult))
  2547.       {
  2548.         case ModAdr: /* ADDA/SUBA/CMPA ? */
  2549.           if (OpSize == eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
  2550.           else
  2551.           {
  2552.             WAsmCode[0] = 0x90c0 | ((AdrResult.AdrPart & 7) << 9) | (Op << 13);
  2553.             if (OpSize == eSymbolSize32Bit) WAsmCode[0] |= 0x100;
  2554.             if (DecodeAdr(&ArgStr[1], SrcMask, &AdrResult))
  2555.             {
  2556.               WAsmCode[0] |= AdrResult.AdrPart;
  2557.               CodeLen = 2 + AdrResult.Cnt;
  2558.               CopyAdrVals(WAsmCode + 1, &AdrResult);
  2559.             }
  2560.           }
  2561.           break;
  2562.  
  2563.         case ModData: /* ADD/SUB/CMP <ea>,Dn ? */
  2564.           WAsmCode[0] = 0x9000 | (OpSize << 6) | ((Reg = AdrResult.AdrPart) << 9) | (Op << 13);
  2565.           DecodeAdr(&ArgStr[1], SrcMask, &AdrResult);
  2566.  
  2567.           /* CMP.B An,Dn allowed for Coldfire? */
  2568.  
  2569.           if ((AdrResult.AdrMode == ModAdr) && (OpSize == eSymbolSize8Bit) && (pCurrCPUProps->Family != eColdfire)) WrError(ErrNum_InvOpSize);
  2570.           if (AdrResult.AdrMode != ModNone)
  2571.           {
  2572.             if ((AdrResult.AdrMode == ModImm) && (Variant == I_Variant))
  2573.             {
  2574.               if (Op == 1) Op = 8;
  2575.               WAsmCode[0] = 0x400 | (OpSize << 6) | (Op << 8) | Reg;
  2576.             }
  2577.             else
  2578.               WAsmCode[0] |= AdrResult.AdrPart;
  2579.             CopyAdrVals(WAsmCode + 1, &AdrResult);
  2580.             CodeLen = 2 + AdrResult.Cnt;
  2581.           }
  2582.           break;
  2583.  
  2584.         case ModNone:
  2585.           break;
  2586.  
  2587.         default: /* CMP/ADD/SUB <ea>, Dn */
  2588.           if (DecodeAdr(&ArgStr[1], MModData | MModImm, &AdrResult) == ModImm)        /* ADDI/SUBI/CMPI ? */
  2589.           {
  2590.             /* we have to set the PC offset before we decode the destination operand.  Luckily,
  2591.                this is only needed afterwards for an immediate source operand, so we know the
  2592.                # of words ahead: */
  2593.  
  2594.             if (*ArgStr[1].str.p_str == '#')
  2595.               RelPos += (OpSize == eSymbolSize32Bit) ? 4 : 2;
  2596.  
  2597.             if (Op == 1) Op = 8;
  2598.             WAsmCode[0] = 0x400 | (OpSize << 6) | (Op << 8);
  2599.             CodeLen = 2 + AdrResult.Cnt;
  2600.             CopyAdrVals(WAsmCode + 1, &AdrResult);
  2601.             if (DecodeAdr(&ArgStr[2], (pCurrCPUProps->Family == eColdfire) ? (Word)MModData : DestMask, &AdrResult))
  2602.             {
  2603.               WAsmCode[0] |= AdrResult.AdrPart;
  2604.               CopyAdrVals(WAsmCode + (CodeLen >> 1), &AdrResult);
  2605.               CodeLen += AdrResult.Cnt;
  2606.             }
  2607.             else
  2608.               CodeLen = 0;
  2609.           }
  2610.           else if (AdrResult.AdrMode != ModNone)    /* ADD Dn,<EA> ? */
  2611.           {
  2612.             if (Op == 1) WrError(ErrNum_InvCmpMode);
  2613.             else
  2614.             {
  2615.               WAsmCode[0] = 0x9100 | (OpSize << 6) | (AdrResult.AdrPart << 9) | (Op << 13);
  2616.               if (DecodeAdr(&ArgStr[2], DestMask, &AdrResult))
  2617.               {
  2618.                 CodeLen = 2 + AdrResult.Cnt; CopyAdrVals(WAsmCode + 1, &AdrResult);
  2619.                 WAsmCode[0] |= AdrResult.AdrPart;
  2620.               }
  2621.             }
  2622.           }
  2623.       }
  2624.     }
  2625.   }
  2626. }
  2627.  
  2628. /* 0=OR 1=AND +4=..I */
  2629.  
  2630. static void DecodeANDOR(Word Index)
  2631. {
  2632.   Word Op = Index & 3, Reg;
  2633.   char Variant = Index & VariantMask;
  2634.   tAdrResult AdrResult;
  2635.  
  2636.   if (!ChkArgCnt(2, 2));
  2637.   else if (CheckColdSize())
  2638.   {
  2639.     if (!as_strcasecmp(ArgStr[2].str.p_str, "CCR"))     /* AND #...,CCR */
  2640.     {
  2641.       if (*AttrPart.str.p_str && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
  2642.       else if (!(pCurrCPUProps->SuppFlags & eFlagLogCCR)) WrError(ErrNum_InstructionNotSupported);
  2643.       {
  2644.         WAsmCode[0] = 0x003c | (Op << 9);
  2645.         OpSize = eSymbolSize8Bit;
  2646.         if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
  2647.         {
  2648.           CodeLen = 4;
  2649.           WAsmCode[1] = AdrResult.Vals[0];
  2650.         }
  2651.       }
  2652.     }
  2653.     else if (!as_strcasecmp(ArgStr[2].str.p_str, "SR")) /* AND #...,SR */
  2654.     {
  2655.       if (*AttrPart.str.p_str && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  2656.       else if (CheckNoFamily(1 << eColdfire))
  2657.       {
  2658.         WAsmCode[0] = 0x007c | (Op << 9);
  2659.         OpSize = eSymbolSize16Bit;
  2660.         if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
  2661.         {
  2662.           CodeLen = 4;
  2663.           WAsmCode[1] = AdrResult.Vals[0];
  2664.           CheckSup();
  2665.         }
  2666.       }
  2667.     }
  2668.     else
  2669.     {
  2670.       DecodeAdr(&ArgStr[2], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult);
  2671.       if (AdrResult.AdrMode == ModData)                 /* AND <EA>,Dn */
  2672.       {
  2673.         Reg = AdrResult.AdrPart;
  2674.         WAsmCode[0] = 0x8000 | (OpSize << 6) | (Reg << 9) | (Op << 14);
  2675.         if (DecodeAdr(&ArgStr[1], ((Variant == I_Variant) ? 0 : MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs) | MModImm, &AdrResult))
  2676.         {
  2677.           if ((AdrResult.AdrMode == ModImm) && (Variant == I_Variant))
  2678.             WAsmCode[0] = (OpSize << 6) | (Op << 9) | Reg;
  2679.           else
  2680.             WAsmCode[0] |= AdrResult.AdrPart;
  2681.           CodeLen = 2 + AdrResult.Cnt;
  2682.           CopyAdrVals(WAsmCode + 1, &AdrResult);
  2683.         }
  2684.       }
  2685.       else if (AdrResult.AdrMode != ModNone)                 /* AND ...,<EA> */
  2686.       {
  2687.         if (DecodeAdr(&ArgStr[1], MModData | MModImm, &AdrResult) == ModImm)                   /* AND #..,<EA> */
  2688.         {
  2689.           WAsmCode[0] = (OpSize << 6) | (Op << 9);
  2690.           CodeLen = 2 + AdrResult.Cnt;
  2691.           CopyAdrVals(WAsmCode + 1, &AdrResult);
  2692.           if (DecodeAdr(&ArgStr[2], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  2693.           {
  2694.             WAsmCode[0] |= AdrResult.AdrPart;
  2695.             CopyAdrVals(WAsmCode + (CodeLen >> 1), &AdrResult);
  2696.             CodeLen += AdrResult.Cnt;
  2697.           }
  2698.           else
  2699.             CodeLen = 0;
  2700.         }
  2701.         else if (AdrResult.AdrMode != ModNone)               /* AND Dn,<EA> ? */
  2702.         {
  2703.           WAsmCode[0] = 0x8100 | (OpSize << 6) | (AdrResult.AdrPart << 9) | (Op << 14);
  2704.           if (DecodeAdr(&ArgStr[2], MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  2705.           {
  2706.             CodeLen = 2 + AdrResult.Cnt;
  2707.             CopyAdrVals(WAsmCode + 1, &AdrResult);
  2708.             WAsmCode[0] |= AdrResult.AdrPart;
  2709.           }
  2710.         }
  2711.       }
  2712.     }
  2713.   }
  2714. }
  2715.  
  2716. /* 0=EOR 4=EORI */
  2717.  
  2718. static void DecodeEOR(Word Index)
  2719. {
  2720.   unsigned Variant = Index | VariantMask;
  2721.   tAdrResult AdrResult;
  2722.  
  2723.   if (!ChkArgCnt(2, 2));
  2724.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "CCR"))
  2725.   {
  2726.     if (*AttrPart.str.p_str && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
  2727.     else if (CheckNoFamily(1 << eColdfire))
  2728.     {
  2729.       WAsmCode[0] = 0xa3c;
  2730.       OpSize = eSymbolSize8Bit;
  2731.       if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
  2732.       {
  2733.         CodeLen = 4;
  2734.         WAsmCode[1] = AdrResult.Vals[0];
  2735.       }
  2736.     }
  2737.   }
  2738.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "SR"))
  2739.   {
  2740.     if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  2741.     else if (CheckNoFamily(1 << eColdfire))
  2742.     {
  2743.       WAsmCode[0] = 0xa7c;
  2744.       if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
  2745.       {
  2746.         CodeLen = 4;
  2747.         WAsmCode[1] = AdrResult.Vals[0];
  2748.         CheckSup();
  2749.       }
  2750.     }
  2751.   }
  2752.   else if (CheckColdSize())
  2753.   {
  2754.     if (DecodeAdr(&ArgStr[1], ((Variant == I_Variant) ? 0 : MModData) | MModImm, &AdrResult) == ModData)
  2755.     {
  2756.       WAsmCode[0] = 0xb100 | (AdrResult.AdrPart << 9) | (OpSize << 6);
  2757.       if (DecodeAdr(&ArgStr[2], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  2758.       {
  2759.         CodeLen = 2 + AdrResult.Cnt;
  2760.         CopyAdrVals(WAsmCode + 1, &AdrResult);
  2761.         WAsmCode[0] |= AdrResult.AdrPart;
  2762.       }
  2763.     }
  2764.     else if (AdrResult.AdrMode == ModImm)
  2765.     {
  2766.       WAsmCode[0] = 0x0a00 | (OpSize << 6);
  2767.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  2768.       CodeLen = 2 + AdrResult.Cnt;
  2769.       if (DecodeAdr(&ArgStr[2], MModData | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs), &AdrResult))
  2770.       {
  2771.         CopyAdrVals(WAsmCode + (CodeLen >> 1), &AdrResult);
  2772.         CodeLen += AdrResult.Cnt;
  2773.         WAsmCode[0] |= AdrResult.AdrPart;
  2774.       }
  2775.       else CodeLen = 0;
  2776.     }
  2777.   }
  2778. }
  2779.  
  2780. static void DecodePEA(Word Index)
  2781. {
  2782.   UNUSED(Index);
  2783.  
  2784.   if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_UseLessAttr);
  2785.   else if (ChkArgCnt(1, 1))
  2786.   {
  2787.     tAdrResult AdrResult;
  2788.  
  2789.     OpSize = eSymbolSize8Bit;
  2790.     if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
  2791.     {
  2792.       CodeLen = 2 + AdrResult.Cnt;
  2793.       WAsmCode[0] = 0x4840 | AdrResult.AdrPart;
  2794.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  2795.     }
  2796.   }
  2797. }
  2798.  
  2799. static void DecodeCLRTST(Word IsTST)
  2800. {
  2801.   if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  2802.   else if (ChkArgCnt(1, 1))
  2803.   {
  2804.     Word w1 = MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs;
  2805.     tAdrResult AdrResult;
  2806.  
  2807.     switch (pCurrCPUProps->Family)
  2808.     {
  2809.       case eCPU32:
  2810.       case e68KGen2:
  2811.       case e68KGen3:
  2812.         if (IsTST)
  2813.         {
  2814.           w1 |= MModPC | MModPCIdx | MModImm;
  2815.           if (OpSize != eSymbolSize8Bit)
  2816.             w1 |= MModAdr;
  2817.         }
  2818.         break;
  2819.       default:
  2820.         break;
  2821.     }
  2822.     if (DecodeAdr(&ArgStr[1], w1, &AdrResult))
  2823.     {
  2824.       CodeLen = 2 + AdrResult.Cnt;
  2825.       WAsmCode[0] = 0x4200 | (IsTST << 11) | (OpSize << 6) | AdrResult.AdrPart;
  2826.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  2827.     }
  2828.   }
  2829. }
  2830.  
  2831. /* 0=JSR 1=JMP */
  2832.  
  2833. static void DecodeJSRJMP(Word Index)
  2834. {
  2835.   if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  2836.   else if (ChkArgCnt(1, 1))
  2837.   {
  2838.     tAdrResult AdrResult;
  2839.  
  2840.     if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
  2841.     {
  2842.       CodeLen = 2 + AdrResult.Cnt;
  2843.       WAsmCode[0] = 0x4e80 | (Index << 6) | AdrResult.AdrPart;
  2844.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  2845.     }
  2846.   }
  2847. }
  2848.  
  2849. /* 0=TAS 1=NBCD */
  2850.  
  2851. static void DecodeNBCDTAS(Word Index)
  2852. {
  2853.   Boolean Allowed;
  2854.  
  2855.   /* TAS is allowed on ColdFire ISA B ff. ... */
  2856.  
  2857.   if (pCurrCPUProps->Family != eColdfire)
  2858.     Allowed = True;
  2859.   else
  2860.     Allowed = Index ? False : (pCurrCPUProps->CfISA >= eCfISA_B);
  2861.  
  2862.   if (*AttrPart.str.p_str && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
  2863.   else if (!Allowed) WrError(ErrNum_InstructionNotSupported);
  2864.   else if (ChkArgCnt(1, 1))
  2865.   {
  2866.     tAdrResult AdrResult;
  2867.  
  2868.     OpSize = eSymbolSize8Bit;
  2869.  
  2870.     /* ...but not on data register: */
  2871.  
  2872.     if (DecodeAdr(&ArgStr[1], ((pCurrCPUProps->Family == eColdfire) ? 0 : MModData) | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  2873.     {
  2874.       CodeLen = 2 + AdrResult.Cnt;
  2875.       WAsmCode[0] = (Index == 1) ? 0x4800 : 0x4ac0;
  2876.       WAsmCode[0] |= AdrResult.AdrPart;
  2877.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  2878.     }
  2879.   }
  2880. }
  2881.  
  2882. /* 0=NEGX 2=NEG 3=NOT */
  2883.  
  2884. static void DecodeNEGNOT(Word Index)
  2885. {
  2886.   if (ChkArgCnt(1, 1)
  2887.    && CheckColdSize())
  2888.   {
  2889.     tAdrResult AdrResult;
  2890.  
  2891.     if (DecodeAdr(&ArgStr[1], (pCurrCPUProps->Family == eColdfire) ? MModData : (MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs), &AdrResult))
  2892.     {
  2893.       CodeLen = 2 + AdrResult.Cnt;
  2894.       WAsmCode[0] = 0x4000 | (Index << 9) | (OpSize << 6) | AdrResult.AdrPart;
  2895.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  2896.     }
  2897.   }
  2898. }
  2899.  
  2900. static void DecodeSWAP(Word Index)
  2901. {
  2902.   UNUSED(Index);
  2903.  
  2904.   if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  2905.   else if (ChkArgCnt(1, 1))
  2906.   {
  2907.     tAdrResult AdrResult;
  2908.  
  2909.     if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
  2910.     {
  2911.       CodeLen = 2;
  2912.       WAsmCode[0] = 0x4840 | AdrResult.AdrPart;
  2913.     }
  2914.   }
  2915. }
  2916.  
  2917. static void DecodeUNLK(Word Index)
  2918. {
  2919.   UNUSED(Index);
  2920.  
  2921.   if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  2922.   else if (ChkArgCnt(1, 1))
  2923.   {
  2924.     tAdrResult AdrResult;
  2925.  
  2926.     if (DecodeAdr(&ArgStr[1], MModAdr, &AdrResult))
  2927.     {
  2928.       CodeLen = 2;
  2929.       WAsmCode[0] = 0x4e58 | AdrResult.AdrPart;
  2930.     }
  2931.   }
  2932. }
  2933.  
  2934. static void DecodeEXT(Word Index)
  2935. {
  2936.   UNUSED(Index);
  2937.  
  2938.   if (!ChkArgCnt(1, 1));
  2939.   else if ((OpSize == eSymbolSize8Bit) || (OpSize > eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  2940.   else
  2941.   {
  2942.     tAdrResult AdrResult;
  2943.  
  2944.     if (DecodeAdr(&ArgStr[1], MModData, &AdrResult) == ModData)
  2945.     {
  2946.       WAsmCode[0] = 0x4880 | AdrResult.AdrPart | (((Word)OpSize - 1) << 6);
  2947.       CodeLen = 2;
  2948.     }
  2949.   }
  2950. }
  2951.  
  2952. static void DecodeWDDATA(Word Index)
  2953. {
  2954.   UNUSED(Index);
  2955.  
  2956.   if (!ChkArgCnt(1, 1));
  2957.   else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  2958.   else if (CheckFamily(1 << eColdfire))
  2959.   {
  2960.     tAdrResult AdrResult;
  2961.  
  2962.     if (DecodeAdr(&ArgStr[1], MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  2963.     {
  2964.       WAsmCode[0] = 0xf400 + (OpSize << 6) + AdrResult.AdrPart;
  2965.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  2966.       CodeLen = 2 + AdrResult.Cnt;
  2967.       CheckSup();
  2968.     }
  2969.   }
  2970. }
  2971.  
  2972. static void DecodeWDEBUG(Word Index)
  2973. {
  2974.   UNUSED(Index);
  2975.  
  2976.   if (ChkArgCnt(1, 1)
  2977.    && CheckFamily(1 << eColdfire)
  2978.    && CheckColdSize())
  2979.   {
  2980.     tAdrResult AdrResult;
  2981.  
  2982.     if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI, &AdrResult))
  2983.     {
  2984.       WAsmCode[0] = 0xfbc0 + AdrResult.AdrPart;
  2985.       WAsmCode[1] = 0x0003;
  2986.       CopyAdrVals(WAsmCode + 2, &AdrResult);
  2987.       CodeLen = 4 + AdrResult.Cnt;
  2988.       CheckSup();
  2989.     }
  2990.   }
  2991. }
  2992.  
  2993. static void DecodeFixed(Word Index)
  2994. {
  2995.   FixedOrder *FixedZ = FixedOrders + Index;
  2996.  
  2997.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2998.   else if (ChkArgCnt(0, 0)
  2999.         && CheckFamily(FixedZ->FamilyMask))
  3000.   {
  3001.     CodeLen = 2;
  3002.     WAsmCode[0] = FixedZ->Code;
  3003.     if (FixedZ->MustSup)
  3004.       CheckSup();
  3005.   }
  3006. }
  3007.  
  3008. static void DecodeMOVEM(Word Index)
  3009. {
  3010.   int z;
  3011.   UNUSED(Index);
  3012.  
  3013.   if (!ChkArgCnt(2, 2));
  3014.   else if ((OpSize < eSymbolSize16Bit) || (OpSize > eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  3015.   else if ((pCurrCPUProps->Family == eColdfire) && (OpSize == 1)) WrError(ErrNum_InvOpSize);
  3016.   else
  3017.   {
  3018.     tAdrResult AdrResult;
  3019.  
  3020.     RelPos = 4;
  3021.     if (DecodeRegList(&ArgStr[2], WAsmCode + 1))
  3022.     {
  3023.       if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModPost | MModAIX | MModPC | MModPCIdx | MModAbs), &AdrResult))
  3024.       {
  3025.         WAsmCode[0] = 0x4c80 | AdrResult.AdrPart | ((OpSize - 1) << 6);
  3026.         CodeLen = 4 + AdrResult.Cnt; CopyAdrVals(WAsmCode + 2, &AdrResult);
  3027.       }
  3028.     }
  3029.     else if (DecodeRegList(&ArgStr[1], WAsmCode + 1))
  3030.     {
  3031.       if (DecodeAdr(&ArgStr[2], MModAdrI | MModDAdrI  | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModPre | MModAIX | MModAbs), &AdrResult))
  3032.       {
  3033.         WAsmCode[0] = 0x4880 | AdrResult.AdrPart | ((OpSize - 1) << 6);
  3034.         CodeLen = 4 + AdrResult.Cnt; CopyAdrVals(WAsmCode + 2, &AdrResult);
  3035.         if (AdrResult.AdrMode == ModPre)
  3036.         {
  3037.           Word Tmp = WAsmCode[1];
  3038.  
  3039.           WAsmCode[1] = 0;
  3040.           for (z = 0; z < 16; z++)
  3041.           {
  3042.             WAsmCode[1] = (WAsmCode[1] << 1) + (Tmp & 1);
  3043.             Tmp >>= 1;
  3044.           }
  3045.         }
  3046.       }
  3047.     }
  3048.     else WrError(ErrNum_InvRegList);
  3049.   }
  3050. }
  3051.  
  3052. static void DecodeMOVEQ(Word Index)
  3053. {
  3054.   UNUSED(Index);
  3055.  
  3056.   if (!ChkArgCnt(2, 2));
  3057.   else if ((*AttrPart.str.p_str) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  3058.   else if (*ArgStr[1].str.p_str != '#') WrStrErrorPos(ErrNum_OnlyImmAddr, &ArgStr[1]);
  3059.   else
  3060.   {
  3061.     tAdrResult AdrResult;
  3062.  
  3063.     if (DecodeAdr(&ArgStr[2], MModData, &AdrResult))
  3064.     {
  3065.       Boolean OK;
  3066.       tSymbolFlags Flags;
  3067.       LongWord Value;
  3068.  
  3069.       WAsmCode[0] = 0x7000 | (AdrResult.AdrPart << 9);
  3070.       Value = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], 1, Int32, &OK, &Flags);
  3071.       if (mFirstPassUnknown(Flags))
  3072.         Value &= 0x7f;
  3073.       else if ((Value > 0xff) && (Value < 0xffffff80ul))
  3074.         WrStrErrorPos((Value & 0x80000000ul) ? ErrNum_UnderRange : ErrNum_OverRange, &ArgStr[1]);
  3075.       else
  3076.       {
  3077.         if ((Value >= 0x80) && (Value <= 0xff))
  3078.         {
  3079.           char str[40];
  3080.           LargeWord v1 = Value, v2 = Value | 0xffffff00ul;
  3081.  
  3082.           as_snprintf(str, sizeof(str), "%llx -> %llx", v1, v2);
  3083.           WrXErrorPos(ErrNum_SignExtension, str, &ArgStr[1].Pos);
  3084.         }
  3085.         CodeLen = 2;
  3086.         WAsmCode[0] |= Value & 0xff;
  3087.       }
  3088.     }
  3089.   }
  3090. }
  3091.  
  3092. static void DecodeSTOP(Word Index)
  3093. {
  3094.   Word HVal;
  3095.   Boolean ValOK;
  3096.   UNUSED(Index);
  3097.  
  3098.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  3099.   else if (!ChkArgCnt(1, 1));
  3100.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  3101.   else
  3102.   {
  3103.     HVal = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int16, &ValOK);
  3104.     if (ValOK)
  3105.     {
  3106.       CodeLen = 4;
  3107.       WAsmCode[0] = 0x4e72;
  3108.       WAsmCode[1] = HVal;
  3109.       CheckSup();
  3110.     }
  3111.   }
  3112. }
  3113.  
  3114. static void DecodeLPSTOP(Word Index)
  3115. {
  3116.   Word HVal;
  3117.   Boolean ValOK;
  3118.   UNUSED(Index);
  3119.  
  3120.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  3121.   else if (!ChkArgCnt(1, 1));
  3122.   else if (!CheckFamily(1 << eCPU32));
  3123.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  3124.   else
  3125.   {
  3126.     HVal = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int16, &ValOK);
  3127.     if (ValOK)
  3128.     {
  3129.       CodeLen = 6;
  3130.       WAsmCode[0] = 0xf800;
  3131.       WAsmCode[1] = 0x01c0;
  3132.       WAsmCode[2] = HVal;
  3133.       CheckSup();
  3134.     }
  3135.   }
  3136. }
  3137.  
  3138. static void DecodeTRAP(Word Index)
  3139. {
  3140.   Byte HVal8;
  3141.   Boolean ValOK;
  3142.   UNUSED(Index);
  3143.  
  3144.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  3145.   else if (!ChkArgCnt(1, 1));
  3146.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  3147.   else
  3148.   {
  3149.     HVal8 = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int4, &ValOK);
  3150.     if (ValOK)
  3151.     {
  3152.       CodeLen = 2;
  3153.       WAsmCode[0] = 0x4e40 + (HVal8 & 15);
  3154.     }
  3155.   }
  3156. }
  3157.  
  3158. static void DecodeBKPT(Word Index)
  3159. {
  3160.   Byte HVal8;
  3161.   Boolean ValOK;
  3162.   UNUSED(Index);
  3163.  
  3164.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  3165.   else if (!ChkArgCnt(1, 1));
  3166.   else if (!CheckNoFamily((1 << e68KGen1a) | (1 << eColdfire)));
  3167.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  3168.   else
  3169.   {
  3170.     HVal8 = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt3, &ValOK);
  3171.     if (ValOK)
  3172.     {
  3173.       CodeLen = 2;
  3174.       WAsmCode[0] = 0x4848 + (HVal8 & 7);
  3175.     }
  3176.   }
  3177.   UNUSED(Index);
  3178. }
  3179.  
  3180. static void DecodeRTD(Word Index)
  3181. {
  3182.   Word HVal;
  3183.   Boolean ValOK;
  3184.   UNUSED(Index);
  3185.  
  3186.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  3187.   else if (!ChkArgCnt(1, 1));
  3188.   else if (!CheckNoFamily((1 << e68KGen1a) | (1 << eColdfire)));
  3189.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  3190.   else
  3191.   {
  3192.     HVal = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int16, &ValOK);
  3193.     if (ValOK)
  3194.     {
  3195.       CodeLen = 4;
  3196.       WAsmCode[0] = 0x4e74;
  3197.       WAsmCode[1] = HVal;
  3198.     }
  3199.   }
  3200. }
  3201.  
  3202. static void DecodeEXG(Word Index)
  3203. {
  3204.   Word HReg;
  3205.   UNUSED(Index);
  3206.  
  3207.   if ((*AttrPart.str.p_str) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  3208.   else if (ChkArgCnt(2, 2)
  3209.         && CheckNoFamily(1 << eColdfire))
  3210.   {
  3211.     tAdrResult AdrResult;
  3212.  
  3213.     if (DecodeAdr(&ArgStr[1], MModData | MModAdr, &AdrResult) == ModData)
  3214.     {
  3215.       WAsmCode[0] = 0xc100 | (AdrResult.AdrPart << 9);
  3216.       if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult) == ModData)
  3217.       {
  3218.         WAsmCode[0] |= 0x40 | AdrResult.AdrPart;
  3219.         CodeLen = 2;
  3220.       }
  3221.       else if (AdrResult.AdrMode == ModAdr)
  3222.       {
  3223.         WAsmCode[0] |= 0x88 | (AdrResult.AdrPart & 7);
  3224.         CodeLen = 2;
  3225.       }
  3226.     }
  3227.     else if (AdrResult.AdrMode == ModAdr)
  3228.     {
  3229.       WAsmCode[0] = 0xc100;
  3230.       HReg = AdrResult.AdrPart & 7;
  3231.       if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult) == ModData)
  3232.       {
  3233.         WAsmCode[0] |= 0x88 | (AdrResult.AdrPart << 9) | HReg;
  3234.         CodeLen = 2;
  3235.       }
  3236.       else
  3237.       {
  3238.         WAsmCode[0] |= 0x48 | (HReg << 9) | (AdrResult.AdrPart & 7);
  3239.         CodeLen = 2;
  3240.       }
  3241.     }
  3242.   }
  3243. }
  3244.  
  3245. static void DecodeMOVE16(Word Index)
  3246. {
  3247.   Word z, z2, w1, w2;
  3248.   UNUSED(Index);
  3249.  
  3250.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  3251.   else if (ChkArgCnt(2, 2)
  3252.         && CheckFamily(1 << e68KGen3))
  3253.   {
  3254.     tAdrResult AdrResult;
  3255.  
  3256.     if (DecodeAdr(&ArgStr[1], MModPost | MModAdrI | MModAbs, &AdrResult))
  3257.     {
  3258.       w1 = AdrResult.AdrMode;
  3259.       z = AdrResult.AdrPart & 7;
  3260.       if ((w1 == ModAbs) && (AdrResult.Cnt == 2))
  3261.       {
  3262.         AdrResult.Vals[1] = AdrResult.Vals[0];
  3263.         AdrResult.Vals[0] = 0 - (AdrResult.Vals[1] >> 15);
  3264.       }
  3265.       if (DecodeAdr(&ArgStr[2], MModPost | MModAdrI | MModAbs, &AdrResult))
  3266.       {
  3267.         w2 = AdrResult.AdrMode;
  3268.         z2 = AdrResult.AdrPart & 7;
  3269.         if ((w2 == ModAbs) && (AdrResult.Cnt == 2))
  3270.         {
  3271.           AdrResult.Vals[1] = AdrResult.Vals[0];
  3272.           AdrResult.Vals[0] = 0 - (AdrResult.Vals[1] >> 15);
  3273.         }
  3274.         if ((w1 == ModPost) && (w2 == ModPost))
  3275.         {
  3276.           WAsmCode[0] = 0xf620 + z;
  3277.           WAsmCode[1] = 0x8000 + (z2 << 12);
  3278.           CodeLen = 4;
  3279.         }
  3280.         else
  3281.         {
  3282.           WAsmCode[1] = AdrResult.Vals[0];
  3283.           WAsmCode[2] = AdrResult.Vals[1];
  3284.           CodeLen = 6;
  3285.           if ((w1 == ModPost) && (w2 == ModAbs))
  3286.             WAsmCode[0] = 0xf600 + z;
  3287.           else if ((w1 == ModAbs) && (w2 == ModPost))
  3288.             WAsmCode[0] = 0xf608 + z2;
  3289.           else if ((w1 == ModAdrI) && (w2 == ModAbs))
  3290.             WAsmCode[0] = 0xf610 + z;
  3291.           else if ((w1 == ModAbs) && (w2 == ModAdrI))
  3292.             WAsmCode[0] = 0xf618 + z2;
  3293.           else
  3294.           {
  3295.             WrError(ErrNum_InvAddrMode);
  3296.             CodeLen = 0;
  3297.           }
  3298.         }
  3299.       }
  3300.     }
  3301.   }
  3302. }
  3303.  
  3304. static void DecodeCacheAll(Word Index)
  3305. {
  3306.   Word w1;
  3307.  
  3308.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  3309.   else if (!ChkArgCnt(1, 1));
  3310.   else if (!CheckFamily(1 << e68KGen3));
  3311.   else if (!CodeCache(ArgStr[1].str.p_str, &w1)) WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
  3312.   else
  3313.   {
  3314.     WAsmCode[0] = 0xf418 + (w1 << 6) + (Index << 5);
  3315.     CodeLen = 2;
  3316.     CheckSup();
  3317.   }
  3318. }
  3319.  
  3320. static void DecodeCache(Word Index)
  3321. {
  3322.   Word w1;
  3323.  
  3324.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  3325.   else if (!ChkArgCnt(2, 2));
  3326.   else if (!CheckFamily(1 << e68KGen3));
  3327.   else if (!CodeCache(ArgStr[1].str.p_str, &w1)) WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
  3328.   else
  3329.   {
  3330.     tAdrResult AdrResult;
  3331.  
  3332.     if (DecodeAdr(&ArgStr[2], MModAdrI, &AdrResult))
  3333.     {
  3334.       WAsmCode[0] = 0xf400 + (w1 << 6) + (Index << 3) + (AdrResult.AdrPart & 7);
  3335.       CodeLen = 2;
  3336.       CheckSup();
  3337.     }
  3338.   }
  3339. }
  3340.  
  3341. static void DecodeMUL_DIV(Word Code)
  3342. {
  3343.   tAdrResult AdrResult;
  3344.  
  3345.   if (!ChkArgCnt(2, 2));
  3346.   else if ((*OpPart.str.p_str == 'D') && !CheckNoFamily(1 << eColdfire));
  3347.   else if (OpSize == eSymbolSize16Bit)
  3348.   {
  3349.     if (DecodeAdr(&ArgStr[2], MModData, &AdrResult))
  3350.     {
  3351.       WAsmCode[0] = 0x80c0 | (AdrResult.AdrPart << 9) | (Code & 0x0100);
  3352.       if (!(Code & 1))
  3353.         WAsmCode[0] |= 0x4000;
  3354.       if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm, &AdrResult))
  3355.       {
  3356.         WAsmCode[0] |= AdrResult.AdrPart;
  3357.         CodeLen = 2 + AdrResult.Cnt; CopyAdrVals(WAsmCode + 1, &AdrResult);
  3358.       }
  3359.     }
  3360.   }
  3361.   else if (OpSize == eSymbolSize32Bit)
  3362.   {
  3363.     Word w1, w2;
  3364.     Boolean OK;
  3365.  
  3366.     if (strchr(ArgStr[2].str.p_str, ':'))
  3367.       OK = DecodeRegPair(&ArgStr[2], &w1, &w2);
  3368.     else
  3369.     {
  3370.       OK = DecodeReg(&ArgStr[2], &w1, True) && (w1 < 8);
  3371.       w2 = w1;
  3372.     }
  3373.     if (!OK) WrStrErrorPos(ErrNum_InvRegPair, &ArgStr[2]);
  3374.     else
  3375.     {
  3376.       WAsmCode[1] = w1 | (w2 << 12) | ((Code & 0x0100) << 3);
  3377.       RelPos = 4;
  3378.       if (w1 != w2)
  3379.         WAsmCode[1] |= 0x400;
  3380.       if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm, &AdrResult))
  3381.       {
  3382.         WAsmCode[0] = 0x4c00 + AdrResult.AdrPart + (Lo(Code) << 6);
  3383.         CopyAdrVals(WAsmCode + 2, &AdrResult);
  3384.         CodeLen = 4 + AdrResult.Cnt;
  3385.         CheckFamily((1 << e68KGen3) | (1 << e68KGen2) | (1 << eCPU32) | ((w1 == w2) ? (1 << eColdfire) : 0));
  3386.       }
  3387.     }
  3388.   }
  3389.   else
  3390.     WrError(ErrNum_InvOpSize);
  3391. }
  3392.  
  3393. static void DecodeDIVL(Word Index)
  3394. {
  3395.   Word w1, w2;
  3396.  
  3397.   if (!*AttrPart.str.p_str)
  3398.     OpSize = eSymbolSize32Bit;
  3399.   if (!ChkArgCnt(2, 2));
  3400.   else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2) | (1 << eCPU32)));
  3401.   else if (OpSize != eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  3402.   else if (!DecodeRegPair(&ArgStr[2], &w1, &w2)) WrStrErrorPos(ErrNum_InvRegPair, &ArgStr[2]);
  3403.   else
  3404.   {
  3405.     tAdrResult AdrResult;
  3406.  
  3407.     RelPos = 4;
  3408.     WAsmCode[1] = w1 | (w2 << 12) | (Index << 11);
  3409.     if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm, &AdrResult))
  3410.     {
  3411.       WAsmCode[0] = 0x4c40 + AdrResult.AdrPart;
  3412.       CopyAdrVals(WAsmCode + 2, &AdrResult);
  3413.       CodeLen = 4 + AdrResult.Cnt;
  3414.     }
  3415.   }
  3416. }
  3417.  
  3418. static void DecodeASBCD(Word Index)
  3419. {
  3420.   if ((OpSize != eSymbolSize8Bit) && *AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  3421.   else if (ChkArgCnt(2, 2)
  3422.         && CheckNoFamily(1 << eColdfire))
  3423.   {
  3424.     tAdrResult AdrResult;
  3425.  
  3426.     OpSize = eSymbolSize8Bit;
  3427.     if (DecodeAdr(&ArgStr[1], MModData | MModPre, &AdrResult))
  3428.     {
  3429.       WAsmCode[0] = 0x8100 | (AdrResult.AdrPart & 7) | (Index << 14) | ((AdrResult.AdrMode == ModPre) ? 8 : 0);
  3430.       if (DecodeAdr(&ArgStr[2], 1 << (AdrResult.AdrMode - 1), &AdrResult))
  3431.       {
  3432.         CodeLen = 2;
  3433.         WAsmCode[0] |= (AdrResult.AdrPart & 7) << 9;
  3434.       }
  3435.     }
  3436.   }
  3437. }
  3438.  
  3439. static void DecodeCHK(Word Index)
  3440. {
  3441.   UNUSED(Index);
  3442.  
  3443.   if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  3444.   else if (ChkArgCnt(2, 2)
  3445.         && CheckNoFamily(1 << eColdfire))
  3446.   {
  3447.     tAdrResult AdrResult;
  3448.  
  3449.     if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm, &AdrResult))
  3450.     {
  3451.       WAsmCode[0] = 0x4000 | AdrResult.AdrPart | ((4 - OpSize) << 7);
  3452.       CodeLen = 2 + AdrResult.Cnt;
  3453.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  3454.       if (DecodeAdr(&ArgStr[2], MModData, &AdrResult) == ModData)
  3455.         WAsmCode[0] |= WAsmCode[0] | (AdrResult.AdrPart << 9);
  3456.       else
  3457.         CodeLen = 0;
  3458.     }
  3459.   }
  3460. }
  3461.  
  3462. static void DecodeLINK(Word Index)
  3463. {
  3464.   UNUSED(Index);
  3465.  
  3466.   if (!*AttrPart.str.p_str && (pCurrCPUProps->Family == eColdfire)) OpSize = eSymbolSize16Bit;
  3467.   if ((OpSize < 1) || (OpSize > 2)) WrError(ErrNum_InvOpSize);
  3468.   else if ((OpSize == eSymbolSize32Bit) && !CheckFamily((1 << eCPU32) | (1 << e68KGen2) | (1 << e68KGen3)));
  3469.   else if (ChkArgCnt(2, 2))
  3470.   {
  3471.     tAdrResult AdrResult;
  3472.  
  3473.     if (DecodeAdr(&ArgStr[1], MModAdr, &AdrResult))
  3474.     {
  3475.       WAsmCode[0] = (OpSize == eSymbolSize16Bit) ? 0x4e50 : 0x4808;
  3476.       WAsmCode[0] += AdrResult.AdrPart & 7;
  3477.       if (DecodeAdr(&ArgStr[2], MModImm, &AdrResult) == ModImm)
  3478.       {
  3479.         CodeLen = 2 + AdrResult.Cnt;
  3480.         memcpy(WAsmCode + 1, AdrResult.Vals, AdrResult.Cnt);
  3481.       }
  3482.     }
  3483.   }
  3484. }
  3485.  
  3486. static void DecodeMOVEP(Word Index)
  3487. {
  3488.   UNUSED(Index);
  3489.  
  3490.   if ((OpSize == eSymbolSize8Bit) || (OpSize > eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  3491.   else if (ChkArgCnt(2, 2)
  3492.         && CheckNoFamily(1 << eColdfire))
  3493.   {
  3494.     tAdrResult AdrResult;
  3495.  
  3496.     if (DecodeAdr(&ArgStr[1], MModData | MModDAdrI, &AdrResult) == ModData)
  3497.     {
  3498.       WAsmCode[0] = 0x188 | ((OpSize - 1) << 6) | (AdrResult.AdrPart << 9);
  3499.       if (DecodeAdr(&ArgStr[2], MModDAdrI, &AdrResult) == ModDAdrI)
  3500.       {
  3501.         WAsmCode[0] |= AdrResult.AdrPart & 7;
  3502.         CodeLen = 4;
  3503.         WAsmCode[1] = AdrResult.Vals[0];
  3504.       }
  3505.     }
  3506.     else if (AdrResult.AdrMode == ModDAdrI)
  3507.     {
  3508.       WAsmCode[0] = 0x108 | ((OpSize - 1) << 6) | (AdrResult.AdrPart & 7);
  3509.       WAsmCode[1] = AdrResult.Vals[0];
  3510.       if (DecodeAdr(&ArgStr[2], MModData, &AdrResult) == ModData)
  3511.       {
  3512.         WAsmCode[0] |= (AdrResult.AdrPart & 7) << 9;
  3513.         CodeLen = 4;
  3514.       }
  3515.     }
  3516.   }
  3517. }
  3518.  
  3519. static void DecodeMOVEC(Word Index)
  3520. {
  3521.   UNUSED(Index);
  3522.  
  3523.   if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  3524.   else if (ChkArgCnt(2, 2))
  3525.   {
  3526.     tAdrResult AdrResult;
  3527.  
  3528.     if (DecodeCtrlReg(ArgStr[1].str.p_str, WAsmCode + 1))
  3529.     {
  3530.       if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
  3531.       {
  3532.         CodeLen = 4;
  3533.         WAsmCode[0] = 0x4e7a;
  3534.         WAsmCode[1] |= AdrResult.AdrPart << 12;
  3535.         CheckSup();
  3536.       }
  3537.     }
  3538.     else if (DecodeCtrlReg(ArgStr[2].str.p_str, WAsmCode + 1))
  3539.     {
  3540.       if (DecodeAdr(&ArgStr[1], MModData | MModAdr, &AdrResult))
  3541.       {
  3542.         CodeLen = 4;
  3543.         WAsmCode[0] = 0x4e7b;
  3544.         WAsmCode[1] |= AdrResult.AdrPart << 12; CheckSup();
  3545.       }
  3546.     }
  3547.     else
  3548.       WrError(ErrNum_InvCtrlReg);
  3549.   }
  3550. }
  3551.  
  3552. static void DecodeMOVES(Word Index)
  3553. {
  3554.   UNUSED(Index);
  3555.  
  3556.   if (!ChkArgCnt(2, 2));
  3557.   else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  3558.   else if (CheckNoFamily((1 << e68KGen1a) | (1 << eColdfire)))
  3559.   {
  3560.     tAdrResult AdrResult;
  3561.  
  3562.     switch (DecodeAdr(&ArgStr[1], MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  3563.     {
  3564.       case ModData:
  3565.       case ModAdr:
  3566.       {
  3567.         WAsmCode[1] = 0x800 | (AdrResult.AdrPart << 12);
  3568.         if (DecodeAdr(&ArgStr[2], MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  3569.         {
  3570.           WAsmCode[0] = 0xe00 | AdrResult.AdrPart | (OpSize << 6);
  3571.           CodeLen = 4 + AdrResult.Cnt;
  3572.           CopyAdrVals(WAsmCode + 2, &AdrResult);
  3573.           CheckSup();
  3574.         }
  3575.         break;
  3576.       }
  3577.       case ModNone:
  3578.         break;
  3579.       default:
  3580.       {
  3581.         WAsmCode[0] = 0xe00 | AdrResult.AdrPart | (OpSize << 6);
  3582.         CodeLen = 4 + AdrResult.Cnt;
  3583.         CopyAdrVals(WAsmCode + 2, &AdrResult);
  3584.         if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
  3585.         {
  3586.           WAsmCode[1] = AdrResult.AdrPart << 12;
  3587.           CheckSup();
  3588.         }
  3589.         else
  3590.           CodeLen = 0;
  3591.       }
  3592.     }
  3593.   }
  3594. }
  3595.  
  3596. static void DecodeCALLM(Word Index)
  3597. {
  3598.   UNUSED(Index);
  3599.  
  3600.   if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  3601.   else if (!(pCurrCPUProps->SuppFlags & eFlagCALLM_RTM)) WrError(ErrNum_InstructionNotSupported);
  3602.   else if (ChkArgCnt(2, 2))
  3603.   {
  3604.     tAdrResult AdrResult;
  3605.  
  3606.     OpSize = eSymbolSize8Bit;
  3607.     if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
  3608.     {
  3609.       WAsmCode[1] = AdrResult.Vals[0];
  3610.       RelPos = 4;
  3611.       if (DecodeAdr(&ArgStr[2], MModAdrI | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
  3612.       {
  3613.         WAsmCode[0] = 0x06c0 + AdrResult.AdrPart;
  3614.         CopyAdrVals(WAsmCode + 2, &AdrResult);
  3615.         CodeLen = 4 + AdrResult.Cnt;
  3616.       }
  3617.     }
  3618.   }
  3619. }
  3620.  
  3621. static void DecodeCAS(Word Index)
  3622. {
  3623.   UNUSED(Index);
  3624.  
  3625.   if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  3626.   else if (ChkArgCnt(3, 3)
  3627.         && CheckFamily((1 << e68KGen3) | (1 << e68KGen2)))
  3628.   {
  3629.     tAdrResult AdrResult;
  3630.  
  3631.     if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
  3632.     {
  3633.       WAsmCode[1] = AdrResult.AdrPart;
  3634.       if (DecodeAdr(&ArgStr[2], MModData, &AdrResult))
  3635.       {
  3636.         RelPos = 4;
  3637.         WAsmCode[1] += (((Word)AdrResult.AdrPart) << 6);
  3638.         if (DecodeAdr(&ArgStr[3], MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  3639.         {
  3640.           WAsmCode[0] = 0x08c0 + AdrResult.AdrPart + (((Word)OpSize + 1) << 9);
  3641.           CopyAdrVals(WAsmCode + 2, &AdrResult);
  3642.           CodeLen = 4 + AdrResult.Cnt;
  3643.         }
  3644.       }
  3645.     }
  3646.   }
  3647. }
  3648.  
  3649. static void DecodeCAS2(Word Index)
  3650. {
  3651.   Word w1, w2;
  3652.   UNUSED(Index);
  3653.  
  3654.   if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  3655.   else if (!ChkArgCnt(3, 3));
  3656.   else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2)));
  3657.   else if (!DecodeRegPair(&ArgStr[1], WAsmCode + 1, WAsmCode + 2)) WrStrErrorPos(ErrNum_InvRegPair, &ArgStr[1]);
  3658.   else if (!DecodeRegPair(&ArgStr[2], &w1, &w2)) WrStrErrorPos(ErrNum_InvRegPair, &ArgStr[2]);
  3659.   else
  3660.   {
  3661.     WAsmCode[1] += (w1 << 6);
  3662.     WAsmCode[2] += (w2 << 6);
  3663.     if (!CodeIndRegPair(&ArgStr[3], &w1, &w2)) WrStrErrorPos(ErrNum_InvRegPair, &ArgStr[3]);
  3664.     else
  3665.     {
  3666.       WAsmCode[1] += (w1 << 12);
  3667.       WAsmCode[2] += (w2 << 12);
  3668.       WAsmCode[0] = 0x0cfc + (((Word)OpSize - 1) << 9);
  3669.       CodeLen = 6;
  3670.     }
  3671.   }
  3672. }
  3673.  
  3674. static void DecodeCMPCHK2(Word Index)
  3675. {
  3676.   if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  3677.   else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2) | (1 << eCPU32)));
  3678.   else if (ChkArgCnt(2, 2))
  3679.   {
  3680.     tAdrResult AdrResult;
  3681.  
  3682.     if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
  3683.     {
  3684.       RelPos = 4;
  3685.       WAsmCode[1] = (((Word)AdrResult.AdrPart) << 12) | (Index << 11);
  3686.       if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
  3687.       {
  3688.         WAsmCode[0] = 0x00c0 + (((Word)OpSize) << 9) + AdrResult.AdrPart;
  3689.         CopyAdrVals(WAsmCode + 2, &AdrResult);
  3690.         CodeLen = 4 + AdrResult.Cnt;
  3691.       }
  3692.     }
  3693.   }
  3694. }
  3695.  
  3696. static void DecodeEXTB(Word Index)
  3697. {
  3698.   UNUSED(Index);
  3699.  
  3700.   if ((OpSize != eSymbolSize32Bit) && *AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  3701.   else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2) | (1 << eCPU32)));
  3702.   else if (ChkArgCnt(1, 1))
  3703.   {
  3704.     tAdrResult AdrResult;
  3705.  
  3706.     if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
  3707.     {
  3708.       WAsmCode[0] = 0x49c0 + AdrResult.AdrPart;
  3709.       CodeLen = 2;
  3710.     }
  3711.   }
  3712. }
  3713.  
  3714. static void DecodePACK(Word Index)
  3715. {
  3716.   if (!ChkArgCnt(3, 3));
  3717.   else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2)));
  3718.   else if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  3719.   else
  3720.   {
  3721.     tAdrResult AdrResult;
  3722.  
  3723.     if (DecodeAdr(&ArgStr[1], MModData | MModPre, &AdrResult))
  3724.     {
  3725.       WAsmCode[0] = (0x8140 + (Index << 6)) | (AdrResult.AdrPart & 7);
  3726.       if (AdrResult.AdrMode == ModPre)
  3727.         WAsmCode[0] += 8;
  3728.       if (DecodeAdr(&ArgStr[2], 1 << (AdrResult.AdrMode - 1), &AdrResult))
  3729.       {
  3730.         WAsmCode[0] |= ((AdrResult.AdrPart & 7) << 9);
  3731.         if (DecodeAdr(&ArgStr[3], MModImm, &AdrResult))
  3732.         {
  3733.           WAsmCode[1] = AdrResult.Vals[0];
  3734.           CodeLen = 4;
  3735.         }
  3736.       }
  3737.     }
  3738.   }
  3739. }
  3740.  
  3741. static void DecodeRTM(Word Index)
  3742. {
  3743.   UNUSED(Index);
  3744.  
  3745.   if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  3746.   else if (!(pCurrCPUProps->SuppFlags & eFlagCALLM_RTM)) WrError(ErrNum_InstructionNotSupported);
  3747.   else if (ChkArgCnt(1, 1))
  3748.   {
  3749.     tAdrResult AdrResult;
  3750.  
  3751.     if (DecodeAdr(&ArgStr[1], MModData | MModAdr, &AdrResult))
  3752.     {
  3753.       WAsmCode[0] = 0x06c0 + AdrResult.AdrPart;
  3754.       CodeLen = 2;
  3755.     }
  3756.   }
  3757. }
  3758.  
  3759. static void DecodeTBL(Word Index)
  3760. {
  3761.   char *p;
  3762.   Word w2, Mode;
  3763.  
  3764.   if (!ChkArgCnt(2, 2));
  3765.   else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  3766.   else if (CheckFamily(1 << eCPU32))
  3767.   {
  3768.     tAdrResult AdrResult;
  3769.  
  3770.     if (DecodeAdr(&ArgStr[2], MModData, &AdrResult))
  3771.     {
  3772.       Mode = AdrResult.AdrPart;
  3773.       p = strchr(ArgStr[1].str.p_str, ':');
  3774.       if (!p)
  3775.       {
  3776.         RelPos = 4;
  3777.         if (DecodeAdr(&ArgStr[1], MModAdrI | MModDAdrI | MModAIX| MModAbs | MModPC | MModPCIdx, &AdrResult))
  3778.         {
  3779.           WAsmCode[0] = 0xf800 | AdrResult.AdrPart;
  3780.           WAsmCode[1] = 0x0100 | (OpSize << 6) | (Mode << 12) | (Index << 10);
  3781.           memcpy(WAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  3782.           CodeLen = 4 + AdrResult.Cnt;
  3783.         }
  3784.       }
  3785.       else
  3786.       {
  3787.         strcpy(ArgStr[3].str.p_str, p + 1);
  3788.         *p = '\0';
  3789.         if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
  3790.         {
  3791.           w2 = AdrResult.AdrPart;
  3792.           if (DecodeAdr(&ArgStr[3], MModData, &AdrResult))
  3793.           {
  3794.             WAsmCode[0] = 0xf800 | w2;
  3795.             WAsmCode[1] = 0x0000 | (OpSize << 6) | (Mode << 12) | AdrResult.AdrPart;
  3796.             if (OpPart.str.p_str[3] == 'S')
  3797.               WAsmCode[1] |= 0x0800;
  3798.             if (OpPart.str.p_str[strlen(OpPart.str.p_str) - 1] == 'N')
  3799.               WAsmCode[1] |= 0x0400;
  3800.             CodeLen = 4;
  3801.           }
  3802.         }
  3803.       }
  3804.     }
  3805.   }
  3806. }
  3807.  
  3808. /* 0=BTST 1=BCHG 2=BCLR 3=BSET */
  3809.  
  3810. static void DecodeBits(Word Index)
  3811. {
  3812.   Word Mask, BitNum, BitMax;
  3813.   tSymbolSize SaveOpSize;
  3814.   unsigned ResCodeLen;
  3815.   Boolean BitNumUnknown = False;
  3816.   tAdrResult AdrResult;
  3817.  
  3818.   if (!ChkArgCnt(2, 2))
  3819.     return;
  3820.  
  3821.   WAsmCode[0] = (Index << 6);
  3822.   ResCodeLen = 1;
  3823.  
  3824.   SaveOpSize = OpSize;
  3825.   OpSize = eSymbolSize8Bit;
  3826.   switch (DecodeAdr(&ArgStr[1], MModData | MModImm, &AdrResult))
  3827.   {
  3828.     case ModData:
  3829.       WAsmCode[0] |= 0x100 | (AdrResult.AdrPart << 9);
  3830.       BitNum = 0; /* implicitly suppresses bit pos check */
  3831.       break;
  3832.     case ModImm:
  3833.       WAsmCode[0] |= 0x800;
  3834.       WAsmCode[ResCodeLen++] = BitNum = AdrResult.Vals[0];
  3835.       BitNumUnknown = mFirstPassUnknown(AdrResult.ImmSymFlags);
  3836.       break;
  3837.     default:
  3838.       return;
  3839.   }
  3840.  
  3841.   OpSize = SaveOpSize;
  3842.   if (!*AttrPart.str.p_str)
  3843.     OpSize = eSymbolSize8Bit;
  3844.  
  3845.   Mask = MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs;
  3846.   if (!Index)
  3847.     Mask |= MModPC | MModPCIdx | MModImm;
  3848.   RelPos = ResCodeLen << 1;
  3849.   DecodeAdr(&ArgStr[2], Mask, &AdrResult);
  3850.  
  3851.   if (!*AttrPart.str.p_str)
  3852.     OpSize = (AdrResult.AdrMode == ModData) ? eSymbolSize32Bit : eSymbolSize8Bit;
  3853.   if (!AdrResult.AdrMode)
  3854.     return;
  3855.   if (((AdrResult.AdrMode == ModData) && (OpSize != eSymbolSize32Bit)) || ((AdrResult.AdrMode != ModData) && (OpSize != eSymbolSize8Bit)))
  3856.   {
  3857.     WrError(ErrNum_InvOpSize);
  3858.     return;
  3859.   }
  3860.  
  3861.   BitMax = (AdrResult.AdrMode == ModData) ? 31 : 7;
  3862.   WAsmCode[0] |= AdrResult.AdrPart;
  3863.   CopyAdrVals(WAsmCode + ResCodeLen, &AdrResult);
  3864.   CodeLen = (ResCodeLen << 1) + AdrResult.Cnt;
  3865.   if (!BitNumUnknown && (BitNum > BitMax))
  3866.     WrError(ErrNum_BitNumberTruncated);
  3867. }
  3868.  
  3869. /* 0=BFTST 1=BFCHG 2=BFCLR 3=BFSET */
  3870.  
  3871. static void DecodeFBits(Word Index)
  3872. {
  3873.   if (!ChkArgCnt(1, 1));
  3874.   else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2)));
  3875.   else if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  3876.   else if (!SplitBitField(&ArgStr[1], WAsmCode + 1)) WrError(ErrNum_InvBitMask);
  3877.   else
  3878.   {
  3879.     tAdrResult AdrResult;
  3880.  
  3881.     RelPos = 4;
  3882.     OpSize = eSymbolSize8Bit;
  3883.     if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModDAdrI | MModAIX | MModAbs | (Memo("BFTST") ? (MModPC | MModPCIdx) : 0), &AdrResult))
  3884.     {
  3885.       WAsmCode[0] = 0xe8c0 | AdrResult.AdrPart | (Index << 10);
  3886.       CopyAdrVals(WAsmCode + 2, &AdrResult);
  3887.       CodeLen = 4 + AdrResult.Cnt;
  3888.     }
  3889.   }
  3890. }
  3891.  
  3892. /* 0=BFEXTU 1=BFEXTS 2=BFFFO */
  3893.  
  3894. static void DecodeEBits(Word Index)
  3895. {
  3896.   if (!ChkArgCnt(2, 2));
  3897.   else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2)));
  3898.   else if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  3899.   else if (!SplitBitField(&ArgStr[1], WAsmCode + 1)) WrError(ErrNum_InvBitMask);
  3900.   else
  3901.   {
  3902.     tAdrResult AdrResult;
  3903.  
  3904.     RelPos = 4;
  3905.     OpSize = eSymbolSize8Bit;
  3906.     if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
  3907.     {
  3908.       LongInt ThisCodeLen = 4 + AdrResult.Cnt;
  3909.  
  3910.       WAsmCode[0] = 0xe9c0 + AdrResult.AdrPart + (Index << 9); CopyAdrVals(WAsmCode + 2, &AdrResult);
  3911.       if (DecodeAdr(&ArgStr[2], MModData, &AdrResult))
  3912.       {
  3913.         WAsmCode[1] |= AdrResult.AdrPart << 12;
  3914.         CodeLen = ThisCodeLen;
  3915.       }
  3916.     }
  3917.   }
  3918. }
  3919.  
  3920. static void DecodeBFINS(Word Index)
  3921. {
  3922.   UNUSED(Index);
  3923.  
  3924.   if (!ChkArgCnt(2, 2));
  3925.   else if (!CheckFamily((1 << e68KGen3) | (1 << e68KGen2)));
  3926.   else if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  3927.   else if (!SplitBitField(&ArgStr[2], WAsmCode + 1)) WrError(ErrNum_InvBitMask);
  3928.   else
  3929.   {
  3930.     tAdrResult AdrResult;
  3931.  
  3932.     OpSize = eSymbolSize8Bit;
  3933.     if (DecodeAdr(&ArgStr[2], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  3934.     {
  3935.       LongInt ThisCodeLen = 4 + AdrResult.Cnt;
  3936.  
  3937.       WAsmCode[0] = 0xefc0 + AdrResult.AdrPart;
  3938.       CopyAdrVals(WAsmCode + 2, &AdrResult);
  3939.       if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
  3940.       {
  3941.         WAsmCode[1] |= AdrResult.AdrPart << 12;
  3942.         CodeLen = ThisCodeLen;
  3943.       }
  3944.     }
  3945.   }
  3946. }
  3947.  
  3948. /* bedingte Befehle */
  3949.  
  3950. static void DecodeBcc(Word CondCode)
  3951. {
  3952.   /* .W, .S, .L, .X erlaubt */
  3953.  
  3954.   if ((OpSize > eSymbolSize32Bit) && (OpSize != eSymbolSizeFloat32Bit) && (OpSize != eSymbolSizeFloat96Bit)) WrError(ErrNum_InvOpSize);
  3955.  
  3956.   /* nur ein Operand erlaubt */
  3957.  
  3958.   else if (ChkArgCnt(1, 1))
  3959.   {
  3960.     LongInt HVal;
  3961.     Integer HVal16;
  3962.     ShortInt HVal8;
  3963.     Boolean ValOK, IsBSR = (1 == CondCode);
  3964.     tSymbolFlags Flags;
  3965.  
  3966.     /* Zieladresse ermitteln, zum Programmzaehler relativieren */
  3967.  
  3968.     HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &Flags);
  3969.     HVal = HVal - (EProgCounter() + 2);
  3970.  
  3971.     /* Bei Automatik Groesse festlegen */
  3972.  
  3973.     if (!*AttrPart.str.p_str)
  3974.     {
  3975.       if (IsDisp8(HVal))
  3976.       {
  3977.         /* BSR with zero displacement cannot be converted to NOP.  Generate a
  3978.            16 bit displacement instead. */
  3979.  
  3980.         if (!HVal && IsBSR)
  3981.           OpSize = eSymbolSize32Bit;
  3982.  
  3983.         /* if the jump target is the address right behind the BSR, keep
  3984.            16 bit displacement to avoid oscillating back and forth between
  3985.            8 and 16 bits: */
  3986.  
  3987.         else if ((Flags & eSymbolFlag_NextLabelAfterBSR) && (HVal == 2) && IsBSR)
  3988.           OpSize = eSymbolSize32Bit;
  3989.         else
  3990.           OpSize = eSymbolSizeFloat32Bit;
  3991.       }
  3992.       else if (IsDisp16(HVal))
  3993.         OpSize = eSymbolSize32Bit;
  3994.       else
  3995.         OpSize = eSymbolSizeFloat96Bit;
  3996.     }
  3997.  
  3998.     if (ValOK)
  3999.     {
  4000.       /* 16 Bit (.L or .W) ? */
  4001.  
  4002.       if ((OpSize == eSymbolSize32Bit) || (OpSize == eSymbolSize16Bit))
  4003.       {
  4004.         /* zu weit ? */
  4005.  
  4006.         HVal16 = HVal;
  4007.         if (!IsDisp16(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  4008.         else
  4009.         {
  4010.           /* Code erzeugen */
  4011.  
  4012.           CodeLen = 4;
  4013.           WAsmCode[0] = 0x6000 | (CondCode << 8);
  4014.           WAsmCode[1] = HVal16;
  4015.         }
  4016.       }
  4017.  
  4018.       /* 8 Bit (.S or .B) ? */
  4019.  
  4020.       else if ((OpSize == eSymbolSizeFloat32Bit) || (OpSize == eSymbolSize8Bit))
  4021.       {
  4022.         /* zu weit ? */
  4023.  
  4024.         HVal8 = HVal;
  4025.         if (!IsDisp8(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  4026.  
  4027.         /* cannot generate short BSR with zero displacement, and BSR cannot
  4028.            be replaced with NOP -> error */
  4029.  
  4030.         else if ((HVal == 0) && IsBSR && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  4031.  
  4032.         /* Code erzeugen */
  4033.  
  4034.         else
  4035.         {
  4036.           CodeLen = 2;
  4037.           if ((HVal8 != 0) || IsBSR)
  4038.           {
  4039.             WAsmCode[0] = 0x6000 | (CondCode << 8) | ((Byte)HVal8);
  4040.           }
  4041.           else
  4042.           {
  4043.             WAsmCode[0] = NOPCode;
  4044.             if ((!Repass) && *AttrPart.str.p_str)
  4045.               WrError(ErrNum_DistNull);
  4046.           }
  4047.         }
  4048.       }
  4049.  
  4050.       /* 32 Bit ?  Complain about non-supported instructio only if .X
  4051.          was requested explicitly: */
  4052.  
  4053.       else if (!(pCurrCPUProps->SuppFlags & eFlagBranch32)) WrError(*AttrPart.str.p_str ? ErrNum_InstructionNotSupported : ErrNum_JmpDistTooBig);
  4054.       else
  4055.       {
  4056.         CodeLen = 6;
  4057.         WAsmCode[0] = 0x60ff | (CondCode << 8);
  4058.         WAsmCode[1] = HVal >> 16;
  4059.         WAsmCode[2] = HVal & 0xffff;
  4060.       }
  4061.     }
  4062.  
  4063.     if ((CodeLen > 0) && IsBSR)
  4064.       AfterBSRAddr = EProgCounter() + CodeLen;
  4065.   }
  4066. }
  4067.  
  4068. static void DecodeScc(Word CondCode)
  4069. {
  4070.   if (*AttrPart.str.p_str && (OpSize != eSymbolSize8Bit)) WrError(ErrNum_InvOpSize);
  4071.   else if (ArgCnt != 1) WrError(ErrNum_InvOpSize);
  4072.   else
  4073.   {
  4074.     tAdrResult AdrResult;
  4075.  
  4076.     OpSize = eSymbolSize8Bit;
  4077.     if (DecodeAdr(&ArgStr[1], MModData | ((pCurrCPUProps->Family == eColdfire) ? 0 : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs), &AdrResult))
  4078.     {
  4079.       WAsmCode[0] = 0x50c0 | (CondCode << 8) | AdrResult.AdrPart;
  4080.       CodeLen = 2 + AdrResult.Cnt;
  4081.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  4082.     }
  4083.   }
  4084. }
  4085.  
  4086. static void DecodeDBcc(Word CondCode)
  4087. {
  4088.   if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  4089.   else if (ChkArgCnt(2, 2)
  4090.         && CheckNoFamily(1 << eColdfire))
  4091.   {
  4092.     Boolean ValOK;
  4093.     tSymbolFlags Flags;
  4094.     LongInt HVal = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &ValOK, &Flags);
  4095.     Integer HVal16;
  4096.  
  4097.     if (ValOK)
  4098.     {
  4099.       HVal -= (EProgCounter() + 2);
  4100.       HVal16 = HVal;
  4101.       if (!IsDisp16(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  4102.       else
  4103.       {
  4104.         tAdrResult AdrResult;
  4105.  
  4106.         CodeLen = 4;
  4107.         WAsmCode[0] = 0x50c8 | (CondCode << 8);
  4108.         WAsmCode[1] = HVal16;
  4109.         if (DecodeAdr(&ArgStr[1], MModData, &AdrResult) == ModData)
  4110.           WAsmCode[0] |= AdrResult.AdrPart;
  4111.         else
  4112.           CodeLen = 0;
  4113.       }
  4114.     }
  4115.   }
  4116. }
  4117.  
  4118. static void DecodeTRAPcc(Word CondCode)
  4119. {
  4120.   int ExpectArgCnt;
  4121.  
  4122.   if (!*AttrPart.str.p_str)
  4123.     OpSize = eSymbolSize8Bit;
  4124.   ExpectArgCnt = (OpSize == eSymbolSize8Bit) ? 0 : 1;
  4125.   if (OpSize > 2) WrError(ErrNum_InvOpSize);
  4126.   else if (!ChkArgCnt(ExpectArgCnt, ExpectArgCnt));
  4127.   else if ((CondCode != 1) && !CheckNoFamily(1 << eColdfire));
  4128.   else
  4129.   {
  4130.     WAsmCode[0] = 0x50f8 + (CondCode << 8);
  4131.     if (OpSize == eSymbolSize8Bit)
  4132.     {
  4133.       WAsmCode[0] += 4;
  4134.       CodeLen = 2;
  4135.     }
  4136.     else
  4137.     {
  4138.       tAdrResult AdrResult;
  4139.  
  4140.       if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
  4141.       {
  4142.         WAsmCode[0] += OpSize + 1;
  4143.         CopyAdrVals(WAsmCode + 1, &AdrResult);
  4144.         CodeLen = 2 + AdrResult.Cnt;
  4145.       }
  4146.     }
  4147.     CheckFamily((1 << eColdfire) | (1 << eCPU32) | (1 << e68KGen2) | (1 << e68KGen3));
  4148.   }
  4149. }
  4150.  
  4151. /*-------------------------------------------------------------------------*/
  4152. /* Dekodierroutinen Gleitkommaeinheit */
  4153.  
  4154. enum { eFMovemTypNone = 0, eFMovemTypDyn = 1, eFMovemTypStatic = 2, eFMovemTypCtrl = 3 };
  4155.  
  4156. static void DecodeFRegList(const tStrComp *pArg, Byte *pTyp, Byte *pList)
  4157. {
  4158.   Word hw, Reg, RegFrom, RegTo;
  4159.   Byte z;
  4160.   char *p, *p2;
  4161.   String ArgStr;
  4162.   tStrComp Arg, Remainder, From, To;
  4163.  
  4164.   StrCompMkTemp(&Arg, ArgStr, sizeof(ArgStr));
  4165.   StrCompCopy(&Arg, pArg);
  4166.  
  4167.   *pTyp = eFMovemTypNone;
  4168.   if (*Arg.str.p_str == '\0')
  4169.     return;
  4170.  
  4171.   switch (DecodeReg(&Arg, &Reg, False))
  4172.   {
  4173.     case eIsReg:
  4174.       if (Reg & 8)
  4175.         return;
  4176.       *pTyp = eFMovemTypDyn;
  4177.       *pList = Reg << 4;
  4178.       return;
  4179.     case eRegAbort:
  4180.       return;
  4181.     default:
  4182.       break;
  4183.   }
  4184.  
  4185.   hw = 0;
  4186.   do
  4187.   {
  4188.     p = strchr(Arg.str.p_str, '/');
  4189.     if (p)
  4190.       StrCompSplitRef(&Arg, &Remainder, &Arg, p);
  4191.     p2 = strchr(Arg.str.p_str, '-');
  4192.     if (p2)
  4193.     {
  4194.       StrCompSplitRef(&From, &To, &Arg, p2);
  4195.       if (!strlen(To.str.p_str)
  4196.        || (DecodeFPReg(&From, &RegFrom, False) != eIsReg)
  4197.        || (RegFrom & REG_FPCTRL)
  4198.        || (DecodeFPReg(&To, &RegTo, False) != eIsReg)
  4199.        || (RegTo & REG_FPCTRL))
  4200.         return;
  4201.       if (RegFrom <= RegTo)
  4202.         for (z = RegFrom; z <= RegTo; z++) hw |= (1 << (7 - z));
  4203.       else
  4204.       {
  4205.         for (z = RegFrom; z <= 7; z++) hw |= (1 << (7 - z));
  4206.         for (z = 0; z <= RegTo; z++) hw |= (1 << (7 - z));
  4207.       }
  4208.     }
  4209.     else
  4210.     {
  4211.       if (DecodeFPReg(&Arg, &Reg, False) != eIsReg)
  4212.         return;
  4213.       if (Reg & REG_FPCTRL)
  4214.         hw |= (Reg & 7) << 8;
  4215.       else
  4216.         hw |= (1 << (7 - Reg));
  4217.     }
  4218.     if (p)
  4219.       Arg = Remainder;
  4220.   }
  4221.   while (p);
  4222.   if (Hi(hw) == 0)
  4223.   {
  4224.     *pTyp = eFMovemTypStatic;
  4225.     *pList = Lo(hw);
  4226.   }
  4227.   else if (Lo(hw) == 0)
  4228.   {
  4229.     *pTyp = eFMovemTypCtrl;
  4230.     *pList = Hi(hw);
  4231.   }
  4232. }
  4233.  
  4234. static Byte Mirror8(Byte List)
  4235. {
  4236.   Byte hList;
  4237.   int z;
  4238.  
  4239.   hList = List; List = 0;
  4240.   for (z = 0; z < 8; z++)
  4241.   {
  4242.     List = List << 1;
  4243.     if (hList & 1)
  4244.       List |= 1;
  4245.     hList = hList >> 1;
  4246.   }
  4247.   return List;
  4248. }
  4249.  
  4250. static void GenerateMovem(Byte Typ, Byte List, tAdrResult *pResult)
  4251. {
  4252.   if (pResult->AdrMode == ModNone)
  4253.     return;
  4254.   CodeLen = 4 + pResult->Cnt;
  4255.   CopyAdrVals(WAsmCode + 2, pResult);
  4256.   WAsmCode[0] = 0xf200 | pResult->AdrPart;
  4257.   switch (Typ)
  4258.   {
  4259.     case eFMovemTypDyn:
  4260.     case eFMovemTypStatic:
  4261.       WAsmCode[1] |= 0xc000;
  4262.       if (Typ == eFMovemTypDyn)
  4263.         WAsmCode[1] |= 0x800;
  4264.       if (pResult->AdrMode != ModPre)
  4265.         WAsmCode[1] |= 0x1000;
  4266.       if ((pResult->AdrMode == ModPre) && (Typ == eFMovemTypStatic))
  4267.         List = Mirror8(List);
  4268.       WAsmCode[1] |= List;
  4269.       break;
  4270.     case eFMovemTypCtrl:
  4271.       WAsmCode[1] |= 0x8000 | (((Word)List) << 10);
  4272.       break;
  4273.   }
  4274. }
  4275.  
  4276. /*-------------------------------------------------------------------------*/
  4277.  
  4278. static void DecodeFPUOp(Word Index)
  4279. {
  4280.   FPUOp *Op = FPUOps + Index;
  4281.   tStrComp *pArg2 = &ArgStr[2];
  4282.  
  4283.   if ((ArgCnt == 1) && (!Op->Dya))
  4284.   {
  4285.     pArg2 = &ArgStr[1];
  4286.     ArgCnt = 2;
  4287.   }
  4288.  
  4289.   if (!CheckFloatSize());
  4290.   else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4291.   else if ((pCurrCPUProps->SuppFlags & Op->NeedsSuppFlags) != Op->NeedsSuppFlags) WrError(ErrNum_InstructionNotSupported);
  4292.   else if (ChkArgCnt(2, 2))
  4293.   {
  4294.     tAdrResult AdrResult;
  4295.  
  4296.     if (DecodeAdr(pArg2, MModFPn, &AdrResult) == ModFPn)
  4297.     {
  4298.       Word SrcMask;
  4299.  
  4300.       WAsmCode[0] = 0xf200;
  4301.       WAsmCode[1] = Op->Code | (AdrResult.AdrPart << 7);
  4302.       RelPos = 4;
  4303.  
  4304.       SrcMask = MModAdrI | MModDAdrI | MModPost | MModPre | MModPC | MModFPn;
  4305.       if (FloatOpSizeFitsDataReg(OpSize))
  4306.         SrcMask |= MModData;
  4307.       if (pCurrCPUProps->Family != eColdfire)
  4308.         SrcMask |= MModAIX | MModAbs | MModPCIdx | MModImm;
  4309.       if (DecodeAdr(&ArgStr[1], SrcMask, &AdrResult) == ModFPn)
  4310.       {
  4311.         WAsmCode[1] |= AdrResult.AdrPart << 10;
  4312.         if (OpSize == NativeFloatSize)
  4313.           CodeLen = 4;
  4314.         else
  4315.           WrError(ErrNum_InvOpSize);
  4316.       }
  4317.       else if (AdrResult.AdrMode != ModNone)
  4318.       {
  4319.         CodeLen = 4 + AdrResult.Cnt;
  4320.         CopyAdrVals(WAsmCode + 2, &AdrResult);
  4321.         WAsmCode[0] |= AdrResult.AdrPart;
  4322.         WAsmCode[1] |= 0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
  4323.       }
  4324.     }
  4325.   }
  4326. }
  4327.  
  4328. static void DecodeFSAVE(Word Code)
  4329. {
  4330.   UNUSED(Code);
  4331.  
  4332.   if (!ChkArgCnt(1, 1));
  4333.   else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4334.   else if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  4335.   else
  4336.   {
  4337.     tAdrResult AdrResult;
  4338.  
  4339.     if (DecodeAdr(&ArgStr[1], MModAdrI | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  4340.     {
  4341.       CodeLen = 2 + AdrResult.Cnt;
  4342.       WAsmCode[0] = 0xf300 | AdrResult.AdrPart;
  4343.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  4344.       CheckSup();
  4345.     }
  4346.   }
  4347. }
  4348.  
  4349. static void DecodeFRESTORE(Word Code)
  4350. {
  4351.   UNUSED(Code);
  4352.  
  4353.   if (!ChkArgCnt(1, 1));
  4354.   else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4355.   else if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  4356.   else
  4357.   {
  4358.     tAdrResult AdrResult;
  4359.  
  4360.     RelPos = 4;
  4361.     if (DecodeAdr(&ArgStr[1], MModAdrI | MModPost | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
  4362.     {
  4363.       CodeLen = 2 + AdrResult.Cnt;
  4364.       WAsmCode[0] = 0xf340 | AdrResult.AdrPart;
  4365.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  4366.       CheckSup();
  4367.     }
  4368.   }
  4369. }
  4370.  
  4371. static void DecodeFNOP(Word Code)
  4372. {
  4373.   UNUSED(Code);
  4374.  
  4375.   if (!ChkArgCnt(0, 0));
  4376.   else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4377.   else if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  4378.   else
  4379.   {
  4380.     CodeLen = 4;
  4381.     WAsmCode[0] = 0xf280;
  4382.     WAsmCode[1] = 0;
  4383.   }
  4384. }
  4385.  
  4386. /* TODO: does a { } suffix to <dest> as k factor conflict
  4387.    with other features, like stringification?  Maybe better
  4388.    check whether this is a valid k factor (register (symbol)
  4389.    or immediate) and only cut off if yes.  We might not be
  4390.    able to use DecodeAdr() for this any more: */
  4391.  
  4392. static char *split_k(tStrComp *p_arg, tStrComp *p_k)
  4393. {
  4394.   int l = strlen(p_arg->str.p_str);
  4395.   char *p_sep;
  4396.  
  4397.   if ((l < 2) || (p_arg->str.p_str[l - 1] != '}'))
  4398.     return NULL;
  4399.   p_sep = RQuotPos(p_arg->str.p_str, '{');
  4400.   if (!p_sep)
  4401.     return NULL;
  4402.  
  4403.   StrCompSplitRef(p_arg, p_k, p_arg, p_sep);
  4404.   StrCompShorten(p_k, 1);
  4405.   KillPostBlanksStrComp(p_arg);
  4406.   KillPrefBlanksStrCompRef(p_k);
  4407.   return p_sep;
  4408. }
  4409.  
  4410. static void DecodeFMOVE(Word Code)
  4411. {
  4412.   Word DestMask, SrcMask;
  4413.   tAdrResult DestAdrResult, SrcAdrResult;
  4414.   tStrComp KArg;
  4415.   Boolean op_size_implicit = !*AttrPart.str.p_str;
  4416.  
  4417.   UNUSED(Code);
  4418.  
  4419.   if (!ChkArgCnt(2, 2))
  4420.     return;
  4421.   if (!FPUAvail)
  4422.   {
  4423.     WrError(ErrNum_FPUNotEnabled);
  4424.     return;
  4425.   }
  4426.   if (!CheckFloatSize())
  4427.     return;
  4428.  
  4429.   /* k-Faktor abspalten */
  4430.  
  4431.   LineCompReset(&KArg.Pos);
  4432.   if (OpSize == eSymbolSizeFloatDec96Bit)
  4433.   {
  4434.     if (!split_k(&AttrPart, &KArg))
  4435.       split_k(&ArgStr[2], &KArg);
  4436.   }
  4437.  
  4438.   DestMask = MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModFPCR | MModFPn;
  4439.   if (pCurrCPUProps->Family != eColdfire)
  4440.     DestMask |= MModAIX | MModAbs | MModImm;
  4441.   if (FloatOpSizeFitsDataReg(OpSize) || op_size_implicit)
  4442.     DestMask |= MModData;
  4443.   switch (DecodeAdr(&ArgStr[2], DestMask, &DestAdrResult))
  4444.   {
  4445.     case ModFPn: /* FMOVE.x <ea>/FPm,FPn ? */
  4446.     {
  4447.       WAsmCode[0] = 0xf200;
  4448.       WAsmCode[1] = DestAdrResult.AdrPart << 7;
  4449.       RelPos = 4;
  4450.       SrcMask = MModAdrI | MModPost | MModPre | MModDAdrI | MModPC | MModFPn;
  4451.       if (pCurrCPUProps->Family != eColdfire)
  4452.         SrcMask |= MModAIX | MModAbs | MModImm | MModPCIdx;
  4453.       if (FloatOpSizeFitsDataReg(OpSize))
  4454.         SrcMask |= MModData;
  4455.       switch (DecodeAdr(&ArgStr[1], SrcMask, &SrcAdrResult))
  4456.       {
  4457.         case ModFPn: /* FMOVE.X FPm,FPn ? */
  4458.         {
  4459.           if (OpSize != NativeFloatSize)
  4460.           {
  4461.             WrError(ErrNum_InvOpSize);
  4462.             return;
  4463.           }
  4464.           WAsmCode[1] |= SrcAdrResult.AdrPart << 10;
  4465.           CodeLen = 4;
  4466.           break;
  4467.         }
  4468.         case ModNone:
  4469.           break;
  4470.         default: /* FMOVE.x <ea>,FPn ? */
  4471.           CodeLen = 4 + SrcAdrResult.Cnt;
  4472.           CopyAdrVals(WAsmCode + 2, &SrcAdrResult);
  4473.           WAsmCode[0] |= SrcAdrResult.AdrPart;
  4474.           WAsmCode[1] |= 0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
  4475.       }
  4476.       break;
  4477.     }
  4478.     case ModFPCR: /* FMOVE.L <ea>,FPcr ? */
  4479.     {
  4480.       if ((OpSize != eSymbolSize32Bit) && !op_size_implicit)
  4481.       {
  4482.         WrError(ErrNum_InvOpSize);
  4483.         return;
  4484.       }
  4485.       RelPos = 4;
  4486.       WAsmCode[0] = 0xf200;
  4487.       WAsmCode[1] = 0x8000 | (DestAdrResult.AdrPart << 10);
  4488.       SrcMask = MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModPC;
  4489.       if (pCurrCPUProps->Family != eColdfire)
  4490.         SrcMask |= MModAIX | MModAbs | MModImm | MModPCIdx;
  4491.       if (DestAdrResult.AdrPart == REG_FPIAR) /* only for FPIAR */
  4492.         SrcMask |= MModAdr;
  4493.       if (DecodeAdr(&ArgStr[1], SrcMask, &SrcAdrResult))
  4494.       {
  4495.         WAsmCode[0] |= SrcAdrResult.AdrPart;
  4496.         CodeLen = 4 + SrcAdrResult.Cnt;
  4497.         CopyAdrVals(WAsmCode + 2, &SrcAdrResult);
  4498.       }
  4499.       break;
  4500.     }
  4501.     case ModNone:
  4502.       break;
  4503.     default: /* FMOVE.x ????,<ea> ? */
  4504.     {
  4505.       WAsmCode[0] = 0xf200 | DestAdrResult.AdrPart;
  4506.       CodeLen = 4 + DestAdrResult.Cnt;
  4507.       CopyAdrVals(WAsmCode + 2, &DestAdrResult);
  4508.       switch (DecodeAdr(&ArgStr[1], (DestAdrResult.AdrMode == ModAdr) ? MModFPCR : MModFPn | MModFPCR, &SrcAdrResult))
  4509.       {
  4510.         case ModFPn:                       /* FMOVE.x FPn,<ea> ? */
  4511.         {
  4512.           if (DestAdrResult.AdrMode == ModAdr)
  4513.           {
  4514.             WrError(ErrNum_InvAddrMode);
  4515.             CodeLen = 0;
  4516.             return;
  4517.           }
  4518.           WAsmCode[1] = 0x6000 | (((Word)FSizeCodes[OpSize]) << 10) | (SrcAdrResult.AdrPart << 7);
  4519.           if (OpSize == eSymbolSizeFloatDec96Bit)
  4520.           {
  4521.             if (KArg.Pos.Len > 0)
  4522.             {
  4523.               tAdrResult KResult;
  4524.  
  4525.               OpSize = eSymbolSize8Bit;
  4526.               switch (DecodeAdr(&KArg, MModData | MModImm, &KResult))
  4527.               {
  4528.                 case ModData:
  4529.                   WAsmCode[1] |= (KResult.AdrPart << 4) | 0x1000;
  4530.                   break;
  4531.                 case ModImm:
  4532.                   WAsmCode[1] |= (KResult.Vals[0] & 127);
  4533.                   break;
  4534.                 default:
  4535.                   CodeLen = 0;
  4536.               }
  4537.             }
  4538.             else
  4539.               WAsmCode[1] |= 17;
  4540.           }
  4541.           break;
  4542.         }
  4543.         case ModFPCR:                  /* FMOVE.L FPcr,<ea> ? */
  4544.         {
  4545.           if (!op_size_implicit && (OpSize != eSymbolSize32Bit))
  4546.           {
  4547.             WrError(ErrNum_InvOpSize);
  4548.             CodeLen = 0;
  4549.             return;
  4550.           }
  4551.           if ((SrcAdrResult.AdrPart != REG_FPIAR) && (DestAdrResult.AdrMode == ModAdr))
  4552.           {
  4553.             WrError(ErrNum_InvAddrMode);
  4554.             CodeLen = 0;
  4555.             return;
  4556.           }
  4557.           WAsmCode[1] = 0xa000 | (SrcAdrResult.AdrPart << 10);
  4558.           break;
  4559.         }
  4560.         default:
  4561.           CodeLen = 0;
  4562.       }
  4563.     }
  4564.   }
  4565. }
  4566.  
  4567. static void DecodeFMOVECR(Word Code)
  4568. {
  4569.   UNUSED(Code);
  4570.  
  4571.   if (!ChkArgCnt(2, 2));
  4572.   else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4573.   else if (!CheckNoFamily(1 << eColdfire));
  4574.   else if (*AttrPart.str.p_str && (OpSize != eSymbolSizeFloat96Bit)) WrError(ErrNum_InvOpSize);
  4575.   else
  4576.   {
  4577.     tAdrResult AdrResult;
  4578.  
  4579.     if (DecodeAdr(&ArgStr[2], MModFPn, &AdrResult) == ModFPn)
  4580.     {
  4581.       WAsmCode[0] = 0xf200;
  4582.       WAsmCode[1] = 0x5c00 | (AdrResult.AdrPart << 7);
  4583.       OpSize = eSymbolSize8Bit;
  4584.       if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult) == ModImm)
  4585.       {
  4586.         if (AdrResult.Vals[0] > 63) WrError(ErrNum_RomOffs063);
  4587.         else
  4588.         {
  4589.           CodeLen = 4;
  4590.           WAsmCode[1] |= AdrResult.Vals[0];
  4591.         }
  4592.       }
  4593.     }
  4594.   }
  4595. }
  4596.  
  4597. static void DecodeFTST(Word Code)
  4598. {
  4599.   UNUSED(Code);
  4600.  
  4601.   if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4602.   else if (!CheckFloatSize());
  4603.   else if (ChkArgCnt(1, 1))
  4604.   {
  4605.     Word Mask;
  4606.     tAdrResult AdrResult;
  4607.  
  4608.     RelPos = 4;
  4609.     Mask = MModAdrI | MModPost | MModPre | MModDAdrI | MModPC | MModFPn;
  4610.     if (pCurrCPUProps->Family != eColdfire)
  4611.       Mask |= MModAIX | MModPCIdx | MModAbs | MModImm;
  4612.     if (FloatOpSizeFitsDataReg(OpSize))
  4613.       Mask |= MModData;
  4614.     if (DecodeAdr(&ArgStr[1], Mask, &AdrResult) == ModFPn)
  4615.     {
  4616.       WAsmCode[0] = 0xf200;
  4617.       WAsmCode[1] = 0x3a | (AdrResult.AdrPart << 10);
  4618.       CodeLen = 4;
  4619.     }
  4620.     else if (AdrResult.AdrMode != ModNone)
  4621.     {
  4622.       WAsmCode[0] = 0xf200 | AdrResult.AdrPart;
  4623.       WAsmCode[1] = 0x403a | (((Word)FSizeCodes[OpSize]) << 10);
  4624.       CodeLen = 4 + AdrResult.Cnt;
  4625.       CopyAdrVals(WAsmCode + 2, &AdrResult);
  4626.     }
  4627.   }
  4628. }
  4629.  
  4630. static void DecodeFSINCOS(Word Code)
  4631. {
  4632.   UNUSED(Code);
  4633.  
  4634.   if (!*AttrPart.str.p_str)
  4635.     OpSize = NativeFloatSize;
  4636.   if (OpSize == 3) WrError(ErrNum_InvOpSize);
  4637.   else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4638.   else if (!CheckNoFamily(1 << eColdfire));
  4639.   else if (ChkArgCnt(2, 3))
  4640.   {
  4641.     tStrComp *pArg2, *pArg3, Arg2, Arg3;
  4642.     tAdrResult AdrResult;
  4643.  
  4644.     if (3 == ArgCnt)
  4645.     {
  4646.       pArg2 = &ArgStr[2];
  4647.       pArg3 = &ArgStr[3];
  4648.     }
  4649.     else
  4650.     {
  4651.       char *pKSep = strrchr(ArgStr[2].str.p_str, ':');
  4652.  
  4653.       if (!pKSep)
  4654.       {
  4655.         WrError(ErrNum_WrongArgCnt);
  4656.         return;
  4657.       }
  4658.       StrCompSplitRef(&Arg2, &Arg3, &ArgStr[2], pKSep);
  4659.       pArg2 = &Arg2;
  4660.       pArg3 = &Arg3;
  4661.     }
  4662.     if (DecodeAdr(pArg2, MModFPn, &AdrResult) == ModFPn)
  4663.     {
  4664.       WAsmCode[1] = AdrResult.AdrPart | 0x30;
  4665.       if (DecodeAdr(pArg3, MModFPn, &AdrResult) == ModFPn)
  4666.       {
  4667.         WAsmCode[1] |= (AdrResult.AdrPart << 7);
  4668.         RelPos = 4;
  4669.         switch (DecodeAdr(&ArgStr[1], ((OpSize <= eSymbolSize32Bit) || (OpSize == eSymbolSizeFloat32Bit))
  4670.                                      ? MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm | MModFPn
  4671.                                      : MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm | MModFPn, &AdrResult))
  4672.         {
  4673.           case ModFPn:
  4674.             WAsmCode[0] = 0xf200;
  4675.             WAsmCode[1] |= (AdrResult.AdrPart << 10);
  4676.             CodeLen = 4;
  4677.             break;
  4678.           case ModNone:
  4679.             break;
  4680.           default:
  4681.             WAsmCode[0] = 0xf200 | AdrResult.AdrPart;
  4682.             WAsmCode[1] |= 0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
  4683.             CodeLen = 4 + AdrResult.Cnt;
  4684.             CopyAdrVals(WAsmCode + 2, &AdrResult);
  4685.         }
  4686.       }
  4687.     }
  4688.   }
  4689. }
  4690.  
  4691. static void DecodeFDMOVE_FSMOVE(Word Code)
  4692. {
  4693.   if (!ChkArgCnt(2, 2));
  4694.   else if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4695.   else if (CheckFamily((1 << e68KGen3) | (1 << eColdfire)))
  4696.   {
  4697.     tAdrResult AdrResult;
  4698.  
  4699.     if (DecodeAdr(&ArgStr[2], MModFPn, &AdrResult) == ModFPn)
  4700.     {
  4701.       unsigned Mask;
  4702.  
  4703.       WAsmCode[0] = 0xf200;
  4704.       WAsmCode[1] = Code | AdrResult.AdrPart << 7;
  4705.       RelPos = 4;
  4706.       if (!*AttrPart.str.p_str)
  4707.         OpSize = NativeFloatSize;
  4708.       Mask = MModFPn | MModAdrI | MModPost | MModPre | MModDAdrI | MModPC;
  4709.       if (pCurrCPUProps->Family != eColdfire)
  4710.         Mask |= MModAIX | MModAbs | MModPCIdx | MModImm;
  4711.       if (FloatOpSizeFitsDataReg(OpSize))
  4712.         Mask |= MModData;
  4713.       if (DecodeAdr(&ArgStr[1], Mask, &AdrResult) == ModFPn)
  4714.       {
  4715.         CodeLen = 4;
  4716.         WAsmCode[1] |= (AdrResult.AdrPart << 10);
  4717.       }
  4718.       else if (AdrResult.AdrMode != ModNone)
  4719.       {
  4720.         CodeLen = 4 + AdrResult.Cnt;
  4721.         CopyAdrVals(WAsmCode + 2, &AdrResult);
  4722.         WAsmCode[0] |= AdrResult.AdrPart;
  4723.         WAsmCode[1] |= 0x4000 | (((Word)FSizeCodes[OpSize]) << 10);
  4724.       }
  4725.     }
  4726.   }
  4727. }
  4728.  
  4729. /*!------------------------------------------------------------------------
  4730.  * \fn     DecodeFMOVEM(Word Code)
  4731.  * \brief  handle FMOVEM instruction
  4732.  * ------------------------------------------------------------------------ */
  4733.  
  4734. static void DecodeFMOVEM(Word Code)
  4735. {
  4736.   Byte Typ, List;
  4737.   Word Mask;
  4738.   tAdrResult AdrResult;
  4739.  
  4740.   UNUSED(Code);
  4741.  
  4742.   if (!ChkArgCnt(2, 2))
  4743.     return;
  4744.   if (!FPUAvail)
  4745.   {
  4746.     WrError(ErrNum_FPUNotEnabled);
  4747.     return;
  4748.   }
  4749.  
  4750.   /* NOTE: An expression of 'Dn' may be the source or destination of a (single)
  4751.      control register FMOVEM, but also a dynamic FPn data register list.  This
  4752.      makes the decision tree a bit more complex: */
  4753.  
  4754.   DecodeFRegList(&ArgStr[2], &Typ, &List);
  4755.   switch (Typ)
  4756.   {
  4757.     case eFMovemTypStatic:
  4758.     case eFMovemTypCtrl:
  4759.       goto fp_list_is_dest;
  4760.  
  4761.     case eFMovemTypDyn:
  4762.     {
  4763.       Byte src_typ, src_list;
  4764.       DecodeFRegList(&ArgStr[1], &src_typ, &src_list);
  4765.       switch (src_typ)
  4766.       {
  4767.         case eFMovemTypStatic:
  4768.         case eFMovemTypCtrl:
  4769.           Typ = src_typ;
  4770.           List = src_list;
  4771.           goto fp_list_is_src;
  4772.         case eFMovemTypDyn:
  4773.           WrError(ErrNum_InvRegList);
  4774.           return;
  4775.         default:
  4776.           goto fp_list_is_dest;
  4777.       }
  4778.     }
  4779.  
  4780.     default: /* eFMovemTypNone */
  4781.       DecodeFRegList(&ArgStr[1], &Typ, &List);
  4782.       if (Typ == eFMovemTypNone)
  4783.       {
  4784.         WrError(ErrNum_InvRegList);
  4785.         return;
  4786.       }
  4787.       /* Fall-Thru */
  4788.  
  4789.     fp_list_is_src:
  4790.       if (*AttrPart.str.p_str && (((Typ < eFMovemTypCtrl) && (OpSize != NativeFloatSize)) || ((Typ == eFMovemTypCtrl) && (OpSize != eSymbolSize32Bit)))) WrError(ErrNum_InvOpSize);
  4791.       else if ((Typ != eFMovemTypStatic) && (pCurrCPUProps->Family == eColdfire)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  4792.       else
  4793.       {
  4794.         Mask = MModAdrI | MModDAdrI;
  4795.         if (pCurrCPUProps->Family != eColdfire)
  4796.           Mask |= MModPre | MModAIX | MModAbs;
  4797.         if (Typ == eFMovemTypCtrl)   /* Steuerregister auch Postinkrement */
  4798.         {
  4799.           Mask |= MModPost;
  4800.           if ((List == REG_FPCR) | (List == REG_FPSR) | (List == REG_FPIAR)) /* nur ein Register */
  4801.             Mask |= MModData;
  4802.           if (List == REG_FPIAR) /* nur FPIAR */
  4803.             Mask |= MModAdr;
  4804.         }
  4805.         if (DecodeAdr(&ArgStr[2], Mask, &AdrResult))
  4806.         {
  4807.           WAsmCode[1] = 0x2000;
  4808.           GenerateMovem(Typ, List, &AdrResult);
  4809.         }
  4810.       }
  4811.       break;
  4812.  
  4813.     fp_list_is_dest:
  4814.       if (*AttrPart.str.p_str
  4815.       && (((Typ < eFMovemTypCtrl) && (OpSize != NativeFloatSize))
  4816.         || ((Typ == eFMovemTypCtrl) && (OpSize != eSymbolSize32Bit))))
  4817.         WrError(ErrNum_InvOpSize);
  4818.       else if ((Typ != eFMovemTypStatic) && (pCurrCPUProps->Family == eColdfire))
  4819.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  4820.       else
  4821.       {
  4822.         RelPos = 4;
  4823.         Mask = MModAdrI | MModDAdrI | MModPC;
  4824.         if (pCurrCPUProps->Family != eColdfire)
  4825.           Mask |= MModPost | MModAIX | MModPCIdx | MModAbs;
  4826.         if (Typ == eFMovemTypCtrl)   /* Steuerregister auch Predekrement */
  4827.         {
  4828.           Mask |= MModPre;
  4829.           if ((List == REG_FPCR) | (List == REG_FPSR) | (List == REG_FPIAR)) /* nur ein Register */
  4830.             Mask |= MModData | MModImm;
  4831.           if (List == REG_FPIAR) /* nur FPIAR */
  4832.             Mask |= MModAdr;
  4833.         }
  4834.         if (DecodeAdr(&ArgStr[1], Mask, &AdrResult))
  4835.         {
  4836.           WAsmCode[1] = 0x0000;
  4837.           GenerateMovem(Typ, List, &AdrResult);
  4838.         }
  4839.       }
  4840.       break;
  4841.   }
  4842. }
  4843.  
  4844. static void DecodeFBcc(Word CondCode)
  4845. {
  4846.   if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4847.   else
  4848.   {
  4849.     if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit) && (OpSize != eSymbolSizeFloat96Bit)) WrError(ErrNum_InvOpSize);
  4850.     else if (ChkArgCnt(1, 1))
  4851.     {
  4852.       LongInt HVal;
  4853.       Integer HVal16;
  4854.       Boolean ValOK;
  4855.       tSymbolFlags Flags;
  4856.  
  4857.       HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &Flags) - (EProgCounter() + 2);
  4858.       HVal16 = HVal;
  4859.  
  4860.       if (!*AttrPart.str.p_str)
  4861.       {
  4862.         OpSize = (IsDisp16(HVal)) ? eSymbolSize32Bit : eSymbolSizeFloat96Bit;
  4863.       }
  4864.  
  4865.       if ((OpSize == eSymbolSize32Bit) || (OpSize == eSymbolSize16Bit))
  4866.       {
  4867.         if (!IsDisp16(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  4868.         else
  4869.         {
  4870.           CodeLen = 4;
  4871.           WAsmCode[0] = 0xf280 | CondCode;
  4872.           WAsmCode[1] = HVal16;
  4873.         }
  4874.       }
  4875.       else
  4876.       {
  4877.         CodeLen = 6;
  4878.         WAsmCode[0] = 0xf2c0 | CondCode;
  4879.         WAsmCode[2] = HVal & 0xffff;
  4880.         WAsmCode[1] = HVal >> 16;
  4881.         if (IsDisp16(HVal) && (PassNo > 1) && !*AttrPart.str.p_str)
  4882.         {
  4883.           WrError(ErrNum_ShortJumpPossible);
  4884.           WAsmCode[0] ^= 0x40;
  4885.           CodeLen -= 2;
  4886.           WAsmCode[1] = WAsmCode[2];
  4887.           StopfZahl++;
  4888.         }
  4889.       }
  4890.     }
  4891.   }
  4892. }
  4893.  
  4894. static void DecodeFDBcc(Word CondCode)
  4895. {
  4896.   if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4897.   else if (CheckNoFamily(1 << eColdfire))
  4898.   {
  4899.     if ((OpSize != eSymbolSize16Bit) && *AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  4900.     else if (ChkArgCnt(2, 2))
  4901.     {
  4902.       tAdrResult AdrResult;
  4903.  
  4904.       if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
  4905.       {
  4906.         LongInt HVal;
  4907.         Integer HVal16;
  4908.         Boolean ValOK;
  4909.         tSymbolFlags Flags;
  4910.  
  4911.         WAsmCode[0] = 0xf248 | AdrResult.AdrPart;
  4912.         WAsmCode[1] = CondCode;
  4913.         HVal = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &ValOK, &Flags) - (EProgCounter() + 4);
  4914.         if (ValOK)
  4915.         {
  4916.           HVal16 = HVal;
  4917.           WAsmCode[2] = HVal16;
  4918.           if (!IsDisp16(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  4919.             else CodeLen = 6;
  4920.         }
  4921.       }
  4922.     }
  4923.   }
  4924. }
  4925.  
  4926. static void DecodeFScc(Word CondCode)
  4927. {
  4928.   if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4929.   else if (!CheckNoFamily(1 << eColdfire));
  4930.   else if ((OpSize != eSymbolSize8Bit) && *AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  4931.   else if (ChkArgCnt(1, 1))
  4932.   {
  4933.     tAdrResult AdrResult;
  4934.  
  4935.     OpSize = eSymbolSize8Bit;
  4936.     if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  4937.     {
  4938.       CodeLen = 4 + AdrResult.Cnt;
  4939.       WAsmCode[0] = 0xf240 | AdrResult.AdrPart;
  4940.       WAsmCode[1] = CondCode;
  4941.       CopyAdrVals(WAsmCode + 2, &AdrResult);
  4942.     }
  4943.   }
  4944. }
  4945.  
  4946. static void DecodeFTRAPcc(Word CondCode)
  4947. {
  4948.   if (!FPUAvail) WrError(ErrNum_FPUNotEnabled);
  4949.   else if (!CheckNoFamily(1 << eColdfire));
  4950.   else
  4951.   {
  4952.     if (!*AttrPart.str.p_str)
  4953.       OpSize = eSymbolSize8Bit;
  4954.     if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  4955.     else if (ChkArgCnt(OpSize ? 1 : 0, OpSize ? 1 : 0))
  4956.     {
  4957.       WAsmCode[0] = 0xf278;
  4958.       WAsmCode[1] = CondCode;
  4959.       if (OpSize == eSymbolSize8Bit)
  4960.       {
  4961.         WAsmCode[0] |= 4;
  4962.         CodeLen = 4;
  4963.       }
  4964.       else
  4965.       {
  4966.         tAdrResult AdrResult;
  4967.  
  4968.         if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
  4969.         {
  4970.           WAsmCode[0] |= (OpSize + 1);
  4971.           CopyAdrVals(WAsmCode + 2, &AdrResult);
  4972.           CodeLen = 4 + AdrResult.Cnt;
  4973.         }
  4974.       }
  4975.     }
  4976.   }
  4977. }
  4978.  
  4979. /*-------------------------------------------------------------------------*/
  4980. /* Hilfsroutinen MMU: */
  4981.  
  4982. static Boolean DecodeFC(const tStrComp *pArg, Word *erg)
  4983. {
  4984.   Boolean OK;
  4985.   Word Val;
  4986.  
  4987.   if (!as_strcasecmp(pArg->str.p_str, "SFC"))
  4988.   {
  4989.     *erg = 0;
  4990.     return True;
  4991.   }
  4992.  
  4993.   if (!as_strcasecmp(pArg->str.p_str, "DFC"))
  4994.   {
  4995.     *erg = 1;
  4996.     return True;
  4997.   }
  4998.  
  4999.   switch (DecodeReg(pArg, erg, False))
  5000.   {
  5001.     case eIsReg:
  5002.       if (*erg < 8)
  5003.       {
  5004.         *erg += 8;
  5005.         return True;
  5006.       }
  5007.       break;
  5008.     case eIsNoReg:
  5009.       break;
  5010.     default:
  5011.       return False;
  5012.   }
  5013.  
  5014.   if (*pArg->str.p_str == '#')
  5015.   {
  5016.     Val = EvalStrIntExpressionOffs(pArg, 1, Int4, &OK);
  5017.     if (OK)
  5018.       *erg = Val + 16;
  5019.     return OK;
  5020.   }
  5021.  
  5022.   return False;
  5023. }
  5024.  
  5025. static Boolean DecodePMMUReg(char *Asc, Word *erg, tSymbolSize *pSize)
  5026. {
  5027.   Byte z;
  5028.  
  5029.   if ((strlen(Asc) == 4) && (!as_strncasecmp(Asc, "BAD", 3)) && ValReg(Asc[3]))
  5030.   {
  5031.     *pSize = eSymbolSize16Bit;
  5032.     *erg = 0x7000 + ((Asc[3] - '0') << 2);
  5033.     return True;
  5034.   }
  5035.   if ((strlen(Asc) == 4) && (!as_strncasecmp(Asc, "BAC", 3)) && ValReg(Asc[3]))
  5036.   {
  5037.     *pSize = eSymbolSize16Bit;
  5038.     *erg = 0x7400 + ((Asc[3] - '0') << 2);
  5039.     return True;
  5040.   }
  5041.  
  5042.   for (z = 0; PMMURegs[z].pName; z++)
  5043.     if (!as_strcasecmp(Asc, PMMURegs[z].pName))
  5044.     {
  5045.       *pSize = PMMURegs[z].Size;
  5046.       *erg = PMMURegs[z].Code << 10;
  5047.       return True;
  5048.     }
  5049.   return False;
  5050. }
  5051.  
  5052. /*-------------------------------------------------------------------------*/
  5053.  
  5054. static void DecodePSAVE(Word Code)
  5055. {
  5056.   UNUSED(Code);
  5057.  
  5058.   if (!ChkArgCnt(1, 1));
  5059.   else if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  5060.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5061.   else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
  5062.   else
  5063.   {
  5064.     tAdrResult AdrResult;
  5065.  
  5066.     if (DecodeAdr(&ArgStr[1], MModAdrI | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  5067.     {
  5068.       CodeLen = 2 + AdrResult.Cnt;
  5069.       WAsmCode[0] = 0xf100 | AdrResult.AdrPart;
  5070.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  5071.       CheckSup();
  5072.     }
  5073.   }
  5074. }
  5075.  
  5076. static void DecodePRESTORE(Word Code)
  5077. {
  5078.   UNUSED(Code);
  5079.  
  5080.   if (!ChkArgCnt(1, 1));
  5081.   else if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  5082.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5083.   else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
  5084.   else
  5085.   {
  5086.     tAdrResult AdrResult;
  5087.  
  5088.     RelPos = 4;
  5089.     if (DecodeAdr(&ArgStr[1], MModAdrI | MModPre | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs, &AdrResult))
  5090.     {
  5091.       CodeLen = 2 + AdrResult.Cnt;
  5092.       WAsmCode[0] = 0xf140 | AdrResult.AdrPart;
  5093.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  5094.       CheckSup();
  5095.     }
  5096.   }
  5097. }
  5098.  
  5099. static void DecodePFLUSHA(Word Code)
  5100. {
  5101.   UNUSED(Code);
  5102.  
  5103.   if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  5104.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5105.   else if (ChkArgCnt(0, 0))
  5106.   {
  5107.     switch (pCurrCPUProps->Family)
  5108.     {
  5109.       case e68KGen3:
  5110.         CodeLen = 2;
  5111.         WAsmCode[0] = 0xf518;
  5112.         break;
  5113.       default:
  5114.         CodeLen = 4;
  5115.         WAsmCode[0] = 0xf000;
  5116.         WAsmCode[1] = 0x2400;
  5117.         break;
  5118.     }
  5119.     CheckSup();
  5120.   }
  5121. }
  5122.  
  5123. static void DecodePFLUSHAN(Word Code)
  5124. {
  5125.   UNUSED(Code);
  5126.  
  5127.   if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  5128.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5129.   else if (ChkArgCnt(0, 0)
  5130.         && CheckFamily(1 << e68KGen3))
  5131.   {
  5132.     CodeLen = 2;
  5133.     WAsmCode[0] = 0xf510;
  5134.     CheckSup();
  5135.   }
  5136. }
  5137.  
  5138. static void DecodePFLUSH_PFLUSHS(Word Code)
  5139. {
  5140.   tAdrResult AdrResult;
  5141.  
  5142.   if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  5143.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5144.   else if (pCurrCPUProps->Family == e68KGen3)
  5145.   {
  5146.     if (Code) WrError(ErrNum_FullPMMUNotEnabled);
  5147.     else if (ChkArgCnt(1, 1))
  5148.     {
  5149.       if (DecodeAdr(&ArgStr[1], MModAdrI, &AdrResult))
  5150.       {
  5151.         WAsmCode[0] = 0xf508 + (AdrResult.AdrPart & 7);
  5152.         CodeLen = 2;
  5153.         CheckSup();
  5154.       }
  5155.     }
  5156.   }
  5157.   else if (!ChkArgCnt(2, 3));
  5158.   else if ((Code) && (!FullPMMU)) WrError(ErrNum_FullPMMUNotEnabled);
  5159.   else if (!DecodeFC(&ArgStr[1], WAsmCode + 1)) WrError(ErrNum_InvFCode);
  5160.   else
  5161.   {
  5162.     OpSize = eSymbolSize8Bit;
  5163.     if (DecodeAdr(&ArgStr[2], MModImm, &AdrResult))
  5164.     {
  5165.       if (AdrResult.Vals[0] > 15) WrError(ErrNum_InvFMask);
  5166.       else
  5167.       {
  5168.         WAsmCode[1] |= (AdrResult.Vals[0] << 5) | 0x3000 | Code;
  5169.         WAsmCode[0] = 0xf000;
  5170.         CodeLen = 4;
  5171.         CheckSup();
  5172.         if (ArgCnt == 3)
  5173.         {
  5174.           WAsmCode[1] |= 0x800;
  5175.           if (!DecodeAdr(&ArgStr[3], MModAdrI | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  5176.             CodeLen = 0;
  5177.           else
  5178.           {
  5179.             WAsmCode[0] |= AdrResult.AdrPart;
  5180.             CodeLen += AdrResult.Cnt;
  5181.             CopyAdrVals(WAsmCode + 2, &AdrResult);
  5182.           }
  5183.         }
  5184.       }
  5185.     }
  5186.   }
  5187. }
  5188.  
  5189. static void DecodePFLUSHN(Word Code)
  5190. {
  5191.   UNUSED(Code);
  5192.  
  5193.   if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  5194.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5195.   else if (ChkArgCnt(1, 1)
  5196.         && CheckFamily(1 << e68KGen3))
  5197.   {
  5198.     tAdrResult AdrResult;
  5199.  
  5200.     if (DecodeAdr(&ArgStr[1], MModAdrI, &AdrResult))
  5201.     {
  5202.       WAsmCode[0] = 0xf500 + (AdrResult.AdrPart & 7);
  5203.       CodeLen = 2;
  5204.       CheckSup();
  5205.     }
  5206.   }
  5207. }
  5208.  
  5209. static void DecodePFLUSHR(Word Code)
  5210. {
  5211.   UNUSED(Code);
  5212.  
  5213.   if (*AttrPart.str.p_str)
  5214.     OpSize = eSymbolSize64Bit;
  5215.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5216.   if (OpSize != eSymbolSize64Bit) WrError(ErrNum_InvOpSize);
  5217.   else if (!ChkArgCnt(1, 1));
  5218.   else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
  5219.   else
  5220.   {
  5221.     tAdrResult AdrResult;
  5222.  
  5223.     RelPos = 4;
  5224.     if (DecodeAdr(&ArgStr[1], MModAdrI | MModPre | MModPost | MModDAdrI | MModAIX | MModPC | MModPCIdx | MModAbs | MModImm, &AdrResult))
  5225.     {
  5226.       WAsmCode[0] = 0xf000 | AdrResult.AdrPart;
  5227.       WAsmCode[1] = 0xa000;
  5228.       CopyAdrVals(WAsmCode + 2, &AdrResult);
  5229.       CodeLen = 4 + AdrResult.Cnt; CheckSup();
  5230.     }
  5231.   }
  5232. }
  5233.  
  5234. static void DecodePLOADR_PLOADW(Word Code)
  5235. {
  5236.   if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  5237.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5238.   else if (!ChkArgCnt(2, 2));
  5239.   else if (!DecodeFC(&ArgStr[1], WAsmCode + 1)) WrError(ErrNum_InvFCode);
  5240.   else
  5241.   {
  5242.     tAdrResult AdrResult;
  5243.  
  5244.     if (DecodeAdr(&ArgStr[2], MModAdrI | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  5245.     {
  5246.       WAsmCode[0] = 0xf000 | AdrResult.AdrPart;
  5247.       WAsmCode[1] |= Code;
  5248.       CodeLen = 4 + AdrResult.Cnt;
  5249.       CopyAdrVals(WAsmCode + 2, &AdrResult);
  5250.       CheckSup();
  5251.     }
  5252.   }
  5253. }
  5254.  
  5255. static void DecodePMOVE_PMOVEFD(Word Code)
  5256. {
  5257.   tSymbolSize RegSize;
  5258.   unsigned Mask;
  5259.   tAdrResult AdrResult;
  5260.  
  5261.   if (!ChkArgCnt(2, 2));
  5262.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5263.   else
  5264.   {
  5265.     if (DecodePMMUReg(ArgStr[1].str.p_str, WAsmCode + 1, &RegSize))
  5266.     {
  5267.       WAsmCode[1] |= 0x200;
  5268.       if (!*AttrPart.str.p_str)
  5269.         OpSize = RegSize;
  5270.       if (OpSize != RegSize) WrError(ErrNum_InvOpSize);
  5271.       else
  5272.       {
  5273.         Mask = MModAdrI | MModDAdrI | MModAIX | MModAbs;
  5274.         if (FullPMMU)
  5275.         {
  5276.           Mask *= MModPost | MModPre;
  5277.           if (RegSize != eSymbolSize64Bit)
  5278.             Mask += MModData | MModAdr;
  5279.         }
  5280.         if (DecodeAdr(&ArgStr[2], Mask, &AdrResult))
  5281.         {
  5282.           WAsmCode[0] = 0xf000 | AdrResult.AdrPart;
  5283.           CodeLen = 4 + AdrResult.Cnt;
  5284.           CopyAdrVals(WAsmCode + 2, &AdrResult);
  5285.           CheckSup();
  5286.         }
  5287.       }
  5288.     }
  5289.     else if (DecodePMMUReg(ArgStr[2].str.p_str, WAsmCode + 1, &RegSize))
  5290.     {
  5291.       if (!*AttrPart.str.p_str)
  5292.         OpSize = RegSize;
  5293.       if (OpSize != RegSize) WrError(ErrNum_InvOpSize);
  5294.       else
  5295.       {
  5296.         RelPos = 4;
  5297.         Mask = MModAdrI | MModDAdrI | MModAIX | MModAbs;
  5298.         if (FullPMMU)
  5299.         {
  5300.           Mask += MModPost | MModPre | MModPC | MModPCIdx | MModImm;
  5301.           if (RegSize != eSymbolSize64Bit)
  5302.             Mask += MModData | MModAdr;
  5303.         }
  5304.         if (DecodeAdr(&ArgStr[1], Mask, &AdrResult))
  5305.         {
  5306.           WAsmCode[0] = 0xf000 | AdrResult.AdrPart;
  5307.           CodeLen = 4 + AdrResult.Cnt;
  5308.           CopyAdrVals(WAsmCode + 2, &AdrResult);
  5309.           WAsmCode[1] += Code;
  5310.           CheckSup();
  5311.         }
  5312.       }
  5313.     }
  5314.     else
  5315.       WrError(ErrNum_InvMMUReg);
  5316.   }
  5317. }
  5318.  
  5319. static void DecodePTESTR_PTESTW(Word Code)
  5320. {
  5321.   tAdrResult AdrResult;
  5322.  
  5323.   if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  5324.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5325.   else if (pCurrCPUProps->Family == e68KGen3)
  5326.   {
  5327.     if (ChkArgCnt(1, 1))
  5328.     {
  5329.       if (DecodeAdr(&ArgStr[1], MModAdrI, &AdrResult))
  5330.       {
  5331.         WAsmCode[0] = 0xf548 + (AdrResult.AdrPart & 7) + (Code << 5);
  5332.         CodeLen = 2;
  5333.         CheckSup();
  5334.       }
  5335.     }
  5336.   }
  5337.   else if (ChkArgCnt(3, 4))
  5338.   {
  5339.     if (!DecodeFC(&ArgStr[1], WAsmCode + 1)) WrError(ErrNum_InvFCode);
  5340.     else
  5341.     {
  5342.       if (DecodeAdr(&ArgStr[2], MModAdrI | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  5343.       {
  5344.         WAsmCode[0] = 0xf000 | AdrResult.AdrPart;
  5345.         CodeLen = 4 + AdrResult.Cnt;
  5346.         WAsmCode[1] |= 0x8000 | (Code << 9);
  5347.         CopyAdrVals(WAsmCode + 2, &AdrResult);
  5348.         if (DecodeAdr(&ArgStr[3], MModImm, &AdrResult))
  5349.         {
  5350.           if (AdrResult.Vals[0] > 7)
  5351.           {
  5352.             WrError(ErrNum_Level07);
  5353.             CodeLen = 0;
  5354.           }
  5355.           else
  5356.           {
  5357.             WAsmCode[1] |= AdrResult.Vals[0] << 10;
  5358.             if (ArgCnt == 4)
  5359.             {
  5360.               if (!DecodeAdr(&ArgStr[4], MModAdr, &AdrResult))
  5361.                 CodeLen = 0;
  5362.               else
  5363.                 WAsmCode[1] |= AdrResult.AdrPart << 5;
  5364.               CheckSup();
  5365.             }
  5366.           }
  5367.         }
  5368.         else
  5369.           CodeLen = 0;
  5370.       }
  5371.     }
  5372.   }
  5373. }
  5374.  
  5375. static void DecodePVALID(Word Code)
  5376. {
  5377.   UNUSED(Code);
  5378.  
  5379.   if (!ChkArgCnt(2, 2));
  5380.   else if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5381.   else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
  5382.   else if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  5383.   else
  5384.   {
  5385.     tAdrResult AdrResult;
  5386.  
  5387.     if (DecodeAdr(&ArgStr[2], MModAdrI | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  5388.     {
  5389.       WAsmCode[0] = 0xf000 | AdrResult.AdrPart;
  5390.       WAsmCode[1] = 0x2800;
  5391.       CodeLen = 4 + AdrResult.Cnt;
  5392.       CopyAdrVals(WAsmCode + 1, &AdrResult);
  5393.       if (!as_strcasecmp(ArgStr[1].str.p_str, "VAL"));
  5394.       else
  5395.       {
  5396.         if (DecodeAdr(&ArgStr[1], MModAdr, &AdrResult))
  5397.           WAsmCode[1] |= 0x400 | (AdrResult.AdrPart & 7);
  5398.         else
  5399.           CodeLen = 0;
  5400.       }
  5401.     }
  5402.   }
  5403. }
  5404.  
  5405. static void DecodePBcc(Word CondCode)
  5406. {
  5407.   if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5408.   else
  5409.   {
  5410.     if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit) && (OpSize != eSymbolSizeFloat96Bit)) WrError(ErrNum_InvOpSize);
  5411.     else if (!ChkArgCnt(1, 1));
  5412.     else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
  5413.     else
  5414.     {
  5415.       LongInt HVal;
  5416.       Integer HVal16;
  5417.       Boolean ValOK;
  5418.       tSymbolFlags Flags;
  5419.  
  5420.       HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &Flags) - (EProgCounter() + 2);
  5421.       HVal16 = HVal;
  5422.  
  5423.       if (!*AttrPart.str.p_str)
  5424.         OpSize = (IsDisp16(HVal)) ? eSymbolSize32Bit : eSymbolSizeFloat96Bit;
  5425.  
  5426.       if ((OpSize == eSymbolSize32Bit) || (OpSize == eSymbolSize16Bit))
  5427.       {
  5428.         if (!IsDisp16(HVal) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  5429.         else
  5430.         {
  5431.           CodeLen = 4;
  5432.           WAsmCode[0] = 0xf080 | CondCode;
  5433.           WAsmCode[1] = HVal16;
  5434.           CheckSup();
  5435.         }
  5436.       }
  5437.       else
  5438.       {
  5439.         CodeLen = 6;
  5440.         WAsmCode[0] = 0xf0c0 | CondCode;
  5441.         WAsmCode[2] = HVal & 0xffff;
  5442.         WAsmCode[1] = HVal >> 16;
  5443.         CheckSup();
  5444.       }
  5445.     }
  5446.   }
  5447. }
  5448.  
  5449. static void DecodePDBcc(Word CondCode)
  5450. {
  5451.   if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5452.   else
  5453.   {
  5454.     if ((OpSize != eSymbolSize16Bit) && *AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  5455.     else if (!ChkArgCnt(2, 2));
  5456.     else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
  5457.     else
  5458.     {
  5459.       tAdrResult AdrResult;
  5460.  
  5461.       if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
  5462.       {
  5463.         LongInt HVal;
  5464.         Integer HVal16;
  5465.         Boolean ValOK;
  5466.         tSymbolFlags Flags;
  5467.  
  5468.         WAsmCode[0] = 0xf048 | AdrResult.AdrPart;
  5469.         WAsmCode[1] = CondCode;
  5470.         HVal = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &ValOK, &Flags) - (EProgCounter() + 4);
  5471.         if (ValOK)
  5472.         {
  5473.           HVal16 = HVal;
  5474.           WAsmCode[2] = HVal16;
  5475.           if ((!IsDisp16(HVal)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  5476.           else
  5477.             CodeLen = 6;
  5478.           CheckSup();
  5479.         }
  5480.       }
  5481.     }
  5482.   }
  5483. }
  5484.  
  5485. static void DecodePScc(Word CondCode)
  5486. {
  5487.   if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5488.   else
  5489.   {
  5490.     if ((OpSize != eSymbolSize8Bit) && *AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  5491.     else if (!ChkArgCnt(1, 1));
  5492.     else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
  5493.     else
  5494.     {
  5495.       tAdrResult AdrResult;
  5496.  
  5497.       OpSize = eSymbolSize8Bit;
  5498.       if (DecodeAdr(&ArgStr[1], MModData | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  5499.       {
  5500.         CodeLen = 4 + AdrResult.Cnt;
  5501.         WAsmCode[0] = 0xf040 | AdrResult.AdrPart;
  5502.         WAsmCode[1] = CondCode;
  5503.         CopyAdrVals(WAsmCode + 2, &AdrResult);
  5504.         CheckSup();
  5505.       }
  5506.     }
  5507.   }
  5508. }
  5509.  
  5510. static void DecodePTRAPcc(Word CondCode)
  5511. {
  5512.   if (!PMMUAvail) WrError(ErrNum_PMMUNotEnabled);
  5513.   else
  5514.   {
  5515.     if (!*AttrPart.str.p_str)
  5516.       OpSize = eSymbolSize8Bit;
  5517.     if (OpSize > 2) WrError(ErrNum_InvOpSize);
  5518.     else if (!ChkArgCnt(OpSize ? 1 : 0, OpSize ? 1 : 0));
  5519.     else if (!FullPMMU) WrError(ErrNum_FullPMMUNotEnabled);
  5520.     else
  5521.     {
  5522.       WAsmCode[0] = 0xf078;
  5523.       WAsmCode[1] = CondCode;
  5524.       if (OpSize == eSymbolSize8Bit)
  5525.       {
  5526.         WAsmCode[0] |= 4;
  5527.         CodeLen = 4;
  5528.         CheckSup();
  5529.       }
  5530.       else
  5531.       {
  5532.         tAdrResult AdrResult;
  5533.  
  5534.         if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
  5535.         {
  5536.           WAsmCode[0] |= (OpSize + 1);
  5537.           CopyAdrVals(WAsmCode + 2, &AdrResult);
  5538.           CodeLen = 4 + AdrResult.Cnt;
  5539.           CheckSup();
  5540.         }
  5541.       }
  5542.     }
  5543.   }
  5544. }
  5545.  
  5546. static void DecodeColdBit(Word Code)
  5547. {
  5548.   if (!*AttrPart.str.p_str)
  5549.     OpSize = eSymbolSize32Bit;
  5550.   if (ChkArgCnt(1, 1)
  5551.    && CheckColdSize()
  5552.    && CheckFamily(1 << eColdfire)
  5553.    && CheckISA((1 << eCfISA_APlus) | (1 << eCfISA_C)))
  5554.   {
  5555.     tAdrResult AdrResult;
  5556.  
  5557.     if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
  5558.     {
  5559.       CodeLen = 2;
  5560.       WAsmCode[0] = Code | (AdrResult.AdrPart & 7);
  5561.     }
  5562.   }
  5563. }
  5564.  
  5565. static void DecodeSTLDSR(Word Code)
  5566. {
  5567.   UNUSED(Code);
  5568.  
  5569.   if (!*AttrPart.str.p_str)
  5570.     OpSize = eSymbolSize16Bit;
  5571.   if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  5572.   else if (ChkArgCnt(1, 1)
  5573.         && CheckFamily(1 << eColdfire)
  5574.         && CheckISA((1 << eCfISA_APlus) | (1 << eCfISA_C)))
  5575.   {
  5576.     tAdrResult AdrResult;
  5577.  
  5578.     if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult))
  5579.     {
  5580.       CodeLen = 6;
  5581.       WAsmCode[0] = 0x40e7;
  5582.       WAsmCode[1] = 0x46fc;
  5583.       WAsmCode[2] = AdrResult.Vals[0];
  5584.     }
  5585.   }
  5586. }
  5587.  
  5588. static void DecodeINTOUCH(Word Code)
  5589. {
  5590.   UNUSED(Code);
  5591.  
  5592.   if (*AttrPart.str.p_str) WrError(ErrNum_InvOpSize);
  5593.   else if (ChkArgCnt(1, 1)
  5594.         && CheckFamily(1 << eColdfire)
  5595.         && (pCurrCPUProps->CfISA >= eCfISA_B))
  5596.   {
  5597.     tAdrResult AdrResult;
  5598.  
  5599.     if (DecodeAdr(&ArgStr[1], MModAdrI, &AdrResult))
  5600.     {
  5601.       CodeLen = 2;
  5602.       WAsmCode[0] = 0xf428 | (AdrResult.AdrPart & 7);
  5603.       CheckSup();
  5604.     }
  5605.   }
  5606. }
  5607.  
  5608. static void DecodeMOV3Q(Word Code)
  5609. {
  5610.   Boolean OK;
  5611.   tSymbolFlags Flags;
  5612.   ShortInt Val;
  5613.   tAdrResult AdrResult;
  5614.  
  5615.   UNUSED(Code);
  5616.  
  5617.   if (!ChkArgCnt(2, 2)
  5618.    || !CheckFamily(1 << eColdfire)
  5619.    || (pCurrCPUProps->CfISA < eCfISA_B)
  5620.    || !CheckColdSize())
  5621.     return;
  5622.  
  5623.   if (!DecodeAdr(&ArgStr[2], MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs, &AdrResult))
  5624.     return;
  5625.  
  5626.   if (*ArgStr[1].str.p_str != '#')
  5627.   {
  5628.     WrStrErrorPos(ErrNum_OnlyImmAddr, &ArgStr[1]);
  5629.     return;
  5630.   }
  5631.  
  5632.   Val = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], 1, SInt4, &OK, &Flags);
  5633.   if (!OK)
  5634.     return;
  5635.   if (mFirstPassUnknown(Flags))
  5636.     Val = 1;
  5637.  
  5638.   if (Val == -1)
  5639.     Val = 0;
  5640.   else if (!ChkRange(Val, 1, 7))
  5641.     return;
  5642.  
  5643.   WAsmCode[0] = 0xa140 | ((Val & 7) << 9) | AdrResult.AdrPart;
  5644.   CopyAdrVals(WAsmCode + 1, &AdrResult);
  5645.   CodeLen = 2 + AdrResult.Cnt;
  5646. }
  5647.  
  5648. static void DecodeMVS_MVZ(Word Code)
  5649. {
  5650.   Word DestReg;
  5651.   tAdrResult AdrResult;
  5652.  
  5653.   if (!ChkArgCnt(2, 2)
  5654.    || !CheckFamily(1 << eColdfire)
  5655.    || (pCurrCPUProps->CfISA < eCfISA_B))
  5656.     return;
  5657.  
  5658.   if (!*AttrPart.str.p_str)
  5659.     OpSize = eSymbolSize16Bit;
  5660.   if (OpSize > eSymbolSize16Bit)
  5661.   {
  5662.     WrError(ErrNum_InvOpSize);
  5663.     return;
  5664.   }
  5665.  
  5666.   if (!DecodeAdr(&ArgStr[2], MModData, &AdrResult))
  5667.     return;
  5668.   DestReg = AdrResult.AdrPart & 7;
  5669.  
  5670.   if (DecodeAdr(&ArgStr[1], MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI | MModAIX | MModAbs | MModImm | MModPC | MModPCIdx, &AdrResult))
  5671.   {
  5672.     WAsmCode[0] = Code | (DestReg << 9) | (OpSize << 6) | AdrResult.AdrPart;
  5673.     CopyAdrVals(WAsmCode + 1, &AdrResult);
  5674.     CodeLen = 2 + AdrResult.Cnt;
  5675.   }
  5676. }
  5677.  
  5678. static void DecodeSATS(Word Code)
  5679. {
  5680.   tAdrResult AdrResult;
  5681.  
  5682.   UNUSED(Code);
  5683.  
  5684.   if (!ChkArgCnt(1, 1)
  5685.    || !CheckFamily(1 << eColdfire)
  5686.    || (pCurrCPUProps->CfISA < eCfISA_B)
  5687.    || !CheckColdSize())
  5688.     return;
  5689.  
  5690.   if (DecodeAdr(&ArgStr[1], MModData, &AdrResult))
  5691.   {
  5692.     WAsmCode[0] = 0x4c80 | (AdrResult.AdrPart & 7);
  5693.     CodeLen = 2;
  5694.   }
  5695. }
  5696.  
  5697. static void DecodeMAC_MSAC(Word Code)
  5698. {
  5699.   Word Rx, Ry, Rw, Ux = 0, Uy = 0, Scale = 0, Mask, AccNum = 0;
  5700.   int CurrArg, RemArgCnt;
  5701.   Boolean ExplicitLoad = !!(Code & 0x8000);
  5702.   tAdrResult AdrResult;
  5703.  
  5704.   Code &= 0x7fff;
  5705.  
  5706.   if (!(pCurrCPUProps->SuppFlags & eFlagMAC))
  5707.   {
  5708.     WrError(ErrNum_InstructionNotSupported);
  5709.     return;
  5710.   }
  5711.  
  5712.   if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit))
  5713.   {
  5714.     WrError(ErrNum_InvOpSize);
  5715.     return;
  5716.   }
  5717.  
  5718.   /* 2 args is the absolute minimum.  6 is the maximum (Ry, Rx, scale, <ea>, Rw, ACC) */
  5719.  
  5720.   if (!ChkArgCnt(2, 6))
  5721.     return;
  5722.  
  5723.   /* Ry and Rx are always present, and are always the first arguments: */
  5724.  
  5725.   if (OpSize == eSymbolSize16Bit)
  5726.   {
  5727.     if (!SplitMACUpperLower(&Uy, &ArgStr[1])
  5728.      || !SplitMACUpperLower(&Ux, &ArgStr[2]))
  5729.       return;
  5730.   }
  5731.  
  5732.   if (!DecodeAdr(&ArgStr[1], MModData | MModAdr, &AdrResult))
  5733.     return;
  5734.   Ry = AdrResult.AdrPart & 15;
  5735.   if (!DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
  5736.     return;
  5737.   Rx = AdrResult.AdrPart & 15;
  5738.   CurrArg = 3;
  5739.  
  5740.   /* Is a scale given as next argument? */
  5741.  
  5742.   if ((ArgCnt >= CurrArg) && DecodeMACScale(&ArgStr[CurrArg], &Scale))
  5743.     CurrArg++;
  5744.  
  5745.   /* We now have between 0 and 3 args left:
  5746.      0 -> no load, ACC0
  5747.      1 -> ACCn
  5748.      2 -> load, ACC0
  5749.      3 -> load, ACCn
  5750.      If the 'L' variant (MACL, MSACL) was given, a parallel
  5751.      load was specified explicitly and there MUST be the <ea> and Rw arguments: */
  5752.  
  5753.   RemArgCnt = ArgCnt - CurrArg + 1;
  5754.   if ((RemArgCnt > 3)
  5755.    || (ExplicitLoad && (RemArgCnt < 2)))
  5756.   {
  5757.     WrError(ErrNum_WrongArgCnt);
  5758.     return;
  5759.   }
  5760.  
  5761.   /* assumed ACC(0) if no accumulator given */
  5762.  
  5763.   if (Odd(RemArgCnt))
  5764.   {
  5765.     if (!DecodeMACACC(ArgStr[ArgCnt].str.p_str, &AccNum))
  5766.     {
  5767.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgCnt]);
  5768.       return;
  5769.     }
  5770.   }
  5771.  
  5772.   /* If parallel load, bit 7 of first word is set for MAC.  This bit is
  5773.      used on EMAC to store accumulator # LSB.  To keep things upward-compatible,
  5774.      accumulator # LSB is stored inverted on EMAC if a parallel load is present.
  5775.      Since MAC only uses accumulator #0, this works for either target: */
  5776.  
  5777.   if (RemArgCnt >= 2)
  5778.     AccNum ^= 1;
  5779.  
  5780.   /* Common things for variant with and without parallel load: */
  5781.  
  5782.   WAsmCode[0] = 0xa000 | ((AccNum & 1) << 7);
  5783.   WAsmCode[1] = ((OpSize - 1) << 11) | (Scale << 9) | Code | (Ux << 7) | (Uy << 6) | ((AccNum & 2) << 3);
  5784.  
  5785.   /* With parallel load? */
  5786.  
  5787.   if (RemArgCnt >= 2)
  5788.   {
  5789.     tStrComp CurrArgStr;
  5790.  
  5791.     if (!DecodeAdr(&ArgStr[CurrArg + 1], MModData | MModAdr, &AdrResult))
  5792.       return;
  5793.     Rw = AdrResult.AdrPart & 15;
  5794.  
  5795.     StrCompRefRight(&CurrArgStr, &ArgStr[CurrArg], 0);
  5796.     if (!SplitMACANDMASK(&Mask, &CurrArgStr))
  5797.       return;
  5798.     if (!DecodeAdr(&CurrArgStr, MModAdrI | MModPre | MModPost | MModDAdrI, &AdrResult))
  5799.       return;
  5800.  
  5801.     WAsmCode[0] |= ((Rw & 7) << 9) | ((Rw & 8) << 3) | AdrResult.AdrPart;
  5802.     WAsmCode[1] |= (Mask << 5) | (Rx << 12) | (Ry << 0);
  5803.     CodeLen = 4 + AdrResult.Cnt;
  5804.     CopyAdrVals(WAsmCode + 2, &AdrResult);
  5805.   }
  5806.  
  5807.   /* multiply/accumulate only */
  5808.  
  5809.   else
  5810.   {
  5811.     WAsmCode[0] |= Ry | ((Rx & 7) << 9) | ((Rx & 8) << 3);
  5812.     CodeLen = 4;
  5813.   }
  5814. }
  5815.  
  5816. static void DecodeMOVCLR(Word Code)
  5817. {
  5818.   Word ACCReg;
  5819.  
  5820.   UNUSED(Code);
  5821.  
  5822.   if (!ChkArgCnt(2,2));
  5823.   else if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  5824.   else if (!(pCurrCPUProps->SuppFlags & eFlagEMAC)) WrError(ErrNum_InstructionNotSupported);
  5825.   else if (!DecodeMACACC(ArgStr[1].str.p_str, &ACCReg)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  5826.   else
  5827.   {
  5828.     tAdrResult AdrResult;
  5829.  
  5830.     if (DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
  5831.     {
  5832.       WAsmCode[0] = 0xa1c0 | AdrResult.AdrPart | (ACCReg << 9);
  5833.       CodeLen = 2;
  5834.     }
  5835.   }
  5836. }
  5837.  
  5838. static void DecodeMxxAC(Word Code)
  5839. {
  5840.   Word Rx, Ry, Ux, Uy, Scale = 0, ACCx, ACCw;
  5841.   tAdrResult AdrResult;
  5842.  
  5843.   if (!(pCurrCPUProps->SuppFlags & eFlagEMAC)
  5844.     || (pCurrCPUProps->CfISA < eCfISA_B))
  5845.   {
  5846.     WrError(ErrNum_InstructionNotSupported);
  5847.     return;
  5848.   }
  5849.  
  5850.   if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit))
  5851.   {
  5852.     WrError(ErrNum_InvOpSize);
  5853.     return;
  5854.   }
  5855.  
  5856.   if (!ChkArgCnt(4, 5))
  5857.     return;
  5858.  
  5859.   if (!DecodeMACACC(ArgStr[ArgCnt - 1].str.p_str, &ACCx))
  5860.   {
  5861.     WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgCnt - 1]);
  5862.     return;
  5863.   }
  5864.   if (!DecodeMACACC(ArgStr[ArgCnt].str.p_str, &ACCw))
  5865.   {
  5866.     WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgCnt]);
  5867.     return;
  5868.   }
  5869.  
  5870.   if (5 == ArgCnt)
  5871.   {
  5872.     if (!DecodeMACScale(&ArgStr[3], &Scale))
  5873.     {
  5874.       WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[3]);
  5875.       return;
  5876.     }
  5877.   }
  5878.  
  5879.   if (OpSize == eSymbolSize16Bit)
  5880.   {
  5881.     if (!SplitMACUpperLower(&Uy, &ArgStr[1])
  5882.      || !SplitMACUpperLower(&Ux, &ArgStr[2]))
  5883.       return;
  5884.   }
  5885.   else
  5886.     Ux = Uy = 0;
  5887.  
  5888.   if (!DecodeAdr(&ArgStr[1], MModData | MModAdr, &AdrResult))
  5889.     return;
  5890.   Ry = AdrResult.AdrPart & 15;
  5891.   if (!DecodeAdr(&ArgStr[2], MModData | MModAdr, &AdrResult))
  5892.     return;
  5893.   Rx = AdrResult.AdrPart & 15;
  5894.  
  5895.   WAsmCode[0] = 0xa000 | ((Rx & 7) << 9) | ((Rx & 8) << 3) | Ry | ((ACCx & 1) << 7);
  5896.   WAsmCode[1] = Code | ((OpSize - 1) << 11) | (Scale << 9) | (Ux << 7) | (Uy << 6) | ((ACCx & 2) << 3) | (ACCw << 2);
  5897.   CodeLen = 4;
  5898. }
  5899.  
  5900. static void DecodeCPBCBUSY(Word Code)
  5901. {
  5902.   if (pCurrCPUProps->CfISA == eCfISA_None) WrError(ErrNum_InstructionNotSupported);
  5903.   else if (*AttrPart.str.p_str && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  5904.   else if (ChkArgCnt(1, 1))
  5905.   {
  5906.     Boolean OK;
  5907.     tSymbolFlags Flags;
  5908.     LongInt Dist;
  5909.  
  5910.     Dist = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt32, &OK, &Flags) - (EProgCounter() + 2);
  5911.     if (OK)
  5912.     {
  5913.       if (!mSymbolQuestionable(Flags) && !IsDisp16(Dist)) WrError(ErrNum_JmpDistTooBig);
  5914.       else
  5915.       {
  5916.         WAsmCode[0] = Code;
  5917.         WAsmCode[1] = Dist & 0xffff;
  5918.         CodeLen = 4;
  5919.       }
  5920.     }
  5921.   }
  5922. }
  5923.  
  5924. static void DecodeCPLDST(Word Code)
  5925. {
  5926.   if (pCurrCPUProps->CfISA == eCfISA_None) WrError(ErrNum_InstructionNotSupported);
  5927.   else if (ChkArgCnt(1, 4))
  5928.   {
  5929.     Boolean OK;
  5930.     Word Reg;
  5931.     const tStrComp *pEAArg = NULL, *pRnArg = NULL, *pETArg = NULL;
  5932.  
  5933.     WAsmCode[0] = Code | (OpSize << 6);
  5934.  
  5935.     /* CMD is always present and i bits 0..8 - immediate marker is optional
  5936.        since it is always a constant. */
  5937.  
  5938.     WAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[ArgCnt], !!(*ArgStr[ArgCnt].str.p_str == '#'), UInt16, &OK);
  5939.     if (!OK)
  5940.       return;
  5941.  
  5942.     if (ArgCnt >= 2)
  5943.       pEAArg = &ArgStr[1];
  5944.     switch (ArgCnt)
  5945.     {
  5946.       case 4:
  5947.         pRnArg = &ArgStr[2];
  5948.         pETArg = &ArgStr[3];
  5949.         break;
  5950.       case 3:
  5951.         if (DecodeReg(&ArgStr[2], &Reg, False) == eIsReg)
  5952.           pRnArg = &ArgStr[2];
  5953.         else
  5954.           pETArg = &ArgStr[2];
  5955.         break;
  5956.      }
  5957.  
  5958.     if (pRnArg)
  5959.     {
  5960.       if (DecodeReg(pRnArg, &Reg, True) != eIsReg)
  5961.         return;
  5962.       WAsmCode[1] |= Reg << 12;
  5963.     }
  5964.     if (pETArg)
  5965.     {
  5966.       Word ET;
  5967.  
  5968.       ET = EvalStrIntExpression(pETArg, UInt3, &OK);
  5969.       if (!OK)
  5970.         return;
  5971.       WAsmCode[1] |= ET << 9;
  5972.     }
  5973.  
  5974.     if (pEAArg)
  5975.     {
  5976.       tAdrResult AdrResult;
  5977.  
  5978.       if (!DecodeAdr(pEAArg, MModData | MModAdr | MModAdrI | MModPost | MModPre | MModDAdrI, &AdrResult))
  5979.         return;
  5980.       WAsmCode[0] |= AdrResult.AdrPart;
  5981.       CopyAdrVals(WAsmCode + 2, &AdrResult);
  5982.       CodeLen = 4 + AdrResult.Cnt;
  5983.     }
  5984.     else
  5985.       CodeLen = 4;
  5986.   }
  5987. }
  5988.  
  5989. static void DecodeCPNOP(Word Code)
  5990. {
  5991.   if (pCurrCPUProps->CfISA == eCfISA_None) WrError(ErrNum_InstructionNotSupported);
  5992.   else if (ChkArgCnt(0, 1))
  5993.   {
  5994.     WAsmCode[0] = Code | (OpSize << 6);
  5995.  
  5996.     /* CMD is always present and i bits 0..8 - immediate marker is optional
  5997.        since it is always a constant. */
  5998.  
  5999.     if (ArgCnt > 0)
  6000.     {
  6001.       Word ET;
  6002.       Boolean OK;
  6003.  
  6004.       ET = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
  6005.       if (!OK)
  6006.         return;
  6007.       WAsmCode[1] |= ET << 9;
  6008.     }
  6009.  
  6010.     CodeLen = 4;
  6011.   }
  6012. }
  6013.  
  6014. /*-------------------------------------------------------------------------*/
  6015. /* Dekodierroutinen Pseudoinstruktionen: */
  6016.  
  6017. static void PutByte(Byte b)
  6018. {
  6019.   if ((CodeLen & 1) && !HostBigEndian)
  6020.   {
  6021.     BAsmCode[CodeLen] = BAsmCode[CodeLen - 1];
  6022.     BAsmCode[CodeLen - 1] = b;
  6023.   }
  6024.   else
  6025.   {
  6026.     BAsmCode[CodeLen] = b;
  6027.   }
  6028.   CodeLen++;
  6029. }
  6030.  
  6031. static void DecodeSTR(Word Index)
  6032. {
  6033.   int l, z;
  6034.   UNUSED(Index);
  6035.  
  6036.   if (!ChkArgCnt(1, 1));
  6037.   else if (((l = strlen(ArgStr[1].str.p_str)) < 2)
  6038.         || (*ArgStr[1].str.p_str != '\'')
  6039.         || (ArgStr[1].str.p_str[l - 1] != '\'')) WrStrErrorPos(ErrNum_ExpectString, &ArgStr[1]);
  6040.   else
  6041.   {
  6042.     PutByte(l - 2);
  6043.     for (z = 1; z < l - 1; z++)
  6044.       PutByte(as_chartrans_xlate(CurrTransTable->p_table, ((usint) ArgStr[1].str.p_str[z]) & 0xff));
  6045.   }
  6046. }
  6047.  
  6048. static void assure_pc_even(Word index)
  6049. {
  6050.   UNUSED(index);
  6051.  
  6052.   if (Odd(EProgCounter()))
  6053.   {
  6054.     if (DoPadding)
  6055.       InsertPadding(1, False);
  6056.     else
  6057.       WrError(ErrNum_AddrNotAligned);
  6058.   }
  6059. }
  6060.  
  6061. /*-------------------------------------------------------------------------*/
  6062. /* Codetabellenverwaltung */
  6063.  
  6064. static void AddFixed(const char *NName, Word NCode, Boolean NSup, unsigned NMask)
  6065. {
  6066.   order_array_rsv_end(FixedOrders, FixedOrder);
  6067.   FixedOrders[InstrZ].Code = NCode;
  6068.   FixedOrders[InstrZ].MustSup = NSup;
  6069.   FixedOrders[InstrZ].FamilyMask = NMask;
  6070.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  6071. }
  6072.  
  6073. static void AddCond(const char *NName, Byte NCode)
  6074. {
  6075.   char TmpName[30];
  6076.  
  6077.   if (NCode >= 2) /* BT is BRA and BF is BSR */
  6078.   {
  6079.     as_snprintf(TmpName, sizeof(TmpName), "B%s", NName);
  6080.     AddInstTable(InstTable, TmpName, NCode, DecodeBcc);
  6081.   }
  6082.   as_snprintf(TmpName, sizeof(TmpName), "S%s", NName);
  6083.   AddInstTable(InstTable, TmpName, NCode, DecodeScc);
  6084.   as_snprintf(TmpName, sizeof(TmpName), "DB%s", NName);
  6085.   AddInstTable(InstTable, TmpName, NCode, DecodeDBcc);
  6086.   as_snprintf(TmpName, sizeof(TmpName), "TRAP%s", NName);
  6087.   AddInstTable(InstTable, TmpName, NCode, DecodeTRAPcc);
  6088. }
  6089.  
  6090. static void AddFPUOp(const char *NName, Byte NCode, Boolean NDya, tSuppFlags NeedFlags)
  6091. {
  6092.   order_array_rsv_end(FPUOps, FPUOp);
  6093.   FPUOps[InstrZ].Code = NCode;
  6094.   FPUOps[InstrZ].Dya = NDya;
  6095.   FPUOps[InstrZ].NeedsSuppFlags = NeedFlags;
  6096.   AddInstTable(InstTable, NName, InstrZ++, DecodeFPUOp);
  6097. }
  6098.  
  6099. static void AddFPUCond(const char *NName, Byte NCode)
  6100. {
  6101.   char TmpName[30];
  6102.  
  6103.   as_snprintf(TmpName, sizeof(TmpName), "FB%s", NName);
  6104.   AddInstTable(InstTable, TmpName, NCode, DecodeFBcc);
  6105.   as_snprintf(TmpName, sizeof(TmpName), "FDB%s", NName);
  6106.   AddInstTable(InstTable, TmpName, NCode, DecodeFDBcc);
  6107.   as_snprintf(TmpName, sizeof(TmpName), "FS%s", NName);
  6108.   AddInstTable(InstTable, TmpName, NCode, DecodeFScc);
  6109.   as_snprintf(TmpName, sizeof(TmpName), "FTRAP%s", NName);
  6110.   AddInstTable(InstTable, TmpName, NCode, DecodeFTRAPcc);
  6111. }
  6112.  
  6113. static void AddPMMUCond(const char *NName)
  6114. {
  6115.   char TmpName[30];
  6116.  
  6117.   as_snprintf(TmpName, sizeof(TmpName), "PB%s", NName);
  6118.   AddInstTable(InstTable, TmpName, InstrZ, DecodePBcc);
  6119.   as_snprintf(TmpName, sizeof(TmpName), "PDB%s", NName);
  6120.   AddInstTable(InstTable, TmpName, InstrZ, DecodePDBcc);
  6121.   as_snprintf(TmpName, sizeof(TmpName), "PS%s", NName);
  6122.   AddInstTable(InstTable, TmpName, InstrZ, DecodePScc);
  6123.   as_snprintf(TmpName, sizeof(TmpName), "PTRAP%s", NName);
  6124.   AddInstTable(InstTable, TmpName, InstrZ, DecodePTRAPcc);
  6125.   InstrZ++;
  6126. }
  6127.  
  6128. static void AddPMMUReg(const char *Name, tSymbolSize Size, Word Code)
  6129. {
  6130.   order_array_rsv_end(PMMURegs, PMMUReg);
  6131.   PMMURegs[InstrZ].pName = Name;
  6132.   PMMURegs[InstrZ].Size = Size;
  6133.   PMMURegs[InstrZ++].Code = Code;
  6134. }
  6135.  
  6136. static void InitFields(void)
  6137. {
  6138.   InstTable = CreateInstTable(607);
  6139.   SetDynamicInstTable(InstTable);
  6140.  
  6141.   inst_table_set_prefix_proc(InstTable, assure_pc_even, 0);
  6142.  
  6143.   AddInstTable(InstTable, "MOVE"   , Std_Variant, DecodeMOVE);
  6144.   AddInstTable(InstTable, "MOVEA"  , A_Variant, DecodeMOVE);
  6145.   AddInstTable(InstTable, "MOVEI"  , I_Variant, DecodeMOVE);
  6146.   AddInstTable(InstTable, "LEA"    , 0, DecodeLEA);
  6147.   AddInstTable(InstTable, "ASR"    , 0, DecodeShift);
  6148.   AddInstTable(InstTable, "ASL"    , 4, DecodeShift);
  6149.   AddInstTable(InstTable, "LSR"    , 1, DecodeShift);
  6150.   AddInstTable(InstTable, "LSL"    , 5, DecodeShift);
  6151.   AddInstTable(InstTable, "ROXR"   , 2, DecodeShift);
  6152.   AddInstTable(InstTable, "ROXL"   , 6, DecodeShift);
  6153.   AddInstTable(InstTable, "ROR"    , 3, DecodeShift);
  6154.   AddInstTable(InstTable, "ROL"    , 7, DecodeShift);
  6155.   AddInstTable(InstTable, "ADDQ"   , 0, DecodeADDQSUBQ);
  6156.   AddInstTable(InstTable, "SUBQ"   , 1, DecodeADDQSUBQ);
  6157.   AddInstTable(InstTable, "ADDX"   , 1, DecodeADDXSUBX);
  6158.   AddInstTable(InstTable, "SUBX"   , 0, DecodeADDXSUBX);
  6159.   AddInstTable(InstTable, "CMPM"   , 0, DecodeCMPM);
  6160.   AddInstTable(InstTable, "SUB"    , Std_Variant + 0, DecodeADDSUBCMP);
  6161.   AddInstTable(InstTable, "CMP"    , Std_Variant + 1, DecodeADDSUBCMP);
  6162.   AddInstTable(InstTable, "ADD"    , Std_Variant + 2, DecodeADDSUBCMP);
  6163.   AddInstTable(InstTable, "SUBI"   , I_Variant + 0, DecodeADDSUBCMP);
  6164.   AddInstTable(InstTable, "CMPI"   , I_Variant + 1, DecodeADDSUBCMP);
  6165.   AddInstTable(InstTable, "ADDI"   , I_Variant + 2, DecodeADDSUBCMP);
  6166.   AddInstTable(InstTable, "SUBA"   , A_Variant + 0, DecodeADDSUBCMP);
  6167.   AddInstTable(InstTable, "CMPA"   , A_Variant + 1, DecodeADDSUBCMP);
  6168.   AddInstTable(InstTable, "ADDA"   , A_Variant + 2, DecodeADDSUBCMP);
  6169.   AddInstTable(InstTable, "AND"    , Std_Variant + 1, DecodeANDOR);
  6170.   AddInstTable(InstTable, "OR"     , Std_Variant + 0, DecodeANDOR);
  6171.   AddInstTable(InstTable, "ANDI"   , I_Variant + 1, DecodeANDOR);
  6172.   AddInstTable(InstTable, "ORI"    , I_Variant + 0, DecodeANDOR);
  6173.   AddInstTable(InstTable, "EOR"    , Std_Variant, DecodeEOR);
  6174.   AddInstTable(InstTable, "EORI"   , I_Variant, DecodeEOR);
  6175.   AddInstTable(InstTable, "PEA"    , 0, DecodePEA);
  6176.   AddInstTable(InstTable, "CLR"    , 0, DecodeCLRTST);
  6177.   AddInstTable(InstTable, "TST"    , 1, DecodeCLRTST);
  6178.   AddInstTable(InstTable, "JSR"    , 0, DecodeJSRJMP);
  6179.   AddInstTable(InstTable, "JMP"    , 1, DecodeJSRJMP);
  6180.   AddInstTable(InstTable, "TAS"    , 0, DecodeNBCDTAS);
  6181.   AddInstTable(InstTable, "NBCD"   , 1, DecodeNBCDTAS);
  6182.   AddInstTable(InstTable, "NEGX"   , 0, DecodeNEGNOT);
  6183.   AddInstTable(InstTable, "NEG"    , 2, DecodeNEGNOT);
  6184.   AddInstTable(InstTable, "NOT"    , 3, DecodeNEGNOT);
  6185.   AddInstTable(InstTable, "SWAP"   , 0, DecodeSWAP);
  6186.   AddInstTable(InstTable, "UNLK"   , 0, DecodeUNLK);
  6187.   AddInstTable(InstTable, "EXT"    , 0, DecodeEXT);
  6188.   AddInstTable(InstTable, "WDDATA" , 0, DecodeWDDATA);
  6189.   AddInstTable(InstTable, "WDEBUG" , 0, DecodeWDEBUG);
  6190.   AddInstTable(InstTable, "MOVEM"  , 0, DecodeMOVEM);
  6191.   AddInstTable(InstTable, "MOVEQ"  , 0, DecodeMOVEQ);
  6192.   AddInstTable(InstTable, "STOP"   , 0, DecodeSTOP);
  6193.   AddInstTable(InstTable, "LPSTOP" , 0, DecodeLPSTOP);
  6194.   AddInstTable(InstTable, "TRAP"   , 0, DecodeTRAP);
  6195.   AddInstTable(InstTable, "BKPT"   , 0, DecodeBKPT);
  6196.   AddInstTable(InstTable, "RTD"    , 0, DecodeRTD);
  6197.   AddInstTable(InstTable, "EXG"    , 0, DecodeEXG);
  6198.   AddInstTable(InstTable, "MOVE16" , 0, DecodeMOVE16);
  6199.   AddInstTable(InstTable, "MULU"   , 0x0000, DecodeMUL_DIV);
  6200.   AddInstTable(InstTable, "MULS"   , 0x0100, DecodeMUL_DIV);
  6201.   AddInstTable(InstTable, "DIVU"   , 0x0001, DecodeMUL_DIV);
  6202.   AddInstTable(InstTable, "DIVS"   , 0x0101, DecodeMUL_DIV);
  6203.   AddInstTable(InstTable, "DIVUL"  , 0, DecodeDIVL);
  6204.   AddInstTable(InstTable, "DIVSL"  , 1, DecodeDIVL);
  6205.   AddInstTable(InstTable, "ABCD"   , 1, DecodeASBCD);
  6206.   AddInstTable(InstTable, "SBCD"   , 0, DecodeASBCD);
  6207.   AddInstTable(InstTable, "CHK"    , 0, DecodeCHK);
  6208.   AddInstTable(InstTable, "LINK"   , 0, DecodeLINK);
  6209.   AddInstTable(InstTable, "MOVEP"  , 0, DecodeMOVEP);
  6210.   AddInstTable(InstTable, "MOVEC"  , 0, DecodeMOVEC);
  6211.   AddInstTable(InstTable, "MOVES"  , 0, DecodeMOVES);
  6212.   AddInstTable(InstTable, "CALLM"  , 0, DecodeCALLM);
  6213.   AddInstTable(InstTable, "CAS"    , 0, DecodeCAS);
  6214.   AddInstTable(InstTable, "CAS2"   , 0, DecodeCAS2);
  6215.   AddInstTable(InstTable, "CMP2"   , 0, DecodeCMPCHK2);
  6216.   AddInstTable(InstTable, "CHK2"   , 1, DecodeCMPCHK2);
  6217.   AddInstTable(InstTable, "EXTB"   , 0, DecodeEXTB);
  6218.   AddInstTable(InstTable, "PACK"   , 0, DecodePACK);
  6219.   AddInstTable(InstTable, "UNPK"   , 1, DecodePACK);
  6220.   AddInstTable(InstTable, "RTM"    , 0, DecodeRTM);
  6221.   AddInstTable(InstTable, "TBLU"   , 0, DecodeTBL);
  6222.   AddInstTable(InstTable, "TBLUN"  , 1, DecodeTBL);
  6223.   AddInstTable(InstTable, "TBLS"   , 2, DecodeTBL);
  6224.   AddInstTable(InstTable, "TBLSN"  , 3, DecodeTBL);
  6225.   AddInstTable(InstTable, "BTST"   , 0, DecodeBits);
  6226.   AddInstTable(InstTable, "BSET"   , 3, DecodeBits);
  6227.   AddInstTable(InstTable, "BCLR"   , 2, DecodeBits);
  6228.   AddInstTable(InstTable, "BCHG"   , 1, DecodeBits);
  6229.   AddInstTable(InstTable, "BFTST"  , 0, DecodeFBits);
  6230.   AddInstTable(InstTable, "BFSET"  , 3, DecodeFBits);
  6231.   AddInstTable(InstTable, "BFCLR"  , 2, DecodeFBits);
  6232.   AddInstTable(InstTable, "BFCHG"  , 1, DecodeFBits);
  6233.   AddInstTable(InstTable, "BFEXTU" , 0, DecodeEBits);
  6234.   AddInstTable(InstTable, "BFEXTS" , 1, DecodeEBits);
  6235.   AddInstTable(InstTable, "BFFFO"  , 2, DecodeEBits);
  6236.   AddInstTable(InstTable, "BFINS"  , 0, DecodeBFINS);
  6237.   AddInstTable(InstTable, "CINVA"  , 0, DecodeCacheAll);
  6238.   AddInstTable(InstTable, "CPUSHA" , 1, DecodeCacheAll);
  6239.   AddInstTable(InstTable, "CINVL"  , 1, DecodeCache);
  6240.   AddInstTable(InstTable, "CPUSHL" , 5, DecodeCache);
  6241.   AddInstTable(InstTable, "CINVP"  , 2, DecodeCache);
  6242.   AddInstTable(InstTable, "CPUSHP" , 6, DecodeCache);
  6243.   AddInstTable(InstTable, "STR"    , 0, DecodeSTR);
  6244.  
  6245.   InstrZ = 0;
  6246.   AddFixed("NOP"    , 0x4e71, False, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32) | (1 << eColdfire));
  6247.   AddFixed("RESET"  , 0x4e70, True,  (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32));
  6248.   AddFixed("ILLEGAL", 0x4afc, False, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32) | (1 << eColdfire));
  6249.   AddFixed("TRAPV"  , 0x4e76, False, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32));
  6250.   AddFixed("RTE"    , 0x4e73, True , (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32) | (1 << eColdfire));
  6251.   AddFixed("RTR"    , 0x4e77, False, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32));
  6252.   AddFixed("RTS"    , 0x4e75, False, (1 << e68KGen1a) | (1 << e68KGen1b) | (1 << e68KGen2) | (1 << e68KGen3) | (1 << eCPU32) | (1 << eColdfire));
  6253.   AddFixed("BGND"   , 0x4afa, False, (1 << eCPU32));
  6254.   AddFixed("HALT"   , 0x4ac8, True , (1 << eColdfire));
  6255.   AddFixed("PULSE"  , 0x4acc, True , (1 << eColdfire));
  6256.  
  6257.   AddCond("T" , 0);  AddCond("F" , 1);  AddCond("HI", 2);  AddCond("LS", 3);
  6258.   AddCond("CC", 4);  AddCond("CS", 5);  AddCond("NE", 6);  AddCond("EQ", 7);
  6259.   AddCond("VC", 8);  AddCond("VS", 9);  AddCond("PL",10);  AddCond("MI",11);
  6260.   AddCond("GE",12);  AddCond("LT",13);  AddCond("GT",14);  AddCond("LE",15);
  6261.   AddCond("HS", 4);  AddCond("LO", 5);
  6262.   AddInstTable(InstTable, "BRA", 0, DecodeBcc);
  6263.   AddInstTable(InstTable, "BSR", 1, DecodeBcc);
  6264.   AddInstTable(InstTable, "DBRA", 1, DecodeDBcc);
  6265.  
  6266.   InstrZ = 0;
  6267.   AddFPUOp("FINT"   , 0x01, False, eFlagNone  );  AddFPUOp("FSINH"  , 0x02, False, eFlagExtFPU);
  6268.   AddFPUOp("FINTRZ" , 0x03, False, eFlagNone  );  AddFPUOp("FSQRT"  , 0x04, False, eFlagNone  );
  6269.   AddFPUOp("FSSQRT" , 0x41, False, eFlagIntFPU);  AddFPUOp("FDSQRT" , 0x45, False, eFlagIntFPU);
  6270.   AddFPUOp("FLOGNP1", 0x06, False, eFlagExtFPU);  AddFPUOp("FETOXM1", 0x08, False, eFlagExtFPU);
  6271.   AddFPUOp("FTANH"  , 0x09, False, eFlagExtFPU);  AddFPUOp("FATAN"  , 0x0a, False, eFlagExtFPU);
  6272.   AddFPUOp("FASIN"  , 0x0c, False, eFlagExtFPU);  AddFPUOp("FATANH" , 0x0d, False, eFlagExtFPU);
  6273.   AddFPUOp("FSIN"   , 0x0e, False, eFlagExtFPU);  AddFPUOp("FTAN"   , 0x0f, False, eFlagExtFPU);
  6274.   AddFPUOp("FETOX"  , 0x10, False, eFlagExtFPU);  AddFPUOp("FTWOTOX", 0x11, False, eFlagExtFPU);
  6275.   AddFPUOp("FTENTOX", 0x12, False, eFlagExtFPU);  AddFPUOp("FLOGN"  , 0x14, False, eFlagExtFPU);
  6276.   AddFPUOp("FLOG10" , 0x15, False, eFlagExtFPU);  AddFPUOp("FLOG2"  , 0x16, False, eFlagExtFPU);
  6277.   AddFPUOp("FABS"   , 0x18, False, eFlagNone  );  AddFPUOp("FSABS"  , 0x58, False, eFlagIntFPU);
  6278.   AddFPUOp("FDABS"  , 0x5c, False, eFlagIntFPU);  AddFPUOp("FCOSH"  , 0x19, False, eFlagExtFPU);
  6279.   AddFPUOp("FNEG"   , 0x1a, False, eFlagNone  );  AddFPUOp("FACOS"  , 0x1c, False, eFlagExtFPU);
  6280.   AddFPUOp("FCOS"   , 0x1d, False, eFlagExtFPU);  AddFPUOp("FGETEXP", 0x1e, False, eFlagExtFPU);
  6281.   AddFPUOp("FGETMAN", 0x1f, False, eFlagExtFPU);  AddFPUOp("FDIV"   , 0x20, True , eFlagNone  );
  6282.   AddFPUOp("FSDIV"  , 0x60, False, eFlagIntFPU);  AddFPUOp("FDDIV"  , 0x64, True , eFlagIntFPU);
  6283.   AddFPUOp("FMOD"   , 0x21, True , eFlagExtFPU);  AddFPUOp("FADD"   , 0x22, True , eFlagNone  );
  6284.   AddFPUOp("FSADD"  , 0x62, True , eFlagIntFPU);  AddFPUOp("FDADD"  , 0x66, True , eFlagIntFPU);
  6285.   AddFPUOp("FMUL"   , 0x23, True , eFlagNone  );  AddFPUOp("FSMUL"  , 0x63, True , eFlagIntFPU);
  6286.   AddFPUOp("FDMUL"  , 0x67, True , eFlagIntFPU);  AddFPUOp("FSGLDIV", 0x24, True , eFlagExtFPU);
  6287.   AddFPUOp("FREM"   , 0x25, True , eFlagExtFPU);  AddFPUOp("FSCALE" , 0x26, True , eFlagExtFPU);
  6288.   AddFPUOp("FSGLMUL", 0x27, True , eFlagExtFPU);  AddFPUOp("FSUB"   , 0x28, True , eFlagNone  );
  6289.   AddFPUOp("FSSUB"  , 0x68, True , eFlagIntFPU);  AddFPUOp("FDSUB"  , 0x6c, True , eFlagIntFPU);
  6290.   AddFPUOp("FCMP"   , 0x38, True , eFlagNone   );
  6291.  
  6292.   AddInstTable(InstTable, "FSAVE", 0, DecodeFSAVE);
  6293.   AddInstTable(InstTable, "FRESTORE", 0, DecodeFRESTORE);
  6294.   AddInstTable(InstTable, "FNOP", 0, DecodeFNOP);
  6295.   AddInstTable(InstTable, "FMOVE", 0, DecodeFMOVE);
  6296.   AddInstTable(InstTable, "FMOVECR", 0, DecodeFMOVECR);
  6297.   AddInstTable(InstTable, "FTST", 0, DecodeFTST);
  6298.   AddInstTable(InstTable, "FSINCOS", 0, DecodeFSINCOS);
  6299.   AddInstTable(InstTable, "FDMOVE", 0x0044, DecodeFDMOVE_FSMOVE);
  6300.   AddInstTable(InstTable, "FSMOVE", 0x0040, DecodeFDMOVE_FSMOVE);
  6301.   AddInstTable(InstTable, "FMOVEM", 0, DecodeFMOVEM);
  6302.  
  6303.   AddFPUCond("EQ"  , 0x01); AddFPUCond("NE"  , 0x0e);
  6304.   AddFPUCond("GT"  , 0x12); AddFPUCond("NGT" , 0x1d);
  6305.   AddFPUCond("GE"  , 0x13); AddFPUCond("NGE" , 0x1c);
  6306.   AddFPUCond("LT"  , 0x14); AddFPUCond("NLT" , 0x1b);
  6307.   AddFPUCond("LE"  , 0x15); AddFPUCond("NLE" , 0x1a);
  6308.   AddFPUCond("GL"  , 0x16); AddFPUCond("NGL" , 0x19);
  6309.   AddFPUCond("GLE" , 0x17); AddFPUCond("NGLE", 0x18);
  6310.   AddFPUCond("OGT" , 0x02); AddFPUCond("ULE" , 0x0d);
  6311.   AddFPUCond("OGE" , 0x03); AddFPUCond("ULT" , 0x0c);
  6312.   AddFPUCond("OLT" , 0x04); AddFPUCond("UGE" , 0x0b);
  6313.   AddFPUCond("OLE" , 0x05); AddFPUCond("UGT" , 0x0a);
  6314.   AddFPUCond("OGL" , 0x06); AddFPUCond("UEQ" , 0x09);
  6315.   AddFPUCond("OR"  , 0x07); AddFPUCond("UN"  , 0x08);
  6316.   AddFPUCond("F"   , 0x00); AddFPUCond("T"   , 0x0f);
  6317.   AddFPUCond("SF"  , 0x10); AddFPUCond("ST"  , 0x1f);
  6318.   AddFPUCond("SEQ" , 0x11); AddFPUCond("SNE" , 0x1e);
  6319.  
  6320.   AddPMMUCond("BS"); AddPMMUCond("BC"); AddPMMUCond("LS"); AddPMMUCond("LC");
  6321.   AddPMMUCond("SS"); AddPMMUCond("SC"); AddPMMUCond("AS"); AddPMMUCond("AC");
  6322.   AddPMMUCond("WS"); AddPMMUCond("WC"); AddPMMUCond("IS"); AddPMMUCond("IC");
  6323.   AddPMMUCond("GS"); AddPMMUCond("GC"); AddPMMUCond("CS"); AddPMMUCond("CC");
  6324.  
  6325.   AddInstTable(InstTable, "PSAVE", 0, DecodePSAVE);
  6326.   AddInstTable(InstTable, "PRESTORE", 0, DecodePRESTORE);
  6327.   AddInstTable(InstTable, "PFLUSHA", 0, DecodePFLUSHA);
  6328.   AddInstTable(InstTable, "PFLUSHAN", 0, DecodePFLUSHAN);
  6329.   AddInstTable(InstTable, "PFLUSH", 0x0000, DecodePFLUSH_PFLUSHS);
  6330.   AddInstTable(InstTable, "PFLUSHS", 0x0400, DecodePFLUSH_PFLUSHS);
  6331.   AddInstTable(InstTable, "PFLUSHN", 0, DecodePFLUSHN);
  6332.   AddInstTable(InstTable, "PFLUSHR", 0, DecodePFLUSHR);
  6333.   AddInstTable(InstTable, "PLOADR", 0x2200, DecodePLOADR_PLOADW);
  6334.   AddInstTable(InstTable, "PLOADW", 0x2000, DecodePLOADR_PLOADW);
  6335.   AddInstTable(InstTable, "PMOVE", 0x0000, DecodePMOVE_PMOVEFD);
  6336.   AddInstTable(InstTable, "PMOVEFD", 0x0100, DecodePMOVE_PMOVEFD);
  6337.   AddInstTable(InstTable, "PTESTR", 1, DecodePTESTR_PTESTW);
  6338.   AddInstTable(InstTable, "PTESTW", 0, DecodePTESTR_PTESTW);
  6339.   AddInstTable(InstTable, "PVALID", 0, DecodePVALID);
  6340.  
  6341.   AddInstTable(InstTable, "BITREV", 0x00c0, DecodeColdBit);
  6342.   AddInstTable(InstTable, "BYTEREV", 0x02c0, DecodeColdBit);
  6343.   AddInstTable(InstTable, "FF1", 0x04c0, DecodeColdBit);
  6344.   AddInstTable(InstTable, "STLDSR", 0x0000, DecodeSTLDSR);
  6345.   AddInstTable(InstTable, "INTOUCH", 0x0000, DecodeINTOUCH);
  6346.   AddInstTable(InstTable, "MOV3Q", 0x0000, DecodeMOV3Q);
  6347.   /* MOVEI? */
  6348.   AddInstTable(InstTable, "MVS", 0x7100, DecodeMVS_MVZ);
  6349.   AddInstTable(InstTable, "MVZ", 0x7180, DecodeMVS_MVZ);
  6350.   AddInstTable(InstTable, "SATS", 0x0000, DecodeSATS);
  6351.   AddInstTable(InstTable, "MAC" , 0x0000, DecodeMAC_MSAC);
  6352.   AddInstTable(InstTable, "MSAC", 0x0100, DecodeMAC_MSAC);
  6353.   AddInstTable(InstTable, "MACL" , 0x8000, DecodeMAC_MSAC);
  6354.   AddInstTable(InstTable, "MSACL", 0x8100, DecodeMAC_MSAC);
  6355.   AddInstTable(InstTable, "MOVCLR" , 0x0000, DecodeMOVCLR);
  6356.   AddInstTable(InstTable, "MAAAC" , 0x0001, DecodeMxxAC);
  6357.   AddInstTable(InstTable, "MASAC" , 0x0003, DecodeMxxAC);
  6358.   AddInstTable(InstTable, "MSAAC" , 0x0101, DecodeMxxAC);
  6359.   AddInstTable(InstTable, "MSSAC" , 0x0103, DecodeMxxAC);
  6360.  
  6361.   AddInstTable(InstTable, "CP0BCBUSY", 0xfcc0, DecodeCPBCBUSY);
  6362.   AddInstTable(InstTable, "CP1BCBUSY", 0xfec0, DecodeCPBCBUSY);
  6363.   AddInstTable(InstTable, "CP0LD", 0xfc00, DecodeCPLDST);
  6364.   AddInstTable(InstTable, "CP1LD", 0xfe00, DecodeCPLDST);
  6365.   AddInstTable(InstTable, "CP0ST", 0xfd00, DecodeCPLDST);
  6366.   AddInstTable(InstTable, "CP1ST", 0xff00, DecodeCPLDST);
  6367.   AddInstTable(InstTable, "CP0NOP", 0xfc00, DecodeCPNOP);
  6368.   AddInstTable(InstTable, "CP1NOP", 0xfe00, DecodeCPNOP);
  6369.  
  6370.   InstrZ = 0;
  6371.   AddPMMUReg("TC"   , eSymbolSize32Bit, 16); AddPMMUReg("DRP"  , eSymbolSize64Bit, 17);
  6372.   AddPMMUReg("SRP"  , eSymbolSize64Bit, 18); AddPMMUReg("CRP"  , eSymbolSize64Bit, 19);
  6373.   AddPMMUReg("CAL"  , eSymbolSize8Bit, 20);  AddPMMUReg("VAL"  , eSymbolSize8Bit, 21);
  6374.   AddPMMUReg("SCC"  , eSymbolSize8Bit, 22);  AddPMMUReg("AC"   , eSymbolSize16Bit, 23);
  6375.   AddPMMUReg("PSR"  , eSymbolSize16Bit, 24); AddPMMUReg("PCSR" , eSymbolSize16Bit, 25);
  6376.   AddPMMUReg("TT0"  , eSymbolSize32Bit,  2); AddPMMUReg("TT1"  , eSymbolSize32Bit,  3);
  6377.   AddPMMUReg("MMUSR", eSymbolSize16Bit, 24); AddPMMUReg(NULL   , eSymbolSizeUnknown, 0);
  6378.  
  6379.   inst_table_set_prefix_proc(InstTable, NULL, 0);
  6380.  
  6381.   AddInstTable(InstTable, "REG", 0, CodeREG);
  6382.   AddMoto16Pseudo(InstTable, e_moto_pseudo_flags_be);
  6383. }
  6384.  
  6385. static void DeinitFields(void)
  6386. {
  6387.   DestroyInstTable(InstTable);
  6388.   order_array_free(FixedOrders);
  6389.   order_array_free(FPUOps);
  6390.   order_array_free(PMMURegs);
  6391. }
  6392.  
  6393. /*-------------------------------------------------------------------------*/
  6394.  
  6395. /*!------------------------------------------------------------------------
  6396.  * \fn     InternSymbol_68K(char *pArg, TempResult *pResult)
  6397.  * \brief  handle built-in (register) symbols for 68K
  6398.  * \param  pArg source argument
  6399.  * \param  pResult result buffer
  6400.  * ------------------------------------------------------------------------ */
  6401.  
  6402. static void InternSymbol_68K(char *pArg, TempResult *pResult)
  6403. {
  6404.   Word RegNum;
  6405.  
  6406.   if (DecodeRegCore(pArg, &RegNum))
  6407.   {
  6408.     pResult->Typ = TempReg;
  6409.     pResult->DataSize = eSymbolSize32Bit;
  6410.     pResult->Contents.RegDescr.Reg = RegNum;
  6411.     pResult->Contents.RegDescr.Dissect = DissectReg_68K;
  6412.     pResult->Contents.RegDescr.compare = compare_reg_68k;
  6413.   }
  6414.   else if (DecodeFPRegCore(pArg, &RegNum))
  6415.   {
  6416.     pResult->Typ = TempReg;
  6417.     pResult->DataSize = NativeFloatSize;
  6418.     pResult->Contents.RegDescr.Reg = RegNum;
  6419.     pResult->Contents.RegDescr.Dissect = DissectReg_68K;
  6420.     pResult->Contents.RegDescr.compare = compare_reg_68k;
  6421.   }
  6422. }
  6423.  
  6424. static Boolean DecodeAttrPart_68K(void)
  6425. {
  6426.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  6427. }
  6428.  
  6429. static void MakeCode_68K(void)
  6430. {
  6431.   if (AttrPartOpSize[0] == eSymbolSizeUnknown)
  6432.     AttrPartOpSize[0] = ((pCurrCPUProps->Family == eColdfire) ? eSymbolSize32Bit : eSymbolSize16Bit);
  6433.   OpSize = AttrPartOpSize[0];
  6434.   RelPos = 2;
  6435.  
  6436.   /* Nullanweisung */
  6437.  
  6438.   if ((*OpPart.str.p_str == '\0') && !*AttrPart.str.p_str && (ArgCnt == 0))
  6439.     return;
  6440.  
  6441.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  6442.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  6443. }
  6444.  
  6445. static Boolean IsDef_68K(void)
  6446. {
  6447.   return Memo("REG");
  6448. }
  6449.  
  6450. static void SwitchTo_68K(void *pUser)
  6451. {
  6452.   TurnWords = True;
  6453.   SetIntConstMode(eIntConstModeMoto);
  6454.  
  6455.   PCSymbol = "*";
  6456.   HeaderID = 0x01;
  6457.   NOPCode = 0x4e71;
  6458.   DivideChars = ",";
  6459.   HasAttrs = True;
  6460.   AttrChars = ".";
  6461.  
  6462.   ValidSegs = (1 << SegCode);
  6463.   Grans[SegCode] = 1;
  6464.   ListGrans[SegCode] = 2;
  6465.   SegInits[SegCode] = 0;
  6466.   SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
  6467.  
  6468.   pCurrCPUProps = (const tCPUProps*)pUser;
  6469.  
  6470.   DecodeAttrPart = DecodeAttrPart_68K;
  6471.   MakeCode = MakeCode_68K;
  6472.   IsDef = IsDef_68K;
  6473.   DissectReg = DissectReg_68K;
  6474.   InternSymbol = InternSymbol_68K;
  6475.  
  6476.   SwitchFrom = DeinitFields;
  6477.   InitFields();
  6478.   onoff_fpu_add();
  6479.   onoff_pmmu_add();
  6480.   onoff_supmode_add();
  6481.   if (onoff_test_and_set(e_onoff_reg_fullpmmu))
  6482.     SetFlag(&FullPMMU, FullPMMUName, True);
  6483.   AddONOFF(FullPMMUName, &FullPMMU  , FullPMMUName  , False);
  6484.   AddMoto16PseudoONOFF(True);
  6485.  
  6486.   SetFlag(&FullPMMU, FullPMMUName, !(pCurrCPUProps->SuppFlags & eFlagIntPMMU));
  6487.   NativeFloatSize = (pCurrCPUProps->Family == eColdfire) ? eSymbolSizeFloat64Bit : eSymbolSizeFloat96Bit;
  6488. }
  6489.  
  6490. static const tCtReg CtRegs_40[] =
  6491. {
  6492.   { "TC"   , 0x003 },
  6493.   { "ITT0" , 0x004 },
  6494.   { "ITT1" , 0x005 },
  6495.   { "DTT0" , 0x006 },
  6496.   { "DTT1" , 0x007 },
  6497.   { "MMUSR", 0x805 },
  6498.   { "URP"  , 0x806 },
  6499.   { "SRP"  , 0x807 },
  6500.   { "IACR0", 0x004 },
  6501.   { "IACR1", 0x005 },
  6502.   { "DACR0", 0x006 },
  6503.   { "DACR1", 0x007 },
  6504.   { NULL   , 0x000 },
  6505. },
  6506. CtRegs_2030[] =
  6507. {
  6508.   { "CAAR" , 0x802 },
  6509.   { NULL   , 0x000 },
  6510. },
  6511. CtRegs_2040[] =
  6512. {
  6513.   { "CACR" , 0x002 },
  6514.   { "MSP"  , 0x803 },
  6515.   { "ISP"  , 0x804 },
  6516.   { NULL   , 0x000 },
  6517. },
  6518. CtRegs_1040[] =
  6519. {
  6520.   { "SFC"  , 0x000 },
  6521.   { "DFC"  , 0x001 },
  6522.   { "USP"  , 0x800 },
  6523.   { "VBR"  , 0x801 },
  6524.   { NULL   , 0x000 },
  6525. };
  6526.  
  6527. static const tCtReg CtRegs_5202[] =
  6528. {
  6529.   { "CACR"   , 0x002 },
  6530.   { "ACR0"   , 0x004 },
  6531.   { "ACR1"   , 0x005 },
  6532.   { "VBR"    , 0x801 },
  6533.   { "SR"     , 0x80e },
  6534.   { "PC"     , 0x80f },
  6535.   { NULL     , 0x000 },
  6536. };
  6537.  
  6538. static const tCtReg CtRegs_5202_5204[] =
  6539. {
  6540.   { "RAMBAR" , 0xc04 },
  6541.   { "MBAR"   , 0xc0f },
  6542.   { NULL     , 0x000 },
  6543. };
  6544.  
  6545. static const tCtReg CtRegs_5202_5208[] =
  6546. {
  6547.   { "RGPIOBAR", 0x009},
  6548.   { "RAMBAR" , 0xc05 },
  6549.   { NULL     , 0x000 },
  6550. };
  6551.  
  6552. static const tCtReg CtRegs_5202_5307[] =
  6553. {
  6554.   { "ACR2"   , 0x006 },
  6555.   { "ACR3"   , 0x007 },
  6556.   { "RAMBAR0", 0xc04 },
  6557.   { "RAMBAR1", 0xc05 },
  6558.   { NULL     , 0x000 },
  6559. };
  6560.  
  6561. static const tCtReg CtRegs_5202_5329[] =
  6562. {
  6563.   { "RAMBAR" , 0xc05 },
  6564.   { NULL     , 0x000 },
  6565. };
  6566.  
  6567. static const tCtReg CtRegs_5202_5407[] =
  6568. {
  6569.   { "ACR2"   , 0x006 },
  6570.   { "ACR3"   , 0x007 },
  6571.   { "RAMBAR0", 0xc04 },
  6572.   { "RAMBAR1", 0xc05 },
  6573.   { "MBAR"   , 0xc0f },
  6574.   { NULL     , 0x000 },
  6575. };
  6576.  
  6577. static const tCtReg CtRegs_Cf_CPU[] =
  6578. {
  6579.   { "D0_LOAD"  , 0x080 },
  6580.   { "D1_LOAD"  , 0x081 },
  6581.   { "D2_LOAD"  , 0x082 },
  6582.   { "D3_LOAD"  , 0x083 },
  6583.   { "D4_LOAD"  , 0x084 },
  6584.   { "D5_LOAD"  , 0x085 },
  6585.   { "D6_LOAD"  , 0x086 },
  6586.   { "D7_LOAD"  , 0x087 },
  6587.   { "A0_LOAD"  , 0x088 },
  6588.   { "A1_LOAD"  , 0x089 },
  6589.   { "A2_LOAD"  , 0x08a },
  6590.   { "A3_LOAD"  , 0x08b },
  6591.   { "A4_LOAD"  , 0x08c },
  6592.   { "A5_LOAD"  , 0x08d },
  6593.   { "A6_LOAD"  , 0x08e },
  6594.   { "A7_LOAD"  , 0x08f },
  6595.   { "D0_STORE" , 0x180 },
  6596.   { "D1_STORE" , 0x181 },
  6597.   { "D2_STORE" , 0x182 },
  6598.   { "D3_STORE" , 0x183 },
  6599.   { "D4_STORE" , 0x184 },
  6600.   { "D5_STORE" , 0x185 },
  6601.   { "D6_STORE" , 0x186 },
  6602.   { "D7_STORE" , 0x187 },
  6603.   { "A0_STORE" , 0x188 },
  6604.   { "A1_STORE" , 0x189 },
  6605.   { "A2_STORE" , 0x18a },
  6606.   { "A3_STORE" , 0x18b },
  6607.   { "A4_STORE" , 0x18c },
  6608.   { "A5_STORE" , 0x18d },
  6609.   { "A6_STORE" , 0x18e },
  6610.   { "A7_STORE" , 0x18f },
  6611.   { "OTHER_A7" , 0x800 },
  6612.   { NULL       , 0x000 },
  6613. };
  6614.  
  6615. static const tCtReg CtRegs_Cf_EMAC[] =
  6616. {
  6617.   { "MACSR"    , 0x804 },
  6618.   { "MASK"     , 0x805 },
  6619.   { "ACC0"     , 0x806 },
  6620.   { "ACCEXT01" , 0x807 },
  6621.   { "ACCEXT23" , 0x808 },
  6622.   { "ACC1"     , 0x809 },
  6623.   { "ACC2"     , 0x80a },
  6624.   { "ACC3"     , 0x80b },
  6625.   { NULL       , 0x000 },
  6626. };
  6627.  
  6628. static const tCtReg CtRegs_MCF51[] =
  6629. {
  6630.   { "VBR"      , 0x801 },
  6631.   { "CPUCR"    , 0x802 },
  6632.   { NULL       , 0x000 },
  6633. };
  6634.  
  6635. static const tCPUProps CPUProps[] =
  6636. {
  6637.   /* 68881/68882 may be attached memory-mapped and emulated on pre-68020 devices */
  6638.   { "68008",    0x000ffffful, e68KGen1a, eCfISA_None  , eFlagExtFPU | eFlagLogCCR, { NULL } },
  6639.   { "68000",    0x00fffffful, e68KGen1a, eCfISA_None  , eFlagExtFPU | eFlagLogCCR, { NULL } },
  6640.   { "68010",    0x00fffffful, e68KGen1b, eCfISA_None  , eFlagExtFPU | eFlagLogCCR, { CtRegs_1040 } },
  6641.   { "68012",    0x7ffffffful, e68KGen1b, eCfISA_None  , eFlagExtFPU | eFlagLogCCR, { CtRegs_1040 } },
  6642.   { "MCF5202",  0xfffffffful, eColdfire, eCfISA_A     , eFlagIntFPU | eFlagIdxScaling, { CtRegs_5202 } },
  6643.   { "MCF5204",  0xfffffffful, eColdfire, eCfISA_A     , eFlagIntFPU | eFlagIdxScaling, { CtRegs_5202, CtRegs_5202_5204 } },
  6644.   { "MCF5206",  0xfffffffful, eColdfire, eCfISA_A     , eFlagIntFPU | eFlagIdxScaling, { CtRegs_5202, CtRegs_5202_5204 } },
  6645.   { "MCF5208",  0xfffffffful, eColdfire, eCfISA_APlus , eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5208, CtRegs_Cf_CPU, CtRegs_Cf_EMAC } }, /* V2 */
  6646.   { "MCF52274", 0xfffffffful, eColdfire, eCfISA_APlus , eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5208, CtRegs_Cf_CPU, CtRegs_Cf_EMAC } }, /* V2 */
  6647.   { "MCF52277", 0xfffffffful, eColdfire, eCfISA_APlus , eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5208, CtRegs_Cf_CPU, CtRegs_Cf_EMAC } }, /* V2 */
  6648.   { "MCF5307",  0xfffffffful, eColdfire, eCfISA_A     , eFlagIntFPU | eFlagIdxScaling | eFlagMAC, { CtRegs_5202, CtRegs_5202_5307 } }, /* V3 */
  6649.   { "MCF5329",  0xfffffffful, eColdfire, eCfISA_APlus , eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5329 } }, /* V3 */
  6650.   { "MCF5373",  0xfffffffful, eColdfire, eCfISA_APlus , eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5329 } }, /* V3 */
  6651.   { "MCF5407",  0xfffffffful, eColdfire, eCfISA_B     , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4 */
  6652.   { "MCF5470",  0xfffffffful, eColdfire, eCfISA_B     , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
  6653.   { "MCF5471",  0xfffffffful, eColdfire, eCfISA_B     , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
  6654.   { "MCF5472",  0xfffffffful, eColdfire, eCfISA_B     , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
  6655.   { "MCF5473",  0xfffffffful, eColdfire, eCfISA_B     , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
  6656.   { "MCF5474",  0xfffffffful, eColdfire, eCfISA_B     , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
  6657.   { "MCF5475",  0xfffffffful, eColdfire, eCfISA_B     , eFlagBranch32 | eFlagIntFPU | eFlagIdxScaling | eFlagMAC | eFlagEMAC, { CtRegs_5202, CtRegs_5202_5407 } }, /* V4e */
  6658.   { "MCF51QM",  0xfffffffful, eColdfire, eCfISA_C     , eFlagBranch32 | eFlagMAC | eFlagIdxScaling | eFlagEMAC, { CtRegs_MCF51 } }, /* V1 */
  6659.   { "68332",    0xfffffffful, eCPU32   , eCfISA_None  , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling, { CtRegs_1040 } },
  6660.   { "68340",    0xfffffffful, eCPU32   , eCfISA_None  , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling, { CtRegs_1040 } },
  6661.   { "68360",    0xfffffffful, eCPU32   , eCfISA_None  , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling, { CtRegs_1040 } },
  6662.   { "68020",    0xfffffffful, e68KGen2 , eCfISA_None  , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling | eFlagExtFPU | eFlagCALLM_RTM, { CtRegs_1040, CtRegs_2040, CtRegs_2030 } },
  6663.   { "68030",    0xfffffffful, e68KGen2 , eCfISA_None  , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling | eFlagExtFPU | eFlagIntPMMU, { CtRegs_1040, CtRegs_2040, CtRegs_2030 } },
  6664.   /* setting eFlagExtFPU assumes instructions of external FPU are emulated/provided by M68040FPSP! */
  6665.   { "68040",    0xfffffffful, e68KGen3 , eCfISA_None  , eFlagBranch32 | eFlagLogCCR | eFlagIdxScaling | eFlagIntPMMU | eFlagExtFPU | eFlagIntFPU, { CtRegs_1040, CtRegs_2040, CtRegs_40 } },
  6666.   { NULL   ,    0           , e68KGen1a, eCfISA_None  , eFlagNone, { NULL } },
  6667. };
  6668.  
  6669. void code68k_init(void)
  6670. {
  6671.   const tCPUProps *pProp;
  6672.   for (pProp = CPUProps; pProp->pName; pProp++)
  6673.     (void)AddCPUUser(pProp->pName, SwitchTo_68K, (void*)pProp, NULL);
  6674. }
  6675.