Subversion Repositories pentevo

Rev

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

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