Subversion Repositories pentevo

Rev

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

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