Subversion Repositories pentevo

Rev

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

  1. /* code97c241.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator TLCS-9000                                                   */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include <assert.h>
  16.  
  17. #include "nls.h"
  18. #include "strutil.h"
  19. #include "bpemu.h"
  20. #include "asmdef.h"
  21. #include "asmsub.h"
  22. #include "asmpars.h"
  23. #include "asmallg.h"
  24. #include "asmitree.h"
  25. #include "asmcode.h"
  26. #include "codepseudo.h"
  27. #include "intpseudo.h"
  28. #include "codevars.h"
  29. #include "errmsg.h"
  30. #include "operator.h"
  31.  
  32. #include "code97c241.h"
  33.  
  34. typedef struct
  35. {
  36.   Byte Code;
  37.   Byte Mask;     /* B0..2=OpSizes, B4=-MayImm, B5=-MayReg */
  38. } RMWOrder;
  39.  
  40. static CPUVar CPU97C241;
  41.  
  42. static int OpSize, OpSize2;
  43. static Integer LowLim4, LowLim8;
  44.  
  45. static Boolean AdrOK;
  46. static Word AdrMode, AdrMode2;
  47. static Byte AdrCnt2;
  48. static Word AdrVals[2], AdrVals2[2];
  49. static int AdrInc;
  50. static Word Prefs[2];
  51. static Boolean PrefUsed[2];
  52. static char Format;
  53. static Boolean MinOneIs0;
  54.  
  55. static RMWOrder *RMWOrders;
  56.  
  57. static const char Conditions[][4] =
  58. {
  59.   "C",   "NC",
  60.   "Z",   "NZ",
  61.   "OV",  "NOV",
  62.   "MI",  "PL",
  63.   "LE",  "GT",
  64.   "LT",  "GE",
  65.   "ULE", "UGT",
  66.   "N",   "A",
  67.   "ULT", "UGE",
  68.   "EQ",  "NE"
  69. };
  70.  
  71. /*--------------------------------------------------------------------------*/
  72.  
  73. static int CheckForcePrefix(const char *pArg, Boolean *pForce)
  74. {
  75.   if (*pArg == '>')
  76.   {
  77.     *pForce = True;
  78.     return 1;
  79.   }
  80.   return 0;
  81. }
  82.  
  83. static void AddSignedPrefix(Byte Index, Byte MaxBits, LongInt Value, Boolean Force)
  84. {
  85.   LongInt Max;
  86.  
  87.   Max = 1l << (MaxBits -1);
  88.   if (Force || ((Value < -Max) || (Value >= Max)))
  89.   {
  90.     PrefUsed[Index] = True;
  91.     Prefs[Index] = (Value >> MaxBits) & 0x7ff;
  92.   }
  93. }
  94.  
  95. static Boolean AddRelPrefix(Byte Index, Byte MaxBits, LongInt *Value, Boolean Force)
  96. {
  97.   LongInt Max1,Max2;
  98.  
  99.   Max1 = 1l << (MaxBits - 1);
  100.   Max2 = 1l << (MaxBits + 10);
  101.   if ((*Value < -Max2) || (*Value >= Max2)) WrError(ErrNum_JmpDistTooBig);
  102.   else
  103.   {
  104.     if (Force || ((*Value < -Max1) || (*Value >= Max1)))
  105.     {
  106.       PrefUsed[Index] = True;
  107.       Prefs[Index] = ((*Value) >> MaxBits) & 0x7ff;
  108.     }
  109.     return True;
  110.   }
  111.   return False;
  112. }
  113.  
  114. static void AddAbsPrefix(Byte Index, Byte MaxBits, LongInt Value, Boolean Force)
  115. {
  116.   LongInt Dist;
  117.  
  118.   Dist = 1l << (MaxBits - 1);
  119.   if (Force || ((Value >= Dist) && (Value < 0x1000000 - Dist)))
  120.   {
  121.     PrefUsed[Index] = True;
  122.     Prefs[Index] = (Value >> MaxBits) & 0x7ff;
  123.   }
  124. }
  125.  
  126. static void InsertSinglePrefix(Byte Index)
  127. {
  128.   if (PrefUsed[Index])
  129.   {
  130.     memmove(WAsmCode + 1, WAsmCode + 0, CodeLen);
  131.     WAsmCode[0] = Prefs[Index] + 0xd000 + (((Word)Index) << 11);
  132.     CodeLen += 2;
  133.   }
  134. }
  135.  
  136. /*!------------------------------------------------------------------------
  137.  * \fn     DecodeRegCore(const char *pArg, Byte *pResult, tSymbolSize *pSize)
  138.  * \brief  check whether argument is a CPU register
  139.  * \param  pArg source argument
  140.  * \param  pResult register number if yes
  141.  * \param  pSize register size if yes
  142.  * \return True if yes
  143.  * ------------------------------------------------------------------------ */
  144.  
  145. static Boolean DecodeRegCore(const char *pArg, Byte *pResult, tSymbolSize *pSize)
  146. {
  147.   Boolean OK;
  148.   int l = strlen(pArg);
  149.  
  150.   if (as_toupper(*pArg) != 'R')
  151.     return False;
  152.   l = strlen(pArg);
  153.   if ((l > 4) || (l < 3))
  154.     return False;
  155.  
  156.   switch (as_toupper(pArg[1]))
  157.   {
  158.     case 'B':
  159.       *pSize = eSymbolSize8Bit;
  160.       break;
  161.     case 'W':
  162.       *pSize = eSymbolSize16Bit;
  163.       break;
  164.     case 'D':
  165.       *pSize = eSymbolSize32Bit;
  166.       break;
  167.     default:
  168.       return False;
  169.   }
  170.   *pResult = ConstLongInt(pArg + 2, &OK, 10);
  171.   if (!OK || (*pResult > 15))
  172.     return False;
  173.   if ((*pSize == eSymbolSize32Bit) && Odd(*pResult))
  174.     return False;
  175.   return True;
  176. }
  177.  
  178. /*!------------------------------------------------------------------------
  179.  * \fn     DissectReg_97C241(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  180.  * \brief  dissect register symbols - TLCS-9000 variant
  181.  * \param  pDest destination buffer
  182.  * \param  DestSize destination buffer size
  183.  * \param  Value numeric register value
  184.  * \param  InpSize register size
  185.  * ------------------------------------------------------------------------ */
  186.  
  187. static void DissectReg_97C241(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  188. {
  189.   switch (InpSize)
  190.   {
  191.     case eSymbolSize8Bit:
  192.       as_snprintf(pDest, DestSize, "RB%u", (unsigned)Value);
  193.       break;
  194.     case eSymbolSize16Bit:
  195.       as_snprintf(pDest, DestSize, "RW%u", (unsigned)Value);
  196.       break;
  197.     case eSymbolSize32Bit:
  198.       as_snprintf(pDest, DestSize, "RD%u", (unsigned)Value);
  199.       break;
  200.     default:
  201.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  202.   }
  203. }
  204.  
  205. /*!------------------------------------------------------------------------
  206.  * \fn     tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
  207.  * \brief  check whether argument is a CPU register or register alias
  208.  * \param  pArg source argument
  209.  * \param  pResult register number if yes
  210.  * \param  pSize register size if yes
  211.  * \param  MustBeReg True if register is expected
  212.  * \return True if yes
  213.  * ------------------------------------------------------------------------ */
  214.  
  215. static tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, tSymbolSize *pSize, Boolean MustBeReg)
  216. {
  217.   tRegEvalResult RegEvalResult;
  218.   tEvalResult EvalResult;
  219.   tRegDescr RegDescr;
  220.  
  221.   if (DecodeRegCore(pArg->str.p_str, pResult, pSize))
  222.     return eIsReg;
  223.  
  224.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
  225.   if (eIsReg == RegEvalResult)
  226.   {
  227.     *pResult = RegDescr.Reg;
  228.     *pSize = EvalResult.DataSize;
  229.   }
  230.   return RegEvalResult;
  231. }
  232.  
  233. static Boolean DecodeSpecReg(char *Asc, Byte *Result)
  234. {
  235.   if (!as_strcasecmp(Asc, "SP")) *Result = 0x8c;
  236.   else if (!as_strcasecmp(Asc, "ISP")) *Result = 0x81;
  237.   else if (!as_strcasecmp(Asc, "ESP")) *Result = 0x83;
  238.   else if (!as_strcasecmp(Asc, "PBP")) *Result = 0x05;
  239.   else if (!as_strcasecmp(Asc, "CBP")) *Result = 0x07;
  240.   else if (!as_strcasecmp(Asc, "PSW")) *Result = 0x89;
  241.   else if (!as_strcasecmp(Asc, "IMC")) *Result = 0x0b;
  242.   else if (!as_strcasecmp(Asc, "CC"))  *Result = 0x0e;
  243.   else return False;
  244.   return True;
  245. }
  246.  
  247. static Boolean DecodeRegAdr(const tStrComp *pArg, Byte *pResult)
  248. {
  249.   tSymbolSize Size;
  250.  
  251.   if (DecodeReg(pArg, pResult, &Size, True) != eIsReg)
  252.     return False;
  253.   if (OpSize == eSymbolSizeUnknown)
  254.     OpSize = Size;
  255.   if (Size != OpSize)
  256.   {
  257.     WrError(ErrNum_ConfOpSizes);
  258.     return False;
  259.   }
  260.   *pResult &= 0x3f;
  261.   return True;
  262. }
  263.  
  264. typedef enum
  265. {
  266.   eImmNo,
  267.   eImmYes,
  268.   eImmAsAbs
  269. } tImmAllow;
  270.  
  271. #define FreeReg 0xff
  272. #define SPReg 0xfe
  273. #define PCReg 0xfd
  274.  
  275. typedef struct
  276. {
  277.   as_eval_cb_data_t cb_data;
  278.   Byte base_reg, ind_reg, scale_fact;
  279.   tSymbolSize base_reg_size, ind_reg_size;
  280. } tlcs9000_eval_cb_data_t;
  281.  
  282. DECLARE_AS_EVAL_CB(tlcs9000_eval_cb)
  283. {
  284.   tlcs9000_eval_cb_data_t *p_eval_cb_data = (tlcs9000_eval_cb_data_t*)p_data;
  285.   Byte this_reg;
  286.   tSymbolSize size;
  287.  
  288.   UNUSED(p_res);
  289.  
  290.   switch (DecodeReg(p_arg, &this_reg, &size, False))
  291.   {
  292.     case eIsReg:
  293.       break;
  294.     case eRegAbort:
  295.       return e_eval_fail;
  296.     default:
  297.       if (!as_strcasecmp(p_arg->str.p_str, "PC"))
  298.       {
  299.         this_reg = PCReg;
  300.         size = eSymbolSize32Bit;
  301.       }
  302.       else if (!as_strcasecmp(p_arg->str.p_str, "SP"))
  303.       {
  304.         this_reg = SPReg;
  305.         size = eSymbolSize32Bit;
  306.       }
  307.       else
  308.         return e_eval_none;
  309.   }
  310.  
  311.   if (size == eSymbolSize8Bit)
  312.   {
  313.     WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  314.     return e_eval_fail;
  315.   }
  316.  
  317.   /* I.4.c. Basisregister */
  318.  
  319.   if (as_eval_cb_data_stack_plain_add(p_data->p_stack))
  320.   {
  321.     if (p_eval_cb_data->base_reg == FreeReg)
  322.     {
  323.       p_eval_cb_data->base_reg = this_reg;
  324.       p_eval_cb_data->base_reg_size = size;
  325.     }
  326.     else if (p_eval_cb_data->ind_reg == FreeReg)
  327.     {
  328.       p_eval_cb_data->ind_reg = this_reg;
  329.       p_eval_cb_data->ind_reg_size = size;
  330.       p_eval_cb_data->scale_fact = 0;
  331.     }
  332.     else
  333.     {
  334.       WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  335.       return e_eval_fail;
  336.     }
  337.     as_tempres_set_int(p_res, 0);
  338.     return e_eval_ok;
  339.   }
  340.  
  341.   /* I.4.b. Indexregister mit Skalierung */
  342.  
  343.   else if (p_data->p_stack
  344.         && as_eval_cb_data_stackelem_mul(p_data->p_stack)
  345.         && as_eval_cb_data_stack_plain_add(p_data->p_stack->p_next))
  346.   {
  347.     if (!p_data->p_other_arg || (p_data->p_other_arg->Typ != TempInt))
  348.     {
  349.       WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  350.       return e_eval_fail;
  351.     }
  352.     for (p_eval_cb_data->scale_fact = 0;
  353.          p_eval_cb_data->scale_fact < 4;
  354.          p_eval_cb_data->scale_fact++)
  355.       if (p_data->p_other_arg->Contents.Int == 1 << p_eval_cb_data->scale_fact)
  356.         break;
  357.     if (p_eval_cb_data->scale_fact >= 4)
  358.     {
  359.       WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  360.       return e_eval_fail;
  361.     }
  362.     if (p_eval_cb_data->ind_reg == FreeReg)
  363.     {
  364.       p_eval_cb_data->ind_reg = this_reg;
  365.       p_eval_cb_data->ind_reg_size = size;
  366.     }
  367.     else
  368.     {
  369.       WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  370.       return e_eval_fail;
  371.     }
  372.     as_tempres_set_int(p_res, 0);
  373.     return e_eval_ok;
  374.   }
  375.   else
  376.   {
  377.     WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  378.     return e_eval_fail;
  379.   }
  380. }
  381.  
  382. static Boolean force_long_op(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
  383. {
  384.   UNUSED(pLVal);
  385.   if (!pRVal)
  386.     return False;
  387.  
  388.   /* clone value as-is */
  389.  
  390.   as_tempres_copy_value(pErg, pRVal);
  391.   pErg->Flags |= (pLVal->Flags & eSymbolFlags_Promotable) | eSymbolFlag_UserLong;
  392.   pErg->DataSize = pLVal->DataSize;
  393.   return True;
  394. }
  395.  
  396. /* NOTE: as unary operator, '>' binds stronger than as binary operator, similar
  397.    to '~' : */
  398.  
  399. static const as_operator_t tlcs9000_operators[] =
  400. {
  401.   { ">" ,1 , e_op_monadic, 1, { TempInt | (TempInt << 4), 0, 0, 0 }, force_long_op},
  402.   {NULL, 0 , e_op_monadic, 0, { 0, 0, 0, 0, 0 }, NULL}
  403. };
  404.  
  405. static void DecodeAdr(const tStrComp *pArg, Byte PrefInd, tImmAllow MayImm, Boolean MayReg)
  406. {
  407.   Byte Reg;
  408.   String AdrPartStr;
  409.   tStrComp AdrPart;
  410.   Boolean OK;
  411.   int ArgLen;
  412.   tSymbolSize Size;
  413.   tRegEvalResult RegEvalResult;
  414.  
  415.   AdrCnt = 0; AdrOK = False;
  416.   StrCompMkTemp(&AdrPart, AdrPartStr, sizeof(AdrPartStr));
  417.  
  418.    /* I. Speicheradresse */
  419.  
  420.   if (IsIndirect(pArg->str.p_str))
  421.   {
  422.     tStrComp Arg, TmpComp;
  423.     String Tmp;
  424.     tlcs9000_eval_cb_data_t eval_cb_data;
  425.     tEvalResult eval_result;
  426.     LongInt DispAcc;
  427.     Boolean force_prefix;
  428.  
  429.     StrCompMkTemp(&TmpComp, Tmp, sizeof(Tmp));
  430.  
  431.     /* I.1. vorkonditionieren */
  432.  
  433.     StrCompRefRight(&Arg, pArg, 1);
  434.     StrCompShorten(&Arg, 1);
  435.     KillPrefBlanksStrCompRef(&Arg);
  436.     KillPostBlanksStrComp(&Arg);
  437.  
  438.     /* I.2. Predekrement */
  439.  
  440.     if ((*Arg.str.p_str == '-') && (Arg.str.p_str[1] == '-'))
  441.     {
  442.       tStrComp RegComp;
  443.  
  444.       StrCompRefRight(&RegComp, &Arg, 2);
  445.       if (DecodeReg(&RegComp, &Reg, &Size, True) == eIsReg)
  446.       {
  447.         switch (Size)
  448.         {
  449.           case eSymbolSize16Bit:
  450.             AdrMode = 0x50 + (Reg & 15);
  451.             AdrOK = True;
  452.             break;
  453.           case eSymbolSize32Bit:
  454.             AdrMode = 0x71 + (Reg & 14);
  455.             AdrOK = True;
  456.             break;
  457.           default:
  458.             WrStrErrorPos(ErrNum_InvAddrMode, &Arg);
  459.             break;
  460.         }
  461.       }
  462.       return;
  463.     }
  464.  
  465.     /* I.3. Postinkrement */
  466.  
  467.     ArgLen = strlen(Arg.str.p_str);
  468.     if ((Arg.str.p_str[ArgLen - 1] == '+') && (Arg.str.p_str[ArgLen - 2] == '+'))
  469.     {
  470.       StrCompCopySub(&AdrPart, &Arg, 0, Arg.Pos.Len - 2);
  471.       if (DecodeReg(&AdrPart, &Reg, &Size, True) == eIsReg)
  472.       {
  473.         switch (Size)
  474.         {
  475.           case eSymbolSize16Bit:
  476.             AdrMode = 0x40 + (Reg & 15);
  477.             AdrOK = True;
  478.             break;
  479.           case eSymbolSize32Bit:
  480.             AdrMode = 0x70 + (Reg & 14);
  481.             AdrOK = True;
  482.             break;
  483.           default:
  484.             WrError(ErrNum_InvAddrMode);
  485.             break;
  486.         }
  487.         return;
  488.       }
  489.     }
  490.  
  491.     /* I.4. Adresskomponenten zerlegen */
  492.  
  493.     as_eval_cb_data_ini(&eval_cb_data.cb_data, tlcs9000_eval_cb);
  494.     eval_cb_data.cb_data.p_operators = tlcs9000_operators;
  495.     eval_cb_data.base_reg = eval_cb_data.ind_reg = FreeReg;
  496.     eval_cb_data.base_reg_size = eval_cb_data.ind_reg_size = eSymbolSizeUnknown;
  497.     eval_cb_data.scale_fact = 0;
  498.     DispAcc = AdrInc + EvalStrIntExprWithResultAndCallback(&Arg, Int32, &eval_result, &eval_cb_data.cb_data);
  499.     if (!eval_result.OK)
  500.       return;
  501.     force_prefix = !!(eval_result.Flags & eSymbolFlag_UserLong);
  502.  
  503.     /* I.5. Indexregister mit Skalierung 1 als Basis behandeln */
  504.  
  505.     if ((eval_cb_data.base_reg == FreeReg) && (eval_cb_data.ind_reg != FreeReg) && (eval_cb_data.scale_fact == 0))
  506.     {
  507.       eval_cb_data.base_reg = eval_cb_data.ind_reg;
  508.       eval_cb_data.base_reg_size = eval_cb_data.ind_reg_size;
  509.       eval_cb_data.ind_reg = FreeReg;
  510.     }
  511.  
  512.     /* I.6. absolut */
  513.  
  514.     if ((eval_cb_data.base_reg == FreeReg) && (eval_cb_data.ind_reg == FreeReg))
  515.     {
  516.       AdrMode = 0x20; /* 0x60 should be equivalent: adding 0 as RW0 or RD0 is irrelvant */
  517.       AdrVals[0] = 0xe000 + (DispAcc & 0x1fff); AdrCnt = 2;
  518.       AddAbsPrefix(PrefInd, 13, DispAcc, force_prefix);
  519.       AdrOK = True;
  520.       return;
  521.     }
  522.  
  523.     /* I.7. Basis [mit Displacement] */
  524.  
  525.     if ((eval_cb_data.base_reg != FreeReg) && (eval_cb_data.ind_reg == FreeReg))
  526.     {
  527.       /* I.7.a. Basis ohne Displacement */
  528.  
  529.       if (DispAcc == 0)
  530.       {
  531.         if (eval_cb_data.base_reg_size == eSymbolSize16Bit)
  532.           AdrMode = 0x10 + (eval_cb_data.base_reg & 15);
  533.         else
  534.           AdrMode = 0x61 + (eval_cb_data.base_reg & 14);
  535.         AdrOK = True;
  536.         return;
  537.       }
  538.  
  539.       /* I.7.b. Nullregister mit Displacement muss in Erweiterungswort */
  540.  
  541.       else if (eval_cb_data.base_reg == 0)
  542.       {
  543.         if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
  544.         else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
  545.         else
  546.         {
  547.           AdrMode = 0x20;
  548.           if (eval_cb_data.base_reg_size == eSymbolSize16Bit)
  549.             AdrVals[0] = ((Word)eval_cb_data.base_reg & 15) << 11;
  550.           else
  551.             AdrVals[0] = (((Word)eval_cb_data.base_reg & 14) << 11) + 0x8000;
  552.           AdrVals[0] += DispAcc & 0x1ff;
  553.           AdrCnt = 2;
  554.           AddSignedPrefix(PrefInd, 9, DispAcc, force_prefix);
  555.           AdrOK = True;
  556.         }
  557.         return;
  558.       }
  559.  
  560.       /* I.7.c. Stack mit Displacement: Optimierung moeglich */
  561.  
  562.       else if (eval_cb_data.base_reg == SPReg)
  563.       {
  564.         if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
  565.         else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
  566.         else if ((DispAcc >= 0) && (DispAcc <= 127))
  567.         {
  568.           AdrMode = 0x80 + (DispAcc & 0x7f);
  569.           AdrOK = True;
  570.         }
  571.         else
  572.         {
  573.           AdrMode = 0x20;
  574.           AdrVals[0] = 0xd000 + (DispAcc & 0x1ff); AdrCnt = 2;
  575.           AddSignedPrefix(PrefInd, 9, DispAcc, force_prefix);
  576.           AdrOK = True;
  577.         }
  578.         return;
  579.       }
  580.  
  581.       /* I.7.d. Programmzaehler mit Displacement: keine Optimierung */
  582.  
  583.       else if (eval_cb_data.base_reg == PCReg)
  584.       {
  585.         if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
  586.         else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
  587.         else
  588.         {
  589.           AdrMode = 0x20;
  590.           AdrVals[0] = 0xd800 + (DispAcc & 0x1ff);
  591.           AdrCnt = 2;
  592.           AddSignedPrefix(PrefInd, 9, DispAcc, force_prefix);
  593.           AdrOK = True;
  594.         }
  595.         return;
  596.       }
  597.  
  598.       /* I.7.e. einfaches Basisregister mit Displacement */
  599.  
  600.       else
  601.       {
  602.         if (DispAcc > 0x7fffff) WrError(ErrNum_OverRange);
  603.         else if (DispAcc < -0x800000) WrError(ErrNum_UnderRange);
  604.         else
  605.         {
  606.           if (eval_cb_data.base_reg_size == eSymbolSize16Bit)
  607.             AdrMode = 0x20 + (eval_cb_data.base_reg & 15);
  608.           else
  609.             AdrMode = 0x60 + (eval_cb_data.base_reg & 14);
  610.           AdrVals[0] = 0xe000 + (DispAcc & 0x1fff);
  611.           AdrCnt = 2;
  612.           AddSignedPrefix(PrefInd, 13, DispAcc, force_prefix);
  613.           AdrOK = True;
  614.         }
  615.         return;
  616.       }
  617.     }
  618.  
  619.     /* I.8. Index- [und Basisregister] */
  620.  
  621.     else
  622.     {
  623.       if (DispAcc > 0x7ffff) WrError(ErrNum_OverRange);
  624.       else if (DispAcc < -0x80000) WrError(ErrNum_UnderRange);
  625.       else if ((eval_cb_data.ind_reg & 15) == 0) WrError(ErrNum_InvAddrMode);
  626.       else
  627.       {
  628.         if (eval_cb_data.ind_reg_size == eSymbolSize16Bit)
  629.           AdrMode = 0x20 + (eval_cb_data.ind_reg & 15);
  630.         else
  631.           AdrMode = 0x60 + (eval_cb_data.ind_reg & 14);
  632.         switch (eval_cb_data.base_reg)
  633.         {
  634.           case FreeReg:
  635.             AdrVals[0] = 0xc000; break;
  636.           case SPReg:
  637.             AdrVals[0] = 0xd000; break;
  638.           case PCReg:
  639.             AdrVals[0] = 0xd800; break;
  640.           default:
  641.             if (eval_cb_data.base_reg_size == eSymbolSize16Bit)
  642.               AdrVals[0] = ((Word)eval_cb_data.base_reg & 15) << 11;
  643.             else
  644.               AdrVals[0] = 0x8000 + (((Word)eval_cb_data.base_reg & 14) << 10);
  645.         }
  646.         AdrVals[0] += (((Word)eval_cb_data.scale_fact) << 9) + (DispAcc & 0x1ff);
  647.         AdrCnt = 2;
  648.         AddSignedPrefix(PrefInd, 9, DispAcc, force_prefix);
  649.         AdrOK = True;
  650.       }
  651.       return;
  652.     }
  653.   }
  654.  
  655.   /* II. Arbeitsregister */
  656.  
  657.   else if ((RegEvalResult = DecodeReg(pArg, &Reg, &Size, False)) != eIsNoReg)
  658.   {
  659.     if (RegEvalResult == eRegAbort)
  660.       return;
  661.     if (!MayReg) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  662.     else
  663.     {
  664.       if (OpSize == eSymbolSizeUnknown)
  665.         OpSize = Size;
  666.       if (Size != OpSize) WrError(ErrNum_ConfOpSizes);
  667.       else
  668.       {
  669.         AdrMode = Reg & 15;
  670.         AdrOK = True;
  671.       }
  672.     }
  673.     return;
  674.   }
  675.  
  676.   /* III. Spezialregister */
  677.  
  678.   else if (DecodeSpecReg(pArg->str.p_str, &Reg))
  679.   {
  680.     if (!MayReg) WrError(ErrNum_InvAddrMode);
  681.     else
  682.     {
  683.       if (OpSize == -1)
  684.         OpSize=Reg >> 6;
  685.       if ((Reg >> 6) != OpSize) WrError(ErrNum_ConfOpSizes);
  686.       else
  687.       {
  688.         AdrMode = 0x30 + (Reg & 15);
  689.         AdrOK = True;
  690.       }
  691.     }
  692.     return;
  693.   }
  694.  
  695.   else switch (MayImm)
  696.   {
  697.     case eImmNo:
  698.       WrError(ErrNum_InvAddrMode);
  699.       break;
  700.     case eImmAsAbs:
  701.     {
  702.       Boolean ForcePrefix = False;
  703.       LongInt DispAcc = EvalStrIntExpressionOffs(pArg, CheckForcePrefix(pArg->str.p_str, &ForcePrefix), Int32, &AdrOK);
  704.  
  705.       if (AdrOK)
  706.       {
  707.         AdrMode = 0x20; /* 0x60 should be equivalent: adding 0 as RW0 or RD0 is irrelvant */
  708.         AdrVals[0] = 0xe000 + (DispAcc & 0x1fff); AdrCnt = 2;
  709.         AddAbsPrefix(PrefInd, 13, DispAcc, ForcePrefix);
  710.         AdrOK = True;
  711.       }
  712.       break;
  713.     }
  714.     case eImmYes:
  715.       if ((OpSize == -1) && (MinOneIs0))
  716.         OpSize = 0;
  717.       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  718.       else
  719.       {
  720.         AdrMode = 0x30;
  721.         switch (OpSize)
  722.         {
  723.           case 0:
  724.             AdrVals[0] = EvalStrIntExpression(pArg, Int8, &OK) & 0xff;
  725.             if (OK)
  726.             {
  727.               AdrCnt = 2;
  728.               AdrOK = True;
  729.             }
  730.             break;
  731.           case 1:
  732.             AdrVals[0] = EvalStrIntExpression(pArg, Int16, &OK);
  733.             if (OK)
  734.             {
  735.               AdrCnt = 2;
  736.               AdrOK = True;
  737.             }
  738.             break;
  739.           case 2:
  740.           {
  741.             LongInt DispAcc = EvalStrIntExpression(pArg, Int32, &OK);
  742.  
  743.             if (OK)
  744.             {
  745.               AdrVals[0] = DispAcc & 0xffff;
  746.               AdrVals[1] = DispAcc >> 16;
  747.               AdrCnt = 4;
  748.               AdrOK = True;
  749.             }
  750.             break;
  751.           }
  752.         }
  753.       }
  754.       break;
  755.   }
  756. }
  757.  
  758. static void CopyAdr(void)
  759. {
  760.   OpSize2 = OpSize;
  761.   AdrMode2 = AdrMode;
  762.   AdrCnt2 = AdrCnt;
  763.   memcpy(AdrVals2, AdrVals, AdrCnt);
  764. }
  765.  
  766. static Boolean IsReg(void)
  767. {
  768.   return (AdrMode <= 15);
  769. }
  770.  
  771. static Boolean Is2Reg(void)
  772. {
  773.   return (AdrMode2 <= 15);
  774. }
  775.  
  776. static Boolean IsImmediate(void)
  777. {
  778.   return (AdrMode == 0x30);
  779. }
  780.  
  781. static Boolean Is2Immediate(void)
  782. {
  783.   return (AdrMode2 == 0x30);
  784. }
  785.  
  786. static LongInt ImmVal(void)
  787. {
  788.   LongInt Tmp1;
  789.   Integer Tmp2;
  790.   ShortInt Tmp3;
  791.  
  792.   switch (OpSize)
  793.   {
  794.     case 0:
  795.       Tmp3 = AdrVals[0] & 0xff;
  796.       return Tmp3;
  797.     case 1:
  798.       Tmp2 = AdrVals[0];
  799.       return Tmp2;
  800.     case 2:
  801.       Tmp1 = (((LongInt)AdrVals[1]) << 16) + AdrVals[0];
  802.       return Tmp1;
  803.     default:
  804.       WrError(ErrNum_InternalError);
  805.       return 0;
  806.   }
  807. }
  808.  
  809. static LongInt ImmVal2(void)
  810. {
  811.   LongInt Tmp1;
  812.   Integer Tmp2;
  813.   ShortInt Tmp3;
  814.  
  815.   switch (OpSize)
  816.   {
  817.     case 0:
  818.       Tmp3 = AdrVals2[0] & 0xff;
  819.       return Tmp3;
  820.     case 1:
  821.       Tmp2 = AdrVals2[0];
  822.       return Tmp2;
  823.     case 2:
  824.       Tmp1 = (((LongInt)AdrVals2[1]) << 16) + AdrVals2[0];
  825.       return Tmp1;
  826.     default:
  827.       WrError(ErrNum_InternalError);
  828.       return 0;
  829.   }
  830. }
  831.  
  832. static Boolean IsAbsolute(void)
  833. {
  834.   return (((AdrMode == 0x20) || (AdrMode == 0x60))
  835.        && (AdrCnt == 2)
  836.        && ((AdrVals[0] & 0xe000) == 0xe000));
  837. }
  838.  
  839. static Boolean Is2Absolute(void)
  840. {
  841.   return (((AdrMode2 == 0x20) || (AdrMode2 == 0x60))
  842.        && (AdrCnt2 == 2)
  843.        && ((AdrVals2[0] & 0xe000) == 0xe000));
  844. }
  845.  
  846. static Boolean IsShort(void)
  847. {
  848.   if (AdrMode < 0x30)
  849.     return True;
  850.   else if (AdrMode == 0x30)
  851.   {
  852.     LongInt ImmValue = ImmVal();
  853.  
  854.     return ((ImmValue >= LowLim4) && (ImmValue <= 7));
  855.   }
  856.   else
  857.     return False;
  858. }
  859.  
  860. static Boolean Is2Short(void)
  861. {
  862.   if (AdrMode2 < 0x30)
  863.     return True;
  864.   else if (AdrMode2 == 0x30)
  865.   {
  866.     LongInt ImmValue = ImmVal2();
  867.  
  868.     return ((ImmValue >= LowLim4) && (ImmValue <= 7));
  869.   }
  870.   else
  871.     return False;
  872. }
  873.  
  874. static void ConvertShort(void)
  875. {
  876.   if (AdrMode == 0x30)
  877.   {
  878.     AdrMode += ImmVal() & 15;
  879.     AdrCnt = 0;
  880.   }
  881. }
  882.  
  883. static void Convert2Short(void)
  884. {
  885.   if (AdrMode2 == 0x30)
  886.   {
  887.     AdrMode2 += ImmVal2() & 15;
  888.     AdrCnt2 = 0;
  889.   }
  890. }
  891.  
  892. static void SetULowLims(void)
  893. {
  894.   LowLim4 = 0;
  895.   LowLim8 = 0;
  896. }
  897.  
  898. static void AddPrefixes(void)
  899. {
  900.   if (CodeLen != 0)
  901.   {
  902.     InsertSinglePrefix(1);
  903.     InsertSinglePrefix(0);
  904.   }
  905. }
  906.  
  907. static Boolean DecodeCondition(const char *pAsc, Word *pCondition)
  908. {
  909.   size_t z;
  910.  
  911.   for (z = 0; z < as_array_size(Conditions); z++)
  912.     if (!as_strcasecmp(pAsc, Conditions[z]))
  913.     {
  914.       *pCondition = z;
  915.       return True;
  916.     }
  917.   return False;
  918. }
  919.  
  920. static char DecideGA(void)
  921. {
  922.   if (((IsShort()) && (Is2Absolute()))
  923.    || ((Is2Short()) && (IsAbsolute())))
  924.     return 'A';
  925.   else
  926.     return 'G';
  927. }
  928.  
  929. /*--------------------------------------------------------------------------*/
  930.  
  931. static void DecodeFixed(Word Code)
  932. {
  933.   if (!ChkArgCnt(0, 0));
  934.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  935.   else
  936.   {
  937.     WAsmCode[0] = Code;
  938.     CodeLen = 2;
  939.   }
  940. }
  941.  
  942. static void DecodeRMW(Word Index)
  943. {
  944.   const RMWOrder *pOrder = RMWOrders + Index;
  945.  
  946.   if ((OpSize == -1) && (pOrder->Mask & 0x20))
  947.     OpSize = 2;
  948.   if (ChkArgCnt(1, 1))
  949.   {
  950.     tImmAllow AllowImm = (pOrder->Mask & 0x10) ? eImmNo : eImmYes;
  951.  
  952.     if (!IsIndirect(ArgStr[1].str.p_str) && (pOrder->Mask & 0x20))
  953.       AllowImm = eImmAsAbs;
  954.     DecodeAdr(&ArgStr[1], 0, AllowImm, !(pOrder->Mask & 0x20));
  955.     if (AdrOK)
  956.     {
  957.       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  958.       else if (!(pOrder->Mask & (1 << OpSize))) WrError(ErrNum_InvOpSize);
  959.       else
  960.       {
  961.         WAsmCode[0] = (((Word)OpSize + 1) << 14) + (((Word)pOrder->Code) << 8) + AdrMode;
  962.         memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  963.         CodeLen = 2 + AdrCnt;
  964.       }
  965.     }
  966.   }
  967. }
  968.  
  969. static void DecodeGASI1(Word Code)
  970. {
  971.   if (ChkArgCnt(2, 2))
  972.   {
  973.     DecodeAdr(&ArgStr[1], 1, eImmNo, True);
  974.     if (AdrOK)
  975.     {
  976.       CopyAdr();
  977.       DecodeAdr(&ArgStr[2], 0, eImmYes, True);
  978.       if (AdrOK)
  979.       {
  980.         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  981.         else
  982.         {
  983.           LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
  984.  
  985.           if (Format == ' ')
  986.           {
  987.             if (((IsReg()) && (Is2Short()))
  988.              || ((Is2Reg()) && (IsShort())))
  989.               Format = 'S';
  990.             else if ((IsImmediate()) && (OpSize > 0) && ((ImmValue > 127) || (ImmValue < -128)))
  991.               Format = 'I';
  992.             else
  993.               Format = DecideGA();
  994.           }
  995.           switch (Format)
  996.           {
  997.             case 'G':
  998.               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
  999.               if ((IsImmediate()) && (ImmValue <= 127) && (ImmValue >= -128))
  1000.               {
  1001.                 AdrMode = ImmValue & 0xff;
  1002.                 AdrCnt = 0;
  1003.               }
  1004.               else
  1005.                 WAsmCode[0] += 0x800;
  1006.               WAsmCode[0] += AdrMode;
  1007.               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1008.               WAsmCode[1 + (AdrCnt >> 1)] = 0x8400 + (Code << 8) + AdrMode2;
  1009.               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
  1010.               CodeLen = 4 + AdrCnt + AdrCnt2;
  1011.               break;
  1012.             case 'A':
  1013.               if ((IsShort()) && (Is2Absolute()))
  1014.               {
  1015.                 ConvertShort();
  1016.                 WAsmCode[0] = 0x3900
  1017.                             + (((Word)OpSize + 1) << 14)
  1018.                             + ((AdrMode & 0xf0) << 5)
  1019.                             + (AdrMode & 15);
  1020.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1021.                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
  1022.                 CodeLen = 4 + AdrCnt;
  1023.               }
  1024.               else if ((Is2Short()) && (IsAbsolute()))
  1025.               {
  1026.                 Convert2Short();
  1027.                 WAsmCode[0] = 0x3980
  1028.                             + (((Word)OpSize + 1) << 14)
  1029.                             + ((AdrMode2 & 0xf0) << 5)
  1030.                             + (AdrMode2 & 15);
  1031.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1032.                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
  1033.                 CodeLen = 4 + AdrCnt2;
  1034.               }
  1035.               else WrError(ErrNum_InvAddrMode);
  1036.               break;
  1037.             case 'S':
  1038.               if ((IsShort()) && (Is2Reg()))
  1039.               {
  1040.                 ConvertShort();
  1041.                 WAsmCode[0] = 0x0000
  1042.                             + (((Word)OpSize + 1) << 14)
  1043.                             + (AdrMode & 15)
  1044.                             + ((AdrMode & 0xf0) << 5)
  1045.                             + ((AdrMode2 & 1) << 12)
  1046.                             + ((AdrMode2 & 14) << 4)
  1047.                             + ((Code & 1) << 4)
  1048.                             + ((Code & 2) << 10);
  1049.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1050.                 CodeLen = 2 + AdrCnt;
  1051.               }
  1052.               else if ((Is2Short()) && (IsReg()))
  1053.               {
  1054.                 Convert2Short();
  1055.                 WAsmCode[0] = 0x0100
  1056.                             + (((Word)OpSize + 1) << 14)
  1057.                             + (AdrMode2 & 15)
  1058.                             + ((AdrMode2 & 0xf0) << 5)
  1059.                             + ((AdrMode & 1) << 12)
  1060.                             + ((AdrMode & 14) << 4)
  1061.                             + ((Code & 1) << 4)
  1062.                             + ((Code & 2) << 11);
  1063.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1064.                 CodeLen = 2 + AdrCnt2;
  1065.               }
  1066.               else WrError(ErrNum_InvAddrMode);
  1067.               break;
  1068.             case 'I':
  1069.               if ((!IsImmediate()) || (OpSize == 0)) WrError(ErrNum_InvAddrMode);
  1070.               else
  1071.               {
  1072.                 WAsmCode[0] = AdrMode2 + (((Word)OpSize-1) << 11) + (Code << 8);
  1073.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1074.                 memcpy(WAsmCode + 1 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
  1075.                 CodeLen = 2 + AdrCnt + AdrCnt2;
  1076.               }
  1077.               break;
  1078.             default:
  1079.                WrError(ErrNum_InvFormat);
  1080.           }
  1081.         }
  1082.       }
  1083.     }
  1084.   }
  1085. }
  1086.  
  1087. static void DecodeGASI2(Word Code)
  1088. {
  1089.   if (ChkArgCnt(2, 2))
  1090.   {
  1091.     DecodeAdr(&ArgStr[1], 1, eImmNo, True);
  1092.     if (AdrOK)
  1093.     {
  1094.       CopyAdr();
  1095.       DecodeAdr(&ArgStr[2], 0, eImmYes, True);
  1096.       if (AdrOK)
  1097.       {
  1098.         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1099.         else
  1100.         {
  1101.           LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
  1102.  
  1103.           if (Format == ' ')
  1104.           {
  1105.             if ((IsReg()) && (Is2Reg()))
  1106.               Format = 'S';
  1107.             else if ((IsImmediate()) && (OpSize > 0) && ((ImmValue > 127) || (ImmValue < -128)))
  1108.               Format = 'I';
  1109.             else
  1110.               Format = DecideGA();
  1111.           }
  1112.           switch (Format)
  1113.           {
  1114.             case 'G':
  1115.               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
  1116.               if ((IsImmediate()) && (ImmValue <= 127) && (ImmValue >= -128))
  1117.               {
  1118.                 AdrMode = ImmValue & 0xff;
  1119.                 AdrCnt = 0;
  1120.               }
  1121.               else
  1122.                 WAsmCode[0] += 0x800;
  1123.               WAsmCode[0] += AdrMode;
  1124.               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1125.               WAsmCode[1 + (AdrCnt >> 1)] = 0xc400 + (Code << 8) + AdrMode2;
  1126.               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
  1127.               CodeLen = 4 + AdrCnt + AdrCnt2;
  1128.               break;
  1129.             case 'A':
  1130.               if ((IsShort()) && (Is2Absolute()))
  1131.               {
  1132.                 ConvertShort();
  1133.                 WAsmCode[0] = 0x3940
  1134.                             + (((Word)OpSize+1) << 14)
  1135.                             + ((AdrMode & 0xf0) << 5)
  1136.                             + (AdrMode & 15);
  1137.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1138.                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
  1139.                 CodeLen = 4 + AdrCnt;
  1140.               }
  1141.               else if ((Is2Short()) && (IsAbsolute()))
  1142.               {
  1143.                 Convert2Short();
  1144.                 WAsmCode[0] = 0x39c0
  1145.                             + (((Word)OpSize+1) << 14)
  1146.                             + ((AdrMode2 & 0xf0) << 5)
  1147.                             + (AdrMode2 & 15);
  1148.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1149.                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
  1150.                 CodeLen = 4 + AdrCnt2;
  1151.               }
  1152.               else WrError(ErrNum_InvAddrMode);
  1153.               break;
  1154.             case 'S':
  1155.               if ((IsReg()) && (Is2Reg()))
  1156.               {
  1157.                 WAsmCode[0] = 0x3800
  1158.                             + (((Word)OpSize+1) << 14)
  1159.                             + (AdrMode & 15)
  1160.                             + (AdrMode2 << 4)
  1161.                             + (Code << 9);
  1162.                 CodeLen = 2;
  1163.               }
  1164.               else WrError(ErrNum_InvAddrMode);
  1165.               break;
  1166.             case 'I':
  1167.               if ((!IsImmediate()) || (OpSize == 0)) WrError(ErrNum_InvAddrMode);
  1168.               else
  1169.               {
  1170.                 WAsmCode[0] = 0x400 + AdrMode2 + (((Word)OpSize-1) << 11) + (Code << 8);
  1171.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1172.                 memcpy(WAsmCode + 1 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
  1173.                 CodeLen = 2 + AdrCnt + AdrCnt2;
  1174.               }
  1175.               break;
  1176.             default:
  1177.               WrError(ErrNum_InvFormat);
  1178.           }
  1179.         }
  1180.       }
  1181.     }
  1182.   }
  1183. }
  1184.  
  1185. static void DecodeTrinom(Word Code)
  1186. {
  1187.   int Cnt;
  1188.   Byte Reg;
  1189.  
  1190.   if (Code == 2) /* MAC */
  1191.     LowLim8 = 0;
  1192.   if (!ChkArgCnt(3, 3));
  1193.   else if (DecodeRegAdr(&ArgStr[1], &Reg))
  1194.   {
  1195.     if (Code >= 2)
  1196.       OpSize--;
  1197.     if (OpSize < 0) WrError(ErrNum_InvOpSize);
  1198.     else
  1199.     {
  1200.       DecodeAdr(&ArgStr[3], 0, eImmYes, True);
  1201.       if (AdrOK)
  1202.       {
  1203.         LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
  1204.  
  1205.         WAsmCode[0] = 0x700;
  1206.         if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
  1207.         {
  1208.           AdrMode = ImmValue & 0xff;
  1209.           AdrCnt = 0;
  1210.         }
  1211.         else
  1212.           WAsmCode[0] += 0x800;
  1213.         WAsmCode[0] += (((Word)OpSize + 1) << 14) + AdrMode;
  1214.         memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1215.         Cnt = AdrCnt;
  1216.         DecodeAdr(&ArgStr[2], 1, eImmNo, True);
  1217.         if (AdrOK)
  1218.         {
  1219.           WAsmCode[1 + (Cnt >> 1)] = AdrMode + (Code << 8) + (((Word)Reg) << 11);
  1220.           memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
  1221.           CodeLen = 4 + Cnt + AdrCnt;
  1222.         }
  1223.       }
  1224.     }
  1225.   }
  1226. }
  1227.  
  1228. static void DecodeRLM_RRM(Word Code)
  1229. {
  1230.   int Cnt;
  1231.   Byte Reg;
  1232.   tSymbolSize Size;
  1233.  
  1234.   if (!ChkArgCnt(3, 3));
  1235.   else if (!DecodeReg(&ArgStr[2], &Reg, &Size, True));
  1236.   else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]);
  1237.   else
  1238.   {
  1239.     Reg &= 0x3f;
  1240.     DecodeAdr(&ArgStr[3], 0, eImmYes, True);
  1241.     if (AdrOK)
  1242.     {
  1243.       LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
  1244.  
  1245.       WAsmCode[0] = 0x700;
  1246.       if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > -128))
  1247.       {
  1248.         AdrMode = ImmValue & 0xff; AdrCnt = 0;
  1249.       }
  1250.       else
  1251.         WAsmCode[0] += 0x800;
  1252.       WAsmCode[0] += AdrMode;
  1253.       memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1254.       Cnt = AdrCnt;
  1255.       DecodeAdr(&ArgStr[1], 1, eImmNo, True);
  1256.       if (AdrOK)
  1257.       {
  1258.         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1259.         else
  1260.         {
  1261.           WAsmCode[0] += ((Word)OpSize + 1) << 14;
  1262.           WAsmCode[1 + (Cnt >> 1)] = Code + (((Word)Reg) << 11)+AdrMode;
  1263.           memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
  1264.           CodeLen = 4 + AdrCnt + Cnt;
  1265.         }
  1266.       }
  1267.     }
  1268.   }
  1269. }
  1270.  
  1271. static void DecodeBit(Word Code)
  1272. {
  1273.   if (ChkArgCnt(2, 2))
  1274.   {
  1275.     DecodeAdr(&ArgStr[1], 1, eImmNo, True);
  1276.     if (AdrOK)
  1277.     {
  1278.       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1279.       else
  1280.       {
  1281.         CopyAdr();
  1282.         OpSize = -1;
  1283.         MinOneIs0 = True;
  1284.         DecodeAdr(&ArgStr[2], 0, eImmYes, True);
  1285.         if (AdrOK)
  1286.         {
  1287.           LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
  1288.  
  1289.           OpSize = OpSize2;
  1290.           if (Format==' ')
  1291.           {
  1292.             if ((Is2Reg()) && (IsImmediate())
  1293.              && (ImmValue > 0)
  1294.              && (ImmValue < (1 << (OpSize + 3))))
  1295.               Format = 'S';
  1296.             else
  1297.               Format = DecideGA();
  1298.           }
  1299.           switch (Format)
  1300.           {
  1301.             case 'G':
  1302.               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
  1303.               if ((IsImmediate()) && (ImmValue >= LowLim8) && (ImmValue < 127))
  1304.               {
  1305.                 AdrMode = ImmValue & 0xff;
  1306.                 AdrCnt = 0;
  1307.               }
  1308.               else
  1309.                 WAsmCode[0] += 0x800;
  1310.               WAsmCode[0] += AdrMode;
  1311.               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1312.               WAsmCode[1 + (AdrCnt >> 1)] = 0xd400 + (Code << 8) + AdrMode2;
  1313.               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
  1314.               CodeLen = 4 + AdrCnt + AdrCnt2;
  1315.               break;
  1316.             case 'A':
  1317.               if ((IsAbsolute()) && (Is2Short()))
  1318.               {
  1319.                 Convert2Short();
  1320.                 WAsmCode[0] = 0x39d0
  1321.                             + (((Word)OpSize+1) << 14)
  1322.                             + ((AdrMode2 & 0xf0) << 5)
  1323.                             + (AdrMode2 & 15);
  1324.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1325.                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
  1326.                 CodeLen = 4 + AdrCnt2;
  1327.               }
  1328.               else if ((Is2Absolute()) && (IsShort()))
  1329.               {
  1330.                 ConvertShort();
  1331.                 WAsmCode[0] = 0x3950
  1332.                             + (((Word)OpSize+1) << 14)
  1333.                             + ((AdrMode & 0xf0) << 5)
  1334.                             + (AdrMode & 15);
  1335.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1336.                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff) + (Code << 13);
  1337.                 CodeLen = 4 + AdrCnt;
  1338.               }
  1339.               else WrError(ErrNum_InvAddrMode);
  1340.               break;
  1341.             case 'S':
  1342.               if ((Is2Reg())
  1343.                && (IsImmediate())
  1344.                && (ImmVal() >= 0)
  1345.                && (ImmVal() < (1 << (3 + OpSize))))
  1346.               {
  1347.                 if (OpSize == 2)
  1348.                 {
  1349.                   if (ImmVal() >= 16)
  1350.                   {
  1351.                     AdrVals[0] -= 16;
  1352.                     AdrMode2++;
  1353.                   }
  1354.                   OpSize = 1;
  1355.                 }
  1356.                 if (OpSize == 1)
  1357.                 {
  1358.                   if (ImmVal() < 8)
  1359.                     OpSize=0;
  1360.                   else
  1361.                     AdrVals[0] -= 8;
  1362.                 }
  1363.                 WAsmCode[0] = 0x1700
  1364.                             + (((Word)OpSize + 1) << 14)
  1365.                             + ((Code & 1) << 7)
  1366.                             + ((Code & 2) << 10)
  1367.                             + (ImmVal() << 4)
  1368.                             + AdrMode2;
  1369.                 CodeLen = 2;
  1370.               }
  1371.               else WrError(ErrNum_InvAddrMode);
  1372.               break;
  1373.             default:
  1374.               WrError(ErrNum_InvFormat);
  1375.           }
  1376.         }
  1377.       }
  1378.     }
  1379.   }
  1380. }
  1381.  
  1382. static void DecodeShift(Word Code)
  1383. {
  1384.   if (ChkArgCnt(2, 2))
  1385.   {
  1386.     DecodeAdr(&ArgStr[1], 1, eImmNo, True);
  1387.     if (AdrOK)
  1388.     {
  1389.       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1390.       else
  1391.       {
  1392.         CopyAdr();
  1393.         OpSize = -1;
  1394.         MinOneIs0 = True;
  1395.         DecodeAdr(&ArgStr[2], 0, eImmYes, True);
  1396.         if (AdrOK)
  1397.         {
  1398.           LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
  1399.  
  1400.           OpSize = OpSize2;
  1401.           if (Format==' ')
  1402.           {
  1403.             if ((IsImmediate()) && (ImmValue == 1))
  1404.               Format = 'S';
  1405.             else
  1406.               Format = DecideGA();
  1407.           }
  1408.           switch (Format)
  1409.           {
  1410.             case 'G':
  1411.               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
  1412.               if ((IsImmediate()) && (ImmValue >= LowLim8) && (ImmVal() < 127))
  1413.               {
  1414.                 AdrMode = ImmValue & 0xff;
  1415.                 AdrCnt = 0;
  1416.               }
  1417.               else
  1418.                 WAsmCode[0] += 0x800;
  1419.               WAsmCode[0] += AdrMode;
  1420.               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1421.               WAsmCode[1 + (AdrCnt >> 1)] = 0xb400
  1422.                                           + ((Code & 3) << 8)
  1423.                                           + ((Code & 4) << 9)
  1424.                                           + AdrMode2;
  1425.               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
  1426.               CodeLen = 4 + AdrCnt + AdrCnt2;
  1427.               break;
  1428.             case 'A':
  1429.               if ((IsAbsolute()) && (Is2Short()))
  1430.               {
  1431.                 Convert2Short();
  1432.                 WAsmCode[0] = 0x39b0
  1433.                             + (((Word)OpSize+1) << 14)
  1434.                             + ((AdrMode2 & 0xf0) << 5)
  1435.                             + (AdrMode2 & 15);
  1436.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1437.                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff) + (Code << 13);
  1438.                 CodeLen = 4 + AdrCnt2;
  1439.               }
  1440.               else if ((Is2Absolute()) && (IsShort()))
  1441.               {
  1442.                 ConvertShort();
  1443.                 WAsmCode[0] = 0x3930
  1444.                             + (((Word)OpSize+1) << 14)
  1445.                             + ((AdrMode & 0xf0) << 5)
  1446.                             + (AdrMode & 15);
  1447.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1448.                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)+ (Code << 13);
  1449.                 CodeLen = 4 + AdrCnt;
  1450.               }
  1451.               else WrError(ErrNum_InvAddrMode);
  1452.               break;
  1453.             case 'S':
  1454.               if ((IsImmediate()) && (ImmValue == 1))
  1455.               {
  1456.                 WAsmCode[0] = 0x2400
  1457.                             + (((Word)OpSize+1) << 14)
  1458.                             + AdrMode2
  1459.                             + ((Code & 3) << 8)
  1460.                             + ((Code & 4) << 9);
  1461.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1462.                 CodeLen =2 + AdrCnt2;
  1463.               }
  1464.               else WrError(ErrNum_InvAddrMode);
  1465.               break;
  1466.             default:
  1467.               WrError(ErrNum_InvFormat);
  1468.           }
  1469.         }
  1470.       }
  1471.     }
  1472.   }
  1473. }
  1474.  
  1475. static void DecodeBField(Word Code)
  1476. {
  1477.   Byte Reg, Num1, Num2;
  1478.   Boolean OK;
  1479.   tSymbolFlags Flags;
  1480.   tSymbolSize Size;
  1481.  
  1482.   if (ChkArgCnt(4, 4))
  1483.   {
  1484.     tStrComp *pArg1 = (Code == 2) ? &ArgStr[2] : &ArgStr[1],
  1485.              *pArg2 = (Code == 2) ? &ArgStr[1] : &ArgStr[2];
  1486.  
  1487.     if (!DecodeReg(pArg1, &Reg, &Size, True));
  1488.     else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, pArg1);
  1489.     else
  1490.     {
  1491.       Reg &= 0x3f;
  1492.       Num2 = EvalStrIntExpressionWithFlags(&ArgStr[4], Int5, &OK, &Flags);
  1493.       if (OK)
  1494.       {
  1495.         if (mFirstPassUnknown(Flags))
  1496.           Num2 &= 15;
  1497.         Num2--;
  1498.         if (Num2 > 15) WrError(ErrNum_OverRange);
  1499.         else if ((OpSize == -1) && (!DecodeRegAdr(pArg2, &Num1)));
  1500.         else
  1501.         {
  1502.           switch (OpSize)
  1503.           {
  1504.             case 0: Num1 = EvalStrIntExpression(&ArgStr[3], UInt3, &OK) & 7; break;
  1505.             case 1: Num1 = EvalStrIntExpression(&ArgStr[3], Int4, &OK) & 15; break;
  1506.             case 2: Num1 = EvalStrIntExpression(&ArgStr[3], Int5, &OK) & 31; break;
  1507.             default: abort();
  1508.           }
  1509.           if (OK)
  1510.           {
  1511.             if ((OpSize == 2) && (Num1 > 15))
  1512.               AdrInc = 2;
  1513.             DecodeAdr(pArg2, 1, eImmNo, True);
  1514.             if (AdrOK)
  1515.             {
  1516.               if ((OpSize == 2) && (Num1 > 15))
  1517.               {
  1518.                 Num1 -= 16;
  1519.                 OpSize--;
  1520.                 if (!(AdrMode & 0xf0))
  1521.                   AdrMode++;
  1522.               }
  1523.               WAsmCode[0] = 0x7000 + (((Word)OpSize + 1) << 8) + AdrMode;
  1524.               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1525.               WAsmCode[1 + (AdrCnt >> 1)] = (((Word)Reg) << 11)
  1526.                                           + Num2
  1527.                                           + (((Word)Num1) << 5)
  1528.                                           + ((Code & 1) << 10)
  1529.                                           + ((Code & 2) << 14);
  1530.               CodeLen = 4 + AdrCnt;
  1531.             }
  1532.           }
  1533.         }
  1534.       }
  1535.     }
  1536.   }
  1537. }
  1538.  
  1539. static void DecodeGAEq(Word Code)
  1540. {
  1541.   if (Hi(Code))
  1542.     SetULowLims();
  1543.   if (ChkArgCnt(2, 2))
  1544.   {
  1545.     DecodeAdr(&ArgStr[1], 1, eImmNo, True);
  1546.     if (AdrOK)
  1547.     {
  1548.       CopyAdr();
  1549.       DecodeAdr(&ArgStr[2], 0, eImmYes, True);
  1550.       if (AdrOK)
  1551.       {
  1552.         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1553.         else
  1554.         {
  1555.           if (OpSize == 0)
  1556.             LowLim8 = -128;
  1557.           if (Format == ' ')
  1558.             Format = DecideGA();
  1559.           switch (Format)
  1560.           {
  1561.             case 'G':
  1562.             {
  1563.               LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
  1564.  
  1565.               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
  1566.               if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
  1567.               {
  1568.                 AdrMode = ImmValue & 0xff;
  1569.                 AdrCnt = 0;
  1570.               }
  1571.               else
  1572.                 WAsmCode[0] += 0x800;
  1573.               WAsmCode[0] += AdrMode;
  1574.               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1575.               WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
  1576.                                           + AdrMode2
  1577.                                           + ((Code & 0xf0) << 8)
  1578.                                           + ((Code & 4) << 9)
  1579.                                           + ((Code & 3) << 8);
  1580.               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
  1581.               CodeLen = 4 + AdrCnt + AdrCnt2;
  1582.               break;
  1583.             }
  1584.             case 'A':
  1585.               if ((IsAbsolute()) && (Is2Short()))
  1586.               {
  1587.                 Convert2Short();
  1588.                 WAsmCode[0] = 0x3980
  1589.                             + (((Word)OpSize + 1) << 14)
  1590.                             + ((AdrMode2 & 0xf0) << 5)
  1591.                             + (AdrMode2 & 15)
  1592.                             + (Code & 0xf0);
  1593.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1594.                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
  1595.                                              + ((Code & 15) << 13);
  1596.                 CodeLen = 4 + AdrCnt2;
  1597.               }
  1598.               else if ((Is2Absolute()) && (IsShort()))
  1599.               {
  1600.                 ConvertShort();
  1601.                 WAsmCode[0] = 0x3900
  1602.                             + (((Word)OpSize + 1) << 14)
  1603.                             + ((AdrMode & 0xf0) << 5)
  1604.                             + (AdrMode & 15)
  1605.                             + (Code & 0xf0);
  1606.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1607.                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
  1608.                                             + ((Code & 15) << 13);
  1609.                 CodeLen = 4 + AdrCnt;
  1610.               }
  1611.               else WrError(ErrNum_InvAddrMode);
  1612.               break;
  1613.             default:
  1614.               WrError(ErrNum_InvFormat);
  1615.           }
  1616.         }
  1617.       }
  1618.     }
  1619.   }
  1620. }
  1621.  
  1622. static void DecodeGAHalf(Word Code)
  1623. {
  1624.   if (ChkArgCnt(2, 2))
  1625.   {
  1626.     DecodeAdr(&ArgStr[1], 1, eImmNo, True);
  1627.     if (AdrOK)
  1628.     {
  1629.       if (OpSize == 0) WrError(ErrNum_InvOpSize);
  1630.       else
  1631.       {
  1632.         if (OpSize != -1)
  1633.           OpSize--;
  1634.         CopyAdr();
  1635.         DecodeAdr(&ArgStr[2], 0, eImmYes, True);
  1636.         if (AdrOK)
  1637.         {
  1638.           if (OpSize == 2) WrError(ErrNum_InvOpSize);
  1639.           else if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1640.           else
  1641.           {
  1642.             if (Format == ' ')
  1643.               Format = DecideGA();
  1644.             switch (Format)
  1645.             {
  1646.               case 'G':
  1647.               {
  1648.                 LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
  1649.  
  1650.                 WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
  1651.                 if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
  1652.                 {
  1653.                   AdrMode = ImmValue & 0xff;
  1654.                   AdrCnt = 0;
  1655.                 }
  1656.                 else
  1657.                   WAsmCode[0] += 0x800;
  1658.                 WAsmCode[0] += AdrMode;
  1659.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1660.                 WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
  1661.                                             + AdrMode2
  1662.                                             + ((Code & 0xf0) << 8)
  1663.                                             + ((Code & 4) << 9)
  1664.                                             + ((Code & 3) << 8);
  1665.                 memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
  1666.                 CodeLen = 4 + AdrCnt + AdrCnt2;
  1667.                 break;
  1668.               }
  1669.               case 'A':
  1670.                 if ((IsAbsolute()) && (Is2Short()))
  1671.                 {
  1672.                   Convert2Short();
  1673.                   WAsmCode[0] = 0x3980
  1674.                               + (((Word)OpSize + 1) << 14)
  1675.                               + ((AdrMode2 & 0xf0) << 5)
  1676.                               + (AdrMode2 & 15)
  1677.                               + (Code & 0xf0);
  1678.                   memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1679.                   WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
  1680.                                                + ((Code & 15) << 13);
  1681.                   CodeLen = 4 + AdrCnt2;
  1682.                 }
  1683.                 else if ((Is2Absolute()) && (IsShort()))
  1684.                 {
  1685.                   ConvertShort();
  1686.                   WAsmCode[0] = 0x3900
  1687.                               + (((Word)OpSize + 1) << 14)
  1688.                               + ((AdrMode & 0xf0) << 5)
  1689.                               + (AdrMode & 15)
  1690.                               + (Code & 0xf0);
  1691.                   memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1692.                   WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
  1693.                                               + ((Code & 15) << 13);
  1694.                   CodeLen = 4 + AdrCnt;
  1695.                 }
  1696.                 else WrError(ErrNum_InvAddrMode);
  1697.                 break;
  1698.               default:
  1699.                 WrError(ErrNum_InvFormat);
  1700.             }
  1701.           }
  1702.         }
  1703.       }
  1704.     }
  1705.   }
  1706. }
  1707.  
  1708. static void DecodeGAFirst(Word Code)
  1709. {
  1710.   if (ChkArgCnt(2, 2))
  1711.   {
  1712.     DecodeAdr(&ArgStr[1], 1, (Memo("STCF") || Memo("TSET")) ? eImmNo : eImmYes, True);
  1713.     if (AdrOK)
  1714.     {
  1715.       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1716.       else
  1717.       {
  1718.         CopyAdr();
  1719.         OpSize = -1;
  1720.         MinOneIs0 = True;
  1721.         DecodeAdr(&ArgStr[2], 0, eImmYes, True);
  1722.         OpSize = OpSize2;
  1723.         if (AdrOK)
  1724.         {
  1725.           if (Format == ' ')
  1726.             Format = DecideGA();
  1727.           switch (Format)
  1728.           {
  1729.             case 'G':
  1730.             {
  1731.               LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
  1732.  
  1733.               WAsmCode[0] = 0x700
  1734.                           + (((Word)OpSize + 1) << 14);
  1735.               if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
  1736.               {
  1737.                 AdrMode = ImmValue & 0xff;
  1738.                 AdrCnt = 0;
  1739.               }
  1740.               else WAsmCode[0] += 0x800;
  1741.               WAsmCode[0] += AdrMode;
  1742.               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1743.               WAsmCode[1 + (AdrCnt >> 1)] = 0x8400
  1744.                                           + AdrMode2
  1745.                                           + ((Code & 0xf0) << 8)
  1746.                                           + ((Code & 4) << 9)
  1747.                                           + ((Code & 3) << 8);
  1748.               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
  1749.               CodeLen = 4 + AdrCnt + AdrCnt2;
  1750.               break;
  1751.             }
  1752.             case 'A':
  1753.               if ((IsAbsolute()) && (Is2Short()))
  1754.               {
  1755.                 Convert2Short();
  1756.                 WAsmCode[0] = 0x3980
  1757.                             + (((Word)OpSize + 1) << 14)
  1758.                             + ((AdrMode2 & 0xf0) << 5)
  1759.                             + (AdrMode2 & 15)
  1760.                             + (Code & 0xf0);
  1761.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1762.                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
  1763.                                              + ((Code & 15) << 13);
  1764.                 CodeLen = 4 + AdrCnt2;
  1765.               }
  1766.               else if ((Is2Absolute()) && (IsShort()))
  1767.               {
  1768.                 ConvertShort();
  1769.                 WAsmCode[0] = 0x3900
  1770.                             + (((Word)OpSize + 1) << 14)
  1771.                             + ((AdrMode & 0xf0) << 5)
  1772.                             + (AdrMode & 15)
  1773.                             + (Code & 0xf0);
  1774.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1775.                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
  1776.                                             + ((Code & 15) << 13);
  1777.                 CodeLen = 4 + AdrCnt;
  1778.               }
  1779.               else WrError(ErrNum_InvAddrMode);
  1780.               break;
  1781.             default:
  1782.               WrError(ErrNum_InvFormat);
  1783.           }
  1784.         }
  1785.       }
  1786.     }
  1787.   }
  1788. }
  1789.  
  1790. static void DecodeGASecond(Word Code)
  1791. {
  1792.   if (ChkArgCnt(2, 2))
  1793.   {
  1794.     DecodeAdr(&ArgStr[2], 0, eImmYes, True);
  1795.     if (AdrOK)
  1796.     {
  1797.       if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1798.       else
  1799.       {
  1800.         CopyAdr();
  1801.         OpSize = -1;
  1802.         DecodeAdr(&ArgStr[1], 1, eImmNo, True);
  1803.         OpSize = OpSize2;
  1804.         if (AdrOK)
  1805.         {
  1806.           if (Format == ' ')
  1807.             Format = DecideGA();
  1808.           switch (Format)
  1809.           {
  1810.             case 'G':
  1811.               WAsmCode[0] = 0x700 + (((Word)OpSize + 1) << 14);
  1812.               if ((Is2Immediate()) && (ImmVal2() < 127) && (ImmVal2() > LowLim8))
  1813.               {
  1814.                 AdrMode2 = ImmVal2() & 0xff;
  1815.                 AdrCnt = 0;
  1816.               }
  1817.               else
  1818.                 WAsmCode[0] += 0x800;
  1819.               WAsmCode[0] += AdrMode2;
  1820.               memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1821.               WAsmCode[1 + (AdrCnt2 >> 1)] = 0x8400
  1822.                                            + AdrMode
  1823.                                            + ((Code & 0xf0) << 8)
  1824.                                            + ((Code & 4) << 9)
  1825.                                            + ((Code & 3) << 8);
  1826.               memcpy(WAsmCode + 2 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
  1827.               CodeLen = 4 + AdrCnt + AdrCnt2;
  1828.               break;
  1829.             case 'A':
  1830.               if ((IsAbsolute()) && (Is2Short()))
  1831.               {
  1832.                 Convert2Short();
  1833.                 WAsmCode[0] = 0x3900
  1834.                             + (((Word)OpSize + 1) << 14)
  1835.                             + ((AdrMode2 & 0xf0) << 5)
  1836.                             + (AdrMode2 & 15)
  1837.                             + (Code & 0xf0);
  1838.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1839.                 WAsmCode[1 + (AdrCnt2 >> 1)] = (AdrVals[0] & 0x1fff)
  1840.                                              + ((Code & 15) << 13);
  1841.                 CodeLen = 4 + AdrCnt2;
  1842.               }
  1843.               else if ((Is2Absolute()) && (IsShort()))
  1844.               {
  1845.                 ConvertShort();
  1846.                 WAsmCode[0] = 0x3980 + (((Word)OpSize + 1) << 14)
  1847.                                      + ((AdrMode & 0xf0) << 5)
  1848.                                      + (AdrMode & 15)
  1849.                                      + (Code & 0xf0);
  1850.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1851.                 WAsmCode[1 + (AdrCnt >> 1)] = (AdrVals2[0] & 0x1fff)
  1852.                                             + ((Code & 15) << 13);
  1853.                 CodeLen = 4 + AdrCnt;
  1854.               }
  1855.               else WrError(ErrNum_InvAddrMode);
  1856.               break;
  1857.             default:
  1858.               WrError(ErrNum_InvFormat);
  1859.           }
  1860.         }
  1861.       }
  1862.     }
  1863.   }
  1864. }
  1865.  
  1866. static void DecodeCHK_CHKS(Word IsSigned)
  1867. {
  1868.   if (!IsSigned)
  1869.     SetULowLims();
  1870.   if (ChkArgCnt(2, 2))
  1871.   {
  1872.     DecodeAdr(&ArgStr[2], 1, eImmNo, True);
  1873.     if (AdrOK)
  1874.     {
  1875.       if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
  1876.       else if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1877.       else
  1878.       {
  1879.         CopyAdr();
  1880.         DecodeAdr(&ArgStr[1], 0, eImmNo, False);
  1881.         if (AdrOK)
  1882.         {
  1883.           if (OpSize == 0)
  1884.             LowLim8 = -128;
  1885.           if (Format == ' ')
  1886.             Format = DecideGA();
  1887.           switch (Format)
  1888.           {
  1889.             case 'G':
  1890.               WAsmCode[0] = 0xf00 + (((Word)OpSize + 1) << 14) + AdrMode2;
  1891.               memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1892.               WAsmCode[1 + (AdrCnt2 >> 1)] = 0xa600 + AdrMode
  1893.                                            + (IsSigned << 8);
  1894.               memcpy(WAsmCode + 2 + (AdrCnt2 >> 1), AdrVals, AdrCnt);
  1895.               CodeLen = 4 + AdrCnt + AdrCnt2;
  1896.               break;
  1897.             case 'A':
  1898.               if ((IsAbsolute()) && (Is2Short()))
  1899.               {
  1900.                 Convert2Short();
  1901.                 WAsmCode[0] = 0x3920
  1902.                             + (((Word)OpSize + 1) << 14)
  1903.                             + ((AdrMode2 & 0xf0) << 5)
  1904.                             + (AdrMode2 & 15);
  1905.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  1906.                 WAsmCode[1 + (AdrCnt2 >> 1)] = 0x4000
  1907.                                              + (AdrVals[0] & 0x1fff)
  1908.                                              + (IsSigned << 13);
  1909.                 CodeLen = 4 + AdrCnt2;
  1910.               }
  1911.               else if ((Is2Absolute()) && (IsShort()))
  1912.               {
  1913.                 ConvertShort();
  1914.                 WAsmCode[0] = 0x39a0
  1915.                             + (((Word)OpSize + 1) << 14)
  1916.                             + ((AdrMode & 0xf0) << 5)
  1917.                             + (AdrMode & 15);
  1918.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1919.                 WAsmCode[1 + (AdrCnt >> 1)] = 0x4000
  1920.                                             + (AdrVals2[0] & 0x1fff)
  1921.                                             + (IsSigned << 13);
  1922.                 CodeLen = 4 + AdrCnt;
  1923.               }
  1924.               else WrError(ErrNum_InvAddrMode);
  1925.               break;
  1926.             default:
  1927.               WrError(ErrNum_InvFormat);
  1928.           }
  1929.         }
  1930.       }
  1931.     }
  1932.   }
  1933. }
  1934.  
  1935. static void DecodeString(Word Code)
  1936. {
  1937.   Byte Reg;
  1938.   int Cnt;
  1939.   tSymbolSize Size;
  1940.  
  1941.   if (!ChkArgCnt(3, 3));
  1942.   else if (!DecodeReg(&ArgStr[3], &Reg, &Size, True));
  1943.   else if (Size != eSymbolSize16Bit) WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[3]);
  1944.   else
  1945.   {
  1946.     Reg &= 0x3f;
  1947.     DecodeAdr(&ArgStr[2], 0, eImmYes, True);
  1948.     if (AdrOK)
  1949.     {
  1950.       LongInt ImmValue = IsImmediate() ? ImmVal() : 0;
  1951.  
  1952.       WAsmCode[0] = 0x700;
  1953.       if ((IsImmediate()) && (ImmValue < 127) && (ImmValue > LowLim8))
  1954.       {
  1955.         AdrMode = ImmValue & 0xff;
  1956.         AdrCnt = 0;
  1957.       }
  1958.       else
  1959.         WAsmCode[0] += 0x800;
  1960.       WAsmCode[0] += AdrMode;
  1961.       memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  1962.       Cnt = AdrCnt;
  1963.       DecodeAdr(&ArgStr[1], 1, eImmYes, True);
  1964.       if (AdrOK)
  1965.       {
  1966.         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1967.         else
  1968.         {
  1969.           WAsmCode[0] += ((Word)OpSize + 1) << 14;
  1970.           WAsmCode[1 + (Cnt >> 1)] = 0x8000 + AdrMode + (Code << 8) + (((Word)Reg) << 11);
  1971.           memcpy(WAsmCode + 2 + (Cnt >> 1), AdrVals, AdrCnt);
  1972.           CodeLen = 4 + AdrCnt + Cnt;
  1973.         }
  1974.       }
  1975.     }
  1976.   }
  1977. }
  1978.  
  1979. static void DecodeEX(Word Code)
  1980. {
  1981.   UNUSED(Code);
  1982.  
  1983.   if (ChkArgCnt(2, 2))
  1984.   {
  1985.     DecodeAdr(&ArgStr[1], 1, eImmNo, True);
  1986.     if (AdrOK)
  1987.     {
  1988.       CopyAdr();
  1989.       DecodeAdr(&ArgStr[2], 0, eImmNo, True);
  1990.       if (AdrOK)
  1991.       {
  1992.         if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  1993.         else
  1994.         {
  1995.           if (Format == ' ')
  1996.           {
  1997.             if ((IsReg()) && (Is2Reg()))
  1998.               Format = 'S';
  1999.             else
  2000.               Format = DecideGA();
  2001.           }
  2002.           switch (Format)
  2003.           {
  2004.             case 'G':
  2005.               WAsmCode[0] = 0x0f00 + (((Word)OpSize + 1) << 14) + AdrMode;
  2006.               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  2007.               WAsmCode[1 + (AdrCnt >> 1)] = 0x8f00 + AdrMode2;
  2008.               memcpy(WAsmCode + 2 + (AdrCnt >> 1), AdrVals2, AdrCnt2);
  2009.               CodeLen = 4 + AdrCnt + AdrCnt2;
  2010.               break;
  2011.             case 'A':
  2012.               if ((IsAbsolute()) && (Is2Short()))
  2013.               {
  2014.                 Convert2Short();
  2015.                 WAsmCode[0] = 0x3980
  2016.                             + (((Word)OpSize + 1) << 14)
  2017.                             + ((AdrMode2 & 0xf0) << 5)
  2018.                             + (AdrMode2 & 15);
  2019.                 memcpy(WAsmCode + 1, AdrVals2, AdrCnt2);
  2020.                 WAsmCode[1 + (AdrCnt2 >> 1)] = AdrVals[0];
  2021.                 CodeLen = 4 + AdrCnt2;
  2022.               }
  2023.               else if ((Is2Absolute()) && (IsShort()))
  2024.               {
  2025.                 ConvertShort();
  2026.                 WAsmCode[0] = 0x3900
  2027.                             + (((Word)OpSize + 1) << 14)
  2028.                             + ((AdrMode & 0xf0) << 5)
  2029.                             + (AdrMode & 15);
  2030.                 memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  2031.                 WAsmCode[1 + (AdrCnt >> 1)] = AdrVals2[0];
  2032.                 CodeLen = 4 + AdrCnt;
  2033.               }
  2034.               else WrError(ErrNum_InvAddrMode);
  2035.               break;
  2036.             case 'S':
  2037.               if ((IsReg()) && (Is2Reg()))
  2038.               {
  2039.                 WAsmCode[0] = 0x3e00
  2040.                             + (((Word)OpSize + 1) << 14)
  2041.                             + (AdrMode2 << 4)
  2042.                             + AdrMode;
  2043.                 CodeLen = 2;
  2044.               }
  2045.               else WrError(ErrNum_InvAddrMode);
  2046.               break;
  2047.             default:
  2048.               WrError(ErrNum_InvFormat);
  2049.           }
  2050.         }
  2051.       }
  2052.     }
  2053.   }
  2054. }
  2055.  
  2056. static void DecodeCALR_JR(Word Code)
  2057. {
  2058.   if (!ChkArgCnt(1, 1));
  2059.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2060.   else
  2061.   {
  2062.     LongInt AdrInt;
  2063.     Boolean OK, ForcePrefix = False;
  2064.  
  2065.     AdrInt = EvalStrIntExpressionOffs(&ArgStr[1], CheckForcePrefix(ArgStr[1].str.p_str, &ForcePrefix), Int32, &OK) - EProgCounter();
  2066.     if ((OK) && (AddRelPrefix(0, 13, &AdrInt, ForcePrefix)))
  2067.     {
  2068.       if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
  2069.       else
  2070.       {
  2071.         WAsmCode[0] = Code + (AdrInt & 0x1ffe);
  2072.         CodeLen = 2;
  2073.       }
  2074.     }
  2075.   }
  2076. }
  2077.  
  2078. static void DecodeJRC(Word Code)
  2079. {
  2080.   UNUSED(Code);
  2081.  
  2082.   if (!ChkArgCnt(2, 2));
  2083.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2084.   else
  2085.   {
  2086.     Word Condition;
  2087.  
  2088.     if (!DecodeCondition(ArgStr[1].str.p_str, &Condition)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  2089.     else
  2090.     {
  2091.       LongInt AdrInt;
  2092.       Boolean OK, ForcePrefix = False;
  2093.  
  2094.       Condition %= 16;
  2095.       AdrInt = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].str.p_str, &ForcePrefix), Int32, &OK) - EProgCounter();
  2096.       if ((OK) && (AddRelPrefix(0, 9, &AdrInt, ForcePrefix)))
  2097.       {
  2098.         if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
  2099.         else
  2100.         {
  2101.           WAsmCode[0] = 0x1000 + ((Condition & 14) << 8) + (AdrInt & 0x1fe) + (Condition & 1);
  2102.           CodeLen = 2;
  2103.         }
  2104.       }
  2105.     }
  2106.   }
  2107. }
  2108.  
  2109. static void DecodeJRBC_JRBS(Word Code)
  2110. {
  2111.   if (!ChkArgCnt(3, 3));
  2112.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2113.   else
  2114.   {
  2115.     int z;
  2116.     Boolean OK;
  2117.  
  2118.     z = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
  2119.     if (OK)
  2120.     {
  2121.       Boolean AdrLongPrefix = False;
  2122.       LongInt AdrLong;
  2123.  
  2124.       AdrLong = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].str.p_str, &AdrLongPrefix), Int24, &OK);
  2125.       if (OK)
  2126.       {
  2127.         LongInt AdrInt;
  2128.         Boolean AdrIntPrefix = False;
  2129.  
  2130.         AddAbsPrefix(1, 13, AdrLong, AdrLongPrefix);
  2131.         AdrInt = EvalStrIntExpressionOffs(&ArgStr[3], CheckForcePrefix(ArgStr[3].str.p_str, &AdrIntPrefix), Int32, &OK) - EProgCounter();
  2132.         if ((OK) && (AddRelPrefix(0, 9, &AdrInt, AdrIntPrefix)))
  2133.         {
  2134.           if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
  2135.           else
  2136.           {
  2137.             CodeLen = 4;
  2138.             WAsmCode[1] = (z << 13) + (AdrLong & 0x1fff);
  2139.             WAsmCode[0] = Code + (AdrInt & 0x1fe);
  2140.           }
  2141.         }
  2142.       }
  2143.     }
  2144.   }
  2145. }
  2146.  
  2147. static void DecodeDJNZ(Word Code)
  2148. {
  2149.   UNUSED(Code);
  2150.  
  2151.   if (ChkArgCnt(2, 2))
  2152.   {
  2153.     DecodeAdr(&ArgStr[1], 0, eImmNo, True);
  2154.     if (AdrOK)
  2155.     {
  2156.       if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
  2157.       else
  2158.       {
  2159.         LongInt AdrInt;
  2160.         Boolean OK, ForcePrefix = False;
  2161.  
  2162.         AdrInt = EvalStrIntExpressionOffs(&ArgStr[2], CheckForcePrefix(ArgStr[2].str.p_str, &ForcePrefix), Int32, &OK) - (EProgCounter() + 4 + AdrCnt +2 * Ord(PrefUsed[0]));
  2163.         if ((OK) && (AddRelPrefix(1, 13, &AdrInt, ForcePrefix)))
  2164.         {
  2165.           if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
  2166.           else
  2167.           {
  2168.             WAsmCode[0] = 0x3700 + (((Word)OpSize + 1) << 14) + AdrMode;
  2169.             memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  2170.             WAsmCode[1 + (AdrCnt >> 1)] = 0xe000 + (AdrInt & 0x1ffe);
  2171.             CodeLen = 4 + AdrCnt;
  2172.           }
  2173.         }
  2174.       }
  2175.     }
  2176.   }
  2177. }
  2178.  
  2179. static void DecodeDJNZC(Word Code)
  2180. {
  2181.   UNUSED(Code);
  2182.  
  2183.   if (ChkArgCnt(3, 3))
  2184.   {
  2185.     Word Condition;
  2186.  
  2187.     if (!DecodeCondition(ArgStr[2].str.p_str, &Condition)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[2]);
  2188.     else
  2189.     {
  2190.       Condition %= 16;
  2191.       DecodeAdr(&ArgStr[1], 0, eImmNo, True);
  2192.       if (AdrOK)
  2193.       {
  2194.         if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
  2195.         else
  2196.         {
  2197.           Boolean OK, ForcePrefix = False;
  2198.           LongInt AdrInt;
  2199.  
  2200.           AdrInt = EvalStrIntExpressionOffs(&ArgStr[3], CheckForcePrefix(ArgStr[3].str.p_str, &ForcePrefix), Int32, &OK) - EProgCounter();
  2201.           if ((OK) && (AddRelPrefix(1, 13, &AdrInt, ForcePrefix)))
  2202.           {
  2203.             if (Odd(AdrInt)) WrError(ErrNum_DistIsOdd);
  2204.             else
  2205.             {
  2206.               WAsmCode[0] = 0x3700 + (((Word)OpSize+1) << 14) + AdrMode;
  2207.               memcpy(WAsmCode + 1, AdrVals, AdrCnt);
  2208.               WAsmCode[1 + (AdrCnt >> 1)] = ((Condition & 14) << 12) + (AdrInt & 0x1ffe) + (Condition & 1);
  2209.               CodeLen =4 + AdrCnt;
  2210.             }
  2211.           }
  2212.         }
  2213.       }
  2214.     }
  2215.   }
  2216. }
  2217.  
  2218. static void DecodeLINK_RETD(Word Code)
  2219. {
  2220.   if (!ChkArgCnt(1, 1));
  2221.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2222.   else
  2223.   {
  2224.     LongInt AdrInt;
  2225.     Boolean OK, ForcePrefix = False;
  2226.     tSymbolFlags Flags;
  2227.  
  2228.     AdrInt = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], CheckForcePrefix(ArgStr[1].str.p_str, &ForcePrefix), Int32, &OK, &Flags);
  2229.     if (mFirstPassUnknown(Flags))
  2230.       AdrInt &= 0x1fe;
  2231.     if (ChkRange(AdrInt, -0x80000, 0x7ffff))
  2232.     {
  2233.       if (Odd(AdrInt)) WrError(ErrNum_NotAligned);
  2234.       else
  2235.       {
  2236.         WAsmCode[0] = Code + (AdrInt & 0x1fe);
  2237.         AddSignedPrefix(0, 9, AdrInt, ForcePrefix);
  2238.         CodeLen = 2;
  2239.       }
  2240.     }
  2241.   }
  2242. }
  2243.  
  2244. static void DecodeSWI(Word Code)
  2245. {
  2246.   UNUSED(Code);
  2247.  
  2248.   if (!ChkArgCnt(1, 1));
  2249.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2250.   else
  2251.   {
  2252.     Boolean OK;
  2253.  
  2254.     WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], Int4, &OK) + 0x7f90;
  2255.     if (OK)
  2256.       CodeLen = 2;
  2257.   }
  2258. }
  2259.  
  2260. static void DecodeLDA(Word Code)
  2261. {
  2262.   UNUSED(Code);
  2263.  
  2264.   if (ChkArgCnt(2, 2))
  2265.   {
  2266.     DecodeAdr(&ArgStr[2], 0, eImmNo, False);
  2267.     if (AdrOK)
  2268.     {
  2269.       int z;
  2270.  
  2271.       WAsmCode[0] = 0x3000 + AdrMode;
  2272.       z = AdrCnt;
  2273.       memcpy(WAsmCode + 1, AdrVals, z);
  2274.       DecodeAdr(&ArgStr[1], 1, eImmNo, True);
  2275.       if (AdrOK)
  2276.       {
  2277.         if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
  2278.         else
  2279.         {
  2280.           WAsmCode[0] += ((Word)OpSize) << 14;
  2281.           WAsmCode[1 + (z >> 1)] = 0x9700 + AdrMode;
  2282.           memcpy(WAsmCode + 2 + (z >> 1), AdrVals, AdrCnt);
  2283.           CodeLen = 4 + z + AdrCnt;
  2284.         }
  2285.       }
  2286.     }
  2287.   }
  2288. }
  2289.  
  2290. /*--------------------------------------------------------------------------*/
  2291.  
  2292. static void AddFixed(const char *NName, Word NCode)
  2293. {
  2294.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  2295. }
  2296.  
  2297. static void AddRMW(const char *NName, Byte NCode, Byte NMask)
  2298. {
  2299.   order_array_rsv_end(RMWOrders, RMWOrder);
  2300.   RMWOrders[InstrZ].Mask = NMask;
  2301.   RMWOrders[InstrZ].Code = NCode;
  2302.   AddInstTable(InstTable, NName, InstrZ++, DecodeRMW);
  2303. }
  2304.  
  2305. static void AddGAEq(const char *NName, Word NCode)
  2306. {
  2307.   AddInstTable(InstTable, NName, NCode, DecodeGAEq);
  2308. }
  2309.  
  2310. static void AddGAHalf(const char *NName, Word NCode)
  2311. {
  2312.   AddInstTable(InstTable, NName, NCode, DecodeGAHalf);
  2313. }
  2314.  
  2315. static void AddGAFirst(const char *NName, Word NCode)
  2316. {
  2317.   AddInstTable(InstTable, NName, NCode, DecodeGAFirst);
  2318. }
  2319.  
  2320. static void AddGASecond(const char *NName, Word NCode)
  2321. {
  2322.   AddInstTable(InstTable, NName, NCode, DecodeGASecond);
  2323. }
  2324.  
  2325. static void InitFields(void)
  2326. {
  2327.   InstTable = CreateInstTable(301);
  2328.  
  2329.   add_null_pseudo(InstTable);
  2330.  
  2331.   AddInstTable(InstTable, "RLM", 0x0400, DecodeRLM_RRM);
  2332.   AddInstTable(InstTable, "RRM", 0x0500, DecodeRLM_RRM);
  2333.   AddInstTable(InstTable, "CHK", 0, DecodeCHK_CHKS);
  2334.   AddInstTable(InstTable, "CHKS", 1, DecodeCHK_CHKS);
  2335.   AddInstTable(InstTable, "EX", 0, DecodeEX);
  2336.   AddInstTable(InstTable, "CALR", 0x2001, DecodeCALR_JR);
  2337.   AddInstTable(InstTable, "JR", 0x2000, DecodeCALR_JR);
  2338.   AddInstTable(InstTable, "JRC", 0, DecodeJRC);
  2339.   AddInstTable(InstTable, "JRBC", 0x1e00, DecodeJRBC_JRBS);
  2340.   AddInstTable(InstTable, "JRBS", 0x1e01, DecodeJRBC_JRBS);
  2341.   AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ);
  2342.   AddInstTable(InstTable, "DJNZC", 0, DecodeDJNZC);
  2343.   AddInstTable(InstTable, "LINK", 0xc001, DecodeLINK_RETD);
  2344.   AddInstTable(InstTable, "RETD", 0xc801, DecodeLINK_RETD);
  2345.   AddInstTable(InstTable, "SWI", 0, DecodeSWI);
  2346.   AddInstTable(InstTable, "LDA", 0, DecodeLDA);
  2347.   AddInstTable(InstTable, "REG", 0, CodeREG);
  2348.  
  2349.   AddFixed("CCF" , 0x7f82);
  2350.   AddFixed("CSF" , 0x7f8a);
  2351.   AddFixed("CVF" , 0x7f86);
  2352.   AddFixed("CZF" , 0x7f8e);
  2353.   AddFixed("DI"  , 0x7fa1);
  2354.   AddFixed("EI"  , 0x7fa3);
  2355.   AddFixed("HALT", 0x7fa5);
  2356.   AddFixed("NOP" , 0x7fa0);
  2357.   AddFixed("RCF" , 0x7f80);
  2358.   AddFixed("RET" , 0x7fa4);
  2359.   AddFixed("RETI", 0x7fa9);
  2360.   AddFixed("RETS", 0x7fab);
  2361.   AddFixed("RSF" , 0x7f88);
  2362.   AddFixed("RVF" , 0x7f84);
  2363.   AddFixed("RZF" , 0x7f8c);
  2364.   AddFixed("SCF" , 0x7f81);
  2365.   AddFixed("SSF" , 0x7f89);
  2366.   AddFixed("SVF" , 0x7f85);
  2367.   AddFixed("SZF" , 0x7f8b);
  2368.   AddFixed("UNLK", 0x7fa2);
  2369.  
  2370.   InstrZ = 0;
  2371.   AddRMW("CALL" , 0x35, 0x36);
  2372.   AddRMW("CLR"  , 0x2b, 0x17);
  2373.   AddRMW("CPL"  , 0x28, 0x17);
  2374.   AddRMW("EXTS" , 0x33, 0x16);
  2375.   AddRMW("EXTZ" , 0x32, 0x16);
  2376.   AddRMW("JP"   , 0x34, 0x36);
  2377.   AddRMW("MIRR" , 0x23, 0x17);
  2378.   AddRMW("NEG"  , 0x29, 0x17);
  2379.   AddRMW("POP"  , 0x20, 0x17);
  2380.   AddRMW("PUSH" , 0x21, 0x07);
  2381.   AddRMW("PUSHA", 0x31, 0x36);
  2382.   AddRMW("RVBY" , 0x22, 0x17);
  2383.   AddRMW("TJP"  , 0x36, 0x16);
  2384.   AddRMW("TST"  , 0x2a, 0x17);
  2385.  
  2386.   InstrZ = 0;
  2387.   AddInstTable(InstTable, "ADD", InstrZ++, DecodeGASI1);
  2388.   AddInstTable(InstTable, "SUB", InstrZ++, DecodeGASI1);
  2389.   AddInstTable(InstTable, "CP" , InstrZ++, DecodeGASI1);
  2390.   AddInstTable(InstTable, "LD" , InstrZ++, DecodeGASI1);
  2391.  
  2392.   InstrZ = 0;
  2393.   AddInstTable(InstTable, "AND", InstrZ++, DecodeGASI2);
  2394.   AddInstTable(InstTable, "OR" , InstrZ++, DecodeGASI2);
  2395.   AddInstTable(InstTable, "XOR", InstrZ++, DecodeGASI2);
  2396.  
  2397.   InstrZ = 0;
  2398.   AddInstTable(InstTable, "ADD3", InstrZ++, DecodeTrinom);
  2399.   AddInstTable(InstTable, "SUB3", InstrZ++, DecodeTrinom);
  2400.   AddInstTable(InstTable, "MAC" , InstrZ++, DecodeTrinom);
  2401.   AddInstTable(InstTable, "MACS", InstrZ++, DecodeTrinom);
  2402.  
  2403.   InstrZ = 0;
  2404.   AddInstTable(InstTable, "BRES", InstrZ++, DecodeBit);
  2405.   AddInstTable(InstTable, "BSET", InstrZ++, DecodeBit);
  2406.   AddInstTable(InstTable, "BCHG", InstrZ++, DecodeBit);
  2407.   AddInstTable(InstTable, "BTST", InstrZ++, DecodeBit);
  2408.  
  2409.   InstrZ = 0;
  2410.   AddInstTable(InstTable, "SLL", InstrZ++, DecodeShift);
  2411.   AddInstTable(InstTable, "SRL", InstrZ++, DecodeShift);
  2412.   AddInstTable(InstTable, "SLA", InstrZ++, DecodeShift);
  2413.   AddInstTable(InstTable, "SRA", InstrZ++, DecodeShift);
  2414.   AddInstTable(InstTable, "RL" , InstrZ++, DecodeShift);
  2415.   AddInstTable(InstTable, "RR" , InstrZ++, DecodeShift);
  2416.   AddInstTable(InstTable, "RLC", InstrZ++, DecodeShift);
  2417.   AddInstTable(InstTable, "RRC", InstrZ++, DecodeShift);
  2418.  
  2419.   InstrZ = 0;
  2420.   AddInstTable(InstTable, "BFEX" , InstrZ++, DecodeBField);
  2421.   AddInstTable(InstTable, "BFEXS", InstrZ++, DecodeBField);
  2422.   AddInstTable(InstTable, "BFIN" , InstrZ++, DecodeBField);
  2423.  
  2424.   AddGAEq("ABCD" , 0x0110);
  2425.   AddGAEq("ADC"  , 0x0004);
  2426.   AddGAEq("CBCD" , 0x0112);
  2427.   AddGAEq("CPC"  , 0x0006);
  2428.   AddGAEq("MAX"  , 0x0116);
  2429.   AddGAEq("MAXS" , 0x0017);
  2430.   AddGAEq("MIN"  , 0x0114);
  2431.   AddGAEq("MINS" , 0x0015);
  2432.   AddGAEq("SBC"  , 0x0105);
  2433.   AddGAEq("SBCD" , 0x0111);
  2434.  
  2435.   AddGAHalf("DIV"  , 0x26);
  2436.   AddGAHalf("DIVS" , 0x27);
  2437.   AddGAHalf("MUL"  , 0x24);
  2438.   AddGAHalf("MULS" , 0x25);
  2439.  
  2440.   AddGAFirst("ANDCF", 0x44);
  2441.   AddGAFirst("LDCF" , 0x47);
  2442.   AddGAFirst("ORCF" , 0x45);
  2443.   AddGAFirst("STCF" , 0x43);
  2444.   AddGAFirst("TSET" , 0x70);
  2445.   AddGAFirst("XORCF", 0x46);
  2446.  
  2447.   AddGASecond("BS0B" , 0x54);
  2448.   AddGASecond("BS0F" , 0x55);
  2449.   AddGASecond("BS1B" , 0x56);
  2450.   AddGASecond("BS1F" , 0x57);
  2451.  
  2452.   AddInstTable(InstTable, "CPSZ", 0, DecodeString);
  2453.   AddInstTable(InstTable, "CPSN", 1, DecodeString);
  2454.   AddInstTable(InstTable, "LDS" , 3, DecodeString);
  2455.  
  2456.   AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
  2457. }
  2458.  
  2459. static void DeinitFields(void)
  2460. {
  2461.   DestroyInstTable(InstTable);
  2462.  
  2463.   order_array_free(RMWOrders);
  2464. }
  2465.  
  2466. static Boolean DecodeAttrPart_97C241(void)
  2467. {
  2468.   char *p;
  2469.  
  2470.   switch (AttrSplit)
  2471.   {
  2472.     case '.':
  2473.       p = strchr(AttrPart.str.p_str, ':');
  2474.       if (p)
  2475.       {
  2476.         Format = (p < AttrPart.str.p_str + strlen(AttrPart.str.p_str) - 1) ? p[1] : ' ';
  2477.         *p = '\0';
  2478.       }
  2479.       else
  2480.         Format = ' ';
  2481.       break;
  2482.     case ':':
  2483.       p = strchr(AttrPart.str.p_str, '.');
  2484.       if (!p)
  2485.       {
  2486.         Format = (*AttrPart.str.p_str);
  2487.         *AttrPart.str.p_str = '\0';
  2488.       }
  2489.       else
  2490.       {
  2491.         Format = (p == AttrPart.str.p_str) ? ' ' : *AttrPart.str.p_str;
  2492.         strmov(AttrPart.str.p_str, p + 1);
  2493.       }
  2494.       break;
  2495.     default:
  2496.       Format = ' ';
  2497.   }
  2498.   Format = as_toupper(Format);
  2499.  
  2500.   if (*AttrPart.str.p_str)
  2501.     switch (as_toupper(*AttrPart.str.p_str))
  2502.     {
  2503.       case 'B':
  2504.         AttrPartOpSize[0] = eSymbolSize8Bit;
  2505.         break;
  2506.       case 'W':
  2507.         AttrPartOpSize[0] = eSymbolSize16Bit;
  2508.         break;
  2509.       case 'D':
  2510.         AttrPartOpSize[0] = eSymbolSize32Bit;
  2511.         break;
  2512.       default:
  2513.        WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  2514.        return False;
  2515.     }
  2516.   return True;
  2517. }
  2518.  
  2519. static void MakeCode_97C241(void)
  2520. {
  2521.   PrefUsed[0] = False;
  2522.   PrefUsed[1] = False;
  2523.   AdrInc = 0;
  2524.   MinOneIs0 = False;
  2525.   LowLim4 = -8; LowLim8 = -128;
  2526.  
  2527.   OpSize = AttrPartOpSize[0];
  2528.  
  2529.   if (LookupInstTable(InstTable, OpPart.str.p_str))
  2530.   {
  2531.     AddPrefixes();
  2532.     return;
  2533.   }
  2534.  
  2535.   WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2536. }
  2537.  
  2538. /*!------------------------------------------------------------------------
  2539.  * \fn     InternSymbol_97C241(char *pArg, TempResult *pResult)
  2540.  * \brief  handle built-in symbols on TLCS-9000
  2541.  * \param  pArg source argument
  2542.  * \param  pResult result buffer
  2543.  * ------------------------------------------------------------------------ */
  2544.  
  2545. static void InternSymbol_97C241(char *pArg, TempResult *pResult)
  2546. {
  2547.   Byte Reg;
  2548.   tSymbolSize Size;
  2549.  
  2550.   if (DecodeRegCore(pArg, &Reg, &Size))
  2551.   {
  2552.     pResult->Typ = TempReg;
  2553.     pResult->DataSize = Size;
  2554.     pResult->Contents.RegDescr.Reg = Reg;
  2555.     pResult->Contents.RegDescr.Dissect = DissectReg_97C241;
  2556.     pResult->Contents.RegDescr.compare = NULL;
  2557.   }
  2558. }
  2559.  
  2560. static Boolean IsDef_97C241(void)
  2561. {
  2562.   return Memo("REG");
  2563. }
  2564.  
  2565. static void SwitchFrom_97C241(void)
  2566. {
  2567.   DeinitFields();
  2568. }
  2569.  
  2570. static void SwitchTo_97C241(void)
  2571. {
  2572.   TurnWords = False;
  2573.   SetIntConstMode(eIntConstModeIntel);
  2574.  
  2575.   PCSymbol = "$";
  2576.   HeaderID = 0x56;
  2577.   NOPCode = 0x7fa0;
  2578.   DivideChars = ",";
  2579.   HasAttrs = True;
  2580.   AttrChars = ".:";
  2581.  
  2582.   ValidSegs = 1 << SegCode;
  2583.   Grans[SegCode] = 1;
  2584.   ListGrans[SegCode] = 2;
  2585.   SegInits[SegCode] = 0;
  2586.   SegLimits[SegCode] = 0xffffffl;
  2587.  
  2588.   DecodeAttrPart = DecodeAttrPart_97C241;
  2589.   MakeCode = MakeCode_97C241;
  2590.   IsDef = IsDef_97C241;
  2591.   InternSymbol = InternSymbol_97C241;
  2592.   DissectReg = DissectReg_97C241;
  2593.   SwitchFrom = SwitchFrom_97C241;
  2594.   InitFields();
  2595. }
  2596.  
  2597. void code97c241_init(void)
  2598. {
  2599.   CPU97C241 = AddCPU("97C241", SwitchTo_97C241);
  2600. }
  2601.