Subversion Repositories pentevo

Rev

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

  1. /* codem16.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Mitsubishi M16                                              */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <string.h>
  14. #include <ctype.h>
  15.  
  16. #include "bpemu.h"
  17. #include "nls.h"
  18. #include "strutil.h"
  19. #include "errmsg.h"
  20. #include "asmdef.h"
  21. #include "asmsub.h"
  22. #include "asmpars.h"
  23. #include "asmitree.h"
  24. #include "asmallg.h"
  25. #include "codepseudo.h"
  26. #include "intpseudo.h"
  27. #include "codevars.h"
  28.  
  29. #define REG_SP 15
  30. #define REG_FP 14
  31.  
  32. #define ModNone      (-1)
  33. #define ModReg       0
  34. #define MModReg      (1 << ModReg)
  35. #define ModIReg      1
  36. #define MModIReg     (1 << ModIReg)
  37. #define ModDisp16    2
  38. #define MModDisp16   (1 << ModDisp16)
  39. #define ModDisp32    3
  40. #define MModDisp32   (1 << ModDisp32)
  41. #define ModImm       4
  42. #define MModImm      (1 << ModImm)
  43. #define ModAbs16     5
  44. #define MModAbs16    (1 << ModAbs16)
  45. #define ModAbs32     6
  46. #define MModAbs32    (1 << ModAbs32)
  47. #define ModPCRel16   7
  48. #define MModPCRel16  (1 << ModPCRel16)
  49. #define ModPCRel32   8
  50. #define MModPCRel32  (1 << ModPCRel32)
  51. #define ModPop       9
  52. #define MModPop      (1 << ModPop)
  53. #define ModPush      10
  54. #define MModPush     (1 << ModPush)
  55. #define ModRegChain  11
  56. #define MModRegChain (1 << ModRegChain)
  57. #define ModPCChain   12
  58. #define MModPCChain  (1 << ModPCChain)
  59. #define ModAbsChain  13
  60. #define MModAbsChain (1 << ModAbsChain)
  61.  
  62. #define Mask_RegOnly    (MModReg)
  63. #define Mask_AllShort   (MModReg | MModIReg | MModDisp16 | MModImm | MModAbs16 | MModAbs32 | MModPCRel16 | MModPCRel32 | MModPop | MModPush | MModPCChain | MModAbsChain)
  64. #define Mask_AllGen     (Mask_AllShort | MModDisp32 | MModRegChain)
  65. #define Mask_NoImmShort (Mask_AllShort & ~MModImm)
  66. #define Mask_NoImmGen   (Mask_AllGen & ~MModImm)
  67. #define Mask_MemShort   (Mask_NoImmShort & ~MModReg)
  68. #define Mask_MemGen     (Mask_NoImmGen & ~MModReg)
  69.  
  70. #define Mask_Source     (Mask_AllGen & ~MModPush)
  71. #define Mask_Dest       (Mask_NoImmGen & ~MModPop)
  72. #define Mask_PureDest   (Mask_NoImmGen & ~(MModPush | MModPop))
  73. #define Mask_PureMem    (Mask_MemGen & ~(MModPush | MModPop))
  74.  
  75. typedef struct
  76. {
  77.   Word Mask;
  78.   Byte OpMask;
  79.   Word Code;
  80. } OneOrder;
  81.  
  82. typedef struct
  83. {
  84.   Word Mask1,Mask2;
  85.   Word SMask1,SMask2;
  86.   Word Code;
  87.   Boolean Signed;
  88. } GE2Order;
  89.  
  90. typedef struct
  91. {
  92.   char *Name;
  93.   Boolean MustByte;
  94.   Word Code1,Code2;
  95. } BitOrder;
  96.  
  97. typedef struct
  98. {
  99.   const char *p_name;
  100. } condition_t;
  101.  
  102. static CPUVar CPUM16;
  103.  
  104. static char *Format;
  105. static Byte FormatCode;
  106. static ShortInt DOpSize, OpSize[5];
  107. static Word AdrMode[5];
  108. static ShortInt AdrType[5];
  109. static Byte AdrCnt1[5], AdrCnt2[5];
  110. static Word AdrVals[5][8];
  111.  
  112. static Byte OptionCnt;
  113. static char Options[2][10];
  114.  
  115. static BitOrder *FixedLongOrders;
  116. static OneOrder *OneOrders;
  117. static GE2Order *GE2Orders;
  118. static BitOrder *BitOrders;
  119. static condition_t *Conditions;
  120.  
  121. /*------------------------------------------------------------------------*/
  122.  
  123. typedef enum
  124. {
  125.   DispSizeNone,
  126.   DispSize4,
  127.   DispSize4Eps,
  128.   DispSize16,
  129.   DispSize32
  130. } DispSize;
  131.  
  132. typedef struct _TChainRec
  133. {
  134.   struct _TChainRec *Next;
  135.   Byte RegCnt;
  136.   Word Regs[5],Scales[5];
  137.   LongInt DispAcc;
  138.   Boolean HasDisp;
  139.   DispSize DSize;
  140. } *PChainRec, TChainRec;
  141. static Boolean ErrFlag;
  142.  
  143. static Boolean IsD4(LongInt inp)
  144. {
  145.   return ((inp >= -32) && (inp <= 28));
  146. }
  147.  
  148. static Boolean IsD16(LongInt inp)
  149. {
  150.   return ((inp >= -32768) && (inp <= 32767));
  151. }
  152.  
  153. /*!------------------------------------------------------------------------
  154.  * \fn     DecodeRegCore(const char *pArg, Word *pResult)
  155.  * \brief  check whether argument is a CPU register
  156.  * \param  pArg argument to check
  157.  * \param  pResult numeric register value if yes
  158.  * \return True if yes
  159.  * ------------------------------------------------------------------------ */
  160.  
  161. static Boolean DecodeRegCore(const char *pArg, Word *pResult)
  162. {
  163.   if (!as_strcasecmp(pArg, "SP"))
  164.     *pResult = REG_SP | REGSYM_FLAG_ALIAS;
  165.   else if (!as_strcasecmp(pArg, "FP"))
  166.     *pResult = REG_FP | REGSYM_FLAG_ALIAS;
  167.   else if ((strlen(pArg) > 1) && (as_toupper(*pArg) == 'R'))
  168.   {
  169.     Boolean OK;
  170.  
  171.     *pResult = ConstLongInt(pArg + 1, &OK, 10);
  172.     return OK && (*pResult <= 15);
  173.   }
  174.   else
  175.     return False;
  176.  
  177.   return True;
  178. }
  179.  
  180. /*!------------------------------------------------------------------------
  181.  * \fn     DissectReg_M16(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  182.  * \brief  dissect register symbols - M16 variant
  183.  * \param  pDest destination buffer
  184.  * \param  DestSize destination buffer size
  185.  * \param  Value numeric register value
  186.  * \param  InpSize register size
  187.  * ------------------------------------------------------------------------ */
  188.  
  189. static void DissectReg_M16(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  190. {
  191.   if (InpSize == eSymbolSize32Bit)
  192.   {
  193.     switch (Value)
  194.     {
  195.       case REGSYM_FLAG_ALIAS | REG_SP:
  196.         as_snprintf(pDest, DestSize, "SP");
  197.         break;
  198.       case REGSYM_FLAG_ALIAS | REG_FP:
  199.         as_snprintf(pDest, DestSize, "FP");
  200.         break;
  201.       default:
  202.         as_snprintf(pDest, DestSize, "R%u", (unsigned)(Value & 15));
  203.     }
  204.   }
  205.   else
  206.     as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  207. }
  208.  
  209. /*!------------------------------------------------------------------------
  210.  * \fn     DecodeReg(const tStrComp *pArg, Word *pResult, Boolean MustBeReg)
  211.  * \brief  parse for register, including register aliases
  212.  * \param  pArg source argument
  213.  * \param  pResult result buffer
  214.  * \param  MustBeReg True if register is expected
  215.  * \return tRegEvalResult
  216.  * ------------------------------------------------------------------------ */
  217.  
  218. static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pResult, Boolean MustBeReg)
  219. {
  220.   tRegDescr RegDescr;
  221.   tEvalResult EvalResult;
  222.   tRegEvalResult RegEvalResult;
  223.  
  224.   if (DecodeRegCore(pArg->str.p_str, pResult))
  225.   {
  226.     *pResult &= ~REGSYM_FLAG_ALIAS;
  227.     return eIsReg;
  228.   }
  229.  
  230.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize32Bit, MustBeReg);
  231.   *pResult = RegDescr.Reg & ~REGSYM_FLAG_ALIAS;
  232.   return RegEvalResult;
  233. }
  234.  
  235. static void SplitSize(tStrComp *pArg, DispSize *Erg)
  236. {
  237.   int ArgLen = strlen(pArg->str.p_str);
  238.  
  239.   if ((ArgLen > 2) && (!strcmp(pArg->str.p_str + (ArgLen - 2), ":4")))
  240.   {
  241.     *Erg = DispSize4;
  242.     StrCompShorten(pArg, 2);
  243.   }
  244.   else if ((ArgLen > 3) && (!strcmp(pArg->str.p_str + (ArgLen - 3), ":16")))
  245.   {
  246.     *Erg = DispSize16;
  247.     StrCompShorten(pArg, 3);
  248.   }
  249.   else if ((ArgLen > 3) && (!strcmp(pArg->str.p_str + (ArgLen - 3), ":32")))
  250.   {
  251.     *Erg = DispSize32;
  252.     StrCompShorten(pArg, 3);
  253.   }
  254. }
  255.  
  256. static void DecideAbs(LongInt Disp, DispSize Size, Word Mask, int Index)
  257. {
  258.   switch (Size)
  259.   {
  260.     case DispSize4:
  261.       Size = DispSize16;
  262.       break;
  263.     case DispSizeNone:
  264.       Size = ((IsD16(Disp)) && (Mask & MModAbs16)) ? DispSize16 : DispSize32;
  265.       break;
  266.     default:
  267.       break;
  268.   }
  269.  
  270.   switch (Size)
  271.   {
  272.     case DispSize16:
  273.       if (ChkRange(Disp, -32768, 32767))
  274.       {
  275.         AdrType[Index] = ModAbs16;
  276.         AdrMode[Index] = 0x09;
  277.         AdrVals[Index][0] = Disp & 0xffff;
  278.         AdrCnt1[Index] = 2;
  279.       }
  280.       break;
  281.     case DispSize32:
  282.       AdrType[Index] = ModAbs32;
  283.       AdrMode[Index] = 0x0a;
  284.       AdrVals[Index][0] = Disp >> 16;
  285.       AdrVals[Index][1] = Disp & 0xffff;
  286.       AdrCnt1[Index] = 4;
  287.       break;
  288.     default:
  289.       WrError(ErrNum_InternalError);
  290.   }
  291. }
  292.  
  293. static void SetError(tErrorNum Code)
  294. {
  295.   WrError(Code);
  296.   ErrFlag = True;
  297. }
  298.  
  299. static PChainRec DecodeChain(tStrComp *pArg)
  300. {
  301.   PChainRec Rec;
  302.   int z;
  303.   char *pCompSplit, *pScaleSplit;
  304.   String SRegStr;
  305.   tStrComp Arg, Remainder, ScaleArg, SReg;
  306.   Boolean OK;
  307.   Byte Scale;
  308.   tRegEvalResult RegEvalResult;
  309.  
  310.   ChkStack();
  311.   Rec = (PChainRec) malloc(sizeof(TChainRec));
  312.   Rec->Next = NULL;
  313.   Rec->RegCnt = 0;
  314.   Rec->DispAcc = 0;
  315.   Rec->HasDisp = False;
  316.   Rec->DSize = DispSizeNone;
  317.  
  318.   StrCompMkTemp(&SReg, SRegStr, sizeof(SRegStr));
  319.   Arg = *pArg;
  320.   do
  321.   {
  322.     /* eine Komponente abspalten */
  323.  
  324.     pCompSplit = QuotPos(Arg.str.p_str, ',');
  325.     if (pCompSplit)
  326.       StrCompSplitRef(&Arg, &Remainder, &Arg, pCompSplit);
  327.  
  328.     StrCompCopy(&SReg, &Arg);
  329.     pScaleSplit = RQuotPos(SReg.str.p_str, '*');
  330.     if (pScaleSplit)
  331.       StrCompSplitRef(&SReg, &ScaleArg, &SReg, pScaleSplit);
  332.  
  333.     /* weitere Indirektion ? */
  334.  
  335.     if (*Arg.str.p_str == '@')
  336.     {
  337.       if (Rec->Next) SetError(ErrNum_InvAddrMode);
  338.       else
  339.       {
  340.         StrCompIncRefLeft(&Arg, 1);
  341.         if (IsIndirect(Arg.str.p_str))
  342.         {
  343.           StrCompIncRefLeft(&Arg, 1);
  344.           StrCompShorten(&Arg, 1);
  345.         }
  346.         Rec->Next = DecodeChain(&Arg);
  347.       }
  348.     }
  349.  
  350.     /* Register, mit Skalierungsfaktor ? */
  351.  
  352.     else if ((RegEvalResult = DecodeReg(&SReg, Rec->Regs + Rec->RegCnt, False)) != eIsNoReg)
  353.     {
  354.       if (RegEvalResult == eRegAbort)
  355.         ErrFlag = True;
  356.       else if (Rec->RegCnt >= 5) SetError(ErrNum_InvAddrMode);
  357.       else
  358.       {
  359.         tSymbolFlags Flags;
  360.  
  361.         if (pScaleSplit)
  362.           Scale = EvalStrIntExpressionWithFlags(&ScaleArg, UInt4, &OK, &Flags);
  363.         else
  364.         {
  365.           OK = True;
  366.           Scale = 1;
  367.            Flags= eSymbolFlag_None;
  368.         }
  369.         if (mFirstPassUnknown(Flags))
  370.           Scale = 1;
  371.         if (!OK) ErrFlag = True;
  372.         else if ((Scale != 1) && (Scale != 2) && (Scale != 4) && (Scale != 8)) SetError(ErrNum_InvAddrMode);
  373.         else
  374.         {
  375.           Rec->Scales[Rec->RegCnt] = 0;
  376.           while (Scale > 1)
  377.           {
  378.             Rec->Scales[Rec->RegCnt]++;
  379.             Scale = Scale >> 1;
  380.           }
  381.           Rec->RegCnt++;
  382.         }
  383.       }
  384.     }
  385.  
  386.     /* PC, mit Skalierungsfaktor ? */
  387.  
  388.     else if (!as_strcasecmp(SReg.str.p_str, "PC"))
  389.     {
  390.       if (Rec->RegCnt >= 5) SetError(ErrNum_InvAddrMode);
  391.       else
  392.       {
  393.         tSymbolFlags Flags;
  394.  
  395.         if (pScaleSplit)
  396.           Scale = EvalStrIntExpressionWithFlags(&ScaleArg, UInt4, &OK, &Flags);
  397.         else
  398.         {
  399.           OK = True;
  400.           Scale = 1;
  401.           Flags = eSymbolFlag_None;
  402.         }
  403.         if (mFirstPassUnknown(Flags))
  404.           Scale = 1;
  405.         if (!OK) ErrFlag = True;
  406.         else if ((Scale != 1) && (Scale != 2) && (Scale != 4) && (Scale != 8)) SetError(ErrNum_InvAddrMode);
  407.         else
  408.         {
  409.           for (z = Rec->RegCnt - 1; z >= 0; z--)
  410.           {
  411.             Rec->Regs[z + 1] = Rec->Regs[z];
  412.             Rec->Scales[z + 1] = Rec->Scales[z];
  413.           }
  414.           Rec->Scales[0] = 0;
  415.           while (Scale > 1)
  416.           {
  417.             Rec->Scales[0]++;
  418.             Scale = Scale >> 1;
  419.           }
  420.           Rec->Regs[0] = 16;
  421.           Rec->RegCnt++;
  422.         }
  423.       }
  424.     }
  425.  
  426.     /* ansonsten Displacement */
  427.  
  428.     else
  429.     {
  430.       SplitSize(&Arg, &(Rec->DSize));
  431.       Rec->DispAcc += EvalStrIntExpression(&Arg, Int32, &OK);
  432.       if (!OK) ErrFlag = True;
  433.       Rec->HasDisp = True;
  434.     }
  435.  
  436.     if (pCompSplit)
  437.       Arg = Remainder;
  438.   }
  439.   while (pCompSplit && !ErrFlag);
  440.  
  441.   if (ErrFlag)
  442.   {
  443.     free(Rec);
  444.     return NULL;
  445.   }
  446.   else return Rec;
  447. }
  448.  
  449. static Boolean ChkAdr(Word Mask, int Index)
  450. {
  451.   AdrCnt2[Index]=AdrCnt1[Index] >> 1;
  452.   if ((AdrType[Index] != -1) && ((Mask & (1 << AdrType[Index])) == 0))
  453.   {
  454.     char Str[30];
  455.  
  456.     AdrCnt1[Index] = AdrCnt2[Index] = 0;
  457.     AdrType[Index] = ModNone;
  458.     as_snprintf(Str, sizeof(Str), "%d", Index);
  459.     WrXError(ErrNum_InvAddrMode, Str);
  460.     return False;
  461.   }
  462.   else
  463.     return (AdrType[Index] != ModNone);
  464. }
  465.  
  466. static Boolean DecodeAdr(const tStrComp *pArg, int Index, Word Mask)
  467. {
  468.   LongInt AdrLong, MinReserve, MaxReserve;
  469.   int z, z2, LastChain;
  470.   Boolean OK, Error;
  471.   PChainRec RootChain, RunChain, PrevChain;
  472.   DispSize DSize;
  473.   tStrComp Arg;
  474.  
  475.   AdrCnt1[Index] = 0;
  476.   AdrType[Index] = ModNone;
  477.  
  478.   /* Register ? */
  479.  
  480.   switch (DecodeReg(pArg, AdrMode + Index, False))
  481.   {
  482.     case eIsReg:
  483.       AdrType[Index] = ModReg;
  484.       AdrMode[Index] += 0x10;
  485.       return ChkAdr(Mask, Index);
  486.     case eIsNoReg:
  487.       break;
  488.     default:
  489.       return False;
  490.   }
  491.  
  492.   /* immediate ? */
  493.  
  494.   if (*pArg->str.p_str == '#')
  495.   {
  496.     switch (OpSize[Index])
  497.     {
  498.       case -1:
  499.         WrError(ErrNum_UndefOpSizes);
  500.         OK = False;
  501.         break;
  502.       case 0:
  503.         AdrVals[Index][0] = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK) & 0xff;
  504.         if (OK)
  505.           AdrCnt1[Index] = 2;
  506.         break;
  507.       case 1:
  508.         AdrVals[Index][0] = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
  509.         if (OK)
  510.           AdrCnt1[Index] = 2;
  511.         break;
  512.       case 2:
  513.         AdrLong = EvalStrIntExpressionOffs(pArg, 1, Int32, &OK);
  514.         if (OK)
  515.         {
  516.           AdrVals[Index][0] = AdrLong >> 16;
  517.           AdrVals[Index][1] = AdrLong & 0xffff;
  518.           AdrCnt1[Index] = 4;
  519.         }
  520.         break;
  521.     }
  522.     if (OK)
  523.     {
  524.       AdrType[Index] = ModImm;
  525.       AdrMode[Index] = 0x0c;
  526.     }
  527.     return ChkAdr(Mask, Index);
  528.   }
  529.  
  530.   /* indirekt ? */
  531.  
  532.   if (*pArg->str.p_str == '@')
  533.   {
  534.     tStrComp IArg;
  535.  
  536.     StrCompRefRight(&IArg,pArg, 1);
  537.     if (IsIndirect(IArg.str.p_str))
  538.     {
  539.       StrCompIncRefLeft(&IArg, 1);
  540.       StrCompShorten(&IArg, 1);
  541.     }
  542.  
  543.     /* Stack Push ? */
  544.  
  545.     if ((!as_strcasecmp(IArg.str.p_str, "-R15")) || (!as_strcasecmp(IArg.str.p_str, "-SP")))
  546.     {
  547.       AdrType[Index] = ModPush;
  548.       AdrMode[Index] = 0x05;
  549.       return ChkAdr(Mask, Index);
  550.     }
  551.  
  552.     /* Stack Pop ? */
  553.  
  554.     if ((!as_strcasecmp(IArg.str.p_str, "R15+")) || (!as_strcasecmp(IArg.str.p_str, "SP+")))
  555.     {
  556.       AdrType[Index] = ModPop;
  557.       AdrMode[Index] = 0x04;
  558.       return ChkAdr(Mask, Index);
  559.     }
  560.  
  561.     /* Register einfach indirekt ? */
  562.  
  563.     switch (DecodeReg(&IArg, AdrMode + Index, False))
  564.     {
  565.       case eIsReg:
  566.         AdrType[Index] = ModIReg;
  567.         AdrMode[Index] += 0x30;
  568.         return ChkAdr(Mask, Index);
  569.       case eIsNoReg:
  570.         break;
  571.       case eRegAbort:
  572.         return False;
  573.     }
  574.  
  575.     /* zusammengesetzt indirekt ? */
  576.  
  577.     ErrFlag = False;
  578.     RootChain = DecodeChain(&IArg);
  579.  
  580.     if (ErrFlag);
  581.  
  582.     else if (!RootChain);
  583.  
  584.     /* absolut ? */
  585.  
  586.     else if ((!RootChain->Next) && (RootChain->RegCnt == 0))
  587.     {
  588.       if (!RootChain->HasDisp)
  589.         RootChain->DispAcc = 0;
  590.       DecideAbs(RootChain->DispAcc, RootChain->DSize, Mask, Index);
  591.       free(RootChain);
  592.     }
  593.  
  594.     /* einfaches Register/PC mit Displacement ? */
  595.  
  596.     else if ((!RootChain->Next) && (RootChain->RegCnt == 1) && (RootChain->Scales[0] == 0))
  597.     {
  598.       if (RootChain->Regs[0] == 16)
  599.         RootChain->DispAcc -= EProgCounter();
  600.  
  601.       /* Displacement-Groesse entscheiden */
  602.  
  603.       if (RootChain->DSize == DispSizeNone)
  604.       {
  605.         if ((RootChain->DispAcc == 0) && (RootChain->Regs[0] < 16));
  606.         else
  607.          RootChain->DSize = (IsD16(RootChain->DispAcc)) ? DispSize16 : DispSize32;
  608.       }
  609.  
  610.       switch (RootChain->DSize)
  611.       {
  612.         /* kein Displacement mit Register */
  613.  
  614.         case DispSizeNone:
  615.           if (ChkRange(RootChain->DispAcc, 0, 0))
  616.           {
  617.             if (RootChain->Regs[0] >= 16) WrError(ErrNum_InvAddrMode);
  618.             else
  619.             {
  620.               AdrType[Index] = ModIReg;
  621.               AdrMode[Index] = 0x30 + RootChain->Regs[0];
  622.             }
  623.           }
  624.           break;
  625.  
  626.         /* 16-Bit-Displacement */
  627.  
  628.         case DispSize4:
  629.         case DispSize16:
  630.           if (ChkRange(RootChain->DispAcc, -32768, 32767))
  631.           {
  632.             AdrVals[Index][0] = RootChain->DispAcc & 0xffff;
  633.             AdrCnt1[Index] = 2;
  634.             if (RootChain->Regs[0] == 16)
  635.             {
  636.               AdrType[Index] = ModPCRel16;
  637.               AdrMode[Index] = 0x0d;
  638.             }
  639.             else
  640.             {
  641.               AdrType[Index] = ModDisp16;
  642.               AdrMode[Index] = 0x20 + RootChain->Regs[0];
  643.             }
  644.           }
  645.           break;
  646.  
  647.         /* 32-Bit-Displacement */
  648.  
  649.         default:
  650.          AdrVals[Index][1] = RootChain->DispAcc & 0xffff;
  651.          AdrVals[Index][0] = RootChain->DispAcc >> 16;
  652.          AdrCnt1[Index] = 4;
  653.          if (RootChain->Regs[0] == 16)
  654.          {
  655.            AdrType[Index] = ModPCRel32;
  656.            AdrMode[Index] = 0x0e;
  657.          }
  658.          else
  659.          {
  660.            AdrType[Index] = ModDisp32;
  661.            AdrMode[Index] = 0x40 + RootChain->Regs[0];
  662.          }
  663.       }
  664.  
  665.       free(RootChain);
  666.     }
  667.  
  668.     /* komplex: dann chained iterieren */
  669.  
  670.     else
  671.     {
  672.       /* bis zum innersten Element der Indirektion als Basis laufen */
  673.  
  674.       RunChain = RootChain;
  675.       while (RunChain->Next)
  676.         RunChain = RunChain->Next;
  677.  
  678.       /* Entscheidung des Basismodus: die Basis darf nicht skaliert
  679.          sein, und wenn ein Modus nicht erlaubt ist, muessen wir mit
  680.          Base-none anfangen... */
  681.  
  682.       z = 0;
  683.       while ((z < RunChain->RegCnt) && (RunChain->Scales[z] != 0))
  684.         z++;
  685.       if (z >= RunChain->RegCnt)
  686.       {
  687.         AdrType[Index] = ModAbsChain;
  688.         AdrMode[Index] = 0x0b;
  689.       }
  690.       else
  691.       {
  692.         if (RunChain->Regs[z] == 16)
  693.         {
  694.           AdrType[Index] = ModPCChain;
  695.           AdrMode[Index] = 0x0f;
  696.           RunChain->DispAcc -= EProgCounter();
  697.         }
  698.         else
  699.         {
  700.           AdrType[Index] = ModRegChain;
  701.           AdrMode[Index] = 0x60 + RunChain->Regs[z];
  702.         }
  703.         for (z2 = z; z2 <= RunChain->RegCnt - 2; z2++)
  704.         {
  705.           RunChain->Regs[z2] = RunChain->Regs[z2 + 1];
  706.           RunChain->Scales[z2] = RunChain->Scales[z2 + 1];
  707.         }
  708.         RunChain->RegCnt--;
  709.       }
  710.  
  711.       /* Jetzt ueber die einzelnen Komponenten iterieren */
  712.  
  713.       LastChain = 0;
  714.       Error = False;
  715.       while ((RootChain) && (!Error))
  716.       {
  717.         RunChain = RootChain;
  718.         PrevChain = NULL;
  719.         while (RunChain->Next)
  720.         {
  721.           PrevChain = RunChain;
  722.           RunChain = RunChain->Next;
  723.         }
  724.  
  725.         /* noch etwas abzulegen ? */
  726.  
  727.         if ((RunChain->RegCnt != 0) || (RunChain->HasDisp))
  728.         {
  729.           LastChain = AdrCnt1[Index] >> 1;
  730.  
  731.           /* Register ablegen */
  732.  
  733.           if (RunChain->RegCnt != 0)
  734.           {
  735.             AdrVals[Index][LastChain] =
  736.               (RunChain->Regs[0] == 16) ? 0x0600 : RunChain->Regs[0] << 10;
  737.             AdrVals[Index][LastChain] += RunChain->Scales[0] << 5;
  738.             for (z2 = 0; z2 <= RunChain->RegCnt - 2; z2++)
  739.             {
  740.               RunChain->Regs[z2] = RunChain->Regs[z2 + 1];
  741.               RunChain->Scales[z2] = RunChain->Scales[z2 + 1];
  742.             }
  743.             RunChain->RegCnt--;
  744.           }
  745.           else
  746.             AdrVals[Index][LastChain] = 0x0200;
  747.           AdrCnt1[Index] += 2;
  748.  
  749.           /* Displacement ablegen */
  750.  
  751.           if (RunChain->HasDisp)
  752.           {
  753.             if ((AdrVals[Index][LastChain] & 0x3e00) == 0x0600)
  754.               RunChain->DispAcc -= EProgCounter();
  755.  
  756.             if (RunChain->DSize == DispSizeNone)
  757.             {
  758.               MinReserve = 32 * RunChain->RegCnt;
  759.               MaxReserve = 28 * RunChain->RegCnt;
  760.               if (IsD4(RunChain->DispAcc))
  761.                 DSize = ((RunChain->DispAcc & 3) == 0) ? DispSize4 : DispSize16;
  762.               else if ((RunChain->DispAcc >= -32 - MinReserve)
  763.                     && (RunChain->DispAcc <= 28 + MaxReserve))
  764.                 DSize = DispSize4Eps;
  765.               else if (IsD16(RunChain->DispAcc))
  766.                 DSize = DispSize16;
  767.               else if ((RunChain->DispAcc >= -32768 - MinReserve)
  768.                     && (RunChain->DispAcc <= 32767 + MaxReserve))
  769.                 DSize = DispSize4Eps;
  770.               else
  771.                 DSize = DispSize32;
  772.             }
  773.             else
  774.               DSize = RunChain->DSize;
  775.             RunChain->DSize = DispSizeNone;
  776.  
  777.             switch (DSize)
  778.             {
  779.               /* Fall 1: passt komplett in 4er-Displacement */
  780.  
  781.               case DispSize4:
  782.                 if (ChkRange(RunChain->DispAcc, -32, 28))
  783.                 {
  784.                   if (RunChain->DispAcc & 3)
  785.                   {
  786.                     WrError(ErrNum_NotAligned);
  787.                     Error = True;
  788.                   }
  789.                   else
  790.                   {
  791.                     AdrVals[Index][LastChain] += (RunChain->DispAcc >> 2) & 0x000f;
  792.                     RunChain->HasDisp = False;
  793.                   }
  794.                 }
  795.                 break;
  796.  
  797.               /* Fall 2: passt nicht mehr in naechstkleineres Displacement, aber wir
  798.                  koennen hier schon einen Teil ablegen, um im naechsten Iterations-
  799.                  schritt ein kuerzeres Displacement zu bekommen */
  800.  
  801.               case DispSize4Eps:
  802.                 if (RunChain->DispAcc > 0)
  803.                 {
  804.                   AdrVals[Index][LastChain] += 0x0007;
  805.                   RunChain->DispAcc -= 28;
  806.                 }
  807.                 else
  808.                 {
  809.                   AdrVals[Index][LastChain] += 0x0008;
  810.                   RunChain->DispAcc += 32;
  811.                 }
  812.                 break;
  813.  
  814.               /* Fall 3: 16 Bit */
  815.  
  816.               case DispSize16:
  817.                 if (ChkRange(RunChain->DispAcc, -32768, 32767))
  818.                 {
  819.                   AdrVals[Index][LastChain] += 0x0011;
  820.                   AdrVals[Index][LastChain + 1] = RunChain->DispAcc & 0xffff;
  821.                   AdrCnt1[Index] += 2;
  822.                   RunChain->HasDisp = False;
  823.                 }
  824.                 else
  825.                   Error = True;
  826.                 break;
  827.  
  828.               /* Fall 4: 32 Bit */
  829.  
  830.               case DispSize32:
  831.                 AdrVals[Index][LastChain] += 0x0012;
  832.                 AdrVals[Index][LastChain+1] = RunChain->DispAcc >> 16;
  833.                 AdrVals[Index][LastChain+2] = RunChain->DispAcc & 0xffff;
  834.                 AdrCnt1[Index] += 4;
  835.                 RunChain->HasDisp = False;
  836.                 break;
  837.  
  838.               default:
  839.                 WrError(ErrNum_InternalError);
  840.                 Error = True;
  841.             }
  842.           }
  843.         }
  844.  
  845.         /* nichts mehr drin: dann ein leeres Steuerwort erzeugen.  Tritt
  846.            auf, falls alles schon im Basisadressierungsbyte verschwunden */
  847.  
  848.         else if (RunChain != RootChain)
  849.         {
  850.           LastChain = AdrCnt1[Index] >> 1;
  851.           AdrVals[Index][LastChain] = 0x0200;
  852.           AdrCnt1[Index] += 2;
  853.         }
  854.  
  855.         /* nichts mehr drin: wegwerfen
  856.            wenn wir noch nicht ganz vorne angekommen sind, dann ein
  857.            Indirektionsflag setzen */
  858.  
  859.         if ((RunChain->RegCnt == 0) && (!RunChain->HasDisp))
  860.         {
  861.           if (RunChain != RootChain)
  862.             AdrVals[Index][LastChain] += 0x4000;
  863.           if (!PrevChain)
  864.             RootChain = NULL;
  865.           else
  866.             PrevChain->Next=NULL;
  867.           free(RunChain);
  868.         }
  869.       }
  870.  
  871.       /* Ende-Kennung fuer letztes Glied */
  872.  
  873.       AdrVals[Index][LastChain] += 0x8000;
  874.     }
  875.  
  876.     return ChkAdr(Mask, Index);
  877.   }
  878.  
  879.   /* ansonsten absolut */
  880.  
  881.   DSize = DispSizeNone;
  882.   Arg = *pArg;
  883.   SplitSize(&Arg, &DSize);
  884.   AdrLong = EvalStrIntExpression(&Arg, Int32, &OK);
  885.   if (OK)
  886.     DecideAbs(AdrLong, DSize, Mask, Index);
  887.  
  888.   return ChkAdr(Mask, Index);
  889. }
  890.  
  891. static LongInt ImmVal(int Index)
  892. {
  893.   switch (OpSize[Index])
  894.   {
  895.     case 0:
  896.       return (ShortInt) (AdrVals[Index][0] & 0xff);
  897.     case 1:
  898.       return (Integer) (AdrVals[Index][0]);
  899.     case 2:
  900.       return (((LongInt)AdrVals[Index][0]) << 16)
  901.             + ((Integer)AdrVals[Index][1]);
  902.     default:
  903.       WrError(ErrNum_InternalError);
  904.       return 0;
  905.   }
  906. }
  907.  
  908. static Boolean IsShort(int Index)
  909. {
  910.   return (!(AdrMode[Index] & 0xc0));
  911. }
  912.  
  913. static void AdaptImm(int Index, Byte NSize, Boolean Signed)
  914. {
  915.   switch (OpSize[Index])
  916.   {
  917.     case 0:
  918.       if (NSize!=0)
  919.       {
  920.         if (((AdrVals[Index][0] & 0x80) == 0x80) && (Signed))
  921.           AdrVals[Index][0] |= 0xff00;
  922.         else
  923.           AdrVals[Index][0] &= 0xff;
  924.         if (NSize == 2)
  925.         {
  926.           if (((AdrVals[Index][0] & 0x8000) == 0x8000) && (Signed))
  927.             AdrVals[Index][1] = 0xffff;
  928.           else
  929.             AdrVals[Index][1] = 0;
  930.           AdrCnt1[Index] += 2;
  931.           AdrCnt2[Index]++;
  932.         }
  933.       }
  934.       break;
  935.     case 1:
  936.       if (NSize == 0)
  937.         AdrVals[Index][0] &= 0xff;
  938.       else if (NSize == 2)
  939.       {
  940.         if (((AdrVals[Index][0] & 0x8000) == 0x8000) && (Signed))
  941.           AdrVals[Index][1] = 0xffff;
  942.         else AdrVals[Index][1] = 0;
  943.         AdrCnt1[Index] += 2;
  944.         AdrCnt2[Index]++;
  945.       }
  946.       break;
  947.     case 2:
  948.       if (NSize != 2)
  949.       {
  950.         AdrCnt1[Index] -= 2;
  951.         AdrCnt2[Index]--;
  952.         if (NSize == 0)
  953.           AdrVals[Index][0] &= 0xff;
  954.       }
  955.       break;
  956.   }
  957.   OpSize[Index] = NSize;
  958. }
  959.  
  960. static ShortInt DefSize(Byte Mask)
  961. {
  962.   ShortInt z;
  963.  
  964.   z = 2;
  965.   while ((z >= 0) && (!(Mask & 4)))
  966.   {
  967.     Mask = (Mask << 1) & 7;
  968.     z--;
  969.   }
  970.   return z;
  971. }
  972.  
  973. static Word RMask(Word No, Boolean Turn)
  974. {
  975.   return (Turn) ? (0x8000 >> No) : (1 << No);
  976. }
  977.  
  978. static Boolean DecodeRegList(const tStrComp *pArg, Word *pResult, Boolean Turn)
  979. {
  980.   String ArgStr;
  981.   tStrComp Arg, Remainder, From, To;
  982.   char *p, *p1, *p2, *p3;
  983.   Word r1, r2, z;
  984.  
  985.   StrCompMkTemp(&Arg, ArgStr, sizeof(ArgStr));
  986.   StrCompCopy(&Arg, pArg);
  987.   if (IsIndirect(Arg.str.p_str))
  988.   {
  989.     StrCompShorten(&Arg, 1);
  990.     StrCompIncRefLeft(&Arg, 1);
  991.   }
  992.  
  993.   *pResult = 0;
  994.   do
  995.   {
  996.     p1 = strchr(Arg.str.p_str, ',');
  997.     p2 = strchr(Arg.str.p_str, '/');
  998.     p = (p1 && (p1 < p2)) ? p1 : p2;
  999.     if (p)
  1000.       StrCompSplitRef(&Arg, &Remainder, &Arg, p);
  1001.     p3 = strchr(Arg.str.p_str, '-');
  1002.     if (!p3)
  1003.     {
  1004.       if (!DecodeReg(&Arg, &r1, True))
  1005.         return False;
  1006.       *pResult |= RMask(r1, Turn);
  1007.     }
  1008.     else
  1009.     {
  1010.       StrCompSplitRef(&From, &To, &Arg, p3);
  1011.       if (!DecodeReg(&From, &r1, True)
  1012.        || !DecodeReg(&To, &r2, True))
  1013.         return False;
  1014.       if (r1 <= r2)
  1015.       {
  1016.         for (z = r1; z <= r2; z++)
  1017.           *pResult |= RMask(z, Turn);
  1018.       }
  1019.       else
  1020.       {
  1021.         for (z = r2; z <= 15; z++)
  1022.           *pResult |= RMask(z, Turn);
  1023.         for (z = 0; z <= r1; z++)
  1024.           *pResult |= RMask(z,Turn);
  1025.       }
  1026.     }
  1027.     if (p)
  1028.       Arg = Remainder;
  1029.   }
  1030.   while (p);
  1031.   return True;
  1032. }
  1033.  
  1034. static Boolean DecodeCondition(const char *Asc, Word *Erg)
  1035. {
  1036.   int z;
  1037.  
  1038.   for (z = 0; Conditions[z].p_name; z++)
  1039.     if (!as_strcasecmp(Asc, Conditions[z].p_name))
  1040.     {
  1041.       *Erg = z;
  1042.       return True;
  1043.     }
  1044.   return False;
  1045. }
  1046.  
  1047. static Boolean DecodeStringCondition(const char *Asc, Word *pErg)
  1048. {
  1049.   Boolean OK = TRUE;
  1050.  
  1051.   if (!as_strcasecmp(Asc, "LTU"))
  1052.     *pErg = 0;
  1053.   else if (!as_strcasecmp(Asc, "GEU"))
  1054.     *pErg = 1;
  1055.   else if (!as_strcasecmp(Asc, "N"))
  1056.     *pErg = 6;
  1057.   else
  1058.     OK = (DecodeCondition(Asc, pErg) && (*pErg > 1) && (*pErg < 6));
  1059.  
  1060.   return OK;
  1061. }
  1062.  
  1063. /*------------------------------------------------------------------------*/
  1064.  
  1065. static Boolean CheckFormat(const char *FSet)
  1066. {
  1067.   const char *p;
  1068.  
  1069.   if (!strcmp(Format, " "))
  1070.     FormatCode = 0;
  1071.   else
  1072.   {
  1073.     p = strchr(FSet, *Format);
  1074.     if (p)
  1075.       FormatCode = p - FSet + 1;
  1076.     else
  1077.       WrError(ErrNum_InvFormat);
  1078.     return (p != NULL);
  1079.   }
  1080.   return True;
  1081. }
  1082.  
  1083. static Boolean CheckBFieldFormat(void)
  1084. {
  1085.   if ((!strcmp(Format, "G:R")) || (!strcmp(Format, "R:G")))
  1086.     FormatCode = 1;
  1087.   else if ((!strcmp(Format, "G:I")) || (!strcmp(Format, "I:G")))
  1088.     FormatCode = 2;
  1089.   else if ((!strcmp(Format, "E:R")) || (!strcmp(Format, "R:E")))
  1090.     FormatCode = 3;
  1091.   else if ((!strcmp(Format, "E:I")) || (!strcmp(Format, "I:E")))
  1092.     FormatCode = 4;
  1093.   else
  1094.   {
  1095.     WrError(ErrNum_InvFormat);
  1096.     return False;
  1097.   }
  1098.   return True;
  1099. }
  1100.  
  1101. static Boolean GetOpSize(tStrComp *pArg, Byte Index)
  1102. {
  1103.   char *p;
  1104.   int ArgLen = strlen(pArg->str.p_str);
  1105.  
  1106.   p = RQuotPos(pArg->str.p_str, '.');
  1107.   if (!p)
  1108.   {
  1109.     OpSize[Index] = DOpSize;
  1110.     return True;
  1111.   }
  1112.   else if (p == pArg->str.p_str + ArgLen - 2)
  1113.   {
  1114.     switch (as_toupper(p[1]))
  1115.     {
  1116.       case 'B':
  1117.         OpSize[Index] = 0;
  1118.         break;
  1119.       case 'H':
  1120.         OpSize[Index] = 1;
  1121.         break;
  1122.       case 'W':
  1123.         OpSize[Index] = 2;
  1124.         break;
  1125.       default:
  1126.         WrXError(ErrNum_UndefAttr, p);
  1127.         return False;
  1128.     }
  1129.     StrCompShorten(pArg, 2);
  1130.     return True;
  1131.   }
  1132.   else
  1133.   {
  1134.     WrError(ErrNum_UndefAttr);
  1135.     return False;
  1136.   }
  1137. }
  1138.  
  1139. static void SplitOptions(void)
  1140. {
  1141.   char *pSplit, *pSrc;
  1142.  
  1143.   pSrc = OpPart.str.p_str;
  1144.   *Options[0] = *Options[1] = '\0';
  1145.   for (OptionCnt = 0; OptionCnt < 2; OptionCnt++)
  1146.   {
  1147.     pSplit = QuotPos(pSrc, '/');
  1148.     if (!pSplit)
  1149.       break;
  1150.     strmaxcpy(Options[OptionCnt], pSplit + 1, sizeof(Options[OptionCnt]));
  1151.     if (OptionCnt)
  1152.       *pSplit = '\0';
  1153.     else
  1154.       pSplit[1] = '\0';
  1155.     pSrc = Options[OptionCnt];
  1156.   }
  1157. }
  1158.  
  1159. static void DecideBranch(LongInt Adr, Byte Index)
  1160. {
  1161.   LongInt Dist = Adr - EProgCounter();
  1162.  
  1163.   if (FormatCode == 0)
  1164.   {
  1165.     /* Groessenangabe erzwingt G-Format */
  1166.     if (OpSize[Index] != -1)
  1167.       FormatCode = 1;
  1168.     /* gerade 9-Bit-Zahl kurz darstellbar */
  1169.     else if (((Dist & 1) == 0) && (Dist <= 254) && (Dist >= -256))
  1170.       FormatCode = 2;
  1171.     /* ansonsten allgemein */
  1172.     else
  1173.       FormatCode = 1;
  1174.   }
  1175.   if ((FormatCode == 1) && (OpSize[Index] == -1))
  1176.   {
  1177.     if ((Dist <= 127) && (Dist >= -128))
  1178.       OpSize[Index] = 0;
  1179.     else if ((Dist <= 32767) && (Dist >= -32768))
  1180.       OpSize[Index] = 1;
  1181.     else
  1182.       OpSize[Index] = 2;
  1183.   }
  1184. }
  1185.  
  1186. static Boolean DecideBranchLength(LongInt *Addr, tSymbolFlags Flags, int Index)
  1187. {
  1188.   *Addr -= EProgCounter();
  1189.   if (OpSize[Index] == -1)
  1190.   {
  1191.     if ((*Addr >= -128) && (*Addr <= 127))
  1192.       OpSize[Index] = 0;
  1193.     else if ((*Addr >= -32768) && (*Addr <= 32767))
  1194.       OpSize[Index] = 1;
  1195.     else OpSize[Index]=2;
  1196.   }
  1197.  
  1198.   if (!mSymbolQuestionable(Flags) &&
  1199.       (((OpSize[Index] == 0) && ((*Addr < -128) || (*Addr > 127)))
  1200.     || ((OpSize[Index] == 1) && ((*Addr < -32768) || (*Addr > 32767)))))
  1201.   {
  1202.     WrError(ErrNum_JmpDistTooBig);
  1203.     return False;
  1204.   }
  1205.   else
  1206.     return True;
  1207. }
  1208.  
  1209. static void Make_G(Word Code)
  1210. {
  1211.   WAsmCode[0] = 0xd000 + (OpSize[1] << 8) + AdrMode[1];
  1212.   memcpy(WAsmCode + 1, AdrVals[1], AdrCnt1[1]);
  1213.   WAsmCode[1 + AdrCnt2[1]] = Code + (OpSize[2] << 8) + AdrMode[2];
  1214.   memcpy(WAsmCode + 2 + AdrCnt2[1], AdrVals[2], AdrCnt1[2]);
  1215.   CodeLen = 4 + AdrCnt1[1] + AdrCnt1[2];
  1216. }
  1217.  
  1218. static void Make_E(Word Code, Boolean Signed)
  1219. {
  1220.   LongInt HVal, Min, Max;
  1221.  
  1222.   Min = 128 * (-Ord(Signed));
  1223.   Max = Min + 255;
  1224.   if (AdrType[1] != ModImm) WrError(ErrNum_InvAddrMode);
  1225.   else
  1226.   {
  1227.     HVal = ImmVal(1);
  1228.     if (ChkRange(HVal, Min, Max))
  1229.     {
  1230.       WAsmCode[0] = 0xbf00 + (HVal & 0xff);
  1231.       WAsmCode[1] = Code + (OpSize[2] << 8) + AdrMode[2];
  1232.       memcpy(WAsmCode + 2, AdrVals[2], AdrCnt1[2]);
  1233.       CodeLen = 4 + AdrCnt1[2];
  1234.     }
  1235.   }
  1236. }
  1237.  
  1238. static void Make_I(Word Code, Boolean Signed)
  1239. {
  1240.   if ((AdrType[1] != ModImm) || (!IsShort(2))) WrError(ErrNum_InvAddrMode);
  1241.   else
  1242.   {
  1243.     AdaptImm(1, OpSize[2], Signed);
  1244.     WAsmCode[0] = Code + (OpSize[2] << 8) + AdrMode[2];
  1245.     memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  1246.     memcpy(WAsmCode + 1 + AdrCnt2[2], AdrVals[1], AdrCnt1[1]);
  1247.     CodeLen = 2 + AdrCnt1[1] + AdrCnt1[2];
  1248.   }
  1249. }
  1250.  
  1251. /*------------------------------------------------------------------------*/
  1252.  
  1253. static void DecodeFixed(Word Code)
  1254. {
  1255.   if (!ChkArgCnt(0, 0));
  1256.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1257.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1258.   else
  1259.   {
  1260.     CodeLen = 2;
  1261.     WAsmCode[0] = Code;
  1262.   }
  1263. }
  1264.  
  1265. static void DecodeACB_SCB(Word IsSCB)
  1266. {
  1267.   if (ChkArgCnt(4, 4)
  1268.    && CheckFormat("GEQR"))
  1269.   {
  1270.     if (GetOpSize(&ArgStr[2], 3))
  1271.     if (GetOpSize(&ArgStr[4], 4))
  1272.     if (GetOpSize(&ArgStr[1], 1))
  1273.     if (GetOpSize(&ArgStr[3], 2))
  1274.     {
  1275.       Word HReg;
  1276.  
  1277.       if ((OpSize[3] == -1) && (OpSize[2] == -1)) OpSize[3] = 2;
  1278.       if ((OpSize[3] == -1) && (OpSize[2] != -1)) OpSize[3] = OpSize[2];
  1279.       else if ((OpSize[3] != -1) && (OpSize[2] == -1)) OpSize[2] = OpSize[3];
  1280.       if (OpSize[1] == -1) OpSize[1] = OpSize[2];
  1281.       if (OpSize[3] != OpSize[2]) WrError(ErrNum_ConfOpSizes);
  1282.       else if (DecodeReg(&ArgStr[2], &HReg, True))
  1283.       {
  1284.         Boolean OK;
  1285.         tSymbolFlags Flags;
  1286.         LongInt AdrLong, HVal;
  1287.  
  1288.         AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[4], Int32, &OK, &Flags);
  1289.         if (OK)
  1290.         {
  1291.           if (DecodeAdr(&ArgStr[1], 1, Mask_Source))
  1292.           {
  1293.             if (DecodeAdr(&ArgStr[3], 2, Mask_Source))
  1294.             {
  1295.               if (FormatCode == 0)
  1296.               {
  1297.                 if (AdrType[1] != ModImm) FormatCode = 1;
  1298.                 else
  1299.                 {
  1300.                   HVal = ImmVal(1);
  1301.                   if ((HVal == 1) && (AdrType[2] == ModReg))
  1302.                     FormatCode = 4;
  1303.                   else if ((HVal == 1) && (AdrType[2] == ModImm))
  1304.                   {
  1305.                     HVal = ImmVal(2);
  1306.                     if ((HVal >= 1 - IsSCB) && (HVal <= 64 - IsSCB))
  1307.                       FormatCode = 3;
  1308.                     else
  1309.                       FormatCode = 2;
  1310.                   }
  1311.                   else if ((HVal >= -128) && (HVal <= 127))
  1312.                     FormatCode = 2;
  1313.                   else
  1314.                     FormatCode = 1;
  1315.                 }
  1316.               }
  1317.               switch (FormatCode)
  1318.               {
  1319.                 case 1:
  1320.                   if (DecideBranchLength(&AdrLong, Flags, 4))  /* ??? */
  1321.                   {
  1322.                     WAsmCode[0] = 0xd000 + (OpSize[1] << 8) + AdrMode[1];
  1323.                     memcpy(WAsmCode + 1, AdrVals[1], AdrCnt1[1]);
  1324.                     WAsmCode[1 + AdrCnt2[1]] = 0xf000 + (IsSCB << 11) + (OpSize[2] << 8) + AdrMode[2];
  1325.                     memcpy(WAsmCode + 2 + AdrCnt2[1], AdrVals[2], AdrCnt1[2]);
  1326.                     WAsmCode[2 + AdrCnt2[1] + AdrCnt2[2]] = (HReg << 10) + (OpSize[4] << 8);
  1327.                     CodeLen = 6 + AdrCnt1[1] + AdrCnt1[2];
  1328.                   }
  1329.                   break;
  1330.                 case 2:
  1331.                   if (DecideBranchLength(&AdrLong, Flags, 4))  /* ??? */
  1332.                   {
  1333.                     if (AdrType[1] != ModImm) WrError(ErrNum_InvAddrMode);
  1334.                     else
  1335.                     {
  1336.                       HVal = ImmVal(1);
  1337.                       if (ChkRange(HVal, -128, 127))
  1338.                       {
  1339.                         WAsmCode[0] = 0xbf00 + (HVal & 0xff);
  1340.                         WAsmCode[1] = 0xf000 + (IsSCB << 11) + (OpSize[2] << 8) + AdrMode[2];
  1341.                         memcpy(WAsmCode + 2, AdrVals[2], AdrCnt1[2]);
  1342.                         WAsmCode[2 + AdrCnt2[2]] = (HReg << 10) + (OpSize[4] << 8);
  1343.                         CodeLen = 6 + AdrCnt1[2];
  1344.                       }
  1345.                     }
  1346.                   }
  1347.                   break;
  1348.                 case 3:
  1349.                   if (DecideBranchLength(&AdrLong, Flags, 4))  /* ??? */
  1350.                   {
  1351.                     if (AdrType[1] != ModImm) WrError(ErrNum_InvAddrMode);
  1352.                     else if (ImmVal(1) != 1) WrError(ErrNum_Only1);
  1353.                     else if (AdrType[2] != ModImm) WrError(ErrNum_InvAddrMode);
  1354.                     else
  1355.                     {
  1356.                       HVal = ImmVal(2);
  1357.                       if (ChkRange(HVal, 1 - IsSCB, 64 - IsSCB))
  1358.                       {
  1359.                         WAsmCode[0] = 0x03d1 + (HReg << 10) + (IsSCB << 1);
  1360.                         WAsmCode[1] = ((HVal & 0x3f) << 10) + (OpSize[4] << 8);
  1361.                         CodeLen = 4;
  1362.                       }
  1363.                     }
  1364.                   }
  1365.                   break;
  1366.                 case 4:
  1367.                   if (DecideBranchLength(&AdrLong, Flags, 4))  /* ??? */
  1368.                   {
  1369.                     if (AdrType[1] != ModImm) WrError(ErrNum_InvAddrMode);
  1370.                     else if (ImmVal(1) != 1) WrError(ErrNum_Only1);
  1371.                     else if (OpSize[2] != 2) WrError(ErrNum_InvOpSize);
  1372.                     else if (AdrType[2] != ModReg) WrError(ErrNum_InvAddrMode);
  1373.                     else
  1374.                     {
  1375.                       WAsmCode[0] = 0x03d0 + (HReg << 10) + (IsSCB << 1);
  1376.                       WAsmCode[1] = ((AdrMode[2] & 15) << 10) + (OpSize[4] << 8);
  1377.                       CodeLen = 4;
  1378.                     }
  1379.                   }
  1380.                   break;
  1381.               }
  1382.               if (CodeLen>0)
  1383.               {
  1384.                 switch (OpSize[4])
  1385.                 {
  1386.                   case 0:
  1387.                     WAsmCode[(CodeLen >> 1) - 1] += AdrLong & 0xff;
  1388.                     break;
  1389.                   case 1:
  1390.                     WAsmCode[CodeLen >> 1] = AdrLong & 0xffff;
  1391.                     CodeLen += 2;
  1392.                     break;
  1393.                   case 2:
  1394.                     WAsmCode[ CodeLen >> 1     ] = AdrLong >> 16;
  1395.                     WAsmCode[(CodeLen >> 1) + 1] = AdrLong & 0xffff;
  1396.                     CodeLen += 4;
  1397.                     break;
  1398.                 }
  1399.               }
  1400.             }
  1401.           }
  1402.         }
  1403.       }
  1404.     }
  1405.   }
  1406. }
  1407.  
  1408. static void DecodeFixedLong(Word Index)
  1409. {
  1410.   BitOrder *pOrder = FixedLongOrders + Index;
  1411.  
  1412.   if (!ChkArgCnt(0, 0));
  1413.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1414.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1415.   else
  1416.   {
  1417.     CodeLen = 10;
  1418.     WAsmCode[0] = 0xd20c;
  1419.     WAsmCode[1] = pOrder->Code1;
  1420.     WAsmCode[2] = pOrder->Code2;
  1421.     WAsmCode[3] = 0x9e09;
  1422.     WAsmCode[4] = 0x0700;
  1423.   }
  1424. }
  1425.  
  1426. static void DecodeMOV(Word Code)
  1427. {
  1428.   LongInt HVal;
  1429.  
  1430.   UNUSED(Code);
  1431.  
  1432.   if (ChkArgCnt(2, 2)
  1433.    && CheckFormat("GELSZQI"))
  1434.   {
  1435.     if ((GetOpSize(&ArgStr[1], 1)) && (GetOpSize(&ArgStr[2], 2)))
  1436.     {
  1437.       if (OpSize[2] == -1)
  1438.         OpSize[2] = 2;
  1439.       if (OpSize[1] == -1)
  1440.         OpSize[1] = OpSize[2];
  1441.       if ((DecodeAdr(&ArgStr[1], 1, Mask_Source))
  1442.        && (DecodeAdr(&ArgStr[2], 2, Mask_AllGen-MModPop)))
  1443.       {
  1444.         if (FormatCode == 0)
  1445.         {
  1446.           if (AdrType[1] == ModImm)
  1447.           {
  1448.             HVal = ImmVal(1);
  1449.             if (HVal == 0)
  1450.               FormatCode = 5;
  1451.             else if ((HVal >= 1) && (HVal <= 8) && (IsShort(2)))
  1452.               FormatCode = 6;
  1453.             else if ((HVal >= -128) && (HVal <= 127))
  1454.               FormatCode = 2;
  1455.             else if (IsShort(2))
  1456.               FormatCode = 7;
  1457.             else
  1458.               FormatCode = 1;
  1459.           }
  1460.           else if ((AdrType[1] == ModReg) && (OpSize[1] == 2) && (IsShort(2)))
  1461.             FormatCode = 4;
  1462.           else if ((AdrType[2] == ModReg) && (OpSize[2] == 2) && (IsShort(1)))
  1463.             FormatCode = 3;
  1464.           else
  1465.             FormatCode = 1;
  1466.         }
  1467.         switch (FormatCode)
  1468.         {
  1469.           case 1:
  1470.             Make_G(0x8800);
  1471.             break;
  1472.           case 2:
  1473.             Make_E(0x8800, True);
  1474.             break;
  1475.           case 3:
  1476.             if ((!IsShort(1)) || (AdrType[2] != ModReg)) WrError(ErrNum_InvAddrMode);
  1477.             else if (OpSize[2] != 2) WrError(ErrNum_InvOpSize);
  1478.             else
  1479.             {
  1480.               WAsmCode[0] = 0x0040 + ((AdrMode[2] & 15) << 10) + (OpSize[1] << 8) + AdrMode[1];
  1481.               memcpy(WAsmCode + 1, AdrVals[1], AdrCnt1[1]);
  1482.               CodeLen = 2 + AdrCnt1[1];
  1483.             }
  1484.             break;
  1485.           case 4:
  1486.             if ((!IsShort(2)) || (AdrType[1] != ModReg)) WrError(ErrNum_InvAddrMode);
  1487.             else if (OpSize[1] != 2) WrError(ErrNum_InvOpSize);
  1488.             else
  1489.             {
  1490.               WAsmCode[0] = 0x0080 + ((AdrMode[1] & 15) << 10) + (OpSize[2] << 8) + AdrMode[2];
  1491.               memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  1492.               CodeLen = 2 + AdrCnt1[2];
  1493.             }
  1494.             break;
  1495.           case 5:
  1496.             if (AdrType[1] != ModImm) WrError(ErrNum_InvAddrMode);
  1497.             else
  1498.             {
  1499.               HVal = ImmVal(1);
  1500.               if (ChkRange(HVal, 0, 0))
  1501.               {
  1502.                 WAsmCode[0] = 0xc400 + (OpSize[2] << 8) + AdrMode[2];
  1503.                 memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  1504.                 CodeLen = 2 + AdrCnt1[2];
  1505.               }
  1506.             }
  1507.             break;
  1508.           case 6:
  1509.             if ((AdrType[1] != ModImm) || (!IsShort(2))) WrError(ErrNum_InvAddrMode);
  1510.             else
  1511.             {
  1512.               HVal = ImmVal(1);
  1513.               if (ChkRange(HVal, 1, 8))
  1514.               {
  1515.                 WAsmCode[0] = 0x6000 + ((HVal & 7) << 10) + (OpSize[2] << 8) + AdrMode[2];
  1516.                 memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  1517.                 CodeLen = 2 + AdrCnt1[2];
  1518.               }
  1519.             }
  1520.             break;
  1521.           case 7:
  1522.             Make_I(0x48c0, True);
  1523.             break;
  1524.         }
  1525.       }
  1526.     }
  1527.   }
  1528. }
  1529.  
  1530. static void DecodeOne(Word Index)
  1531. {
  1532.   OneOrder *pOrder = OneOrders + Index;
  1533.  
  1534.   if (ChkArgCnt(1, 1)
  1535.    && CheckFormat("G"))
  1536.   {
  1537.     if (GetOpSize(&ArgStr[1], 1))
  1538.     {
  1539.       if ((OpSize[1] == -1) && (pOrder->OpMask != 0))
  1540.         OpSize[1] = DefSize(pOrder->OpMask);
  1541.       if ((OpSize[1] != -1) && (((1 << OpSize[1]) & pOrder->OpMask) == 0)) WrError(ErrNum_InvOpSize);
  1542.       else
  1543.       {
  1544.         if (DecodeAdr(&ArgStr[1], 1, pOrder->Mask))
  1545.         {
  1546.           /* da nur G, Format ignorieren */
  1547.           WAsmCode[0] = pOrder->Code + AdrMode[1];
  1548.           if (pOrder->OpMask != 0)
  1549.             WAsmCode[0] += OpSize[1] << 8;
  1550.           memcpy(WAsmCode + 1, AdrVals[1], AdrCnt1[1]);
  1551.           CodeLen = 2 + AdrCnt1[1];
  1552.         }
  1553.       }
  1554.     }
  1555.   }
  1556. }
  1557.  
  1558. static void DecodeADD_SUB(Word IsSUB)
  1559. {
  1560.   if (ChkArgCnt(2, 2)
  1561.    && CheckFormat("GELQI"))
  1562.   {
  1563.     if ((GetOpSize(&ArgStr[2], 2)) && (GetOpSize(&ArgStr[1], 1)))
  1564.     {
  1565.       if (OpSize[2] == -1) OpSize[2] = 2;
  1566.       if (OpSize[1] == -1) OpSize[1] = OpSize[2];
  1567.       if ((DecodeAdr(&ArgStr[1], 1, Mask_Source)) && (DecodeAdr(&ArgStr[2], 2, Mask_PureDest)))
  1568.       {
  1569.         if (FormatCode==0)
  1570.         {
  1571.           if (AdrType[1] == ModImm)
  1572.           {
  1573.             LongInt HVal = ImmVal(1);
  1574.  
  1575.             if (IsShort(2))
  1576.             {
  1577.               if ((HVal >= 1) && (HVal <= 8))
  1578.                 FormatCode = 4;
  1579.               else
  1580.                 FormatCode = 5;
  1581.             }
  1582.             else if ((HVal >= -128) && (HVal < 127))
  1583.               FormatCode = 2;
  1584.             else
  1585.               FormatCode = 1;
  1586.           }
  1587.           else if (IsShort(1) && (AdrType[2] == ModReg) && (OpSize[1] == 2) && (OpSize[2] == 2))
  1588.             FormatCode = 3;
  1589.           else
  1590.             FormatCode = 1;
  1591.         }
  1592.         switch (FormatCode)
  1593.         {
  1594.           case 1:
  1595.             Make_G(IsSUB << 11);
  1596.             break;
  1597.           case 2:
  1598.             Make_E(IsSUB << 11, True);
  1599.             break;
  1600.           case 3:
  1601.             if ((!IsShort(1)) || (AdrType[2] != ModReg)) WrError(ErrNum_InvAddrMode);
  1602.             else if ((OpSize[1] != 2) || (OpSize[2] != 2)) WrError(ErrNum_InvOpSize);
  1603.             else
  1604.             {
  1605.               WAsmCode[0] = 0x8100 + (IsSUB << 6) + ((AdrMode[2] & 15) << 10) + AdrMode[1];
  1606.               memcpy(WAsmCode + 1, AdrVals[1], AdrCnt1[1]);
  1607.               CodeLen = 2 + AdrCnt1[1];
  1608.               if ((AdrMode[1] == 0x04) & (AdrMode[2] == 15))
  1609.                 WrError(ErrNum_Unpredictable);
  1610.             }
  1611.             break;
  1612.           case 4:
  1613.             if ((AdrType[1] != ModImm) || (!IsShort(2))) WrError(ErrNum_InvAddrMode);
  1614.             else
  1615.             {
  1616.               LongInt HVal = ImmVal(1);
  1617.               if (ChkRange(HVal, 1, 8))
  1618.               {
  1619.                 WAsmCode[0] = 0x4040 + (IsSUB << 13) + ((HVal & 7) << 10) + (OpSize[2] << 8) + AdrMode[2];
  1620.                 memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  1621.                 CodeLen = 2 + AdrCnt1[2];
  1622.               }
  1623.             }
  1624.             break;
  1625.           case 5:
  1626.             Make_I(0x44c0 + (IsSUB << 11), True);
  1627.             break;
  1628.         }
  1629.       }
  1630.     }
  1631.   }
  1632. }
  1633.  
  1634. static void DecodeCMP(Word Code)
  1635. {
  1636.   LongInt HVal;
  1637.  
  1638.   UNUSED(Code);
  1639.  
  1640.   if (ChkArgCnt(2, 2)
  1641.    && CheckFormat("GELZQI")
  1642.    && GetOpSize(&ArgStr[1], 1)
  1643.    && GetOpSize(&ArgStr[2], 2))
  1644.   {
  1645.     if (OpSize[2] == -1) OpSize[2] = 2;
  1646.     if (OpSize[1] == -1) OpSize[1] = OpSize[2];
  1647.     if ((DecodeAdr(&ArgStr[1], 1, Mask_Source))
  1648.      && (DecodeAdr(&ArgStr[2], 2, Mask_NoImmGen-MModPush)))
  1649.     {
  1650.       if (FormatCode == 0)
  1651.       {
  1652.         if (AdrType[1] == ModImm)
  1653.         {
  1654.           HVal = ImmVal(1);
  1655.           if (HVal == 0)
  1656.             FormatCode = 4;
  1657.           else if ((HVal >= 1) && (HVal <= 8) && (IsShort(2)))
  1658.             FormatCode = 5;
  1659.           else if ((HVal >= -128) && (HVal <= 127))
  1660.             FormatCode = 2;
  1661.           else if (AdrType[2] == ModReg)
  1662.             FormatCode = 3;
  1663.           else if (IsShort(2))
  1664.             FormatCode = 5;
  1665.           else
  1666.             FormatCode = 1;
  1667.         }
  1668.         else if ((IsShort(1)) && (AdrType[2] == ModReg))
  1669.           FormatCode = 3;
  1670.         else
  1671.           FormatCode = 1;
  1672.       }
  1673.       switch (FormatCode)
  1674.       {
  1675.         case 1:
  1676.           Make_G(0x8000);
  1677.           break;
  1678.         case 2:
  1679.           Make_E(0x8000, True);
  1680.           break;
  1681.         case 3:
  1682.           if ((!IsShort(1)) || (AdrType[2] != ModReg)) WrError(ErrNum_InvAddrMode);
  1683.           else if (OpSize[2] != 2) WrError(ErrNum_InvOpSize);
  1684.           else
  1685.           {
  1686.             WAsmCode[0] = ((AdrMode[2] & 15) << 10) + (OpSize[1] << 8) + AdrMode[1];
  1687.             memcpy(WAsmCode + 1, AdrVals[1], AdrCnt1[1]);
  1688.             CodeLen = 2 + AdrCnt1[1];
  1689.           }
  1690.           break;
  1691.         case 4:
  1692.           if (AdrType[1] != ModImm) WrError(ErrNum_InvAddrMode);
  1693.           else
  1694.           {
  1695.             HVal = ImmVal(1);
  1696.             if (ChkRange(HVal, 0, 0))
  1697.             {
  1698.               WAsmCode[0] = 0xc000 + (OpSize[2] << 8) + AdrMode[2];
  1699.               memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  1700.               CodeLen = 2 + AdrCnt1[2];
  1701.             }
  1702.           }
  1703.           break;
  1704.         case 5:
  1705.           if ((AdrType[1] != ModImm) || (!IsShort(2))) WrError(ErrNum_InvAddrMode);
  1706.           else
  1707.           {
  1708.             HVal = ImmVal(1);
  1709.             if (ChkRange(HVal, 1, 8))
  1710.             {
  1711.               WAsmCode[0] = 0x4000 + (OpSize[2] << 8) + AdrMode[2] + ((HVal & 7) << 10);
  1712.               memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  1713.               CodeLen = 2 + AdrCnt1[2];
  1714.             }
  1715.           }
  1716.           break;
  1717.         case 6:
  1718.           Make_I(0x40c0, True);
  1719.           break;
  1720.       }
  1721.     }
  1722.   }
  1723. }
  1724.  
  1725. static void DecodeGE2(Word Index)
  1726. {
  1727.   GE2Order *pOrder = GE2Orders + Index;
  1728.  
  1729.   if (ChkArgCnt(2, 2)
  1730.    && CheckFormat("GE")
  1731.    && GetOpSize(&ArgStr[2], 2)
  1732.    && GetOpSize(&ArgStr[1], 1))
  1733.   {
  1734.     if (OpSize[2] == -1)
  1735.       OpSize[2] = DefSize(pOrder->SMask2);
  1736.     if (OpSize[1] == -1)
  1737.       OpSize[1] = DefSize(pOrder->SMask1);
  1738.     if (((pOrder->SMask1 & (1 << OpSize[1])) == 0)
  1739.      || ((pOrder->SMask2 & (1 << OpSize[2])) == 0)) WrError(ErrNum_InvOpSize);
  1740.     else if ((DecodeAdr(&ArgStr[1], 1, pOrder->Mask1))
  1741.           && (DecodeAdr(&ArgStr[2], 2, pOrder->Mask2)))
  1742.     {
  1743.       if (FormatCode==0)
  1744.       {
  1745.         if (AdrType[1] == ModImm)
  1746.         {
  1747.           LongInt HVal = ImmVal(1);
  1748.  
  1749.           if ((pOrder->Signed) && (HVal >= -128) && (HVal <= 127))
  1750.             FormatCode = 2;
  1751.           else if ((!pOrder->Signed) && (HVal >= 0) && (HVal <= 255))
  1752.             FormatCode = 2;
  1753.           else
  1754.             FormatCode = 1;
  1755.         }
  1756.         else
  1757.           FormatCode = 1;
  1758.       }
  1759.       switch (FormatCode)
  1760.       {
  1761.         case 1:
  1762.           Make_G(pOrder->Code);
  1763.           break;
  1764.         case 2:
  1765.           Make_E(pOrder->Code, pOrder->Signed);
  1766.           break;
  1767.       }
  1768.     }
  1769.   }
  1770. }
  1771.  
  1772. static void DecodeLog(Word Index)
  1773. {
  1774.   if (ChkArgCnt(2, 2)
  1775.    && CheckFormat("GERI")
  1776.    && GetOpSize(&ArgStr[1], 1)
  1777.    && GetOpSize(&ArgStr[2], 2))
  1778.   {
  1779.     if (OpSize[2] == -1)
  1780.       OpSize[2] = 2;
  1781.     if (OpSize[1] == -1)
  1782.       OpSize[1] = OpSize[2];
  1783.     if ((DecodeAdr(&ArgStr[1], 1, Mask_Source))
  1784.      && (DecodeAdr(&ArgStr[2], 2, Mask_Dest - MModPush)))
  1785.     {
  1786.       if (FormatCode == 0)
  1787.       {
  1788.         if (AdrType[1] == ModImm)
  1789.         {
  1790.           LongInt HVal = ImmVal(1);
  1791.  
  1792.           if ((HVal >= 0) && (HVal <= 255))
  1793.             FormatCode = 2;
  1794.           else if (IsShort(2))
  1795.             FormatCode = 4;
  1796.           else
  1797.             FormatCode = 1;
  1798.         }
  1799.         else if ((AdrType[1] == ModReg) && (AdrType[2] == ModReg) && (OpSize[1] == 2) && (OpSize[2] == 2))
  1800.           FormatCode = 3;
  1801.         else
  1802.           FormatCode = 1;
  1803.       }
  1804.       switch (FormatCode)
  1805.       {
  1806.         case 1:
  1807.           Make_G(0x2000 + (Index << 10));
  1808.           break;
  1809.         case 2:
  1810.           Make_E(0x2000 + (Index << 10), False);
  1811.           break;
  1812.         case 3:
  1813.           if ((AdrType[1] != ModReg) || (AdrType[2] != ModReg)) WrError(ErrNum_InvAddrMode);
  1814.           else if ((OpSize[1] != 2) || (OpSize[2] != 2)) WrError(ErrNum_InvOpSize);
  1815.           else
  1816.           {
  1817.             WAsmCode[0] = 0x00c0 + (Index << 8) + (AdrMode[1] & 15) + ((AdrMode[2] & 15) << 10);
  1818.             CodeLen = 2;
  1819.           }
  1820.           break;
  1821.         case 4:
  1822.           if ((AdrType[1] != ModImm) || (!IsShort(2))) WrError(ErrNum_InvAddrMode);
  1823.           else
  1824.           {
  1825.             WAsmCode[0] = 0x50c0 + (OpSize[2] << 8) + (Index << 10) + AdrMode[2];
  1826.             memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  1827.             AdaptImm(1, OpSize[2], False);
  1828.             memcpy(WAsmCode + 1 + AdrCnt2[2], AdrVals[1], AdrCnt1[1]);
  1829.             CodeLen = 2 + AdrCnt1[1] + AdrCnt1[2];
  1830.           }
  1831.           break;
  1832.       }
  1833.       if (OpSize[1] > OpSize[2])
  1834.         WrError(ErrNum_Unpredictable);
  1835.     }
  1836.   }
  1837. }
  1838.  
  1839. static void DecodeMul(Word Index)
  1840. {
  1841.   Boolean Unsigned = Index & 1;
  1842.  
  1843.   if (ChkArgCnt(2,  2)
  1844.    && CheckFormat(Unsigned ? "GE" : "GER")
  1845.    && GetOpSize(&ArgStr[1], 1)
  1846.    && GetOpSize(&ArgStr[2], 2))
  1847.   {
  1848.     if (OpSize[2] == -1)
  1849.       OpSize[2] = 2;
  1850.     if (OpSize[1] == -1)
  1851.       OpSize[1] = OpSize[2];
  1852.     if ((DecodeAdr(&ArgStr[1], 1, Mask_Source))
  1853.      && (DecodeAdr(&ArgStr[2], 2, Mask_PureDest)))
  1854.     {
  1855.       if (FormatCode == 0)
  1856.       {
  1857.         if (AdrType[1] == ModImm)
  1858.         {
  1859.           LongInt HVal = ImmVal(1);
  1860.           if ((HVal >= -128 + (Unsigned << 7))
  1861.            && (HVal <= 127 + (Unsigned << 7)))
  1862.             FormatCode = 2;
  1863.           else
  1864.             FormatCode = 1;
  1865.         }
  1866.         else if ((!Unsigned)
  1867.               && (AdrType[1] == ModReg) && (OpSize[1] == 2)
  1868.               && (AdrType[2] == ModReg) && (OpSize[2] == 2))
  1869.           FormatCode = 3;
  1870.         else
  1871.           FormatCode = 1;
  1872.       }
  1873.       switch (FormatCode)
  1874.       {
  1875.         case 1:
  1876.           Make_G(0x4000 + (Index << 10));
  1877.           break;
  1878.         case 2:
  1879.           Make_E(0x4000 + (Index << 10), !Unsigned);
  1880.           break;
  1881.         case 3:
  1882.           if ((AdrType[1] != ModReg) || (AdrType[2] != ModReg)) WrError(ErrNum_InvAddrMode);
  1883.           else if ((OpSize[1] != 2) || (OpSize[2] != 2)) WrError(ErrNum_InvOpSize);
  1884.           else
  1885.           {
  1886.             WAsmCode[0] = 0x00d0
  1887.                         + ((AdrMode[2] & 15) << 10)
  1888.                         + (Index << 7)
  1889.                         + (AdrMode[1] & 15);
  1890.             CodeLen = 2;
  1891.           }
  1892.       }
  1893.     }
  1894.   }
  1895. }
  1896.  
  1897. static void DecodeGetPut(Word Code)
  1898. {
  1899.   Word AdrWord, Mask, Mask2;
  1900.  
  1901.   if (Code & 0x80)
  1902.   {
  1903.     Mask = Mask_Source; Mask2 = MModReg; AdrWord = 1;
  1904.   }
  1905.   else
  1906.   {
  1907.     Mask = MModReg; Mask2 = Mask_Dest; AdrWord = 2;
  1908.   }
  1909.   if (ChkArgCnt(2, 2)
  1910.    && CheckFormat("G")
  1911.    && GetOpSize(&ArgStr[1], 1)
  1912.    && GetOpSize(&ArgStr[2], 2))
  1913.   {
  1914.     if (OpSize[AdrWord] == -1) OpSize[AdrWord] = Code & 3;
  1915.     if (OpSize[3 - AdrWord] == -1) OpSize[3 - AdrWord] = 2;
  1916.     if ((OpSize[AdrWord] != (Code & 3)) || (OpSize[3 - AdrWord] != 2)) WrError(ErrNum_InvOpSize);
  1917.     else if ((DecodeAdr(&ArgStr[1], 1, Mask))
  1918.           && (DecodeAdr(&ArgStr[2], 2, Mask2)))
  1919.     {
  1920.       Make_G(Code & 0xff00);
  1921.       WAsmCode[0] += 0x0400;
  1922.     }
  1923.   }
  1924. }
  1925.  
  1926. static void DecodeMOVA(Word Code)
  1927. {
  1928.   UNUSED(Code);
  1929.  
  1930.   if (ChkArgCnt(2, 2)
  1931.    && CheckFormat("GR")
  1932.    && GetOpSize(&ArgStr[2], 2))
  1933.   {
  1934.     if (OpSize[2] == -1)
  1935.       OpSize[2] = 2;
  1936.     OpSize[1] = 0;
  1937.     if (OpSize[2] != 2) WrError(ErrNum_InvOpSize);
  1938.     else if ((DecodeAdr(&ArgStr[1], 1, Mask_PureMem))
  1939.           && (DecodeAdr(&ArgStr[2], 2, Mask_Dest)))
  1940.     {
  1941.       if (FormatCode == 0)
  1942.       {
  1943.         if ((AdrType[1] == ModDisp16) && (AdrType[2] == ModReg))
  1944.           FormatCode = 2;
  1945.         else
  1946.           FormatCode = 1;
  1947.       }
  1948.       switch (FormatCode)
  1949.       {
  1950.         case 1:
  1951.           Make_G(0xb400);
  1952.           WAsmCode[0] += 0x800;
  1953.           break;
  1954.         case 2:
  1955.           if ((AdrType[1] != ModDisp16) || (AdrType[2] != ModReg)) WrError(ErrNum_InvAddrMode);
  1956.           else
  1957.           {
  1958.             WAsmCode[0] = 0x03c0 + ((AdrMode[2] & 15) << 10) + (AdrMode[1] & 15);
  1959.             WAsmCode[1] = AdrVals[1][0];
  1960.             CodeLen = 4;
  1961.           }
  1962.           break;
  1963.       }
  1964.     }
  1965.   }
  1966. }
  1967.  
  1968. static void DecodeQINS_QDEL(Word IsQINS)
  1969. {
  1970.   if (ChkArgCnt(2, 2)
  1971.    && CheckFormat("G")
  1972.    && (IsQINS || GetOpSize(&ArgStr[2], 2)))
  1973.   {
  1974.     if (OpSize[2] == -1)
  1975.       OpSize[2] = 2;
  1976.     OpSize[1] = 0;
  1977.     if (OpSize[2] != 2) WrError(ErrNum_InvOpSize);
  1978.     else if ((DecodeAdr(&ArgStr[1], 1, Mask_PureMem))
  1979.           && (DecodeAdr(&ArgStr[2], 2, Mask_PureMem | (IsQINS ? 0 : MModReg))))
  1980.     {
  1981.       Make_G(0xb000 + IsQINS);
  1982.       WAsmCode[0] += 0x800;
  1983.     }
  1984.   }
  1985. }
  1986.  
  1987. static void DecodeRVBY(Word Code)
  1988. {
  1989.   UNUSED(Code);
  1990.  
  1991.   if (ChkArgCnt(2, 2)
  1992.    && CheckFormat("G")
  1993.    && GetOpSize(&ArgStr[1], 1)
  1994.    && GetOpSize(&ArgStr[2], 2))
  1995.   {
  1996.     if (OpSize[2] == -1)
  1997.       OpSize[2] = 2;
  1998.     if (OpSize[1] == -1)
  1999.       OpSize[1] = OpSize[2];
  2000.     if ((DecodeAdr(&ArgStr[1], 1, Mask_Source))
  2001.      && (DecodeAdr(&ArgStr[2], 2, Mask_Dest)))
  2002.     {
  2003.       Make_G(0x4000);
  2004.       WAsmCode[0] += 0x400;
  2005.     }
  2006.   }
  2007. }
  2008.  
  2009. static void DecodeSHL_SHA(Word IsSHA)
  2010. {
  2011.   if (ChkArgCnt(2, 2)
  2012.    && CheckFormat("GEQ")
  2013.    && GetOpSize(&ArgStr[1], 1)
  2014.    && GetOpSize(&ArgStr[2], 2))
  2015.   {
  2016.     if (OpSize[1] == -1)
  2017.       OpSize[1] = 0;
  2018.     if (OpSize[2] == -1)
  2019.       OpSize[2] = 2;
  2020.     if (OpSize[1] != 0)
  2021.       WrError(ErrNum_InvOpSize);
  2022.     else if ((DecodeAdr(&ArgStr[1], 1, Mask_Source))
  2023.           && (DecodeAdr(&ArgStr[2], 2, Mask_PureDest)))
  2024.     {
  2025.       if (FormatCode == 0)
  2026.       {
  2027.         if (AdrType[1] == ModImm)
  2028.         {
  2029.           LongInt HVal = ImmVal(1);
  2030.           if ((IsShort(2)) && (abs(HVal) >= 1) && (abs(HVal) <= 8) && ((IsSHA == 0) || (HVal < 0)))
  2031.             FormatCode = 3;
  2032.           else if ((HVal >= -128) && (HVal <= 127))
  2033.             FormatCode = 2;
  2034.           else
  2035.             FormatCode = 1;
  2036.         }
  2037.         else
  2038.           FormatCode = 1;
  2039.       }
  2040.       switch (FormatCode)
  2041.       {
  2042.         case 1:
  2043.           Make_G(0x3000 + (IsSHA << 10));
  2044.           break;
  2045.         case 2:
  2046.           Make_E(0x3000 + (IsSHA << 10), True);
  2047.           break;
  2048.         case 3:
  2049.           if ((AdrType[1] != ModImm) || (!IsShort(2))) WrError(ErrNum_InvAddrMode);
  2050.           else
  2051.           {
  2052.             LongInt HVal = ImmVal(1);
  2053.             if (ChkRange(HVal, -8, (1 - IsSHA) << 3))
  2054.             {
  2055.               if (HVal == 0) WrError(ErrNum_InvShiftArg);
  2056.               else
  2057.               {
  2058.                 if (HVal < 0)
  2059.                   HVal += 16;
  2060.                 else HVal &= 7;
  2061.                 WAsmCode[0] = 0x4080 + (HVal << 10) + (IsSHA << 6) + (OpSize[2] << 8) + AdrMode[2];
  2062.                 memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  2063.                 CodeLen = 2 + AdrCnt1[2];
  2064.               }
  2065.             }
  2066.           }
  2067.           break;
  2068.       }
  2069.     }
  2070.   }
  2071. }
  2072.  
  2073. static void DecodeSHXL_SHXR(Word Code)
  2074. {
  2075.   if (ChkArgCnt(1, 1)
  2076.    && CheckFormat("G")
  2077.    && GetOpSize(&ArgStr[1], 1))
  2078.   {
  2079.     if (OpSize[1] == -1)
  2080.       OpSize[1] = 2;
  2081.     if (OpSize[1] != 2) WrError(ErrNum_InvOpSize);
  2082.     else if (DecodeAdr(&ArgStr[1], 1, Mask_PureDest))
  2083.     {
  2084.       WAsmCode[0] = 0x02f7;
  2085.       WAsmCode[1] = Code + AdrMode[1];
  2086.       memcpy(WAsmCode + 1, AdrVals, AdrCnt1[1]);
  2087.       CodeLen = 4 + AdrCnt1[1];
  2088.     }
  2089.   }
  2090. }
  2091.  
  2092. static void DecodeCHK(Word Code)
  2093. {
  2094.   UNUSED(Code);
  2095.  
  2096.   if (OptionCnt > 1) WrError(ErrNum_WrongOptCnt);
  2097.   else if (ChkArgCnt(3, 3)
  2098.         && CheckFormat("G")
  2099.         && GetOpSize(&ArgStr[1], 2)
  2100.         && GetOpSize(&ArgStr[2], 1)
  2101.         && GetOpSize(&ArgStr[3], 3))
  2102.   {
  2103.     Boolean OptOK;
  2104.     Word IsSigned;
  2105.  
  2106.     if ((OptionCnt == 0)
  2107.      || (!as_strcasecmp(Options[0], "N")))
  2108.     {
  2109.       OptOK = True;
  2110.       IsSigned = 0;
  2111.     }
  2112.     else if (!as_strcasecmp(Options[0], "S"))
  2113.     {
  2114.       OptOK = True;
  2115.       IsSigned = 1;
  2116.     }
  2117.     else
  2118.     {
  2119.       OptOK = False;
  2120.       IsSigned = 0;
  2121.     }
  2122.  
  2123.     if (OpSize[3] == -1) OpSize[3] = 2;
  2124.     if (OpSize[2] == -1) OpSize[2] = OpSize[3];
  2125.     if (OpSize[1] == -1) OpSize[1] = OpSize[3];
  2126.     if ((OpSize[1] != OpSize[2]) || (OpSize[2] != OpSize[3])) WrError(ErrNum_ConfOpSizes);
  2127.     else if (!OptOK) WrXError(ErrNum_UndefCond, Options[0]);
  2128.     else if ((DecodeAdr(&ArgStr[1], 2, Mask_MemGen-MModPop-MModPush))
  2129.           && (DecodeAdr(&ArgStr[2], 1, Mask_Source))
  2130.           && (DecodeAdr(&ArgStr[3], 3, MModReg)))
  2131.     {
  2132.       OpSize[2] = 2 + IsSigned;
  2133.       Make_G((AdrMode[3] & 15) << 10);
  2134.       WAsmCode[0] += 0x400;
  2135.     }
  2136.   }
  2137. }
  2138.  
  2139. static void DecodeCSI(Word Code)
  2140. {
  2141.   UNUSED(Code);
  2142.  
  2143.   if (ChkArgCnt(3, 3)
  2144.    && CheckFormat("G")
  2145.    && GetOpSize(&ArgStr[1], 3)
  2146.    && GetOpSize(&ArgStr[2], 1)
  2147.    && GetOpSize(&ArgStr[3], 2))
  2148.   {
  2149.     if (OpSize[3] == -1) OpSize[3] = 2;
  2150.     if (OpSize[2] == -1) OpSize[2] = OpSize[3];
  2151.     if (OpSize[1] == -1) OpSize[1] = OpSize[2];
  2152.     if ((OpSize[1] != OpSize[2]) || (OpSize[2] != OpSize[3])) WrError(ErrNum_ConfOpSizes);
  2153.     else if ((DecodeAdr(&ArgStr[1], 3, MModReg))
  2154.           && (DecodeAdr(&ArgStr[2], 1, Mask_Source))
  2155.           && (DecodeAdr(&ArgStr[3], 2, Mask_PureMem)))
  2156.     {
  2157.       OpSize[2] = 0;
  2158.       Make_G((AdrMode[3] & 15) << 10);
  2159.       WAsmCode[0] += 0x400;
  2160.     }
  2161.   }
  2162. }
  2163.  
  2164. static void DecodeDIVX_MULX(Word Code)
  2165. {
  2166.   if (ChkArgCnt(3, 3)
  2167.    && CheckFormat("G")
  2168.    && GetOpSize(&ArgStr[1], 1)
  2169.    && GetOpSize(&ArgStr[2], 2)
  2170.    && GetOpSize(&ArgStr[3], 3))
  2171.   {
  2172.     if (OpSize[3] == -1) OpSize[3] = 2;
  2173.     if (OpSize[2] == -1) OpSize[2] = OpSize[3];
  2174.     if (OpSize[1] == -1) OpSize[1] = OpSize[2];
  2175.     if ((OpSize[1] != 2) || (OpSize[2] != 2) || (OpSize[3] != 2)) WrError(ErrNum_InvOpSize);
  2176.     else if ((DecodeAdr(&ArgStr[1], 1, Mask_Source))
  2177.           && (DecodeAdr(&ArgStr[2], 2, Mask_PureDest))
  2178.           && (DecodeAdr(&ArgStr[3], 3, MModReg)))
  2179.     {
  2180.       OpSize[2] = 0;
  2181.       Make_G(Code + ((AdrMode[3] & 15) << 10));
  2182.       WAsmCode[0] += 0x400;
  2183.     }
  2184.   }
  2185. }
  2186.  
  2187. static void DecodeWAIT(Word Code)
  2188. {
  2189.   UNUSED(Code);
  2190.  
  2191.   if (!ChkArgCnt(1, 1));
  2192.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2193.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  2194.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  2195.   else
  2196.   {
  2197.     Boolean OK;
  2198.  
  2199.     WAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt3, &OK);
  2200.     if (OK)
  2201.     {
  2202.       WAsmCode[0] = 0x0fd6;
  2203.       CodeLen = 4;
  2204.     }
  2205.   }
  2206. }
  2207.  
  2208. static void DecodeBit(Word Index)
  2209. {
  2210.   const BitOrder *pOrder = BitOrders + Index;
  2211.  
  2212.   if (ChkArgCnt(2, 2)
  2213.    && CheckFormat(pOrder->Code2 ? "GEQ" : "GE")
  2214.    && GetOpSize(&ArgStr[1], 1)
  2215.    && GetOpSize(&ArgStr[2], 2))
  2216.   {
  2217.     if (OpSize[1] == -1)
  2218.       OpSize[1] = 2;
  2219.     if ((DecodeAdr(&ArgStr[1], 1, Mask_Source))
  2220.      && (DecodeAdr(&ArgStr[2], 2, Mask_PureDest)))
  2221.     {
  2222.       if (OpSize[2] == -1)
  2223.         OpSize[2] = ((AdrType[2] == ModReg) && (!pOrder->MustByte)) ? 2 : 0;
  2224.  
  2225.       if (((AdrType[2] != ModReg) || (pOrder->MustByte)) && (OpSize[2] != 0)) WrError(ErrNum_InvOpSize);
  2226.       else
  2227.       {
  2228.         if (FormatCode == 0)
  2229.         {
  2230.           if (AdrType[1] == ModImm)
  2231.           {
  2232.             LongInt HVal = ImmVal(1);
  2233.  
  2234.             if ((HVal >= 0) && (HVal <= 7) && (IsShort(2)) && (pOrder->Code2 != 0) && (OpSize[2] == 0))
  2235.               FormatCode = 3;
  2236.             else if ((HVal >= -128) && (HVal < 127))
  2237.               FormatCode = 2;
  2238.             else
  2239.               FormatCode = 1;
  2240.           }
  2241.           else
  2242.             FormatCode = 1;
  2243.         }
  2244.         switch (FormatCode)
  2245.         {
  2246.           case 1:
  2247.             Make_G(pOrder->Code1);
  2248.             break;
  2249.           case 2:
  2250.             Make_E(pOrder->Code1, True);
  2251.             break;
  2252.           case 3:
  2253.             if ((AdrType[1] != ModImm) || (!IsShort(2))) WrError(ErrNum_InvAddrMode);
  2254.             else if (OpSize[2] != 0) WrError(ErrNum_InvOpSize);
  2255.             else
  2256.             {
  2257.               LongInt HVal = ImmVal(1);
  2258.               if (ChkRange(HVal, 0, 7))
  2259.               {
  2260.                 WAsmCode[0] = pOrder->Code2 + ((HVal & 7) << 10) + AdrMode[2];
  2261.                 memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  2262.                 CodeLen = 2 + AdrCnt1[2];
  2263.               }
  2264.             }
  2265.             break;
  2266.         }
  2267.       }
  2268.     }
  2269.   }
  2270. }
  2271.  
  2272. static void DecodeBField(Word Code)
  2273. {
  2274.   if (ChkArgCnt(4, 4)
  2275.    && CheckBFieldFormat()
  2276.    && GetOpSize(&ArgStr[1], 1)
  2277.    && GetOpSize(&ArgStr[2], 2)
  2278.    && GetOpSize(&ArgStr[3], 3)
  2279.    && GetOpSize(&ArgStr[4], 4))
  2280.   {
  2281.     if (OpSize[1] == -1) OpSize[1] = 2;
  2282.     if (OpSize[2] == -1) OpSize[2] = 2;
  2283.     if (OpSize[3] == -1) OpSize[3] = 2;
  2284.     if (OpSize[4] == -1) OpSize[4] = 2;
  2285.     if ((DecodeAdr(&ArgStr[1], 1, MModReg | MModImm))
  2286.      && (DecodeAdr(&ArgStr[3], 3, MModReg | MModImm))
  2287.      && (DecodeAdr(&ArgStr[2], 2, Mask_Source))
  2288.      && (DecodeAdr(&ArgStr[4], 4, Mask_PureMem)))
  2289.     {
  2290.       if (FormatCode == 0)
  2291.       {
  2292.         if (AdrType[3] == ModReg)
  2293.           FormatCode = (AdrType[1] == ModReg) ? 1 : 2;
  2294.         else
  2295.           FormatCode = (AdrType[1] == ModReg) ? 3 : 4;
  2296.       }
  2297.       switch (FormatCode)
  2298.       {
  2299.         case 1:
  2300.           if ((AdrType[1] != ModReg) || (AdrType[3] != ModReg)) WrError(ErrNum_InvAddrMode);
  2301.           else if ((OpSize[1] != 2) || (OpSize[3] != 2) || (OpSize[4] != 2)) WrError(ErrNum_InvOpSize);
  2302.           else
  2303.           {
  2304.             WAsmCode[0] = 0xd000 + (OpSize[2] << 8) + AdrMode[2];
  2305.             memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  2306.             WAsmCode[1 + AdrCnt2[2]] = 0xc200 + (Code << 10) + AdrMode[4];
  2307.             memcpy(WAsmCode + 2 + AdrCnt2[2], AdrVals[4], AdrCnt1[4]);
  2308.             WAsmCode[2 + AdrCnt2[2] + AdrCnt2[4]] = ((AdrMode[3] & 15) << 10) + (AdrMode[1] & 15);
  2309.             CodeLen = 6 + AdrCnt1[2] + AdrCnt1[4];
  2310.           }
  2311.           break;
  2312.         case 2:
  2313.           if ((AdrType[1] != ModImm) || (AdrType[3] != ModReg)) WrError(ErrNum_InvAddrMode);
  2314.           else if ((OpSize[3] != 2) || (OpSize[4] != 2)) WrError(ErrNum_InvOpSize);
  2315.           else
  2316.           {
  2317.             WAsmCode[0] = 0xd000 + (OpSize[2] << 8) + AdrMode[2];
  2318.             memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  2319.             WAsmCode[1 + AdrCnt2[2]] = 0xd200 + (Code << 10) + AdrMode[4];
  2320.             memcpy(WAsmCode + 2 + AdrCnt2[2], AdrVals[4], AdrCnt1[4]);
  2321.             WAsmCode[2 + AdrCnt2[2] + AdrCnt2[4]] = ((AdrMode[3] & 15) << 10) + (OpSize[1] << 8);
  2322.             CodeLen = 6 + AdrCnt1[2] + AdrCnt1[4];
  2323.             if (OpSize[1] == 0)
  2324.               WAsmCode[(CodeLen-2) >> 1] += AdrVals[1][0] & 0xff;
  2325.             else
  2326.             {
  2327.               memcpy(WAsmCode + (CodeLen >> 1), AdrVals[1], AdrCnt1[1]);
  2328.               CodeLen += AdrCnt1[1];
  2329.             }
  2330.           }
  2331.           break;
  2332.         case 3:
  2333.           if ((AdrType[1] != ModReg) || (AdrType[2] != ModImm) || (AdrType[3] != ModImm)) WrError(ErrNum_InvAddrMode);
  2334.           else if ((OpSize[1] != 2) || (OpSize[4] != 2)) WrError(ErrNum_InvOpSize);
  2335.           else
  2336.           {
  2337.             LongInt Offset = ImmVal(2);
  2338.             if (ChkRange(Offset, -128, 127))
  2339.             {
  2340.               LongInt Width = ImmVal(3);
  2341.               if (ChkRange(Width, 1, 32))
  2342.               {
  2343.                 WAsmCode[0] = 0xbf00 + (Offset & 0xff);
  2344.                 WAsmCode[1] = 0xc200 + (Code << 10) + AdrMode[4];
  2345.                 memcpy(WAsmCode + 2, AdrVals[4], AdrCnt1[4]);
  2346.                 WAsmCode[2 + AdrCnt2[4]] = ((Width & 31) << 10) + (AdrMode[1] & 15);
  2347.                 CodeLen =6 + AdrCnt1[4];
  2348.               }
  2349.             }
  2350.           }
  2351.           break;
  2352.         case 4:
  2353.           if ((AdrType[1] != ModImm) || (AdrType[2] != ModImm) || (AdrType[3] != ModImm)) WrError(ErrNum_InvAddrMode);
  2354.           else if (OpSize[4] != 2) WrError(ErrNum_InvOpSize);
  2355.           else
  2356.           {
  2357.             LongInt Offset = ImmVal(2);
  2358.             if (ChkRange(Offset, -128, 127))
  2359.             {
  2360.               LongInt Width = ImmVal(3);
  2361.               if (ChkRange(Offset, 1, 32))
  2362.               {
  2363.                 WAsmCode[0] = 0xbf00 + (Offset & 0xff);
  2364.                 WAsmCode[1] = 0xd200 + (Code << 10) + AdrMode[4];
  2365.                 memcpy(WAsmCode + 2, AdrVals[4], AdrCnt1[4]);
  2366.                 WAsmCode[2 + AdrCnt2[4]] = ((Width & 31) << 10) + (OpSize[1] << 8);
  2367.                 CodeLen = 6 + AdrCnt1[4];
  2368.                 if (OpSize[1] == 0)
  2369.                   WAsmCode[(CodeLen - 1) >> 1] += AdrVals[1][0] & 0xff;
  2370.                 else
  2371.                 {
  2372.                   memcpy(WAsmCode + (CodeLen >> 1), AdrVals[1], AdrCnt1[1]);
  2373.                   CodeLen += AdrCnt1[1];
  2374.                 }
  2375.               }
  2376.             }
  2377.           }
  2378.           break;
  2379.       }
  2380.     }
  2381.   }
  2382. }
  2383.  
  2384. static void DecodeBFEXT_BFEXTU(Word IsEXTU)
  2385. {
  2386.   if (ChkArgCnt(4, 4)
  2387.    && CheckFormat("GE")
  2388.    && GetOpSize(&ArgStr[1], 1)
  2389.    && GetOpSize(&ArgStr[2], 2)
  2390.    && GetOpSize(&ArgStr[3], 3)
  2391.    && GetOpSize(&ArgStr[4], 4))
  2392.   {
  2393.     if (OpSize[1] == -1) OpSize[1] = 2;
  2394.     if (OpSize[2] == -1) OpSize[2] = 2;
  2395.     if (OpSize[3] == -1) OpSize[3] = 2;
  2396.     if (OpSize[4] == -1) OpSize[4] = 2;
  2397.     if ((DecodeAdr(&ArgStr[4], 4, MModReg))
  2398.      && (DecodeAdr(&ArgStr[3], 3, Mask_MemGen & ~(MModPop | MModPush)))
  2399.      && (DecodeAdr(&ArgStr[2], 2, MModReg | MModImm)))
  2400.     {
  2401.       if (DecodeAdr(&ArgStr[1], 1, (AdrType[2] == ModReg) ? Mask_Source : MModImm))
  2402.       {
  2403.         if (FormatCode == 0)
  2404.           FormatCode =  (AdrType[2]== ModReg) ? 1 : 2;
  2405.         switch (FormatCode)
  2406.         {
  2407.           case 1:
  2408.             if ((OpSize[2] != 2) || (OpSize[3] != 2) || (OpSize[4] != 2)) WrError(ErrNum_InvOpSize);
  2409.             else
  2410.             {
  2411.               WAsmCode[0] = 0xd000 + (OpSize[1] << 8) + AdrMode[1];
  2412.               memcpy(WAsmCode + 1, AdrVals[1], AdrCnt1[1]);
  2413.               WAsmCode[1 + AdrCnt2[1]] = 0xea00 + (IsEXTU << 10) + AdrMode[3];
  2414.               memcpy(WAsmCode + 2 + AdrCnt2[1], AdrVals[3], AdrCnt1[3]);
  2415.               WAsmCode[2 + AdrCnt2[1] + AdrCnt2[3]] = ((AdrMode[2] & 15) << 10) + (AdrMode[4] & 15);
  2416.               CodeLen = 6 + AdrCnt1[1] + AdrCnt1[3];
  2417.             }
  2418.             break;
  2419.           case 2:
  2420.             if ((AdrType[1] != ModImm) || (AdrType[2] != ModImm)) WrError(ErrNum_InvAddrMode);
  2421.             else if ((OpSize[3] != 2) || (OpSize[4] != 2)) WrError(ErrNum_InvAddrMode);
  2422.             else
  2423.             {
  2424.               LongInt Offset = ImmVal(1);
  2425.               if (ChkRange(Offset, -128, 127))
  2426.               {
  2427.                 LongInt Width = ImmVal(2);
  2428.                 if (ChkRange(Width, 1, 32))
  2429.                 {
  2430.                   WAsmCode[0] = 0xbf00 + (Offset & 0xff);
  2431.                   WAsmCode[1] = 0xea00 + (IsEXTU << 10) + AdrMode[3];
  2432.                   memcpy(WAsmCode + 2, AdrVals[3], AdrCnt1[3]);
  2433.                   WAsmCode[2 + AdrCnt2[3]] = ((Width & 31) << 10) + (AdrMode[4] & 15);
  2434.                   CodeLen = 6 + AdrCnt1[3];
  2435.                 }
  2436.               }
  2437.             }
  2438.             break;
  2439.         }
  2440.       }
  2441.     }
  2442.   }
  2443. }
  2444.  
  2445. static void DecodeBSCH(Word Code)
  2446. {
  2447.   UNUSED(Code);
  2448.  
  2449.   if (!ChkArgCnt(2, 2));
  2450.   else if (OptionCnt != 1) WrError(ErrNum_WrongOptCnt);
  2451.   else if ((strcmp(Options[0], "0")) && (strcmp(Options[0], "1"))) WrXError(ErrNum_UndefCond, Options[0]);
  2452.   else if ((CheckFormat("G"))
  2453.         && (GetOpSize(&ArgStr[1], 1))
  2454.         && (GetOpSize(&ArgStr[2], 2)))
  2455.   {
  2456.     if (OpSize[1] == -1) OpSize[1] = 2;
  2457.     if (OpSize[2] == -1) OpSize[2] = 2;
  2458.     if (OpSize[1] != 2) WrError(ErrNum_InvOpSize);
  2459.     else if ((DecodeAdr(&ArgStr[1], 1, Mask_Source))
  2460.           && (DecodeAdr(&ArgStr[2], 2, Mask_PureDest)))
  2461.     {
  2462.       /* immer G-Format */
  2463.       WAsmCode[0] = 0xd600 + AdrMode[1];
  2464.       memcpy(WAsmCode + 1, AdrVals[1], AdrCnt1[1]);
  2465.       WAsmCode[1 + AdrCnt2[1]] = Code + ((Options[0][0] - '0') << 10)+ (OpSize[2] << 8) + AdrMode[2];
  2466.       memcpy(WAsmCode + 2 + AdrCnt2[1], AdrVals[2], AdrCnt1[2]);
  2467.       CodeLen = 4 + AdrCnt1[1] + AdrCnt1[2];
  2468.     }
  2469.   }
  2470. }
  2471.  
  2472. static void DecodeBSR_BRA(Word IsBSR)
  2473. {
  2474.   if (ChkArgCnt(1, 1)
  2475.    && CheckFormat("GD")
  2476.    && GetOpSize(&ArgStr[1], 1))
  2477.   {
  2478.     Boolean OK;
  2479.     tSymbolFlags Flags;
  2480.     LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags);
  2481.     if (OK)
  2482.     {
  2483.       DecideBranch(AdrLong, 1);
  2484.       switch (FormatCode)
  2485.       {
  2486.         case 2:
  2487.           if (OpSize[1] != -1) WrError(ErrNum_UseLessAttr);
  2488.           else
  2489.           {
  2490.             AdrLong -= EProgCounter();
  2491.             if (!mSymbolQuestionable(Flags) && ((AdrLong < -256) || (AdrLong > 254))) WrError(ErrNum_JmpDistTooBig);
  2492.             else if (Odd(AdrLong)) WrError(ErrNum_DistIsOdd);
  2493.             else
  2494.             {
  2495.               CodeLen = 2;
  2496.               WAsmCode[0] = 0xae00 + (IsBSR << 8) + Lo(AdrLong >> 1);
  2497.             }
  2498.           }
  2499.           break;
  2500.         case 1:
  2501.           WAsmCode[0] = 0x20f7 + (IsBSR << 11) + (((Word)OpSize[1]) << 8);
  2502.           AdrLong -= EProgCounter();
  2503.           switch (OpSize[1])
  2504.           {
  2505.             case 0:
  2506.               if (!mSymbolQuestionable(Flags) && ((AdrLong < -128) || (AdrLong > 127))) WrError(ErrNum_JmpDistTooBig);
  2507.               else
  2508.               {
  2509.                 CodeLen = 4;
  2510.                 WAsmCode[1] = Lo(AdrLong);
  2511.               }
  2512.               break;
  2513.             case 1:
  2514.               if (!mSymbolQuestionable(Flags) && ((AdrLong < -32768) || (AdrLong > 32767))) WrError(ErrNum_JmpDistTooBig);
  2515.               else
  2516.               {
  2517.                 CodeLen = 4;
  2518.                 WAsmCode[1] = AdrLong & 0xffff;
  2519.               }
  2520.               break;
  2521.             case 2:
  2522.               CodeLen = 6;
  2523.               WAsmCode[1] = AdrLong >> 16;
  2524.               WAsmCode[2] = AdrLong & 0xffff;
  2525.               break;
  2526.           }
  2527.           break;
  2528.       }
  2529.     }
  2530.   }
  2531. }
  2532.  
  2533. static void DecodeBcc(Word Code)
  2534. {
  2535.   if (ChkArgCnt(1, 1)
  2536.    && CheckFormat("GD")
  2537.    && GetOpSize(&ArgStr[1], 1))
  2538.   {
  2539.     Boolean OK;
  2540.     tSymbolFlags Flags;
  2541.     LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags);
  2542.     if (OK)
  2543.     {
  2544.       DecideBranch(AdrLong, 1);
  2545.       switch (FormatCode)
  2546.       {
  2547.         case 2:
  2548.           if (OpSize[1] != -1) WrError(ErrNum_UseLessAttr);
  2549.           else
  2550.           {
  2551.             AdrLong -= EProgCounter();
  2552.             if (!mSymbolQuestionable(Flags) && ((AdrLong < -256) || (AdrLong > 254))) WrError(ErrNum_JmpDistTooBig);
  2553.             else if (Odd(AdrLong)) WrError(ErrNum_DistIsOdd);
  2554.             else
  2555.             {
  2556.               CodeLen = 2;
  2557.               WAsmCode[0] = 0x8000 + Code + Lo(AdrLong >> 1);
  2558.             }
  2559.           }
  2560.           break;
  2561.         case 1:
  2562.           WAsmCode[0] = 0x00f6 + Code + (((Word)OpSize[1]) << 8);
  2563.           AdrLong -= EProgCounter();
  2564.           switch (OpSize[1])
  2565.           {
  2566.             case 0:
  2567.               if ((AdrLong < -128) || (AdrLong > 127)) WrError(ErrNum_JmpDistTooBig);
  2568.               else
  2569.               {
  2570.                 CodeLen = 4;
  2571.                 WAsmCode[1] = Lo(AdrLong);
  2572.               }
  2573.               break;
  2574.             case 1:
  2575.               if ((AdrLong < -32768) || (AdrLong > 32767)) WrError(ErrNum_JmpDistTooBig);
  2576.               else
  2577.               {
  2578.                 CodeLen = 4;
  2579.                 WAsmCode[1] = AdrLong & 0xffff;
  2580.               }
  2581.               break;
  2582.             case 2:
  2583.               CodeLen = 6;
  2584.               WAsmCode[1] = AdrLong >> 16;
  2585.               WAsmCode[2] = AdrLong & 0xffff;
  2586.               break;
  2587.           }
  2588.           break;
  2589.       }
  2590.     }
  2591.   }
  2592. }
  2593.  
  2594. static void DecodeTRAP(Word Code)
  2595. {
  2596.   Word Condition;
  2597.  
  2598.   UNUSED(Code);
  2599.  
  2600.   if (!ChkArgCnt(0, 0));
  2601.   else if (OptionCnt != 1) WrError(ErrNum_WrongOptCnt);
  2602.   else if (!DecodeCondition(Options[0], &Condition)) WrXError(ErrNum_UndefCond, Options[0]);
  2603.   else
  2604.   {
  2605.     CodeLen = 2;
  2606.     WAsmCode[0] = 0x03d4 | (Condition << 10);
  2607.   }
  2608. }
  2609.  
  2610. static void DecodeTRAPA(Word Code)
  2611. {
  2612.   UNUSED(Code);
  2613.  
  2614.   if (!ChkArgCnt(1, 1));
  2615.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2616.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  2617.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  2618.   else
  2619.   {
  2620.     Word AdrWord;
  2621.     Boolean OK;
  2622.  
  2623.     AdrWord = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt4, &OK);
  2624.     if (OK)
  2625.     {
  2626.       CodeLen = 2;
  2627.       WAsmCode[0] = 0x03d5 + (AdrWord << 10);
  2628.     }
  2629.   }
  2630. }
  2631.  
  2632. static void DecodeENTER_EXITD(Word IsEXITD)
  2633. {
  2634.   if (ChkArgCnt(2, 2))
  2635.   {
  2636.     tStrComp *pRegList = IsEXITD ? &ArgStr[1] : &ArgStr[2],
  2637.              *pSizeArg = IsEXITD ? &ArgStr[2] : &ArgStr[1];
  2638.  
  2639.     if ((CheckFormat("GE"))
  2640.      && (GetOpSize(pSizeArg, 1))
  2641.      && (GetOpSize(pRegList, 2)))
  2642.     {
  2643.       Word RegList;
  2644.  
  2645.       if (OpSize[1] == -1) OpSize[1] = 2;
  2646.       if (OpSize[2] == -1) OpSize[2] = 2;
  2647.       if (OpSize[2] != 2) WrError(ErrNum_InvOpSize);
  2648.       else if ((DecodeAdr(pSizeArg, 1, MModReg | MModImm))
  2649.             && (DecodeRegList(pRegList, &RegList, IsEXITD)))
  2650.       {
  2651.         if ((RegList & 0xc000) != 0) WrXError(ErrNum_InvRegList,"SP/FP");
  2652.         else
  2653.         {
  2654.           if (FormatCode == 0)
  2655.           {
  2656.             if (AdrType[1] == ModImm)
  2657.             {
  2658.               LongInt HVal = ImmVal(1);
  2659.               if ((HVal >= -128) && (HVal <= 127))
  2660.                 FormatCode = 2;
  2661.               else
  2662.                 FormatCode = 1;
  2663.             }
  2664.             else
  2665.               FormatCode = 1;
  2666.           }
  2667.           switch (FormatCode)
  2668.           {
  2669.             case 1:
  2670.               WAsmCode[0] = 0x02f7;
  2671.               WAsmCode[1] = 0x8c00 + (IsEXITD << 12) + (OpSize[1] << 8) + AdrMode[1];
  2672.               memcpy(WAsmCode + 2, AdrVals[1], AdrCnt1[1]);
  2673.               WAsmCode[2 + AdrCnt2[1]] = RegList;
  2674.               CodeLen = 6 + AdrCnt1[1];
  2675.               break;
  2676.             case 2:
  2677.               if (AdrType[1] != ModImm) WrError(ErrNum_InvAddrMode);
  2678.               else
  2679.               {
  2680.                 LongInt HVal = ImmVal(1);
  2681.                 if (ChkRange(HVal, -128, 127))
  2682.                 {
  2683.                   WAsmCode[0] = 0x8e00 + (IsEXITD << 12) + (HVal & 0xff);
  2684.                   WAsmCode[1] = RegList;
  2685.                   CodeLen = 4;
  2686.                 }
  2687.               }
  2688.               break;
  2689.           }
  2690.         }
  2691.       }
  2692.     }
  2693.   }
  2694. }
  2695.  
  2696. static void DecodeSCMP(Word Code)
  2697. {
  2698.   UNUSED(Code);
  2699.  
  2700.   if (DOpSize == -1) DOpSize = 2;
  2701.   if (!ChkArgCnt(0, 0));
  2702.   else if (OptionCnt > 1) WrError(ErrNum_WrongOptCnt);
  2703.   else
  2704.   {
  2705.     Boolean OK = True;
  2706.     Word Condition = 6;
  2707.  
  2708.     if (OptionCnt == 1)
  2709.       OK = DecodeStringCondition(Options[0], &Condition);
  2710.  
  2711.     if (!OK) WrXError(ErrNum_UndefCond, Options[0]);
  2712.     else
  2713.     {
  2714.       WAsmCode[0] = 0x00e0 + (DOpSize << 8) + (Condition << 10);
  2715.       CodeLen = 2;
  2716.     }
  2717.   }
  2718. }
  2719.  
  2720. static void DecodeSMOV_SSCH(Word Code)
  2721. {
  2722.   if (DOpSize == -1) DOpSize = 2;
  2723.   if (ChkArgCnt(0, 0))
  2724.   {
  2725.     int z;
  2726.     Word Condition = 6, Mask = 0;
  2727.     Boolean OK = True;
  2728.  
  2729.     for (z = 0; z < OptionCnt; z++)
  2730.     {
  2731.       if (!as_strcasecmp(Options[z], "F"))
  2732.         Mask = 0;
  2733.       else if (!as_strcasecmp(Options[z], "B"))
  2734.         Mask = 1;
  2735.       else
  2736.         OK = DecodeStringCondition(Options[z], &Condition);
  2737.       if (!OK)
  2738.         break;
  2739.     }
  2740.     if (!OK) WrXError(ErrNum_UndefCond, Options[z]);
  2741.     else
  2742.     {
  2743.       WAsmCode[0] = 0x00e4 + (DOpSize << 8) + (Condition << 10) + Mask + Code;
  2744.       CodeLen = 2;
  2745.     }
  2746.   }
  2747. }
  2748.  
  2749. static void DecodeSSTR(Word Code)
  2750. {
  2751.   UNUSED(Code);
  2752.  
  2753.   if (DOpSize == -1) DOpSize = 2;
  2754.   if (ChkArgCnt(0, 0))
  2755.   {
  2756.     WAsmCode[0] = 0x24f7 + (DOpSize << 8);
  2757.     CodeLen = 2;
  2758.   }
  2759. }
  2760.  
  2761. static void DecodeLDM_STM(Word Code)
  2762. {
  2763.   if (ChkArgCnt(2, 2)
  2764.    && CheckFormat("G"))
  2765.   {
  2766.     Word Mask = MModIReg | MModDisp16 | MModDisp32 | MModAbs16 | MModAbs32 | MModPCRel16 | MModPCRel32;
  2767.     tStrComp *pRegList, *pMemArg;
  2768.     Word RegList;
  2769.  
  2770.     if (Code)
  2771.     {
  2772.       Mask |= MModPop;
  2773.       pRegList = &ArgStr[2];
  2774.       pMemArg = &ArgStr[1];
  2775.     }
  2776.     else
  2777.     {
  2778.       Mask |= MModPush;
  2779.       pRegList = &ArgStr[1];
  2780.       pMemArg = &ArgStr[2];
  2781.     }
  2782.     if ((GetOpSize(pRegList, 1))
  2783.      && (GetOpSize(pMemArg, 2)))
  2784.     {
  2785.       if (OpSize[1] == -1) OpSize[1] = 2;
  2786.       if (OpSize[2] == -1) OpSize[2] = 2;
  2787.       if ((OpSize[1] != 2) || (OpSize[2] != 2)) WrError(ErrNum_InvOpSize);
  2788.       else if ((DecodeAdr(pMemArg, 2, Mask))
  2789.             && (DecodeRegList(pRegList, &RegList, AdrType[2] != ModPush)))
  2790.        {
  2791.          WAsmCode[0] = 0x8a00 + Code + AdrMode[2];
  2792.          memcpy(WAsmCode + 1, AdrVals[2], AdrCnt1[2]);
  2793.          WAsmCode[1 + AdrCnt2[2]] = RegList;
  2794.          CodeLen = 4 + AdrCnt1[2];
  2795.        }
  2796.     }
  2797.   }
  2798. }
  2799.  
  2800. static void DecodeSTC_STP(Word Code)
  2801. {
  2802.   if (ChkArgCnt(2, 2)
  2803.    && CheckFormat("G")
  2804.    && GetOpSize(&ArgStr[1], 1)
  2805.    && GetOpSize(&ArgStr[2], 2))
  2806.   {
  2807.     if (OpSize[2] == -1) OpSize[2] = 2;
  2808.     if (OpSize[1] == -1) OpSize[1] = OpSize[1];
  2809.     if (OpSize[1] != OpSize[2]) WrError(ErrNum_UndefOpSizes);
  2810.     else if ((!Code) && (OpSize[2] != 2)) WrError(ErrNum_InvOpSize);
  2811.     else if ((DecodeAdr(&ArgStr[1], 1, Mask_PureMem))
  2812.           && (DecodeAdr(&ArgStr[2], 2, Mask_Dest)))
  2813.     {
  2814.       OpSize[1] = 0;
  2815.       Make_G(0xa800 + Code);
  2816.       WAsmCode[0] += 0x800;
  2817.     }
  2818.   }
  2819. }
  2820.  
  2821. static void DecodeJRNG(Word Code)
  2822. {
  2823.   UNUSED(Code);
  2824.  
  2825.   if (ChkArgCnt(1, 1)
  2826.    && CheckFormat("GE")
  2827.    && GetOpSize(&ArgStr[1], 1))
  2828.   {
  2829.     if (OpSize[1] == -1) OpSize[1] = 1;
  2830.     if (OpSize[1] != 1) WrError(ErrNum_InvOpSize);
  2831.     else if (DecodeAdr(&ArgStr[1], 1, MModReg | MModImm))
  2832.     {
  2833.       if (FormatCode == 0)
  2834.       {
  2835.         if (AdrType[1] == ModImm)
  2836.         {
  2837.           LongInt HVal = ImmVal(1);
  2838.           if ((HVal >= 0) && (HVal <= 255))
  2839.             FormatCode = 2;
  2840.           else
  2841.             FormatCode = 1;
  2842.         }
  2843.         else
  2844.           FormatCode = 1;
  2845.       }
  2846.       switch (FormatCode)
  2847.       {
  2848.         case 1:
  2849.           WAsmCode[0] = 0xba00 + AdrMode[1];
  2850.           memcpy(WAsmCode + 1 , AdrVals[1], AdrCnt1[1]);
  2851.           CodeLen = 2 + AdrCnt1[1];
  2852.           break;
  2853.         case 2:
  2854.           if (AdrType[1] != ModImm) WrError(ErrNum_InvAddrMode);
  2855.           else
  2856.           {
  2857.             LongInt HVal = ImmVal(1);
  2858.             if (ChkRange(HVal, 0, 255))
  2859.             {
  2860.               WAsmCode[0] = 0xbe00 + (HVal & 0xff);
  2861.               CodeLen = 2;
  2862.             }
  2863.           }
  2864.           break;
  2865.       }
  2866.     }
  2867.   }
  2868. }
  2869.  
  2870. /*------------------------------------------------------------------------*/
  2871.  
  2872. static void AddFixed(const char *NName, Word NCode)
  2873. {
  2874.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  2875. }
  2876.  
  2877. static void AddFixedLong(const char *NName, Word NCode1, Word NCode2)
  2878. {
  2879.   order_array_rsv_end(FixedLongOrders, BitOrder);
  2880.   FixedLongOrders[InstrZ].Code1 = NCode1;
  2881.   FixedLongOrders[InstrZ].Code2 = NCode2;
  2882.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixedLong);
  2883. }
  2884.  
  2885. static void AddOne(const char *NName, Byte NOpMask, Word NMask, Word NCode)
  2886. {
  2887.   order_array_rsv_end(OneOrders, OneOrder);
  2888.   OneOrders[InstrZ].Code = NCode;
  2889.   OneOrders[InstrZ].Mask = NMask;
  2890.   OneOrders[InstrZ].OpMask = NOpMask;
  2891.   AddInstTable(InstTable, NName, InstrZ++, DecodeOne);
  2892. }
  2893.  
  2894. static void AddGE2(const char *NName, Word NMask1, Word NMask2,
  2895.                    Byte NSMask1, Byte NSMask2, Word NCode,
  2896.                    Boolean NSigned)
  2897. {
  2898.   order_array_rsv_end(GE2Orders, GE2Order);
  2899.   GE2Orders[InstrZ].Mask1 = NMask1;
  2900.   GE2Orders[InstrZ].Mask2 = NMask2;
  2901.   GE2Orders[InstrZ].SMask1 = NSMask1;
  2902.   GE2Orders[InstrZ].SMask2 = NSMask2;
  2903.   GE2Orders[InstrZ].Code = NCode;
  2904.   GE2Orders[InstrZ].Signed = NSigned;
  2905.   AddInstTable(InstTable, NName, InstrZ++, DecodeGE2);
  2906. }
  2907.  
  2908. static void AddBit(const char *NName, Boolean NMust, Word NCode1, Word NCode2)
  2909. {
  2910.   order_array_rsv_end(BitOrders, BitOrder);
  2911.   BitOrders[InstrZ].Code1 = NCode1;
  2912.   BitOrders[InstrZ].Code2 = NCode2;
  2913.   BitOrders[InstrZ].MustByte = NMust;
  2914.   AddInstTable(InstTable, NName, InstrZ++, DecodeBit);
  2915. }
  2916.  
  2917. static void AddGetPut(const char *NName, Byte NSize, Word NCode, Boolean NTurn)
  2918. {
  2919.   AddInstTable(InstTable, NName, NCode | NSize | (NTurn << 7), DecodeGetPut);
  2920. }
  2921.  
  2922. static void Addcc(const char *p_branch_name)
  2923. {
  2924.   order_array_rsv_end(Conditions, condition_t);
  2925.   Conditions[InstrZ].p_name = p_branch_name + 1;
  2926.   if (p_branch_name)
  2927.     AddInstTable(InstTable, p_branch_name, InstrZ << 10, DecodeBcc);
  2928.   InstrZ++;
  2929. }
  2930.  
  2931. static void InitFields(void)
  2932. {
  2933.   Format = (char*)malloc(sizeof(char) * STRINGSIZE);
  2934.  
  2935.   InstTable = CreateInstTable(301);
  2936.   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
  2937.   AddInstTable(InstTable, "ADD", 0, DecodeADD_SUB);
  2938.   AddInstTable(InstTable, "SUB", 1, DecodeADD_SUB);
  2939.   AddInstTable(InstTable, "ACB", 0, DecodeACB_SCB);
  2940.   AddInstTable(InstTable, "SCB", 1, DecodeACB_SCB);
  2941.   AddInstTable(InstTable, "CMP", 0, DecodeCMP);
  2942.   AddInstTable(InstTable, "MOVA", 0, DecodeMOVA);
  2943.   AddInstTable(InstTable, "QINS", 1 << 11, DecodeQINS_QDEL);
  2944.   AddInstTable(InstTable, "QDEL", 0 << 11, DecodeQINS_QDEL);
  2945.   AddInstTable(InstTable, "RVBY", 0, DecodeRVBY);
  2946.   AddInstTable(InstTable, "SHL", 0, DecodeSHL_SHA);
  2947.   AddInstTable(InstTable, "SHA", 1, DecodeSHL_SHA);
  2948.   AddInstTable(InstTable, "SHXL", 0x8a00, DecodeSHXL_SHXR);
  2949.   AddInstTable(InstTable, "SHXR", 0x9a00, DecodeSHXL_SHXR);
  2950.   AddInstTable(InstTable, "CHK", 0, DecodeCHK);
  2951.   AddInstTable(InstTable, "CHK/", 0, DecodeCHK);
  2952.   AddInstTable(InstTable, "CSI", 0, DecodeCSI);
  2953.   AddInstTable(InstTable, "DIVX", 0x8300, DecodeDIVX_MULX);
  2954.   AddInstTable(InstTable, "MULX", 0x8200, DecodeDIVX_MULX);
  2955.   AddInstTable(InstTable, "WAIT", 0, DecodeWAIT);
  2956.   AddInstTable(InstTable, "BFEXT", 0, DecodeBFEXT_BFEXTU);
  2957.   AddInstTable(InstTable, "BFEXTU", 1, DecodeBFEXT_BFEXTU);
  2958.   AddInstTable(InstTable, "BSCH/", 0x5000, DecodeBSCH);
  2959.   AddInstTable(InstTable, "BSR", 1, DecodeBSR_BRA);
  2960.   AddInstTable(InstTable, "BRA", 0, DecodeBSR_BRA);
  2961.   AddInstTable(InstTable, "TRAPA", 0, DecodeTRAPA);
  2962.   AddInstTable(InstTable, "TRAP/", 0, DecodeTRAP);
  2963.   AddInstTable(InstTable, "ENTER", 0, DecodeENTER_EXITD);
  2964.   AddInstTable(InstTable, "EXITD", 1, DecodeENTER_EXITD);
  2965.   AddInstTable(InstTable, "SCMP", 0, DecodeSCMP);
  2966.   AddInstTable(InstTable, "SCMP/", 0, DecodeSCMP);
  2967.   AddInstTable(InstTable, "SMOV", 0, DecodeSMOV_SSCH);
  2968.   AddInstTable(InstTable, "SMOV/", 0, DecodeSMOV_SSCH);
  2969.   AddInstTable(InstTable, "SSCH", 16, DecodeSMOV_SSCH);
  2970.   AddInstTable(InstTable, "SSCH/", 16, DecodeSMOV_SSCH);
  2971.   AddInstTable(InstTable, "SSTR", 0, DecodeSSTR);
  2972.   AddInstTable(InstTable, "LDM", 0x1000, DecodeLDM_STM);
  2973.   AddInstTable(InstTable, "STM", 0x0000, DecodeLDM_STM);
  2974.   AddInstTable(InstTable, "STC", 0x0000, DecodeSTC_STP);
  2975.   AddInstTable(InstTable, "STP", 0x0400, DecodeSTC_STP);
  2976.   AddInstTable(InstTable, "JRNG", 0, DecodeJRNG);
  2977.  
  2978.   AddFixed("NOP"  , 0x1bd6); AddFixed("PIB"  , 0x0bd6);
  2979.   AddFixed("RIE"  , 0x08f7); AddFixed("RRNG" , 0x3bd6);
  2980.   AddFixed("RTS"  , 0x2bd6); AddFixed("STCTX", 0x07d6);
  2981.   AddFixed("REIT" , 0x2fd6);
  2982.  
  2983.   InstrZ = 0;
  2984.   AddFixedLong("STOP", 0x5374, 0x6f70);
  2985.   AddFixedLong("SLEEP", 0x5761, 0x6974);
  2986.  
  2987.   InstrZ = 0;
  2988.   AddOne("ACS"   , 0x00, Mask_PureMem,                    0x8300);
  2989.   AddOne("NEG"   , 0x07, Mask_PureDest,                   0xc800);
  2990.   AddOne("NOT"   , 0x07, Mask_PureDest,                   0xcc00);
  2991.   AddOne("JMP"   , 0x00, Mask_PureMem,                    0x8200);
  2992.   AddOne("JSR"   , 0x00, Mask_PureMem,                    0xaa00);
  2993.   AddOne("LDCTX" , 0x00, MModIReg | MModDisp16 | MModDisp32 |
  2994.                          MModAbs16 | MModAbs32 | MModPCRel16 | MModPCRel32, 0x8600);
  2995.   AddOne("LDPSB" , 0x02, Mask_Source,                     0xdb00);
  2996.   AddOne("LDPSM" , 0x02, Mask_Source,                     0xdc00);
  2997.   AddOne("POP"   , 0x04, Mask_PureDest,                   0x9000);
  2998.   AddOne("PUSH"  , 0x04, Mask_Source-MModPop,             0xb000);
  2999.   AddOne("PUSHA" , 0x00, Mask_PureMem,                    0xa200);
  3000.   AddOne("STPSB" , 0x02, Mask_Dest,                       0xdd00);
  3001.   AddOne("STPSM" , 0x02, Mask_Dest,                       0xde00);
  3002.  
  3003.   InstrZ = 0;
  3004.   AddGE2("ADDU" , Mask_Source, Mask_PureDest, 7, 7, 0x0400, False);
  3005.   AddGE2("ADDX" , Mask_Source, Mask_PureDest, 7, 7, 0x1000, True );
  3006.   AddGE2("SUBU" , Mask_Source, Mask_PureDest, 7, 7, 0x0c00, False);
  3007.   AddGE2("SUBX" , Mask_Source, Mask_PureDest, 7, 7, 0x1800, True );
  3008.   AddGE2("CMPU" , Mask_Source, Mask_PureDest|MModPop, 7, 7, 0x8400, False);
  3009.   AddGE2("LDC"  , Mask_Source, Mask_PureDest, 7, 4, 0x9800, True );
  3010.   AddGE2("LDP"  , Mask_Source, Mask_PureMem , 7, 7, 0x9c00, True );
  3011.   AddGE2("MOVU" , Mask_Source, Mask_Dest    , 7, 7, 0x8c00, True );
  3012.   AddGE2("REM"  , Mask_Source, Mask_PureDest, 7, 7, 0x5800, True );
  3013.   AddGE2("REMU" , Mask_Source, Mask_PureDest, 7, 7, 0x5c00, True );
  3014.   AddGE2("ROT"  , Mask_Source, Mask_PureDest, 1, 7, 0x3800, True );
  3015.  
  3016.   InstrZ = 0;
  3017.   AddBit("BCLR" , False, 0xb400, 0xa180);
  3018.   AddBit("BCLRI", True , 0xa400, 0x0000);
  3019.   AddBit("BNOT" , False, 0xb800, 0x0000);
  3020.   AddBit("BSET" , False, 0xb000, 0x8180);
  3021.   AddBit("BSETI", True , 0xa000, 0x81c0);
  3022.   AddBit("BTST" , False, 0xbc00, 0xa1c0);
  3023.  
  3024.   AddGetPut("GETB0", 0, 0xc000, False);
  3025.   AddGetPut("GETB1", 0, 0xc400, False);
  3026.   AddGetPut("GETB2", 0, 0xc800, False);
  3027.   AddGetPut("GETH0", 1, 0xcc00, False);
  3028.   AddGetPut("PUTB0", 0, 0xd000, True );
  3029.   AddGetPut("PUTB1", 0, 0xd400, True );
  3030.   AddGetPut("PUTB2", 0, 0xd800, True );
  3031.   AddGetPut("PUTH0", 1, 0xdc00, True );
  3032.  
  3033.   InstrZ = 0;
  3034.   AddInstTable(InstTable, "BFCMP" , InstrZ++, DecodeBField);
  3035.   AddInstTable(InstTable, "BFCMPU", InstrZ++, DecodeBField);
  3036.   AddInstTable(InstTable, "BFINS" , InstrZ++, DecodeBField);
  3037.   AddInstTable(InstTable, "BFINSU", InstrZ++, DecodeBField);
  3038.  
  3039.   InstrZ = 0;
  3040.   AddInstTable(InstTable, "MUL" , InstrZ++, DecodeMul);
  3041.   AddInstTable(InstTable, "MULU", InstrZ++, DecodeMul);
  3042.   AddInstTable(InstTable, "DIV" , InstrZ++, DecodeMul);
  3043.   AddInstTable(InstTable, "DIVU", InstrZ++, DecodeMul);
  3044.  
  3045.   InstrZ = 0;
  3046.   Addcc("BXS");
  3047.   Addcc("BXC");
  3048.   Addcc("BEQ");
  3049.   Addcc("BNE");
  3050.   Addcc("BLT");
  3051.   Addcc("BGE");
  3052.   Addcc("BLE");
  3053.   Addcc("BGT");
  3054.   Addcc("BVS");
  3055.   Addcc("BVC");
  3056.   Addcc("BMS");
  3057.   Addcc("BMC");
  3058.   Addcc("BFS");
  3059.   Addcc("BFC");
  3060.   Addcc(NULL);
  3061.  
  3062.   InstrZ = 0;
  3063.   AddInstTable(InstTable, "AND", InstrZ++, DecodeLog);
  3064.   AddInstTable(InstTable, "OR" , InstrZ++, DecodeLog);
  3065.   AddInstTable(InstTable, "XOR", InstrZ++, DecodeLog);
  3066.  
  3067.   AddInstTable(InstTable, "REG", 0, CodeREG);
  3068. }
  3069.  
  3070. static void DeinitFields(void)
  3071. {
  3072.   order_array_free(Conditions);
  3073.   order_array_free(Format);
  3074.   order_array_free(FixedLongOrders);
  3075.   order_array_free(OneOrders);
  3076.   order_array_free(GE2Orders);
  3077.   order_array_free(BitOrders);
  3078.   DestroyInstTable(InstTable);
  3079. }
  3080.  
  3081. /*------------------------------------------------------------------------*/
  3082.  
  3083. static Boolean DecodeAttrPart_M16(void)
  3084. {
  3085.   char *p;
  3086.  
  3087.   switch (AttrSplit)
  3088.   {
  3089.     case '.':
  3090.       p = strchr(AttrPart.str.p_str, ':');
  3091.       if (p)
  3092.       {
  3093.         if (p < AttrPart.str.p_str + strlen(AttrPart.str.p_str) - 1)
  3094.           strmaxcpy(Format, p + 1, STRINGSIZE);
  3095.         else
  3096.           strcpy(Format, " ");
  3097.         *p = '\0';
  3098.       }
  3099.       else
  3100.         strcpy(Format, " ");
  3101.       break;
  3102.     case ':':
  3103.       p = strchr(AttrPart.str.p_str, '.');
  3104.       if (!p)
  3105.       {
  3106.         strmaxcpy(Format, AttrPart.str.p_str, STRINGSIZE);
  3107.         *AttrPart.str.p_str = '\0';
  3108.       }
  3109.       else
  3110.       {
  3111.         *p = '\0';
  3112.         if (p == AttrPart.str.p_str)
  3113.           strcpy(Format, " ");
  3114.         else
  3115.           strmaxcpy(Format, AttrPart.str.p_str, STRINGSIZE);
  3116.       }
  3117.       break;
  3118.     default:
  3119.       strcpy(Format," ");
  3120.   }
  3121.   NLS_UpString(Format);
  3122.  
  3123.   if (*AttrPart.str.p_str)
  3124.     switch (as_toupper(*AttrPart.str.p_str))
  3125.     {
  3126.       case 'B':
  3127.         AttrPartOpSize[0] = eSymbolSize8Bit; break;
  3128.       case 'H':
  3129.         AttrPartOpSize[0] = eSymbolSize16Bit; break;
  3130.       case 'W':
  3131.         AttrPartOpSize[0] = eSymbolSize32Bit; break;
  3132.       default:
  3133.         WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); return False;
  3134.     }
  3135.   return True;
  3136. }
  3137.  
  3138. static void MakeCode_M16(void)
  3139. {
  3140.   int z;
  3141.  
  3142.   DOpSize = AttrPartOpSize[0];
  3143.   for (z = 1; z <= ArgCnt; OpSize[z++] = eSymbolSizeUnknown);
  3144.  
  3145.   /* zu ignorierendes */
  3146.  
  3147.   if (Memo(""))
  3148.     return;
  3149.  
  3150.   /* Pseudoanweisungen */
  3151.  
  3152.   if (DecodeIntelPseudo(False))
  3153.     return;
  3154.  
  3155.   SplitOptions();
  3156.  
  3157.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  3158.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  3159. }
  3160.  
  3161. static Boolean IsDef_M16(void)
  3162. {
  3163.   return Memo("REG");
  3164. }
  3165.  
  3166. /*!------------------------------------------------------------------------
  3167.  * \fn     InternSymbol_M16(char *pArg, TempResult *pResult)
  3168.  * \brief  handle built-in (register) symbols for M16
  3169.  * \param  pArg source argument
  3170.  * \param  pResult result buffer
  3171.  * ------------------------------------------------------------------------ */
  3172.  
  3173. static void InternSymbol_M16(char *pArg, TempResult *pResult)
  3174. {
  3175.   Word RegNum;
  3176.  
  3177.   if (DecodeRegCore(pArg, &RegNum))
  3178.   {
  3179.     pResult->Typ = TempReg;
  3180.     pResult->DataSize = eSymbolSize32Bit;
  3181.     pResult->Contents.RegDescr.Reg = RegNum;
  3182.     pResult->Contents.RegDescr.Dissect = DissectReg_M16;
  3183.     pResult->Contents.RegDescr.compare = NULL;
  3184.   }
  3185. }
  3186.  
  3187. static void SwitchFrom_M16(void)
  3188. {
  3189.   DeinitFields();
  3190. }
  3191.  
  3192. static void SwitchTo_M16(void)
  3193. {
  3194.   TurnWords = True;
  3195.   SetIntConstMode(eIntConstModeIntel);
  3196.  
  3197.   PCSymbol = "$";
  3198.   HeaderID = 0x13;
  3199.   NOPCode = 0x1bd6;
  3200.   DivideChars=",";
  3201.   HasAttrs = True;
  3202.   AttrChars = ".:";
  3203.  
  3204.   ValidSegs = 1 << SegCode;
  3205.   Grans[SegCode] = 1;
  3206.   ListGrans[SegCode] = 2;
  3207.   SegInits[SegCode] = 0;
  3208.   SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
  3209.  
  3210.   DecodeAttrPart = DecodeAttrPart_M16;
  3211.   MakeCode = MakeCode_M16;
  3212.   IsDef = IsDef_M16;
  3213.   DissectReg = DissectReg_M16;
  3214.   InternSymbol = InternSymbol_M16;
  3215.   SwitchFrom = SwitchFrom_M16;
  3216.   InitFields();
  3217. }
  3218.  
  3219. void codem16_init(void)
  3220. {
  3221.   CPUM16 = AddCPU("M16", SwitchTo_M16);
  3222. }
  3223.